Logikprogrammering
mån 9/9
David Hjelm
Repetition
• Ett prologprogram består av en mängd klausuler som
definierar ett antal predikat (relationer).
• Ett predikats ställighet (aritet) betecknar hur många
argument det tar. Nedanstående klausuler tillhör inte
samma predikat utan två olika: spelar/1 och spelar/2
spelar(pelle).
spelar(pelle,gitarr).
• Argumenten till predikat kallas termer. Termer kan vara
atomer, tal, variabler eller sammansatta termer (mer om
det senare).
Repetition forts.
• Atomer börjar med liten bokstav eller citationstecken
– sagan_om_ringen, ’112’
• Tal kan vara negativa eller positiva heltal eller decimaltal
– 14, -2.5, 3.14, -999
• Variabler börjar med stor bokstav eller understreck
– X, Y, _lisa
• Variabler kan instantieras under programmets gång
• Den anonyma variabeln, _, används när man inte är
intresserad av en eventuell instantiering.
Repetition forts.
• Ett predikats klausuler kan vara fakta eller regler. Regler
består av ett huvud och en kropp där kroppen består av
en lista med mål. Följande exempelprogram består av
sex predikat som definieras av sju klausuler varav de
fyra första är fakta och tre övriga är regler.
spelar(pelle,gitarr).
spelar(lisa,bandy)
instrument(gitarr).
sport(bandy).
gitarrist(X) :- spelar(X,gitarr).
musiker(X) :- spelar(X,Y), instrument(Y).
idrottare(X) :- spelar(X,Y), sport(Y).
Repetition forts.
• Klausuler tillämpas i den ordning de är skrivna i
programmet. Givet föregående exempelprogram:
| ?- spelar(X,Y).
X = pelle,
Y = gitarr ? ;
X = lisa,
Y = bandy ? ;
no
1. Vi ställer en fråga till prolog.
2. Eftersom spelar(pelle,gitarr) står
innan spelar(lisa,bandy) så
instantieras variabeln X till atomen pelle
och variabeln Y till atomen gitarr första
gången.
3. Vi ber om ett nytt svar genom att skriva ;.
Den här gången instantieras X till lisa
och Y till bandy.
4. Vi ber om ett tredje svar, men det finns
inget och prolog svarar no.
Repetition forts.
• Rekursion – när ett predikat anropar sig självt
• Lite rekursion på onsdag. Se Bratko 1.3 så länge.
Dagens föreläsning
• Listor
• Tecken
• Strängar
Listor
• En lista är en sammansatt term (struktur i kursboken).
Här är några exempel på listor i prolog:
[pelle,lisa] är en lista med två element, atomerna pelle och
lisa
[-99,1,0.1] är en lista med tre element, heltalen -99 och 1 samt
decimaltalet 0.1
[[1,2],[3]] är en lista med två element, listan [1,2] och listan
[3]
[] är en lista utan några element och kallas den tomma listan
Listor
•
Prologs interna representation av en lista är lite
annorlunda än den vi använder här. Egentligen är listor
ett specialfall av trädstrukturer (se kursboken för mer om
detta).
• Elementen i en lista kan vara vilka termer som helst.
Man kan också blanda olika sorters termer hur som
helst:
[Detta, är, 1, [korrekt, lista]]
är t.ex. en lista med fyra element: variabeln Detta,
atomen är, talet 1 och listan [korrekt, lista]
Listor
• Antingen så är en lista tom eller så består den av ett
huvud och en svans.
• Huvudet på en lista är det första elementet i listan.
Svansen på en lista är en lista som består av resten av
elementen i listan.
– [pelle,lisa] består av huvudet pelle samt svansen [lisa]
som i sin tur består av huvudet lisa samt svansen [] (den
tomma listan).
– [1,2,3,4,5] består av huvudet 1 samt svansen [2,3,4,5]
som består av huvudet 2 samt svansen [3,4,5] som består av
huvudet 3 samt svansen [4,5] som består av huvudet 4 samt
svansen [5] som består av huvudet 5 samt svansen [].
Listor
• Ofta är det intressant att dela upp en lista i huvudet och
svansen. Då skriver man listan som [Huvud|Svans].
Exempel:
| ?- [Huvud|Svans] = [pelle,lisa].
Huvud = pelle,
Svans = [lisa] ?
Huvudet Huvud instantieras
till pelle och svansen Svans
instantieras till [lisa]
| ?- [X|Xs] = [1,2,3].
X = 1,
Xs = [2,3] ?
Huvudet X instantieras till 1
och svansen Xs instantieras
till [2,3]
| ?- [Y|Ys] = [].
no
Misslyckas eftersom den
tomma listan varken har
huvud eller svans.
Listor
• Fler exempel:
Listan [pelle,lisa] är samma lista som [pelle|[lisa]] som är
samma lista som [pelle|[lisa|[]]] .
[pelle,[]] är inte samma som [pelle|[]]. Däremot så är
[pelle,[]] samma lista som [pelle|[[]|[]]].
• Generellt kan en (icke-tom) lista skrivas som
[A,B,…,K|Resten] där A,B,…,K är de första elementen i
listan och Resten är resten av listan.
[a,b,c] är samma som [a|[b,c]] som är samma som
[a,b|[c]] som är samma som [a,b,c|[]]
Listor
Två exempel till:
| ?- [X,Y|Xs]=[pelle,lisa].
X = pelle,
Y = lisa,
Xs = []
X instantieras till pelle
Y instantieras till lisa.
Xs instantieras till den
tomma listan
| ?- [X,Y,Z|Xs] = [pelle,lisa].
no
Misslyckas eftersom
[X,Y,Z|Xs] måste
ha minst tre element.
Strängar och tecken
• Tecken är atomer av längden 1
– Exempel på tecken: ’a’, ’b’, ’2’, ’X’, ’ ’
• Strängar skrivs i SICstus prolog som ”detta är en
sträng” och är en förkortning för en lista med tecken.
”detta är en sträng” är ett enklare sätt att skriva listan
[d,e,t,t,a,’ ’,ä,r,’ ’,e,n,’ ’,s,t,r,ä,n,g] .
• Exempel:
–
–
–
–
”lisa” är samma som [l,i,s,a]
”1 - 0” är samma som [’1’,’ ’,-,’ ’,’0’]
”” är samma som []
[”Pelle”,”Lisa”] är samma som
[[’P’,e,l,l,e],[’L’,i,s,a]]
Strängar
• Strängar är listor. Alltså är
”exempel” samma som
[e|”xempel”] som är samma som
[e,x|”empel] som är samma som
[e,x,e|”mpel”] som är samma som
[e,x,e,m|”pel”] som är samma som
[e,x,e,m,p|”el”] som är samma som
[e,x,e,m,p,e|”l”] som är samma som
[e,x,e,m,p,e,l|””] som är samma som
[e,x,e,m,p,e,l]
Predikat med listor
• Eftersom listor är termer kan man ju skriva predikat som
tar listor som argument.
• lang_lista/1 lyckas om argumentet är en lista med åtta
element eller fler:
lang_lista([_,_,_,_,_,_,_,_|_]).
| ?- lang_lista([1,2,3,4,5,6,7,8,9]).
yes
| ?- lang_lista([1,2,3,4,5,6,7]).
no
Predikat med listor forts.
• borjar_med/2 lyckas om det andra argumentet är en lista
vars första element är det första argumentet.
borjar_med(X,[X|_]).
| ?- borjar_med(1,[1,2,3]).
yes
| ?- borjar_med(b,[a,b,c]).
no
| ?- borjar_med(A,”Pelle”).
A = 'P' ?