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

Offline Toivo

  • Pomożesze: 205
  • Wiadomości: 486
  • Country: fi
  • Conlangi: wigierski
Mój generator słów
« dnia: 16 lip 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 for Hiden:
hekislem
sil
pɒputɒ
bunot
lbim
pu

hɒmku

tepri

ækkit
læpægil

de
pɒmsom
liglæp
pgurgulu
dlepkeg
tæb
tumɒlu
sbɒn
tuɒ
dupsɒrbɒk
tihmeb
ri
bær

sɒsɒd


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 for Hiden:
ugavi
muga
ise
ñugus
nogusda
tiñus
šuvehes
riuñus
cessu
ve
leshu
nema
uñi
kegas
malsca
ami
pu
soñu
pemu
maru
vuis
u
lori
nede
ruisa
resma
sidesnas
nasi
vasca
mešusres

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 for Hiden:
kerifþos
dogtes
gālos
rūfis
fokos
risfarþos
rēhiti
nīribþiti
lusþahren
meþēda
þuliti
þeþkos
dahos
līkōtos
gorgos
lutos
mīþones
bīgusos
nōþiti
kilfiti
nelros
nīrignos
biftādos
letīkos
fikbes
hēgos
pefiti
desþoþis
þupþīfiti
hohapis

Co sądzicie?