Oppgaver Prolog Bok Kapittel 11 Oppgave 11.1. Definer relasjoner /* Database */ /* mammas famile */ father( nicolai, edny ). father( nicolai, harald ). /* min famile */ father( rasmus, eva ). father( rasmus, liv ). father( rasmus, anne ). father( rasmus, janne ). /* onkel harald sin famile */ father( harald, kent ). /* mammas famile */ mother( jenny, edny ). mother( jenny, harald ). /* min famile */ mother( edny, eva ). mother( edny, liv ). mother( edny, anne ). mother( edny, janne ). /* liv og janne sin famile */ mother( liv, rene ). mother( liv, malin ). mother( janne, thomas ). mother( janne, kristian ). /* kvinner i familen */ female( jenny ). female( edny ). female( eva ). female( liv ). female( anne ). female( janne ). female( malin ). /* menn i familen */ male( nicolai ). male( rasmus ). male( harald ). male( rene ). male( thomas ). male( kristian ). male( kent ). 1
Oppgave 11.1 a /* Sibling, søster, bror */ /* A er søster til B hvis X er far til A og B og X er mor til A og B */ sibling(a,b) :- father(x,a), father(x,b), mother(y,a), mother(y,b), A\==B. Oppgave 11.1 b /* Bare søster */ /* A er søster til B hvis A er kvinne og A er søster/bror til B */ sister(a,b) :- female(a), sibling(a,b), A\==B. Oppgave 11.1 c /* Grandson */ /* A er barnebarn til B hvis A er mann, og mor til A er datter til B */ grandson(a,b) :- male(a), mother(b,c), mother(c,a). Oppgave 11.1 d /* Fetter, kusine*/ /* A er fetter til B hvis mann, mor til A og B er søsken */ cousin(a,b) :- male(a), mother(c,a), mother(d,b), sibling(c,d), A\==B. Oppgave 11.2 a, Finne 3. element Listen Xs = [10, 20, 30, 40]. Xs = [ a, b, c, d ]. :- Xs = [ _, _, Y _ ]. // Den siste _ henviser til resten av listen pga // Må ha :- hvis dette legges i en fil, interaktiv uten :- Ved bruk av append :- append( [], Xs, [ _, _, Y _ ]). Får svar I tall Xs = [_G160, _G163, _G166 _G167] Y = _G166 append( [], [a, b, c, d], [_, _, Y _]). Y = c [a, b, c, d] = [_, _, Y _]. Y = c?- append([1,2,],[x [4,5]],[1,2,3,4,5]). X = 3 app([1,2,3],[4,5,6],[1,2,x,4,5,6]). X = 3 2
Oppgave 11.2 b, Finne siste element Xs = [10, 20, 30, 40]. :- append( _, [Y], Xs). Y = _G160 Xs = [_G160] // _ er [10, 20, 30] // [Y] er [40] // _ skal konkratineres med Y for å få Xs // Siden [Y], henviser til kun ett element, derfor må Y være [40] // [ _, _.] siden _ i en liste henviser _ til hvert element i listen // ( _. _ ) siden _ ikke er i en lise kan _ henvise til en hel liste, en _ kan matche en hel // liste?- append([1,2,3,4],x,[1,2,3,4,5]). X = [5] Oppgave 11.2c, Finne alle unntatt siste element Xs = [a, b, c, d]. :- append(y, [_], Xs). :- append(y, [_],[a, b, c, d]). Y = [a, b, c]?- append(x,[5],[1,2,3,4,5]). X = [1,2,3,4] Oppgave 11.2 d, Finne om listen består av 3 like kopier Xs = [10, 20, 10, 20, 10, 20]. Ys = [10, 20]. // Sekvens som gjentas 3 ganger :- append (Ys, Ys, Zs), append(zs, Ys, Xs). // Første sekvens 10, 20 er Ys, andre sekvens 10, 20 er Ys, tredje sekvens 10, 20 er Ys // Første og andre sekvens sammen er Zs // Første append setter sammen Ys (første sekvens) med Ys (andre sekvens) til Zs // Andre append Zs (første og andre sekvens) med Ys (tredje sekvens) sjekker om dette // blir Xs **Oppgave 11.2 e. Hvis liste Y er lik liste X + element A et eller annet sted i liste X Alternativer: append([1,2,3,4], 1, [1,1,2,3,4] eller [1,2,1,3,4] eller [1,2,3,1,4] eller [1,2,3,4,1]) X A Y 3
Oppgave 11.3 a. Er en liste en permutasjon av en annen liste Alternativer: - [1,2,3] er en permutasjon til [3,2,1] - [1,2,4] er ikke en permutasjon til [3,2,1] permutasjon([], []). # Permutasjon av en tom liste er en tom liste permutasjon([x Y], Z) :- permutasjon(y, W), taut(x, Z, W). # Z er en permutasjon av [X Y] gitt at W er en permutasjon av Y og da settes X inn i W for å gi Z taut(x, [X R], R). # Når X er tatt ut av [X R] står R igjen taut(x, [F R], [F S]) :- taut(x, R, S). # Når X tas ut at halen til [F R] får man [F S], her er S resultatet ved at man tar ut F av R?- permutasjon([2,1,3], [3,2,1]).?- permutasjon([1,2,3], [3,2,1]).?- permutasjon([1,2,4], [3,2,1]). Oppgave 11.3 b. Er antall elementer i listen partall Alternativer: - [1,2,3,4] - [1,2,3] even_length([]). even_length([x, Y Rest]) :- even_length(rest).?- even_lengtn([1,2,3]).?- even_lengtn([1,2,3,4]). 4
Oppgave 11.3 c. Er en liste laget ved å merge to lister Bruke append. app er lik append Alternativer: - [1,2,3], [4,5], [1,2,3,4,5] - [1,2,3], [4,5], [1,2,3,4,6] app([], X, X). # Legge til en tom liste til X gir X app([x Y], Z, [X W]) :- app(y, Z, W). # Legge til listen X Y til Z gir listen X W hvis det å legge til Y og Z gir W?- app([1,2,3], [3,4,5], [1,2,3,3,4,5]).?- app([1,2,3], [3,4,5], [1,2,3,3,4,6]). Oppgave 11.3 d. Er en liste et palindrom Alternativer: - [1,2,3,2,1], [a,b,a] - [1,2,3,3,1], [s,e,g,d,c,s] % palindrome( list ) is true if List is a palindrome. palindrome( List ) :- reverse( List, List ). %reverse( L1, L2 ) is true is list L2 is the in reverse order of list L1. reverse( [], [] ). % base case reverse( [X Tail ], Rev_List ) :- reverse( Tail, Rev_Tail ), conc( Rev_Tail, [X], Rev_List ). %conc(l1, L2, L3) is true if L3 is the result of concatenating lists L1 and L2 conc( [], L, L). %base case the empty list conc( [X L1], L2, [X L3] ) :- conc( L1, L2, L3 ). % smaller caller case?- palindrome([1,2,3,3,2,1]).?- palindrome([a,b,a]).?- palindrome([1,2,3,3,1]).?- palindrome([s,e,g,d,c,s]). 5
Oppave 11.6 a. Lag en relasjon til fact funksjon fact(0, 1). fact(n, F) :- N > 0, N1 is N-1, fact(n1, F1), F is N * F1. [ fil.pl ]. Kan brukes både for å finne ut hva fact til N blir?- fact(4, Z). Z = 24 Kan også brukes for å finne ut om fact til et N er M (N=4, M=24)?- fact(4, 24). Oppgave 11.6 b. Lag en fact funksjon som er halerekursiv fact2(0, F, F). fact2(n, A, F) :- N > 0, A1 is N * A, N1 is N-1, fact2(n1, A1, F). [ fact2.pl ]?- fact2(4, 1, F). F = 24 Oppgave 11.8 a, tegn et søketre til member(b, [a,b,c]). :- member(b, [a, b, c]). :- member(b, [b, c]). true 6
Oppgave 11.8 b, tegn et søketre til member(d, [a,b,c]). :- member(d, [a, b, c]). :- member(d, [b, c]). :- member(d, [c]). :- member(d, []). fail Oppgave 11.9 b, sjekke om et element finnes i en listen Finnes M i en liste member( M, [M _ ]). // Sjekker om M er lik første element I listen member (M, [_ T ]) :- member (M, T). // M er ikke lik første element, tar resten av listen og kaller metoden igjen med resten av listen (T) :- member (X, [1, 2, 3]). // X matcher 1, 2, og 3 i tur og orden :- X = [1, 2, 3], member(a, X). // a er en constant, sjekke om a finnes I listen X Tre :- X = [1, 2, 3], member (a, X) // X = [1, 2, 3] :- member(a, [1, 2, 3]). :- member(a, [2, 3]). :- member(a, [3]). :- member(a, []). fail Ved true stopper, viser svar. Hvis du trykker ; backtracker og søker etter flere løsninger. 7
Andre ting del (5, [1, 5, 8], Xs) // Xs = [1, 8] :- del (X, [1, 5, 8], Xs). // X = 1, Xs = [5, 8] // X= 5, Xs [1, 8] // X= 8, Xs = [1, 5] NB!! Prolog har dybde søk først Length of a list can thus be defined as follows: length([], 0). length([head Tail], Length) :- length(tail, Tail_length), Length is Tail_length + 1. 8
Andre oppgaver Oppgave 1a, skriv queries for alle personer under 25 år person(john, 45, 187). person(adam, 34, 155). person(liza, 23, 178). person(eva, 21, 134). person(stig, 30, 177). person(frode, 51, 187). [ person.pl].?-person(x, Y, _), Y < 25. X = liza Y = 23 ; X = eva Y = 21?- person(x,y,z), X = _, Y < 25, Z = _. Oppgave 1b skriv queries for alle personer som heter stig eller frode og er enten minst 31 år eller kortere enn 180 cm?- person(x, Y, Z), (X = stig ; X = frode), (Y >= 31 ; Z < 180). Er navnet stig eller frode og at alder er større eller lik 31 eller høyde mindre enn 180?- person(x,y,z), (X = 'Frode' X = 'Stig'), ((Y < 30, Z < 180) (Y > 30)). X = stig Y = 30 Z = 177 ; stig riktig navn (true) er yngre enn 30 (false) mindre enn 180 (true) X = frode Y = 51 Z = 187 ; frode riktig navn (true) er eldre enn 31 (true) høyere enn 180 (false) 9
person1(stig, 30, 177). person1(frode, 27, 187). [ person1.pl ].?- person1(x, Y, Z), (X = stig ; X = frode), (Y >= 31 ; Z < 180). X = stig Y = 30 Z = 177 ; frode ikke lengre med. Alder er mindre enn 31 samtidig som høyden er større enn 180 Oppgave 2, svarsubstituasjon for A i følgende program member( X, [X Xs]). du finner X i listen og X er første element member( X, [_ Xs]) :- member( X, Xs). du finner X i listen som har en tail Xs hvis X finnes i Xs A er en variable, setter inn A der starter med p :- member( p(a), [p(f(g)), g(w), p(10), p(r)]). A = f(g) A = 10 A = r Listen består av 4 elementer, P(f(g)), g(w), p(10), p(r) Skal finne ut om p(a) er I listen. A er en variable og kan da inneholde ulike ting 10