Mida millest saab, mis millest koosneb

Näitena nimistute kasutamisest koostame väikese keemiliste reaktsioonide ekspertsüsteemi, mis võimaldab otsida, milliseid aineid on olemasolevatest ainetest esitatud reaktsioonide abil võimalik saada. Lähteandmed (olemasolevad ained ja reaktsioonid) on samad, mida kasutas insener Cyrus Smith (J. Verne "Saladuslik Saar") kalju õhkimisel.
Reaktsioonid on loomulik kirjeldada kahekohalise predikaadiga, mille esimene argument on nimistu kõigist reaktsiooni lähteainetest, teine - reaktsiooni käigus tekkiv aine:

reaktsioon([pyriit, sysi], raudsulfaat).
reaktsioon([pyriit, sysi], alumiiniumsulfaat).
reaktsioon([meretaimed], sooda).
reaktsioon([rasv, sooda], seep).
reaktsioon([rasv, sooda], glytseriin).
reaktsioon([raudsulfaat], väävelhape).
reaktsioon([väävelhape, salpeeter], lämmastikhape).
reaktsioon([väävelhape, lämmastikhape], nitroglytseriin).

Edasi kirjeldame olemasolevad ained; need võib esitada ühekohalise predikaadiga:

olemas(pyriit).
olemas(sysi).
olemas(meretaimed).
olemas(rasv).
olemas(salpeeter).

Mingit ainet saab valmistada, kui ta kas on juba olemas:

saab_valmistada(Aine):-
olemas(Aine).
või saab seda ainet reaktsiooniga, mille kõiki lähteaineid saab valmistada:
saab_valmistada(Aine):-
reaktsioon(Ained, Aine),
saab_kõikki(Ained).

Predikaadi saab_kõikki(Ained) argumendiks on ainete nimistu. Kõikki nimistusse kuuluvaid aineid saab valmistada, kui see nimistu on kas tühi või siis on valmistav nii nimistu esimene aine (element) Esimene kui ka kõik ülejäänud ained alamnimistust Muud:

saab_kõikki([]).
saab_kõikki([Esimene|Muud]):-
saab_valmistada(Esimene),
saab_kõikki(Muud).

Kirjeldatud predikaatide abil saab (näiteks) kontrollida, kas nendest ainetest saab valmistada nitroglytseriini:

?- saab_valmistada(nitroglytseriin).
yes

Reaktsioonid moodustavad nn mitmealuselise graafi, kus kaar tipuni (reaktsiooni tulemus) ei lähe ühest tipust, vaid tippude hulgast (reaktsiooni lähteained), näiteks ainetest Aine1, Aine2, Aine3 saab valmistada (läheb nn multikaar) tippu Aine4. Sellisel graafil tekkivad ülesanded on analoogilised tavalise (näiteks linnade) graafil tee otsimise ülesandega, ainult nüüd tuleb koostada erinevad programmid alt-üles (mida antud ainetest võib saada) ja ülalt-alla (mida on vaja, et saada nõutud ainet/aineid), näiteks mingi Aine saamiseks vajalike ainete (kordusteta) nimistu võib saada predikaatiga vaja :

vaja(Aine,[Aine]):-
not(clause(reaktsioon(_,Aine),true)),
!. % kui aine jaoks ei ole mingit reaktsiooni tulemus, siis
%peab see aine olemas olema
vaja(Aine,Vajalikud):-
reaktsioon(Ained,Aine),
vaja_kõikki(Ained,Vajalikud).

Predikaat vaja_kõikki otsib kõigi esimese argumendina olevate ainete nimistu jaoks ained, mida nende valmistamiseks on vaja ja koostab siis predikaadiga yhenda vajalikest ainetest kordusteta nimistu. Nimistute ühendamisel kontrollib predikaat yhenda vaid esimese argumendi elementide kordumist, teise argumendi elementide kordumise võib (siin) kontrollimata jätta (miks ?):

vaja_kõikki([],[]):-
!.
vaja_kõikki([Aine|Ained],Vajalikud):-
vaja(Aine,Ained1),
vaja_kõikki(Ained,Ained2),
yhenda(Ained1,Ained2,Vajalikud).

Nimistute ühendamise predikaat yhenda kasutab abipredikaati member, mis kontrollib, kas element juba esineb nimistus (st siin tehakse korduvate elementideta nimistu):

yhenda([],Ained,Ained):-!.
yhenda([Aine|Ained1],Ained2,Ained):-
not(member(Aine,Ained2)),!,
yhenda(Ained1,[Aine|Ained2],Ained).
yhenda([Aine|Ained1],Ained2,Ained):-
member(Aine,Ained2),
yhenda(Ained1,Ained2,Ained).

Ülesandeid:
1. Koosta predikaat, mis leiab reaktsioonide kirjelduse ja olemasolevate ainete nimistute esitamisel (need on sisendid) kõigi ainete (kordusteta) nimistu, mida olemasolevatest ainetest saab valmistada; kuna paljude reaktsioonide tulemusena tekib mitu ainet, peaks reaktsioonipredikaati modifitseerima nii, et ka tulemus on ainete nimistu. Programm peab oskama (testimiseks) näidata, et reaktsioonide
MgO + H2 Mg + H2O
C + O2 CO2
CO2 + H2O H2CO3

abil saab aintetest MgO, H2, O2, C valmistada ainet H2CO3
2. Koosta predikaat, mis leiab reaktsioonide hulga kirjelduse põhjal kõik vaheproduktid, mis tekivad olemasolevatest ainetest mingi aine valmistamisel (analoogia: kõik matka ajal läbitud linnad).
3. Mitmealuseline hierarhiline graafi tekib kõigi hierahiliste struktuuride, näiteks seadmete ja organisatsioonide struktuuri kirjeldamisel: predikaat koosneb(jalgratas, [raam, esiratas, tagaratas, juhtraud]) on oma struktuuri ja semantika poolest täiesti analoogiline ülalvaadeldud prodikaadiga reaktsioon (ainult argumendid on vastupidises järjekorras). Koosta jalgratta (või mõne muu üldtuntud mehhanismi või struktuuri, näiteks TTÜ administratiivstruktuuri ) vähemalt kolmetasemeline kirjeldus ja predikaadid, mis leiavad nii elemendi alluvad (millest jalgrattas ise või jalgratta tagaratas koosneb; millised struktuuriüksused on dekanaadi all (vt TTÜ WWW-lehekülgi) ja vastupidi, leiavad antud osa/elemendi jaoks kõik sellest kõrgemal olevad osad (näiteks tudengi jaoks kõik otse tudengit käsutavad instantsid kuni graafi tipuni, s.t. kas (abstraktse) TTÜ või (konkreetse) rektorini (erinevate infoloogiliste kirjelduste korral tekkivad erineva nimetusega tipud).
4. "Majanduskeemias" käituvad firmad nagu ülalvaadeldud näites reaktsioonid - kui nad saavad vajalikke tooraineid, valmistavad nad tooteid, mis omakorda võivad olla vajalikud järgnevate toodete valmistamisel. Erinevalt keemilistest reaktsioonidest on "majandusreaktsioonidel" oluline ka toote maksumus - sama toodet võivad valmistada mitmed firmad, kuid nende toodete hind võib olla erinev. Koosta predikaadid, mis võimaldaks leida kõige
odavama valmistusahela; lähteandmeteks on toorained ja eri tooraineliikide hinnad, firmade "reaktsioonid", s.t.
millest nad mida teevad ja firmade poolt toote valmistamisel selle toorainete hinnale lisatud hinnalisad.


Küsimused, probleemid: ©2004 Jaak Henno