Ekspertsüsteemid

Ekspertsüsteemid on programmid, mille ülesandeks on mingil (tavaliselt kitsal) alal toimida asjatundja tasemel (või pareminigi). Neis on salvestatud paljude selle ala asjatundjate (ekspertide) teadmised ja nende ülesandeks on liigitamine (äratundmine): leida avarii põhjus (liigitada avarii selles ilmnenud tunnuste järgi), leida maagimaardlaid geoloogiliste tunnuste järgi, klassifitseerida objekte (taimi, loomi) jne jne. Ekspertide teadmised on programmis salvestatud tavaliselt if... then... reeglite kujul ja kuna programmi on võimalik salvestada paljude antud ala asjatundjate teadmised, suudavad ekspertsüsteemid sageli ületada inimesi.

Kuna kasutajale pole tavaliselt teada, millised uuritava nähtuse või objekti tunnused on liigitamiseks vajalikud ja olulised (kui ta teab seda, oskab ta arvatavasti ise juba objekti liigitada), töötavad ekspertsüsteemid interaktiivselt: kasutajale esitatakse küsimus (järgmise) olulise tunnuse kohta ja kasutaja vastuse põhjal otsustab süsteem, mida edasi pärida.

Järgnevas on esitatud lihtne taimede tunnistamise süsteem; vajalikud teadmised on võetud raamatust Viktor Masing, "100 tavalisemat taime", Tallinn, Koolibri 1999. (siin on lõpuni mindud vaid vee all kasvavate taimede osas).

Taime tunnistamine edeneb saam-sammult otsustuspuus (decision tree), mis algab tipust taim. Igas tipus esitatakse kasutajale küsimus uuritava taime mõne omaduse (mis on selles tipus oluline) kohta; kasutaja vastuse põhjal süsteem otsustab, millise alampuuga jätkata. Puu tipp on iseloomustatud:

- tipu nimega; see on kas taimede klass (taim, maismaataim, veetaim) või loetelu (nimistu) selle tipu iseloomulikest tunnustest ([veesisene,lihtlehed]);
- tipus kasutajale esitatava küsimusega ('Kas taim kasvab maal või vees?') ja selle vastusevõimalustega (maal, vees); vastus määrab puu järgmise tipu.

Prolog salvestab tipu informatsiooni predikaatides küsi(Tipp) ja tipp(Tipp,[[Vastus1,Tipp1],[Vastus2,Tipp2],...,[Vastusn, Tippn]]). Predikaadi küsi argumendiks on tipu nimi (või loetelu tipu olulistest tunnustest) ja ta kirjutab ekraanile tipu küsimuse; predikaadi tipp esimene argument on (praeguse) tipu nimi; sellele järgneb nimistu paaridest [Vastus,Uustipp], kus Uustipp on tipp, millesse minnakse kasutaja vastuse Vastus korral. Kui kasutaja ei saa aru, miks esitati just selline küsimus (suure otsustuspuu korral võib see kergesti juhtuda), võib ta vastuseks anda ? - pärast seda Prolog loetleb kõik faktid, mida ta juba teab (küsimus valitakse nende põhjal) ja kordab küsimust. Uurimine algab puu juurest taim; kui Prolog jõuab otsustuspuu viimase tasemeni, loetleb ta kõik puus ülal-alla liikumisel leitud faktid ; täieliku puu korral on viimase taseme tipu nimeks uuritava taime nimi.

küsi(taim) :-
write('Kas taim kasvab maal või vees? (maal/vees) ').

küsi(maismaataim) :-
write('Kas kasvukoht on varjus (metsas, võsas), poolvarjus (metsaserval, puisniidul) või lagedal (niidul, soos, rannikul)? (varjus/poolvarjus/lagedal) ').

küsi(veetaim) :-
write('Kas lehed on üleni vees, ujuvad veepinnal või tõusevad veest välja? (vees/pinnal/õhus) ').
küsi(veesisene) :-
write('Kas taimel on lihtlehed või ei (liitlehed või liigestunud labaga lehed)? (lihtlehed/liitlehed)').

küsi([veesisene,lihtlehed]):-
write('Kas õied on suured (suuremad kui hernetera) või alla 5 mm (või puuduvad üldse)? (suured/väiksed)').

küsi([veesisene,lihtlehed,suureõieline]):-
write('Kas õied on valged ja kolmetised või valged ja viietised? (kolmetised/viietised)').

küsi(taim):-
write('Kas õis on suur (suurem kui hernetera) või alla 5 mm? (suur/väike)').

küsi([veesisene,liitlehed]):-
write('Kas õied on a)valged, viietised, b)kollased, kahekülgsed või c)väikesed või puuduvad hoopis? (valged/kollased/väikesed)').tipp(taim,[[maal,maismaataim],[vees,veetaim]]).

tipp(maismaataim,[[varjus,varjutaim],[poolvarjus,poolvarjutaim],[lagedal,valgustaim]]).
tipp(veetaim,[[vees,veesisene],[pinnal, ujulehine],[õhus,veepinnapealne]]).
tipp(veesisene,[[lihtlehed,[veesisene,lihtlehed]],[liitlehed,[veesisene,liitlehed]]]).
tipp([veesisene,lihtlehed],[[suured,[veesisene,lihtlehed,suureõieline]],[väikesed,[penikeel, kuuskhein, vesikatk, vesikuusk]]]).
tipp([veesisene,lihtlehed,suureõieline],[[kolmetised,vesikarikas],[viietised,vesilobeelia]]).
tipp([veesisene,liitlehed],[[valged, 'särjesilm või vesisulg'],[kollased,vesihernes],[väikesed,kardhein]]).
uus_tunnus(Vastus,[[Vastus,Uus_tunnus]|_],Uus_tunnus).

uus_tunnus(Vastus,[_|Nimistu],Uus_tunnus) :-
uus_tunnus(Vastus,Nimistu,Uus_tunnus).

esita([]) :-
nl.

esita([[Tunnused]|Juhud]) :-
write(Tunnused),
nl,
esita(Juhud).

tunnused([Tunnus|Tunnused]) :-
nl,
küsi(Tunnus), nl,
read(Vastus),
analyysi(Tunnus,Tunnused,Vastus).

tunnused(Tunnused) :-
nl,
write('Tean, et uuritav taim on: '),
nl,
esita(Tunnused).

taimetundja :-
write('Ma oskan määrata mõningaid taimi.'),
nl,
write('Vasta kysimustele ja anna uuritava taime tunnused (vali üks esitatud võimalustest).'),
nl,
write('Et näha, mida ma taime kohta juba tean, kirjuta vastuseks ? .'),
tunnused([taim]).
esita([Tunnus|Nimistu]) :-
esita(Nimistu),
write(Tunnus),
nl.

esita([]) :-
nl.

analyysi(Tunnus,Tunnused,'?') :-
!,
nl,
write('Tean, et uuritav taim on: '),
esita([Tunnus|Tunnused]),
nl,
write('Jätkamiseks tahan teada: '),
tunnused([Tunnus|Tunnused]).

analyysi(Tunnus,Tunnused,Vastus) :-
tipp(Tunnus,Juhud),
uus_tunnus(Vastus,Juhud,Uus),
tunnused([Uus,Tunnus|Tunnused]).
analyysi(Tunnus,Tunnused,Vastus) :-
tipp(Tunnus,Juhud),
nl,
write('Ei saanud vastusest aru. Võimalused on: '),
nl,
esita(Juhud),
tunnused([Tunnus|Tunnused]).



Ülesandeid:
1. Ylesande tekst


Küsimused, probleemid: ©2004 Jaak Henno