Mój generator słów

Zaczęty przez Toivo, Lipiec 16, 2016, 11:59:50

Poprzedni wątek - Następny wątek

Toivo

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

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

[Zamknij]

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

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
[Zamknij]

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

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
[Zamknij]

Co sądzicie?
  •