Przejdź do treści

olski.skład.słownik

Przestrzenie nazw nad składnią: lemat jako nazwa, a nie jako łańcuch.

To jest cała zdejmowalna warstwa tego pakietu. Operatory stoją w olski.skład.składnia, bo są zapisem konstruktorów, a tutaj zostaje to, co da się odjąć, nie tracąc języka. Import tego modułu nie zmienia zachowania tamtego i tę własność trzyma test.

Zdanie zostaje wywołaniem, choć grupa imienna dostaje operatory. Powód jest jeden: zdanie ma role, a role czyta się z nazw. Zapis operatorowy kazałby czytać je z kolejności oraz z pierwszeństwa działań, którego ten język nie projektował.

Nazw nie brakuje za to łańcuchowi metod po zdaniu, czyli zapisowi V.zejść(kto).którędy_po(~R.schody), i on odpada z dwóch powodów. Relacja i słowo są dwiema osiami, które autor wybiera osobno, bo Gdzie.w i Dokąd.w są dwiema rzeczami do powiedzenia pisanymi jednym przyimkiem, a nazwa metody zwija te osie w jedną listę nazw w rodzaju gdzie_w. Drugiego nie widać w zapisie, tylko w tym, co z nim robi ruff format: znacznik tematu nie ma w takim łańcuchu czego wyróżnić poza tym, co dopisano ostatnio, więc staje się pozycyjny, a formater dokleja go do wywołania następnego, i wtedy źródło wyróżnia co innego, niż wygląda, że wyróżnia. Znacznik przyrostkowy tego nie ma, bo nie sięga poza konstytuent, przy którym stoi, i stoi razem z operatorami w olski.skład.składnia.

Wielka litera odróżnia tu kategorię od funkcji, która coś nad argumentem liczy. Funkcja składa listę, zwija człon do samego siebie albo dokłada domyślną liczbę, a kategoria mówi tylko, czym konstytuent jest, więc zostaje klasą wołaną wprost: druga nazwa dla jednego konstruktora nie kupiłaby nic poza małą literą.

Zwykłe konstrukcje Pythona są tu częścią zapisu, a nie obejściem. Zmienna nazywa poddrzewo i pozwala postawić je w dwóch zdaniach. Funkcja jest wzorcem zdania, a funkcja zwracająca listę jest wzorcem akapitu. Lista wchodzi do zdania przez razem, więc człony koordynacji mogą powstać z tego, co program dopiero policzył. To jest cała odpowiedź tej biblioteki na pytanie, skąd wziąć powtórzenie i abstrakcję.

__all__ = ['A', 'Czym', 'D', 'Dlaczego', 'Dokąd', 'Gdzie', 'Kiedy', 'Którędy', 'R', 'Skutek', 'Skąd', 'Treść', 'V', 'jest', 'komu', 'nie', 'opis', 'potem', 'razem'] module-attribute

R = Słownik(Rzecz) module-attribute

A = Słownik(Cecha) module-attribute

V = Czyny() module-attribute

D = Słownik(Przysłówek) module-attribute

Gdzie = Okoliczności('miejsce') module-attribute

Dokąd = Okoliczności('cel') module-attribute

Skąd = Okoliczności('źródło') module-attribute

Którędy = Okoliczności('droga') module-attribute

Kiedy = Okoliczności('czas') module-attribute

Dlaczego = Okoliczności('przyczyna') module-attribute

Czym = Okoliczności('narzędzie') module-attribute

Skutek = Okoliczności('skutek') module-attribute

Treść dataclass

To, co ktoś mówi, wie albo w co nie wierzy: zdarzenie jako uczestnik.

Kategorią dziedziny jest tu treść, a nie zdanie podrzędne, i zawinięcie jest potrzebne, bo drzewo samo tej różnicy nie niesie. V.chcieć(kot, V.spać(kot)) i V.wiedzieć(kot, Treść(V.spać(kot))) stawiają pod czasownikiem to samo zdarzenie i mówią dwie różne rzeczy, więc nie ma jak policzyć tego z tego, kto w zdarzeniu działa. Po co ta kategoria jest opowieści, mówi docs/kategorie-zapisu.md.

