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' ?