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)),
!.
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