Ladda ner presentationen
1
Prolog, Mån 16/9 Rebecca Jonson
2
Repetition Predikat med listor Rekursiva predikat med listor
hänga_gubbe/1 hänga_gubbe([A,n,B,C,D,t,A,E]). ?- hänga_gubbe("infantil"). yes Rekursiva predikat med listor lika_långa/2 lika_långa([],[]). lika_långa([_|Xs],[_|Ys]):- lika_långa(Xs,Ys).
3
Repetition forts. Basfall: Elementet är huvud på listan
member/2 kollar om en term är ett element i en lista Basfall: Elementet är huvud på listan Rekursivt fall: Elementet finns i svansen member(X,[X|_]). member(X,[_|Xs]) :- member(X,Xs).
4
Repetition forts. append/3, som kallas conc i kursboken, sätter ihop två listor till en tredje lista. Basfall: den första listan är tom – resultatet blir den andra listan Rekursivt fall: den första listan har huvud och svans. I så fall vet vi att den första listans och resultatlistans första element är samma. Resten av resultatlistan fås genom att sätta ihop den första listans svans med den andra listan. append([],Xs,Xs). append([X|Xs],Ys,[X|Zs]) :- append(Xs,Ys,Zs). ?- append([1,2],[3],X). Sätter ihop en lista. X = [1,2,3] ? ?- append(Xs,Ys,"lisa"). Kan också dela upp en lista.
5
Dagens föreläsning Rekursion forts.
Ordningen på regler och klausuler i rekursiva predikat, terminering Mappning/Översättning Filtrering
6
Rekursion Ett predikat är rekursivt om det anropar sig själv med någon del av ett argument. För att rekursionen ska lyckas måste det dessutom finnas minst en klausul utan något rekursivt anrop. Rekursionsfall: regler som någonstans i kroppen anropar sig själv Basfall: fakta eller regler som inte anropar sig självt. Idén med listrekursion är att rekursionsfallet fångar upp en godtyckligt lång lista, delar upp den i en eller flera mindre lista/listor och anropar sig själv med delarna. Eftersom delarna hela tiden blir mindre och mindre så måste vi till slut komma till en liten lista som kan fångas av basfallet/basfallen.
7
Regel-, klausul- ordning
Utan basfall som stoppar rekursionen kan Prolog aldrig terminera. p:- p. Ordningen på regler och klausuler hos rekursiva predikat påverkar predikatets möjlighet till termination. Tips Basfallsregeln först, sedan rekursionsregeln. Rekursionsklausul efter basfallsklausul i kroppen. P:-p Enkelt predikat. Från en deklarativ synvinkel riktig definition om egenskap p gäller så gäller egenskap p. Farligt påstående med tanke på hur prolog jobbar.
8
Regelordning lika_långa([],[]). lika_långa([_|Xs],[_|Ys]):-
?- lika_långa(X,Y). Ger svar på alla möjliga listor och börjar med svaret att de båda variablerna är tomma listor, sedan en variabel följt av tomma listan, två variabler följt av tomma listan osv. ?- lika_långa2(X,Y). Loopar eftersom den hela tiden kommer gå in i första regeln med de nya variablerna.
9
Klausulordning barn(anna,maria). barn(maria,alva). barn(alva,eva).
härstamma(X,Y):-barn(X,Y). härstamma(X,Y):-barn(X,Z),härstamma(Z,Y). härstamma2(X,Y):-barn(X,Y). härstamma2(X,Y):-härstamma2(Z,Y),barn(X,Z). härstamma3(X,Y):-härstamma3(Z,Y),barn(X,Z). härstamma3(X,Y):-barn(X,Y).
10
Klausulordning forts. ?- härstamma(alva,Vem). Vem=eva; No
LOOP!!! ?- härstamma3(alva,Vem). Vad gör prolog i det här fallet? Trädstruktur på tavlan.
11
Mappning, översättning
Ofta vill man applicera något predikat på varje element i en given lista för att få en annan lista (en mappning eller översättning av listan) Exempel: Predikatet trans översätter svenska ord till engelska ?- trans("bil", X). X = "car” ?- trans("hus", Y). Y = "house” ?- trans("en", Z). Z = "a” ?- trans("ett", Z). Z = "a" Många rekursiva predikat är egentligen varianter på ett och samma tema, man vill applicera något predikat på varje element i en given lista för att få en annan lista.
12
Translist Nu kan vi skriva ett predikat som översätter svenska meningar givna som listor av ord till engelska meningar. Basfallet är den minsta möjliga listan, i det här fallet tomma listan som översätts till sig själv. translist([], []). Rekursionsfallet är när vi har ett huvud (ett svenskt ord) och en svans (en svensk mening). Huvudet översätts till ett engelskt ord och svansen översätts till en engelsk mening, och resultatet kommer då att ha det engelska ordet som huvud och den engelska meningen som svans. translist([SveOrd|SveMening], [EngOrd|EngMening]) :-trans(SveOrd, EngOrd), translist(SveMening,EngMening).
13
Translist forts. Observera att det går alldeles utmärkt att översätta från svenska till engelska, så länge predikatet trans/2 klarar av båda riktningarna. ?- translist(["en","bil","är","i","ett","hus"], Engelska). Engelska = ["a","car","is","in","a","house"] ?-translist(Svenska,["a","car","is","in","a","house"]). Svenska = ["en","bil","är","i","en","hus"] ; Svenska = ["en","bil","är","i","ett","hus"] ; Svenska = ["ett","bil","är","i","en","hus"] ; Svenska = ["ett","bil","är","i","ett","hus"] ;
14
Mappning forts. En variant på mappning är att en term översätts till flera termer Ex. svenska ordet ”bilen” till frasen ”the car” Vi gör om översättningspredikatet till översätta ord till en lista med ord. ?- trans2("bil", X). X = ["car"] ?- trans2("bilen", X). X = ["the","car"] Observera att även ord som översätts till enstaka ord måste ge listor som resultat
15
Translist2/2 Basfallet är som förut. translist2([], []).
Rekursionsfallet översätter huvudet till en lista, och svansen till en annan lista. Slutligen konkateneras de två listorna med append/3 till en resultatlista. translist2([Ord|Mening], Resultat) :- trans2(Ord, Resultat1), translist2(Mening, Resultat2), append(Resultat1, Resultat2, Resultat). I denna version kan vi endast översätta i en riktning, från svenska till engelska. ?- translist2(["bilen","är","i","huset"], Engelska). Engelska = ["the","car","is","in","the","house"]
16
Filtrering Filtrering: Man vill endast plocka ut vissa element ur listan, andra ska kastas. Antag att vi har ett predikat behåll/1 som säger om en term ska behållas och ett predikat kasta/1 som säger om en term ska kastas bort. Antag dessutom att de termer som ska behållas är de positiva talen (inklusive noll), och de som ska kastas är de negativa. ?- behåll(3). Yes ?- behåll(-3). No ?- kastas(-3). Yes ?- kastas(0). no
17
Filtrering forts. Då kan vi tillverka predikatet positiva/2 som tar en lista med tal, och behåller de positiva talen som resultat. Vi har ett basfall och två rekursionsfall. Basfallet är åter igen tomma listan. positiva([], []). Det första rekursionsfallet är när vi har ett huvud som ska behållas, då stoppar vi in huvudet i resultatet och filtrerar svansen. positiva([Pos|Resten], [Pos|Positiva]) :- behåll(Pos), positiva(Resten, Positiva). Det andra rekursionsfallet är när huvudet ska kastas, i vilket fall vi inte stoppar in det i resultatet. positiva([Neg|Resten], Positiva) :- kasta(Neg),
18
Filtrering ?- positiva([1,2,3,4], Lista). Lista = [1,2,3,4]
19
Tack för idag!
Liknande presentationer
© 2024 SlidePlayer.se Inc.
All rights reserved.