Föreläsning 9 i programmeringsparadigm. Unifiering (Brna Chapter 4.1). Repetition: I Haskell är mönster-passning (pattern-matchning) jättepraktiskt: När vi gör ett anrop av en funktion med ett visst argument mönster-passas argumentet mot olika mönster i funktionens definitioner : Ex Vi vill räkna ut f (Sq 6 7)(Chess ((Sq 2 3, NoChessman): [])) där f :: Square -> Chess -> Bool f _ (Chess [] ) = False f sq (Chess ((sq1, ch1):sqcms)) = sq == sq1 f sq (Chess sqcms) Första ekvationens vänsterled matchar inte; men den andra går bra och följande bindningar görs: f (Sq 6 7)(Chess ((Sq 2 3, NoChessman): [] )) -- argumentet f sq (Chess ((sq1, ch1) : sqcms)) -- vänsterledet sq binds till (Sq 6 7) sq1 binds till Sq 2 3 ch1 binds till NoChessman sqcms binds till [] Dessa bindningar används sedan i högerledet (utom ch1 varför man skulle kunna använda _ i stället i mönstret). Bindningarna görs till namnen (identifierarna) sq, sq1, ch1, sqcms. Namnen finns i mönstren i funktiondefinitionerna och namnen måste inledas med en gemen (liten bokstav). Konstruerarna skall stämma exakt, i vårt fall Chess, : (,) (Konstruerarna med namn har versal initial, börjar med stora bokstäver). Matchningen är "en-vägs", eftersom de namn som binds bara finns "på ena sidan", i mönstren i funkttionsdefinitonerna. Prolog : I Prolog kan bindningar (substitioner) göras till logiska variabler, med versal initial, medan värden (t ex atomer) har gemen intial. M a o är det tvärtom när det gäller gemener och versaler. Brna kallar matchning för unifiering. (Vissa författare skiljer på unifiering och matchning, den förenklade form av unifiering som används i Prolog av effektivitetsskäl). Unifieringen i Prolog är "två-vägs", eftersom logiska variabler kan finnas "på båda sidorna", både i det mål som Prolog försöker satisfiera och predikathuvuena (vänsterleden) i predikatens definitioner (de olika klausulerna) i databasen. I Prolog är unifiering det kanske allra viktigaste mekanismen för språkets funktion. Om unifieringen lyckas försöker Prolog använda klausulen, dvs satisfiera målen i klausulens kropp om en sådan finns. I prolog är unifiering fundamentalt för språkets semantik. Unifiering används för övrigt också i Haskell för att klura ut typer och kontrollera typer. Unifiering beskrevs första gången i detalj 1964 i en "landmark thesis" av Robinson. Unifiering är en mycket viktig teoretisk grundval för de båda deklarativa paradigmen (= logik- och funktionella paradigmen).
Byrd Box - modellen (Sökningarna i Brna Chapter 3 beskrivna med en variant av Box-modellen i Brna Chapter 5). En Byrd Box är ett grafiskt sätt att rita procedur-synen på ett predikat. Tre olika exempel : eller a(x):- b(x), och a/1 c(x). a(x) :- b(x), c(x). Procedurell läsnig: Proceduren Procedurell läsnig: Proceduren (med portar) a(x) : försök b(x) sedan ev. e(x) Logisk läsnig: Predikatet Logisk läsnig: Predikat med aritet (ställighet) 1 med med 1 klausuler, en regel 4 klausuler, alla faktum. med två konjugerade submål Exempel Byrd Box model förfrågan happy(p): e(x):- e(x):- e/1 g(x). h(x). eller e(x) :- g(x). e(x) :- h(x). Procedurell läsnig: Proceduren a(x) : försök b(x) eller e(x) Logisk läsnig: Predikat med 2 klausuler, 2 regler med varsitt submål, disjunkta. Byrd Box model för frågan happy(p) Program Database wise(jean). happy(p) :- happy(p) :- wealthy(p), happy(p) :- wise(p), e l l e r n y s a t s wealthy(p), wise(p), wise(jean). och,
En "körning" av Prolog kan spåras med trace och illustreras i Box-modellen. Genom att göra trace i Sixstus skriver Sixstus ut vad som händer på ett sätt som underlättar förståelsen av förloppet i Box-modellen. Två enkla körningar av ett predikat med fyra fakta illustrerade i Box-modellen: (streckade pilar skrivs ej ut av Sicstus)?- trace. {The debugger will first creep -- showing everything (trace)}?- 1 1 : woman(jean)? 1 1 : woman(jean)??- 1 1 : woman(joan)? 1 1 : woman(joan)? woman(jean) woman(joan) Dessa två körningar fungerar som motsvarande körning av denna Haskell-funktion woman :: Atom -> Bool -- Ett anrop motsvarar -porten woman Jean = True -- Resultatet True woman Jane = True -- motsvarar -porten woman Joan = True woman Pat = True woman _ = False -- False motsvarar -porten, no. Vi får svaret istället för True. I Prolog skall parametern/argument omges med (). I Prolog lämnar vi proceduren med -porten. Eftersom vi fått svar på vår fråga skriver Prolog. Körningar av ett predikat med fyra fakta som misslyckas:?- woman(eve). 1 1 : woman(eve)? 1 1 : woman(eve)? no Motsvarande Haskell-funktion skulle returnera False. I Prolog lämnar vi proceduren med -porten. Eftersom vi fått svar på vår fråga skriver Prolog no.
Körningar av ett predikat med fyra fakta. Frågan innehåller en logisk variabel. Prolog föreslår en substitution för att frågan skall kunna besvaras jakande. Vi är nöjda med Prologs första förslag till substitution:?- woman(w). 1 1 : woman(_206)?? 1 1 : woman(jean)? W = jean??- woman(w) W = jean? I körningen mönsterpassar ("matchar", unifierar) vi anropet woman(w), dvs ett anrop med en logisk variabel W, med ett "mönster med "ett värde" Sådan "baklänges" matchning gjorde vi aldrig i Haskell, men Prolog gör det och föreslår substitutionen W = jean?. Vi är nöjda ( bara vagnretur efer W = jean? ) så svarar sedan Prolog. Körning av ett predikat med fyra fakta. Frågan innehåller en logisk variabel. Vi vill ha flera förslag. Prolog föreslår en substitution för att frågan skall kunna besvaras jakande. Vi är dock ej nöjda med Prologs två första förslag till substitutioner, vilket vi visar genom att ge ; i stället för att ge vagnretur.?- woman(w). 1 1 : woman(_206)?? 1 1 : woman(jean)? W = jean? ; 1 1 : woman(jean)?? 1 1 : woman(jane)? W = jane? ; 1 1 : woman(jane)?? 1 1 : woman(joan)? W = joan? woman(w) W = jean?; W = jane?; W = joan?- I körningen tvingar vi Prolog att pröva ytterligare två gånger. Att Prologprocedurer kan "försöka igen med nästa klausul" illustreras med att vi använder -porten. Skulle vi inte vara nöjda med något förslag så svarar till slut Prolog no, dvs Prolog kan inte finna några ytterligare förslag till substitution av den logiska variablen som gör frågan sann.
Lyckad körning av ett predikat med regel: happy(jean) Byrd Box model för frågan happy(jean)?- happy(jean). 1 1 : happy(jean)? 2 2 : healthy(jean)? 2 2 : healthy(jean)? 3 2 : woman(jean)? 3 2 : woman(jean)?? 1 1 : happy(jean)? wealthy(p) avkortad bild Missyckad körning av ett predikat med regel: Byrd Box model för frågan happy(pat)?- happy(pat). 1 1 : happy(pat)? 2 2 : healthy(pat)? 2 2 : healthy(pat)? 3 2 : wealthy(pat)? 3 2 : wealthy(pat)? 4 2 : wise(pat)? 4 2 : wise(pat)? 1 1 : happy(pat)? no?- happy(pat) wealthy(p), wise(p), wise(jean)
Två körningar av ett predikat definierat med en regel. Frågor med logisk variabel : happy(p) Byrd Box model för frågan happy(p)?- happy(p). 1 1 : happy(_206)? 2 2 : healthy(_206)?? 2 2 : healthy(jim)? 3 2 : woman(jim)? 3 2 : woman(jim)? 2 2 : healthy(jim)?? 2 2 : healthy(jane)? 4 2 : woman(jane)? 4 2 : woman(jane)?? 1 1 : happy(jane)? P = jane? - - wealthy(p), - wise(p), wise(jean)?- happy(r). 1 1 : happy(_206)? 2 2 : healthy(_206)?... som ovan? 1 1 : happy(jane)? R = jane? ; 1 1 : happy(jane)? 2 2 : healthy(jane)? 2 2 : healthy(jean)? 5 2 : woman(jean)? 5 2 : woman(jean)?? 1 1 : happy(jean)? R = jane? happy(r) R = jean? ; 1 1 : happy(jean)? 6 2 : wealthy(_206)?? 6 2 : wealthy(jane)? 7 2 : woman(jane)? 7 2 : woman(jane)?? 1 1 : happy(jane)? Byrd Box model för frågan wealthy(p), wise(p), wise(jean) happy(p)
Prologs semantik (i procedurell syn) beskriven med Byrds boxmodell: 1. Anrop av procedure: Vi kommer in genom -porten (fungerar ungefär som vanliga programspråk): Vi finner ett faktum som unifierar. Vi finner ej någon klausul (regel eller faktum) med huvud som unifierar.... Vi finner en regel med huvud som unifierar. Vi gör ett anrop () på första delmål (subgoal) i koppen. 2. Förnyat försök att satisfiera en procedure: Vi kommer in genom -porten: Vi lämnade proceduren via ett faktum Vi finner ett nytt faktum som unifierar. (Vi kommer ihåg vilka vi redan testat) Vi lämnade proceduren via ett fakum Vi finner ej något ytterligarefaktum eller regel som unifierar. (Vi kommer ihåg vilka vi redan testat) Vi lämnade proceduren via ett fakum Vi finner en ny regel med huvud som unifierar. (Vi kommer ihåg regler/fakta vilka vi redan testat) Vi lämnade proceduren via en regel. 3. Kopplingar. Vi kommer ut genom -portar eller -portar : ( från frågan ger no)... =.... =..? Inga logiska Logiska variabler variabler i frågan. Förslag i frågan till substitution. Vi är nöjda. från procduren som är frågan.. =.... =..?; Logiska variabler i frågan. Förslag till substitution. Vi är ej nöjda.
talksabout(a, B) talksabout(a, B) Rekursion (Exemplet i Brna Chapter 4.2). talksabout(a, B):-. talksabout(a, B):- knows(a, C), talksabout(c,b). knows(bill, jane). knows(jane, pat). knows(jane, fred). knows(fred, bill). % Faktum. Ex på till-slut-på-raden-kommentar /* Körning?- talksabout(x, Y). Y = jane? ; X = jane, Y = pat? ; X = jane, Y = fred? ; X = fred, Y = bill? ; talksabout(a, B) talksabout(a, B) Y = pat? ; talksabout(a, B) Y = fred? ; Y = bill? ; Y = jane? ; Y = pat? ; */.