Zdaniem ta klasa nie jest, choć zdanie w sobie trzyma, i jest to rozstrzygnięcie, a nie wygoda dziedziczenia. Zdaniem jest to, co orzeka o kimś, a treść o nikim nie orzeka: stoi w roli uczestnika i o tym, kto ją niesie, mówi czasownik nad nią. Gdyby zdaniem była, Okolicznik wpuściłby ją tam, gdzie czeka na zdarzenie, i wypuścił gdy że, czyli dwa spójniki jeden po drugim.

Pól ta klasa nie ma poza objętym zdaniem i każde z brakujących ma swój powód. Kontroli nie ma czego zapisywać, bo zdanie podrzędne niesie podmiot własny, a przeczenia tym bardziej: dopełniacz negacji przez tę pozycję nie sięga, bo zdanie podrzędne rozdaje przypadki własne. Idzie to samo z siebie, bo Kontekst.podrzędne nie przekazuje w dół ani wykonawcy, ani przeczenia, i jest to ta sama metoda, która puszcza czas. Wyróżnienia ta klasa nie przyjmuje, bo pozycję ma jedną i wziętą z polszczyzny, a nie z tego, o czym zdanie jest; rozstrzyga o niej _miejsce niżej.

Source code in olski/skład/składnia.py
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
@dataclass(frozen=True)
class Treść:
    """To, co ktoś mówi, wie albo w co nie wierzy: zdarzenie jako uczestnik.

    Kategorią dziedziny jest tu treść, a nie zdanie podrzędne,
    i zawinięcie jest potrzebne, bo drzewo samo tej różnicy nie niesie.
    ``V.chcieć(kot, V.spać(kot))`` i ``V.wiedzieć(kot, Treść(V.spać(kot)))``
    stawiają pod czasownikiem to samo zdarzenie i mówią dwie różne rzeczy,
    więc nie ma jak policzyć tego z tego, kto w zdarzeniu działa.
    Po co ta kategoria jest opowieści, mówi ``docs/kategorie-zapisu.md``.

    Zdaniem ta klasa nie jest, choć zdanie w sobie trzyma,
    i jest to rozstrzygnięcie, a nie wygoda dziedziczenia.
    Zdaniem jest to, co orzeka o kimś, a treść o nikim nie orzeka:
    stoi w roli uczestnika i o tym, kto ją niesie, mówi czasownik nad nią.
    Gdyby zdaniem była, ``Okolicznik`` wpuściłby ją tam, gdzie czeka na zdarzenie,
    i wypuścił `gdy że`, czyli dwa spójniki jeden po drugim.

    Pól ta klasa nie ma poza objętym zdaniem i każde z brakujących ma swój powód.
    Kontroli nie ma czego zapisywać, bo zdanie podrzędne niesie podmiot własny,
    a przeczenia tym bardziej: dopełniacz negacji przez tę pozycję nie sięga,
    bo zdanie podrzędne rozdaje przypadki własne.
    Idzie to samo z siebie, bo ``Kontekst.podrzędne`` nie przekazuje w dół
    ani wykonawcy, ani przeczenia, i jest to ta sama metoda, która puszcza czas.
    Wyróżnienia ta klasa nie przyjmuje, bo pozycję ma jedną i wziętą z polszczyzny,
    a nie z tego, o czym zdanie jest; rozstrzyga o niej ``_miejsce`` niżej.
    """

    zdanie: Zdanie

    #: Spójnik, którym polszczyzna wprowadza treść orzekaną wprost. Stoi tu stałą,
    #: a nie w leksykonie jak słowo okoliczności, bo autor nie ma tu czego wybierać:
    #: ``żeby`` mówi, że tak ma być, czyli jest inną kategorią, i trzyma to ``todo/``.
    SŁOWO = "że"

    def linearyzuj(self, kontekst: Kontekst = TERAZ) -> Kawałek:
        return _podrzędne(self.SŁOWO, self.zdanie, kontekst)

zdanie instance-attribute

