Logikprogrammering, Mån 23/9 Rebecca Jonson
Repetition P :- Q, R. Deklarativ syn: –P är sann om Q och R är sanna. –Av Q och R följer P Procedurell syn: –För att lösa problemet P, lös först delproblemet Q och sedan delproblemet R –För att uppfylla P, uppfyll först Q och sen R
Repetition Prolog svarar på frågor genom att försöka hitta en klausul i programmet (fakta eller huvud i regel) som överensstämmer med frågan. Letar uppifrån och ned. Namnbyte av variabler. Om huvud, försöker lösa kroppen. Alltid vänstraste målet först. Backtracking: Prolog håller reda på sina vägval och kan på så sätt gå tillbaka till vägvalet när den valda vägen misslyckas eller när användaren ber om ytterligare alternativ för att välja en alternativ väg (t.ex nästa regel)
Repetition Konjunktion ”,” ?- member(X, "abcd"), member(X, "fedc"). ''vilket X finns både i listan [a,b,c,d] och i listan [f,e,d,c]?''. Disjunktion ”;” ?- member(X, "abcd") ; member(X, "fedc"). ”vilket X finns antingen i listan [a,b,c,d] eller i listan [f,e,d,c] (eller i båda listorna)?''. Semikolon inte nödvändig i regler, kan skriva flera regler istället. Kommatecken binder hårdare än semikolon!
Repetition Negation ”\+” man(X) :- \+ kvinna(X). Används i kroppen och i frågor (ej huvud och fakta). Kan användas för att definiera motsatser. Ex: Kasta/Inte behålla. ?- man(sverige). Yes Ej negation i logisk bemärkelse. Sverige ingen kvinna därför man. ?- man(X). No Problem med fria variabler. Bevisa att det inte finns någon kvinna vilket det finns och då blir svaret nej. Negation binder hårdare \+ p,q? betyder (\+ p),q?
Repetition Mappning med negation translist3([], []). translist3([SveOrd|SveMening], [EngOrd|EngMening]) :- trans(SveOrd, EngOrd), translist3(SveMening, EngMening). translist3([Ord|SveMening], [Ord|EngMening]) :- \+ trans(Ord, _), translist3(SveMening, EngMening). Andra rekursionregeln används när det inte finns ngn översättning för första ordet i listan d.v.s. när predikatet trans misslyckas, då behåller vi ordet som det är.
Repetition Filtrering med negation positiva([], []). positiva([Pos|Resten], [Pos|Positiva]) :- behåll(Pos), positiva(Resten, Positiva). positiva([Neg|Resten], Positiva) :- \+ behåll(Neg), positiva(Resten, Positiva). Vi vill filtrera negativa tal. Om predikatet behåll är sant för talet behåller vi det, om behåll misslyckas (3:e regeln) kastar vi det.
Repetition Olikhet syskon(A, B) :- förälder(Förälder, A), förälder(Förälder, B), \+ (A = B). \+ (A = B), \+ A = B, A \= B Kan användas för att jämföra listor. Två listor är lika om de är lika långa och har samma element. Ex [a] \= [a]? No Inte olika d.v.s. LIKA! [a,b] \= [a] ? Yes Olika!
Dagens föreläsning Jämförelser –Större än, mindre än Ordnade listor Sortering av listor Insättningssortering Quicksort
Jämförelser Större än och mindre än För att jämföra tal använder man : 26<55 ? 102>3 ? Prolog kan inte jämföra variabler utan värden: ?- A < 11 Instantiation Error Man kan inte använda för att jämföra annat än tal (då får man ) ?- lisa < 167 Domain Error Större/mindre än eller lika med: >= och =< X>=Y Talet X är större eller lika med Y
Ordnade listor En lista är ordnad i stigande ordning om varje par av grannar är ordnat Listan [2,4,6,8,9] är ordnad om 2<4, 4<6, 6<8 och 8<9 En lista är ordnad om den är tom eller bara har ett element eller om de två första talen i listan är ordnade och resten av listan är ordnad. stigande_ordning([]). stigande_ordning([_]). stigande_ordning([M,N|Ns]):- M < N, stigande_ordning([N|Ns]).
Ordnade listor ?- stigande_ordning([2,4,6,9]). Yes Listor med duplikat anses inte ordnade: ?- stigande_ordning([1,2,3,3,4]) No Vi får felmeddelanden om vi inte ger en lista med tal t.ex. en lista med termer eller variabler ?- stigande_ordning([2,4,lisa,43]). \DOMAIN ERROR: …
Sortering av listor Sortering –Standardproblem inom databehandling –Hur sorterar vi objekt? Bokstavsordning, Storleksordning, Kronologisk ordning –Olika sorteringsmetoder, mer eller mindre effektiva. Bubble sort (enkel men ej effektiv) Insertion sort (insättningssortering) Quicksort (effektivare)
Insättningssortering Utgår från en tom lista och placerar sedan in ett element i taget. Andra elementet placeras in i listan antingen före eller efter det andra beroende på vilket som är ”störst”. Tredje elementet placeras in i rätt ordning i förhållande till de tidigare två etc. Man ser alltså till att listan är sorterad efter varje insättning.
Insert/3 Hur stoppar vi in ett tal i en redan ordnad lista? Vi har talet, en ordnad lista och listan med talet insatt. insert(Tal,[],[Tal]). insert(Tal,[N|Ns],[Tal,N|Ns]):- Tal<N. insert(Tal,[N|Ns],[N|NMs]:- Tal>N, insert(Tal,Ns,NMs). 1.Om listan är tom, skapa lista med talet 2.Talet mindre än huvudet, sätt först i listan 3.Talet större än huvudet, sätt huvudet först sortera svansen och talet.
Insättningssortering/2 För att sortera en given lista använder vi oss av vårt predikat insert. Den tomma listan är redan sorterad (basfall), en sammansatt lista sorteras genom att först sortera svansen och sedan stoppa in huvudet i den ordnade/sorterade listan med insert/3. insertsort([],[]). insertsort([Huvud|Svans],SorteradLista):- insertsort(Svans,SorteradSvans), insert(Huvud,SorteradSvans,SorteradLista). OBS! ordningen, vi måste först sortera svansen innan vi kan stoppa i huvudet. ?-insertsort([4,7,1,5], SorteradLista).
Sortera listor med duplikat Om vi försöker stoppa in ett tal som redan finns i listan, eller sortera en lista med duplikat så kommer anropen misslyckas eftersom det inte finns ngt passande fall. ?-insert(6,[2,4,6,8], Xs).No ?-insertsort([4,2,3,2,4],Zs). No Om vi vill kunna behandla de här fallen måste vi skriva om vårt predikat insert/3
Insättning av duplikat 1.Antingen ändrar vi Tal<N i andra basfallet till Tal=<N ?-insert(6,[2,4,6,8], Xs).Xs=[2,4,6,6,8] ?-insertsort([4,2,3,2,4],Zs). Zs=[2,2,3,4,4] 2.Eller så lägger vi till ett tredje basfall som gäller om talet och huvudet är lika. I så fall ska listan inte förändras. Insert(Tal,[Tal|Ns],[Tal|Ns]). ?-insert(6,[2,4,6,8], Xs).Xs=[2,4,6,8] ?-insertsort([4,2,3,2,4],Zs). Zs=[2,3,4]
Quicksort En snabbare sorteringsmetod är quicksort, som bygger på principen att man väljer ett element X och delar en given lista i två, där den ena listan innehåller alla element mindre än X och den andra med element som är större. Sedan sorterar man dessa listor var för sig för att slutligen sätta ihop dem till en sorterad lista.
Quicksort quicksort([],[]). quicksort([X|Xs],Sorted):- delning(Xs,X,Littles,Bigs), quicksort(Littles,Ls), quicksort(Bigs,Bs), append(Ls,[X|Bs],Sorted).
Delning/4 Predikatet delar en lista i två. Den ena med de små elementen och den andra med de stora. Vi jämför med ett givet tal. delning([],Y,[],[]). delning([X|Xs],Y,[X|Ls],Bs):- X =< Y, delning(Xs,Y,Ls,Bs). delning([X|Xs],Y,Ls,[X|Bs]):- X > Y, delning(Xs,Y,Ls,Bs).
Quicksort ?- quicksort([5,3,2,4],Sorted). Sorted = [2,3,4,5] ?- delning([3,2,4],5,Littles,Bigs). Littles= [3,2] Bigs= [4]
Tack för idag!