Esimerkkiohjelma 1: Ruokalista

Yksinkertaisimmillaan Prologohjelma voi olla pelkkä tietokanta, johon tehdään kyselyitä. Oikeastaan varsinainen ohjelma onkin tulkki, joka suorittaa käyttäjän määrittelemiä sääntöjä. Tällainen yksinkertainen säännöstö on ruokalista.pl, joka sisältää listan ruokalajeista ja niiden allergisoivista tai muuten vaan vältettävistä ainesosista. Lisäksi tiedostossa on määritelty muutama apupredikaatti sekä erilaisia erikoisruokavalioita. Kokeillaanpa sitä:
% gprolog
GNU Prolog 1.2.13
By Daniel Diaz
Copyright (C) 1999-2002 Daniel Diaz
| ?- [ruokalista].
compiling /home/ai/prolog_esimerkkeja/ruokalista.pl for byte code...
/home/ai/prolog_esimerkkeja/ruokalista.pl compiled, 58 lines read - 7194 bytes written, 83 ms

(10 ms) yes
Kysytään mitä aineita eri ruuissa on:
koostuu(lasagne,X).

X = [liha,vilja,laktoosi,sipuli,selleri,porkkana,tomaatti]

yes
| ?- koostuu(pippuripihvi,X).

X = [liha,vilja,laktoosi]

yes
| ?- koostuu(sipulikeitto,X).

no

Koska ruokalistasta ei löydy sipulikeittoa, on vastaus "no".

Voidaan myös kysyä, mikä ruokalaji koostuu tietyistä aineista ja mitä koostuu-muotoista dataa on ylipäätään tarjolla:

| ?- koostuu(X,[sieni,laktoosi]).

X = sienikeitto

yes 
| ?- koostuu(X,L).

L = [liha,vilja,sipuli,selleri,porkkana,tomaatti]
X = spagetti_bolognese ? ;

L = [liha,vilja,laktoosi,sipuli,selleri,porkkana,tomaatti]
X = lasagne ? ;

L = [vilja,laktoosi,sipuli,selleri,porkkana,tomaatti]
X = kasvislasagne ? 

yes

Kuitenkaan tällä tavalla ei voida kysyä esimerkiksi kaikkia niitä ruokia, joissa on lihaa, vaan kysymys täytyy aina tehdä täydellä listalla:

 
| ?- koostuu(X,[liha]).

no
Kysely, jossa ruokalajissa on ainetta X voidaan sen sijaan tehdä erillisen koostuu-predikaatin ja listaoperaation member avulla muodostetulla sisaltaa-predikaatilla:
 
| ?- sisaltaa(X,liha).

X = spagetti_bolognese ? ;

X = lasagne ? ;

X = pippuripihvi ? ;

X = kinkkumunakas ? ;

no
Useinmiten kuitenkin haluaisimme tietää ne ruokalajit, joissa ei ole jotakin tiettyä allergisoivaa ainesosaa, kuten laktoosia. Siispä tarvitsemme negaatiota. Prologissa ei ole loogista negaatiota, vaan "negation by failure", joka on toteutettu leikkauksen avulla. Gprologissa tämä on toteutettu järjestelmäpredikaatilla "\+". Onnistuisikohan laktoosittomien ruoka-aineiden kysyminen siis näin?

| ?- \+sisaltaa(X,laktoosi).

no
Eipä onnistunut. Nyt kysyimme, "Onko niin, että tietämyskannasta ei löydy yhtään ruokalajia, joka sisältää laktoosia?", ja näinhän ei ole. Koska kyselyn tyydyttäviä ratkaisuja ei löydy, emme luonnollisesti saa X:n arvojakaan. Meidän täytyy siis tehdä uusi predikaatti ei_sisalla(X,Y), siten että kysymme "Onko niin, että tietämyskannasta löytyy jokin ruokalaji, joka ei sisällä laktoosia?":

| ?- ei_sisalla(X,laktoosi).       

X = spagetti_bolognese ? ;

X = kasvispaistos ? ;

X = savulohisalaatti ? ;

X = purjoperunakeitto ? 

yes

Nyt meillä onkin ainekset, joiden avulla kirjoitella erilaisia ruokavalioita kuvaavia predikaatteja. Esimerkiksi lakto-ovovegetaristille kelpaavat kaikki ruuat, joille sekä predikaatit ei_sisalla(liha) ja ei_sisalla(kala) onnistuvat:


| ?- lakto_ovovegetaristi(X).

X = kasvislasagne ? ;

X = kasvispaistos ? ;

X = kasvismunakas ? ;

X = kreikkalainen_salaatti ? ;

X = purjoperunakeitto ? ;

X = sienikeitto

yes

Predikaatti kosher(X) taas onnistuu, jos joko predikaatti ei_sisalla(liha) tai ei_sisalla(maito) onnistuu. Huomaa, että siinä missä "," on Prologohjelmassa looginen ja, on ";" looginen tai. Periaatteessa jokaisen predikaatin vaihtoehtoiset kaavat voisi liittää toisiinsa puolipisteillä. Tämä ei kuitenkaan ole ohjelman selkeyden kannalta suotavaa.


| ?- kosher(X).

X = spagetti_bolognese ? ;

X = kasvispaistos ? ;

X = savulohisalaatti ? ;

X = purjoperunakeitto ? 

yes