SŁOWO = 'że' class-attribute instance-attribute

linearyzuj(kontekst=TERAZ)

Source code in olski/skład/składnia.py
685
686
def linearyzuj(self, kontekst: Kontekst = TERAZ) -> Kawałek:
    return _podrzędne(self.SŁOWO, self.zdanie, kontekst)

__init__(zdanie)

Cecha dataclass

Przymiotnik, dopóki nie wiadomo, czego dotyczy.

Source code in olski/skład/słownik.py
86
87
88
89
90
91
92
93
94
95
96
97
98
@dataclass(frozen=True)
class Cecha:
    """Przymiotnik, dopóki nie wiadomo, czego dotyczy."""

    lemat: str

    def __mul__(self, inne):
        """Określenie: zwykły razy tekst daje zwykły tekst."""
        if isinstance(inne, Cecha):
            return Cechy((self, inne))
        if isinstance(inne, Byt):
            return Byt(Jaki(self.lemat, inne.rzecz), inne.number)
        return Jaki(self.lemat, inne)

lemat instance-attribute

__init__(lemat)

__mul__(inne)

Określenie: zwykły razy tekst daje zwykły tekst.

Source code in olski/skład/słownik.py
92
93
94
95
96
97
98
def __mul__(self, inne):
    """Określenie: zwykły razy tekst daje zwykły tekst."""
    if isinstance(inne, Cecha):
        return Cechy((self, inne))
    if isinstance(inne, Byt):
        return Byt(Jaki(self.lemat, inne.rzecz), inne.number)
    return Jaki(self.lemat, inne)

Cechy dataclass

Kilka przymiotników czekających na rzecz.

Klasa jest tu dlatego, że mnożenie wiąże w lewo, więc dwa przymiotniki spotykają się ze sobą, zanim spotkają rzeczownik.

Source code in olski/skład/słownik.py
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
@dataclass(frozen=True)
class Cechy:
    """Kilka przymiotników czekających na rzecz.

    Klasa jest tu dlatego, że mnożenie wiąże w lewo,
    więc dwa przymiotniki spotykają się ze sobą, zanim spotkają rzeczownik.
    """

    lematy: tuple[Cecha, ...]

    def __mul__(self, inne):
        if isinstance(inne, Cecha):
            return Cechy((*self.lematy, inne))
        wynik = inne
        for cecha in reversed(self.lematy):
            wynik = cecha * wynik
        return wynik

lematy instance-attribute

__init__(lematy)

__mul__(inne)

Source code in olski/skład/słownik.py
111
112
113
114
115
116
117
def __mul__(self, inne):
    if isinstance(inne, Cecha):
        return Cechy((*self.lematy, inne))
    wynik = inne
    for cecha in reversed(self.lematy):
        wynik = cecha * wynik
    return wynik

Słownik

Nazwa atrybutu jako lemat, zamiast lematu pisanego w cudzysłowie.

Leksykon jest otwarty, bo otwarty jest słownik pod spodem, więc ta przestrzeń nazw nie ma listy i nie sprawdza niczego: forma, której SGJP nie zna, zgłasza się dopiero przy linearyzacji.

Source code in olski/skład/słownik.py
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
class Słownik:
    """Nazwa atrybutu jako lemat, zamiast lematu pisanego w cudzysłowie.

    Leksykon jest otwarty, bo otwarty jest słownik pod spodem,
    więc ta przestrzeń nazw nie ma listy i nie sprawdza niczego:
    forma, której SGJP nie zna, zgłasza się dopiero przy linearyzacji.
    """

    def __init__(self, buduj) -> None:
        self._buduj = buduj

    def __getattr__(self, nazwa: str):
        if nazwa.startswith("_"):
            raise AttributeError(nazwa)
        return self._buduj(_lemat(nazwa))

__init__(buduj)

Source code in olski/skład/słownik.py
137
138
def __init__(self, buduj) -> None:
    self._buduj = buduj

__getattr__(nazwa)

Source code in olski/skład/słownik.py
140
141
142
143
def __getattr__(self, nazwa: str):
    if nazwa.startswith("_"):
        raise AttributeError(nazwa)
    return self._buduj(_lemat(nazwa))

