22

Arvsõnade semantika

Vaatleme järgnevas, kuidas õpetada Prologi aru saama sõnadega esitatud arvsõna tähendusest. Arvsõna (kümnendsüsteemis) koosneb osadest, milles on algul mingi number (1..9) ja siis kümne aste:
kuus-tuhat--kolm-kümmend--viis = 6*1000 + 3*10 + 5.
Seega kõigepealt tuleb selgitada numbrite ja kümne astmete tähendus.

tähendus(null,0).
tähendus(üks,1).
tähendus(kaks,2).
tähendus(kolm,3).
tähendus(neli,4).
tähendus(viis,5).
tähendus(kuus,6).
tähendus(seitse,7).
tähendus(kaheksa,8).
tähendus(üheksa,9).
tähendus(kümme,10).
aste(kümmend,10).
aste(sada,100).
aste(tuhat,1000).

Arvsõna väärtus saadakse osade kaupa:
kuus-tuhat- -kolm-kümmend- -viis
Tekstina esitatud arvsõna väärtuse arvutab lõpprekursiivne predikaat tõlgi, mis "loeb" arvsõna osade (number + aste) kaupa, leiab iga osa väärtuse ja lisab selle arvsõna juba loetud osa väärtusele.
Predikaadi esimene argument on arvsõna veel lugemata osa (tekst), teine argument on juba loetud osa väärtus (number), kolmas argu ment - osa lugemise järel saadav uus väärtus (number).
Kui kogu sõna on loetud, on teine ja kolmas argument loomulikult võrdsed; see reegel tuleb paigutada esimeseks:

tõlgi('',Arv,Arv) :-

!.

Kui järele jäänud osa on üks number (seda saab interpreteerida numbreid esitava predikaadiga tähendus), lisatakse see number juba loetud osa väärtusele:

tõlgi(ArvSõna,Loetud,Arv) :-

tähendus(ArvSõna,Number),
Arv is Loetud + Number.

Arvsõna interpreteerimise kõige olulisem reegel on:
- erista arvsõnas numbrist ja kümne astmest koosnev osa kuus-tuhat-...
- leia nende väärtused ja lisa nende korrutis (s.t. kogu osa väärtus) arvsõna juba loetud osa väärtusele;
- seejärel rakenda sama reeglit arvsõna lõpposale.
Järgnevas predikaadi tõlgi kirjelduses on muutujate Arvsõna, Arvsõna1 väärtus alati "normaalne" arvsõna; Arvsõna1 on Arvsõna alamlõik, mis on saadud Arvsõna esimese osa (number+kümne aste) ärajätmisel. Muutuja Astearv on alati arvsõna, mis algab kümne astmega; see on saadud muutuja Arvsõna väärtusest esimese numbri ärajätmisega.

tõlgi(ArvSõna,Loetud,Arv) :-

tähendus(Sõna,Number),
concat(Sõna,AsteArv,ArvSõna),
aste(AsteSõna,Aste),
concat(AsteSõna,ArvSõna1,AsteArv),
!,
Loetud1 is Loetud + Aste * Number,
tõlgi(ArvSõna1,Loetud1,Arv).

Veidi erinevalt tuleb käsitleda teistkümneid; kuna mõnikord öeldakse viisteist ja teinekord viisteistkümmend, on vastavad võimalused reeglis ühendatud loogilise või ( ;) abil:

tõlgi(ArvSõna,Loetud,Arv) :-

tähendus(Sõna,Number),
(concat(Sõna, teist, ArvSõna);concat(Sõna, teistkümmend, ArvSõna)),
Arv is Loetud + 10 + Number.

Erireeglit tuleb kasutada ka arvsõnadele, kus number "üks" on jäänud ära (tuhat kolmsada kakskümmend):

tõlgi(ArvSõna,Loetud,Arv) :-

aste(Sõna,Aste),
concat(Sõna,ArvSõna1,ArvSõna),
Loetud1 is Loetud + Aste,
tõlgi(ArvSõna1,Loetud1,Arv).

Ka mitmesõnalistes arvsõnades esinevate tühikute jaoks peab olema reegel:

tõlgi(ArvSõna,Loetud,Arv) :-

concat(' ',ArvSõna1,ArvSõna),
!,
tõlgi(ArvSõna1,Loetud,Arv).

Arvsõna interpreteerimisprotsess käivitatakse kahekohalise predikaadiga tõlgi, mille esimeseks argumendiks on interpreteeritav arvsõna, teiseks saadakse selle väärtus; see omakorda käivitab ülalvaadeldud kol mekohalise predikaadi tõlgi. Kuna midagi ei ole veel loetud, on loetud osa väärtus 0:

tõlgi(ArvSõna,Arv) :-

tõlgi(ArvSõna,0,Arv).

Ülesanne
Tee programm (sõnaliselt esitatud) järgarvude väärtuse leidmiseks.


Küsimused, probleemid:
jaak@cc.ttu.ee

Tagasi loengute sisukorra juurde