Autor Wątek: Mój generator słów  (Przeczytany 1805 razy)

Offline Toivo

  • Wiadomości: 488
    • Zobacz profil
Mój generator słów
« dnia: Lipiec 16, 2016, 11:59:50 »
Ostatnio naszła mnie ochota stworzenia języka a priori. W tym celu zacząłem się rozglądać za generatorem słów/rdzeni, ale wszystkie apleciki, jakie znalazłem w necie, nie dawały zadowalających mnie wyników - zazwyczaj jedyne, co można w nich ustawić, to struktura sylaby. Szczególnie brakowało mi możliwości ustalania częstości różnych głosek, struktur itp. Postanowiłem więc napisać prosty skrypt implementujący na potrzeby generowania słów bardzo ograniczony podzbiór gramatyk probabilistycznych.

Ogólna zasada jest następująca: słowo jest generowane z symbolu Start przez stosowanie reguł produkcyjnych dopóki się da. Reguła produkcyjna wygląda np. tak:

Syl -> C V 1, C V C 1, C C V C 0.5
Poniższa reguła oznacza, że symbol Syl może zostać zastąpiony przez następujące sekwencje symboli: CV, CVC lub CCVC, przy czym ostatnia sekwencja jest o połowę rzadsza (=mniej prawdopodobna), niż każda z poprzednich. Wagi te nie muszą się sumować do 1 - są automatycznie normalizowane.

Reguły podlegają pewnym restrykcjom:
  • Po lewej stronie może znajdować się dokładnie jeden symbol.
  • Zabroniona jest rekursja, czyli jeśli z symbolu X mogę wyprowadzić Y, to z Y nie mogę wyprowadzić X; nie mogę też wyprowadzić symbolu samego z siebie (X -> X)

Mimo bardzo ograniczonej formy takie gramatyki dają całkiem spore możliwości generowania słów, co widać w poniższych przykładach. Co do programu - powstał on podczas jednego piątkowego wieczoru przy piwie, więc nie jest może przepiękny, ale jeśli okaże się przydatny, to będę go dalej rozwijał. Do jego uruchomienia potrzebny jest Python 3, gramatykę należy zapisać w osobnym pliku (tekstowym).

Przykład 1. Harmonia samogłoskowa

Kluczowa jest pierwsza reguła, dzięki której określamy, jaki typ samogłosek będzie zawierało wyprowadzane słowo.

Start -> FrontWord 1, BackWord 1

FrontWord -> FrontSyl 1, FrontSyl FrontSyl 0.7, FrontSyl FrontSyl FrontSyl 0.3
BackWord -> BackSyl 1, BackSyl BackSyl 0.7, BackSyl BackSyl BackSyl 0.3

FrontSyl -> FV 0.1, C FV 1, C FV C 1, C C FV C 0.2
BackSyl -> BV 0.1, C BV 1, C BV C 1, C C BV C 0.2

FV -> æ 1, e 0.5, i 1
BV -> ɒ 1, o 0.5, u 1
C -> m 1, n 1, p 1, t 1, k 1, b 1, d 1, g 1,
     s 1, h 1, r 1, l 1

Przykładowe wyniki:
Spoiler
[close]

Przykład 2. Pseudo-wigierski

W wigierskim występują istotne różnice w składzie sylab początkowych i niepoczątkowych:
  • nagłosowe p, t, k jest bardzo rzadkie w sylabach niepoczątkowych,
  • zaś nagłosowe d, g prawie nie występuje w sylabach początkowych,
  • č występuje tylko w śródgłosie (nagłosie sylab niepoczątkowych),
  • y, o i dyftongi występują tylko w sylabach początkowych.

Nasza gramatyka radzi sobie z tym bez problemu:

Start -> InitialSyllable 0.3,
InitialSyllable NonInitialSyllable 1,
InitialSyllable NonInitialSyllable NonInitialSyllable 0.2

InitialSyllable -> InitialVowel 0.2, InitialConsonant InitialVowel 1,
InitialConsonant InitialVowel s 0.2

NonInitialSyllable -> NonInitialConsonant NonInitialVowel 1,
NonInitialConsonant NonInitialVowel s 0.5

InitialVowel -> y 0.2, o 0.5, Diphthong 0.5, NonInitialVowel 3

Diphthong -> NonInitialVowel Sonorant 1,
ai 0.2, ei 0.2, yi 0.1, oi 0.1, ui 0.2,
au 0.1, eu 0.1, iu 0.1,
ea 0.1

NonInitialVowel -> a 1, e 1, i 1, u 1
Sonorant -> r 1, l 1, n 1

InitialConsonant -> p 1, t 1, k 1, v 1, d 0.02, g 0.02,
m 1, n 1, ñ 0.1, c 1, s 1, š 0.5, h 0.5,
r 1, l 1

NonInitialConsonant -> p 0.1, t 0.1, k 0.1, v 1, d 1, g 1,
m 1, n 1, ñ 1, c 1, č 0.1, s 1, š 0.5, h 0.5,
r 1, l 1

Przykładowe wyniki:
Spoiler
[close]

Przykład 3. Prosta morfologia

Często wymagamy, żeby nasze słowa kończyły się jakąś określoną końcówką - np. mianownika lub bezokolicznika. Również tą własność możemy przemycić w gramatyce:

Start -> Noun 1, Verb 1, Adjective 1

Noun -> Syl C NounSuffix 1, Syl Syl C NounSuffix 1
Verb -> Syl C VerbSuffix 1, Syl Syl C VerbSuffix 1
Adjective -> Syl C AdjectiveSuffix 1, Syl Syl C AdjectiveSuffix 1

NounSuffix -> os 1, a 1, on 1, es 1, is 1, en 1
VerbSuffix -> iti 1
AdjectiveSuffix -> os 1

Syl -> C V 1, C LV 1, C V C 1, Obstr Son V C 0.2

C -> Obstr 1, Son 0.5
LV -> ā 1, ē 1, ī 1, ō 1, ū 1
V -> a 1, e 1, i 1, o 1, u 1

Obstr -> p 1, t 1, k 1, b 1, d 1, g 1, f 1, þ 1, h 1, s 1
Son -> m 0.5, n 1, r 1, l 1

Przykładowe wyniki:
Spoiler
[close]

Co sądzicie?