Czyny

Czasownik jako wywołanie wraz z rolami: zapisywać przez kogo i co.

Rozdzielaniem argumentów zajmuje się zdarzenie w olski.skład.składnia, bo to jest składanie drzewa, a nie nazywanie go, i tutaj zostaje samo wzięcie lematu z nazwy atrybutu.

Source code in olski/skład/słownik.py
146
147
148
149
150
151
152
153
154
155
156
157
158
class Czyny:
    """Czasownik jako wywołanie wraz z rolami: zapisywać przez kogo i co.

    Rozdzielaniem argumentów zajmuje się ``zdarzenie`` w ``olski.skład.składnia``,
    bo to jest składanie drzewa, a nie nazywanie go,
    i tutaj zostaje samo wzięcie lematu z nazwy atrybutu.
    """

    def __getattr__(self, nazwa: str):
        if nazwa.startswith("_"):
            raise AttributeError(nazwa)
        lemat = _lemat(nazwa)
        return lambda kto, *reszta: zdarzenie(kto, lemat, *reszta)

__getattr__(nazwa)

Source code in olski/skład/słownik.py
154
155
156
157
158
def __getattr__(self, nazwa: str):
    if nazwa.startswith("_"):
        raise AttributeError(nazwa)
    lemat = _lemat(nazwa)
    return lambda kto, *reszta: zdarzenie(kto, lemat, *reszta)

Okoliczności

Słowo jako nazwa, w relacji, którą ta przestrzeń nazw trzyma.

Relacja jest tu wybrana raz, przy nazwie, bo to ona jest kategorią dziedziny, a przyimek albo spójnik jest tylko słowem, które tę relację po polsku wyraża. Gdzie.w i Dokąd.w są więc dwiema różnymi rzeczami do powiedzenia, choć piszą się jednym przyimkiem.

Relację bez słowa pisze się wywołaniem samej przestrzeni nazw, bo polszczyzna wyraża część relacji samym przypadkiem: Czym(R.lustro) daje lustrem, a Kiedy(R.wieczór) daje wieczorem. Osobnej funkcji na to nie ma i nie ma być: relacja bez przyimka jest tą samą kategorią co z nim, a każda taka funkcja byłaby drugą drogą do jednego konstruktora.

Rzecz i zdarzenie wchodzą jedną drogą, bo pytanie stawia się jedno: Kiedy.w(R.noc) i Kiedy.gdy(V.zgasnąć(świeca)) mówią, kiedy. Nic tu tych dwóch nie rozdziela, bo byt przepuszcza wszystko, co rzeczą nie jest, a co ze słowem zrobić, wie Okolicznik.

Source code in olski/skład/słownik.py
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
class Okoliczności:
    """Słowo jako nazwa, w relacji, którą ta przestrzeń nazw trzyma.

    Relacja jest tu wybrana raz, przy nazwie, bo to ona jest kategorią dziedziny,
    a przyimek albo spójnik jest tylko słowem, które tę relację po polsku wyraża.
    ``Gdzie.w`` i ``Dokąd.w`` są więc dwiema różnymi rzeczami do powiedzenia,
    choć piszą się jednym przyimkiem.

    Relację bez słowa pisze się wywołaniem samej przestrzeni nazw,
    bo polszczyzna wyraża część relacji samym przypadkiem:
    ``Czym(R.lustro)`` daje `lustrem`, a ``Kiedy(R.wieczór)`` daje `wieczorem`.
    Osobnej funkcji na to nie ma i nie ma być:
    relacja bez przyimka jest tą samą kategorią co z nim,
    a każda taka funkcja byłaby drugą drogą do jednego konstruktora.

    Rzecz i zdarzenie wchodzą jedną drogą, bo pytanie stawia się jedno:
    ``Kiedy.w(R.noc)`` i ``Kiedy.gdy(V.zgasnąć(świeca))`` mówią, kiedy.
    Nic tu tych dwóch nie rozdziela, bo ``byt`` przepuszcza wszystko,
    co rzeczą nie jest, a co ze słowem zrobić, wie ``Okolicznik``.
    """

    def __init__(self, relacja: str) -> None:
        self._relacja = relacja

    def __call__(self, co) -> Okolicznik:
        return Okolicznik("", self._relacja, byt(co))

    def __getattr__(self, nazwa: str):
        if nazwa.startswith("_"):
            raise AttributeError(nazwa)
        słowo = _lemat(nazwa)
        return lambda co: Okolicznik(słowo, self._relacja, byt(co))

__init__(relacja)

Source code in olski/skład/słownik.py
182
183
def __init__(self, relacja: str) -> None:
    self._relacja = relacja

__call__(co)

Source code in olski/skład/słownik.py
185
186
def __call__(self, co) -> Okolicznik:
    return Okolicznik("", self._relacja, byt(co))

__getattr__(nazwa)

Source code in olski/skład/słownik.py
188
189
190
191
192
def __getattr__(self, nazwa: str):
    if nazwa.startswith("_"):
        raise AttributeError(nazwa)
    słowo = _lemat(nazwa)
    return lambda co: Okolicznik(słowo, self._relacja, byt(co))

nie(zdanie)

To samo zdanie zaprzeczone.

Konstruktorem to nie jest, tylko zmianą jednej cechy zdania, bo zaprzeczone zdanie ma te same role co twierdzące i drugi konstruktor kazałby wypisać je jeszcze raz.

Sięga jednego orzeczenia, bo tyle znaczy nie w polszczyźnie, więc ciąg zdarzeń przeczy się zdarzenie po zdarzeniu, a nie w całości: Nie podniosła deski i nie zeszła po schodach.

Source code in olski/skład/składnia.py
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
def nie(zdanie: Jest | Robi) -> Jest | Robi:
    """To samo zdanie zaprzeczone.

    Konstruktorem to nie jest, tylko zmianą jednej cechy zdania,
    bo zaprzeczone zdanie ma te same role co twierdzące
    i drugi konstruktor kazałby wypisać je jeszcze raz.

    Sięga jednego orzeczenia, bo tyle znaczy ``nie`` w polszczyźnie,
    więc ciąg zdarzeń przeczy się zdarzenie po zdarzeniu,
    a nie w całości: `Nie podniosła deski i nie zeszła po schodach.`
    """
    return replace(zdanie, przeczenie=True)

razem(elementy)

Lista jako koordynacja: to, co w Pythonie stoi obok siebie, stoi obok siebie i w zdaniu.

Zapis ten zarabia na siebie tam, gdzie człony powstają z listy, bo & żąda ich wypisania jeden po drugim i nie ma jak wziąć ich z czegoś, co program dopiero policzył.

Source code in olski/skład/słownik.py
221
222
223
224
225
226
227
228
229
230
231
232
def razem(elementy) -> Rola:
    """Lista jako koordynacja: to, co w Pythonie stoi obok siebie, stoi obok siebie i w zdaniu.

    Zapis ten zarabia na siebie tam, gdzie człony powstają z listy,
    bo ``&`` żąda ich wypisania jeden po drugim
    i nie ma jak wziąć ich z czegoś, co program dopiero policzył.
    """
    człony = list(elementy)
    wynik = byt(człony[0])
    for element in człony[1:]:
        wynik = wynik & element
    return wynik

potem(*zdarzenia)

Zdarzenia jednym zdaniem, w kolejności, w której się stały.

Nazwa mówi o następstwie, a nie o spójniku, bo tyle autor rozstrzyga: że jedno stało się po drugim i że jest to jedna rzecz do opowiedzenia. Że wyjdzie z tego i, a podmiot wyjdzie raz, rozstrzyga Ciąg.

Jedno zdarzenie przechodzi tędy nietknięte, tak samo jak jeden byt przez razem: następstwo, w którym nic po niczym nie następuje, jest samym zdarzeniem.

Source code in olski/skład/słownik.py
235
236
237
238
239
240
241
242
243
244
245
def potem(*zdarzenia) -> Ciąg:
    """Zdarzenia jednym zdaniem, w kolejności, w której się stały.

    Nazwa mówi o następstwie, a nie o spójniku, bo tyle autor rozstrzyga:
    że jedno stało się po drugim i że jest to jedna rzecz do opowiedzenia.
    Że wyjdzie z tego ``i``, a podmiot wyjdzie raz, rozstrzyga ``Ciąg``.

    Jedno zdarzenie przechodzi tędy nietknięte, tak samo jak jeden byt przez
    ``razem``: następstwo, w którym nic po niczym nie następuje, jest samym zdarzeniem.
    """
    return Ciąg(zdarzenia) if len(zdarzenia) > 1 else zdarzenia[0]

opis(rzecz, zdanie)

Rzecz wraz ze zdarzeniem, które mówi, o którą rzecz chodzi.

Rzecz stoi tu dwa razy: raz jako ta opisywana, a raz w zdaniu, które ją opisuje, i to drugie wystąpienie jest tym, co wyjdzie zaimkiem. Zapisu na to nie ma, bo zapisem jest zmienna: ta sama zmienna postawiona w obu miejscach jest tą samą rzeczą, a rzecz napisana dwa razy z osobna jest dwiema, jak wszędzie w tym pakiecie.

Source code in olski/skład/słownik.py
248
249
250
251
252
253
254
255
256
257
def opis(rzecz: Rola, zdanie) -> Opis:
    """Rzecz wraz ze zdarzeniem, które mówi, o którą rzecz chodzi.

    Rzecz stoi tu dwa razy: raz jako ta opisywana, a raz w zdaniu, które ją opisuje,
    i to drugie wystąpienie jest tym, co wyjdzie zaimkiem.
    Zapisu na to nie ma, bo zapisem jest zmienna:
    ta sama zmienna postawiona w obu miejscach jest tą samą rzeczą,
    a rzecz napisana dwa razy z osobna jest dwiema, jak wszędzie w tym pakiecie.
    """
    return Opis(byt(rzecz), zdanie)

komu(kto)

Ten, komu zdarzenie się przydarza, wraz z domyślnością, że rzecz znaczy jeden egzemplarz.

Funkcją, a nie kategorią wołaną wprost, z tego samego powodu co jest niżej: dokłada domyślną liczbę, a tyle wystarcza, żeby autor nie pisał jej sam.

Source code in olski/skład/słownik.py
260
261
262
263
264
265
266
def komu(kto: Nominalne | Rola) -> Komu:
    """Ten, komu zdarzenie się przydarza, wraz z domyślnością, że rzecz znaczy jeden egzemplarz.

    Funkcją, a nie kategorią wołaną wprost, z tego samego powodu co ``jest`` niżej:
    dokłada domyślną liczbę, a tyle wystarcza, żeby autor nie pisał jej sam.
    """
    return Komu(byt(kto))

jest(co, czym, *okoliczności, czasownik=Jest.CZASOWNIK)

Orzeczenie imienne wraz z domyślnością, że rzecz znaczy jeden egzemplarz.

Kopula jest tu argumentem nazwanym, bo autor wybiera ją rzadziej, niż pisze samo orzekanie: zostawać mówi o zmianie, a być o niej milczy. Okoliczności wchodzą tak jak do zdarzenia, czyli po tyle, ile autor postawi.

Source code in olski/skład/słownik.py
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
def jest(
    co: Nominalne | Rola,
    czym: Nominalne | Rola,
    *okoliczności,
    czasownik: str = Jest.CZASOWNIK,
) -> Jest:
    """Orzeczenie imienne wraz z domyślnością, że rzecz znaczy jeden egzemplarz.

    Kopula jest tu argumentem nazwanym, bo autor wybiera ją rzadziej,
    niż pisze samo orzekanie: `zostawać` mówi o zmianie, a `być` o niej milczy.
    Okoliczności wchodzą tak jak do zdarzenia, czyli po tyle, ile autor postawi.
    """
    return Jest(
        co=byt(co),
        czym=byt(czym),
        czasownik=czasownik,
        okoliczniki=tuple(okoliczności),
    )