1 / 57

L OGIC P ROGRAMMING with P ROLOG

"Programming Paradigms", Dept. of Computer Science, Aalborg Uni. (Fall 2009). L OGIC P ROGRAMMING with P ROLOG. Claus Brabrand brabrand@itu.dk IT University of Copenhagen [ http://www.itu.dk/people/brabrand/ ]. Plan for Today. Lecture: "Lists and Arithmetic" ( 10:15 – 11:00 )

abeni
Download Presentation

L OGIC P ROGRAMMING with P ROLOG

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. "Programming Paradigms", Dept. of Computer Science, Aalborg Uni. (Fall 2009) LOGIC PROGRAMMINGwith PROLOG Claus Brabrand brabrand@itu.dk IT University of Copenhagen [http://www.itu.dk/people/brabrand/]

  2. Plan for Today • Lecture: "Lists and Arithmetic" (10:15 – 11:00) • Exercise 1, 2, and 3 (11:15 – 12:00) • Lunch break (12:00 – 12:30) • Lecture: "Reversibility, Cut, Negation, and Language Interpretation" (12:30 – 13:15) • Lecture: "Non-termination and Undecidability” (13:30 – 14:00) • Exercises 4, 5, and 6 (14:15 – 16:15)

  3. Outline • Part 1: • Lists • Arithmetic • Part 2: • Reversibility • Cut and Negation • Language Interpretation • Part 3: • Non-termination • Undecidability

  4. PROLOG's Search Order axioms (5x) f(a). f(b). g(a). g(b). h(b). k(X) :- f(X),g(X),h(X). rule (1x) rule body rule head • Resolution: • 1. Search knowledge base (from top to bottom) for(axiomor rule head) matching with (first)goal: • Axiom match:remove goal and process nextgoal[1] • Rule match: (as in this case): [2] • No match:backtrack(= undo; try next choice in 1.) [1] • 2. "-convert" variables (to avoid name clashes, later): • Goal: (record “Y = _G225”) • Match: [3] • 3. Replace goal with rule body: • Now resolvenew goals (from left to right); [1] k(Y) k(X) :- f(X),g(X),h(X). k(_G225) k(_G225) :- f(_G225),g(_G225),h(_G225). f(_G225),g(_G225),h(_G225). Possible outcomes: - success: no more goals to match (all matched w/ axioms and removed) - failure: unmatched goal (tried all possibilities: exhaustive backtracking) -non-termination: inherent risk (same- / bigger-and-bigger- / more-and-more -goals)

  5. LISTS Keywords: (Encoded) lists, (built-in) lists, efficiency issues, ...

  6. Lists (home-made) • Lists are easily represented: • // empty list • // construct new list from element and list • Example: • The list [1,2,3] may be representedas: • i.e., "representation of information" • Now, let's look at: ~Haskell nil cons(E,L) cons(1, cons(2, cons(3, nil))) "Transformation of representation of information" (= programming)

  7. T Lists (example "functions") • Length: • Member: • Using underscore '_'(anonymous "ignore" variable)may improve readability len(0, nil). len(succ(N), cons(_, L)) :- len(N, L). len(0, nil). len(succ(N), cons(E, L)) :- len(N, L). member(X, cons(X, _)). member(X, cons(_, L)) :- member(X, L). member(X, cons(X, L)). member(X, cons(E, L)) :- member(X, L). PROLOG also has built-in lists; let’s have a look at them…

  8. Lists (built-in) • Constant lists: • // the empty list • // constant list • Lists are (also) untyped;=finite sequence of (any) terms: • [] • [ [] ] • [ vincent, jules, marcellus ] • [ [], mia, 42, 'The Gimp', dead(zed), Z ] • [ [], [], [ [] ], [ [ x, X , [] ] ] ] ~Haskell [] [ X, Y, Z ] Q: What is the length of the lists?

  9. The Head-Tail Constructor • PROLOG(like many other languages) has: • // "head-tail constructor" • Hhead (element) of list, Ttail of list (rest) • for construction and deconstruction: (bigger) list element and (smaller) list • Example: “construction”: • Example: “deconstruction”: ~Haskell h:t [ H | T ] ?- [ a | [b,c] ]= L. L = [a,b,c] ?- [a,b,c]= [ H | T ]. H = a T = [b,c]

  10. Examples: “[ H | T ]” • Empty list example: • Mixed type example: • Tricky’ish example: ?- []= [ H | T ]. No ?- [ [], mia, 42, 'The Gimp', dead(zed), Z ]= [ X | Y ]. X = [] Y = [ mia, 42, 'The Gimp', dead(zed), _G225 ] Z = _G225 ?- [ [], [] ] = [ X | Y ]. X = [] Y = [ [] ]

  11. Length and Member (revisited) ~ Haskell • Length/2: • Member/2: • Usage: len(0, []). len(succ(N), [ _|L ]) :- len(N, L). member(X, [ X|_ ]). member(X, [ _|L ]) :- member(X, L). ?- member(2, [1,2,3]). Yes ?- member(X, [1,2,3]). // gimme elements from list X=1 ; // next... X=2 ; X=3 ; No

  12. T Append append([], L, L). append([X|L1], L2, [X|L3]) :- append(L1,L2,L3). • Append/3: Search treefor: ?- append([a,b,c], [d,e,f], R) R= [a,b,c,d,e,f] append([a,b,c],[d,e,f],_G1) append([a,b,c],[d,e,f],[a,b,c,d,e,f]) rule _G1 = [a|_G2] append([b,c],[d,e,f],_G2) append([b,c],[d,e,f],[b,c,d,e,f]) _G2 = [b|_G3] rule append([c],[d,e,f],_G3) append([c],[d,e,f],[c,d,e,f]) rule _G3 = [c|_G4] append([],[d,e,f],_G4) append([],[d,e,f],[d,e,f]) axiom _G4 = [d,e,f]

  13. Using Append • Prefix/2: • Suffix/2: • SubList/2: ...alternatively...: prefix(P, L) :- append(P, _, L). suffix(S, L) :- append(_, S, L). subList(Lsub, L) :- suffix(S, L), prefix(Lsub, S). subList(Lsub, L) :- prefix(P, L), suffix(Lsub, P).

  14. Reverse (and efficiency issues) • Reverse/2: • Idea; exploit property: “(x L)R = LR x” • Problem: [X|L] is asymmetrically left-to-right biased we cannot put the list in front and write: “[ L | X ]” • Let's useappend: rev([], []). rev([X|L], R) :- rev(L, L_rev), [L_rev | X] = R. rev([X|L], R) :- rev(L, L_rev), append(L_rev, [X], R). Q: What about efficiency? 1) …of append? ; 2) …of reverse?

  15. Recall ("big-Odefinition"): f O(g) def n,k>0: N>n => |f(N)|  k·|g(N)| "f is dominated by g for large values (larger than n)" Efficiency • Efficiency(append): • Efficiency(reverse): |arg1|+1 app([], L, L). app([X|L1], L2, [X|L3]) :- app(L1,L2,L3). O(|arg1|) rev([], []). rev([H|T], R) :- rev(T,TR), app(TR,[H],R). Q: Efficiency(reverse)...?

  16. Search Tree: rev rev([], []). rev([H|T], R) :- rev(T,TR), app(TR,[H],R). rev([1, 2, 3], _G1) rev rule rev([2, 3], _G2), app(_G2, [1], _G1) |L|+1 steps (of reverse) rev rule O(|L|) rev([3], _G3), app(_G3, [2], _G2), app(_G2, [1], _G1) rev rule rev([], _G4), app(_G4, [3], _G3), app(_G3, [2], _G2), app(_G2, [1], _G1) + _G4 = [] rev axiom app([], [3], _G3), app(_G3, [2], _G2), app(_G2, [1], _G1) _G3 = [3] (1 step of append) app([3], [2], _G2), app(_G2, [1], _G1) 1+2+3 steps (of append) _G2 = [3,2] (2 steps of append) O(|L|2) app([3,2], [1], _G1) _G1 = [3,2,1] (3' append)

  17. T Accumulator • Let's use an accumulator: ~ Haskell accRev([H|T], A, R) :- accRev(T, [H|A], R). accRev([], A, A). rev(L, R) :- accRev(L, [], R). oldRev vs. newRev: rev([1,2,3], _G1) 1 step (of rev) steps rev rule + O(n2) accRev([1,2,3], [], _G1) accRev rule oldRev accRev([2,3], [1], _G1) |L| steps (of accRev) accRev rule O(|L|) O(n) accRev([3], [2,1], _G1) newRev accRev rule accRev([], [3,2,1], _G1) 0 1 2 3 4 5 6 7 8 |L|

  18. ARITHMETIC Keywords: Evaluation, ...

  19. Binary Infix Functors: {+,-,*,/} • Consider: • What is going on...?!? • The symbols {+,-,*,/} are just: • (Binary) infix functors: • i.e., "2+2" is just a short-hand for "+(2,2)"; • in fact: ?-2+2 = 4 No ?-2*2 = 4 No ?-2-2 = 0 No ?-2/2 = 1 No ~ Haskell ?-2+2 = +(2,2) Yes

  20. Binary Infix Functors (cont'd) • The symbols {+,-,*,/} just (conveniently)represent structured information: • is understood as • precedence:{*,/}stronger-than{+,-} • associativity:{+,-,*,/}left-associative • ...and is thus just a short-hand for: • ...which is, structurally, no different than: • However, their interpretation may be very different;e.g., "represents" an expression that may be evaluated 1-2/3+4*5*6 (1-(2/3))+((4*5)*6) "standard" precedence/ associativityrules +(-(1,/(2,3)),*(*(4,5),6) a(b(1,c(2,3)),d(d(4,5),6) ~ Haskell

  21. The "is/2" Predicate • is/2 TERM TERM: • Evaluatesits right argument(as arithmetic expression) • ...provided all variables are instantiated! • Example (in predicate definition): ?-4 is 2+2 Yes ?-2+2 is 4 No ?-Xis 2+2 X=4 ?-2+2 isX *** ERROR: is/2: uninstantiated argument sq(X,Y) :- YisX*X. ?- sq(5,Y). Y=25 ?- sq(X,25). *** ERROR: is/2: uninstantiated argument

  22. T Careful w/ Arithmetic Evaluation ...with unary encoding of numerals: • Recall "len/2": • Arithmetic version(s): len([], 0). len([_|L], succ(N)) :- len(L, N). len1([], 0). len1([_|L], N_succ) :- len1(L, N), NisN_succ-1.  ?-len1([1,2,3], R). *** ERROR: is/2: uninstantiated argument len2([], 0). len2([_|L], N) :- len2(L, N_pred), NisN_pred+1.  ?-len2([1,2,3], R). R=3 len3([], 0). len3([_|L], N) :- NisN_pred+1, len3(L, N_pred).  -?len3([1,2,3], R). *** ERROR: is/2: uninstantiated argument

  23. Accumulators (revisited) • "len/2": • Version withaccumulator: len([], 0). len([_|T], N) :- len(T, X), NisX+1. accLen([], A, A). accLen([_|T], A, N) :- AnewisA+1, accLen(T, Anew, N) len(List, Length) :- accLen(List, 0, Length). Same #steps (both 7x)… len([1,2,3], _G1) accLen([1,2,3], 0, _G1) However;NOT tail recursive: "calculation after recursion" len rule accLen rule; then "is" len([2,3], _G2), _G1 is _G2+1 accLen([2,3], 1, _G1) len rule accLen rule; then "is" len([3], _G3), _G2 is _G3+1, _G1 is _G2+1 accLen([3], 2, _G1) O(n) wide! len rule accLen rule; then "is" len([], _G4), _G3 is _G4+1, _G2 is _G3+1, _G1 is _G2+1 accLen([], 3, _G1) accLen axiom len axiom is is is Tail recursive! "calculation during recursion" _G3 is 0+1, _G2 is _G3+1, _G1 is _G2+1 ~ Haskell

  24. Comparison Operators • More integer comparison operators (with arithmetic evaluation side-effects): • "<""less than" • "<=""less than or equal to" • ">""greater than" • ">=""greater than or equal to" • "=:=""equal to" • "=\=""not equal to" • Evaluate both arguments • Again, all variables have to be instantiated • Otherwise no surprises...

  25. Exercise 1, 2, and 3: 11:15 – 12:00

  26. 1. ... • Purpose: • Learn how to ...

  27. 2. ... • Purpose: • Learn how to ...

  28. 3. ... • Purpose: • Learn how to ...

  29. REVERSIBILITY

  30. Ex: Symbolic Differentiation • Symbolic differentiation: d dx d dx (k) = 0 (xn) = n * xn-1 d dx d dx (x) = 1 (ex) = ex 1 x d dx d dx d dx d dx (f+g) = (f) + (g) (ln(x)) = d dx d dx d dx d dx (f-g) = (f) - (g) (sin(x)) = cos(x) d dx d dx d dx d dx (f*g) = f (g) + g (f) (cos(x)) = -sin(x) d dx d dx g (f) + f ( ) (g) d dx d dx d dx d dx (f/g) = (gof) = (g)o f * (f) g * g

  31. ...in PROLOG ex • In PROLOG: dX(K, 0) :- number(K). // constant dX(x, 1). // variable dX(F+G, Df+Dg) :- dX(F,Df), dX(G,Dg). // add dX(F-G, Df-Dg) :- dX(F,Df), dX(G,Dg). // sub dX(F*G, Df*G+F*Dg) :- dX(F, Df), dX(G, Dg). // mul dX(F/G, (Df*G-F*Dg)/(G*G)) :- dX(F, Df), dX(G, Dg). // div [...] dX(cos(x), 0-sin(x)). // cos dX(F;G, (F;Dg)*Df) :- dX(F,Df), dX(G,Dg). // compose

  32. Differentiation • Interaction: • Reverse: • Does this mean we can do integration? • No, just certain functions in "anti - normal form" (ANF); i.e., functions that are in the image of the differentiation ?- dX(x/exp(x), Df). Df=(1*exp(x)-x*exp(x)) / (exp(x)*exp(x)) ?- dX(F,(1*exp(x)-x*exp(x)) / (exp(x)*exp(x))). F=x/exp(x) ANF f' f

  33. CUT AND NEGATION Keywords (chapter 10): Side-effect, Backtracking, Cut, Fail, Cut-Fail, Negation, ...

  34. The Cut Operator: '!' • Consider max/3: • Cut, "!", (locally) disablesbacktracking • Cut version: • Note: this cut changes only efficiency properties = "Green Cut" max(X,Y,Y) :- X =< Y. max(X,Y,X) :- X > Y. Note: mutually exclusive conditions ?- max(3,4,M). M = 4 ?-; // backtracking now causes futile re-evaluation of max max(X,Y,Y) :- X =< Y , ! . // commit (throw away max-backtracking) max(X,Y,X) :- X > Y.

  35. "Green Cuts" vs. "Red Cuts" • "Green cut" version: • Alternative "Red cut" version (= relying on cut): • Seems okay...: • ...but: max(X,Y,Y) :- X =< Y , ! . max(X,Y,X) :- X > Y. max(X,Y,Y) :- X =< Y , ! . max(X,Y,X). // only succeeds if above fails (...or?) ?-max(99,100,X). X = 100 // ok! ?-max(100,99,X). X = 100 // ok! Advice: "cut down on cut" ?- max(1,100,1). Yes // Oops!(evaluation never made it to the cut)

  36. Fail and exception predicating • Consider: • ...but maybe Vincent likes all burgers, except "Big Kahuna burgers". • PROLOG features a built-in "fail/0"-predicate: • Syntax: • Semantics: "always fails (and forces backtracking)" enjoys(vincent, X) :- burger(X). fail enjoys(vincent, X) :- big_kahuna_burger(X), !, fail enjoys(vincent, X) :- burger(X). the rulerelies (operationally) on the cut = red cut big_kahuna_burger(b1). big_mac(b0). ?- enjoys(vincent, b0). Yes ?- enjoys(vincent, b1). No

  37. The Cut-Fail Combination • The "cut-failcombination"... • ...expresses negation • ...and is so common that it is built-in: • not/1; equivalent to: • It's better to use "not" • it's a higher level abstraction (than cut-fail); However...: enjoys(vincent, X) :- big_kahuna_burger(X), !, fail enjoys(vincent, X) :- burger(X). not(Goal) :- Goal, !, fail. not(Goal). Cut has operationally(well-)defined semantics which relation ?! Isn't always "well-defined": |_ P(x) |_ P(x) Inf. Sys. vs. PROLOG p(x) :- not(p(x)).

  38. If-then-else: "( A -> B ; C )" • PROLOG has an if-then-else construction: • Syntax: • ( A -> B ; C ) • Semantics: • "if A; then B, else C" • Alternative version of max/3: • ...using if-then-else: max(X,Y,Z) :- ( X =< Y -> Z = Y ; Z = X ).

  39. LANGUAGE INTERPRETATION Keywords: Interpretation, Evaluation, Syntax, Semantics, ...

  40. Expressions (and syntax vs. semantics) • Expressions: • Syntax: • Semantics(via evaluation relation: " |-eval  Exp  N"): Exp: N [const] : +(Exp,Exp) [add] : *(Exp,Exp) [mul] here in prefix notationjust to emphasize difference between syntax and semantics |_evalE1N1|_evalE2 N2 |_eval+(E1,E2)N [add] N = N1  N2 [const] semantic  |_evalNN syntactic "+" |_evalE1N1|_evalE2N2 |_eval*(E1,E2)N [mul] N = N1  N2 multiple levels of abstraction...!

  41. Alice and Knight talking Alice in Wonderland • Different levels of abstraction: • Things ‘A Sitting on a Gate’ • Names of things ‘The Aged Aged Man.’ • Things are called something ‘Ways and Means’ • Names are called something ‘Haddocks’ Eyes.’ K> "[...] The name of the song is called‘Haddocks’ Eyes.’” A> “Oh, that’s the name of the song, is it?” Alice said, trying to feel interested.K> “No, you don’t understand,” the Knight said, looking a little vexed. K> “That’s what the name is called. The name really is ‘The Aged Aged Man.’” A> “Then I ought to have said, ‘That’s what the song is called’?” Alice corrected herself. K> “No, you oughtn’t: that’s another thing. The song is called‘Ways and Means’: K> but that’s only what it’s called, you know!” A> “Well, what is the song, then?” said Alice, who was by this time completely bewildered. K> “I was coming to that,” the Knight said. “The song really is‘A Sitting on a Gate’: K> and the tune’s my own invention.”

  42. [...back to]:(syntax vs. semantics) • Expressions: • Syntax: • Semantics(via evaluation relation: " |-eval  Exp  N"): Exp: N [const] : +(Exp,Exp) [add] : *(Exp,Exp) [mul] here in prefix notationjust to emphasize difference between syntax and semantics |_evalE1N1|_evalE2 N2 |_eval+(E1,E2)N [add] N = N1  N2 [const] semantic  |_evalNN syntactic "+" |_evalE1N1|_evalE2N2 |_eval*(E1,E2)N [mul] N = N1  N2

  43. Expressions (in PROLOG) • Syntax: • Semantics: exp(con(N)) :- number(N). exp(add(E1,E2)) :- exp(E1), exp(E2). exp(mul(E1,E2)) :- exp(E1), exp(E2). ?-exp(mul(add(con(2),con(4)),con(7))). Yes eval(con(N), N). eval(add(E1,E2),N) :- eval(E1,N1), eval(E2,N2), N is N1 + N2. eval(mul(E1,E2),N) :- eval(E1,N1), eval(E2,N2), N is N1 * N2. ?-eval(mul(add(con(2),con(4)),con(7)),X). X = 42 binary infix syntax binary infix syntax eval(N, N) :- number(N). eval(E1+E2,N):- eval(E1,N1), eval(E2,N2), N is N1 + N2. eval(E1*E2,N):- eval(E1,N1), eval(E2,N2), N is N1 * N2. ?-eval((2+4)*7,X). X = 42

  44. The "WHILE" Language • The "WHILE" Language: • Syntax: • Semantics: • Similar techniques (albeit somewhat more complicated)... Exp : N// const : X// var : ExpExp,   {+,-,*,/}// binop Com : skip// skip : X := Exp// assign : if ( Exp ) thenComelseCom// if : while( Exp ) doCom// while : Com; Com// sequence

  45. The Lambda Calculus • The Lambda Calculus • Syntax: • Semantics (call-by-value): You only have to understand here that The Lambda Calculus can be encoded in PROLOG  : VAR  Z Note: this is a variant of the semantics you saw earlier

  46. The Lambda Calculus (in PROLOG) • Syntax: • << Exercise 4 >> • Semantics: • Similar techniques (as with the expression language) ?- eval(apply(lambda(x,variable(x)), lambda(y,variable(y)), Res). Res = lambda(y,variable(y))

  47. NON-TERMINATION Keywords: Turing-Completeness, Reduction, Self-referentiality, Undecidability, ...

  48. Prolog • A French programming language (from 1971): • "Programmation en Logique"(="programming in logic") • A declarative, relationalstyle of programming based on first-order logic: • Originally intended for natural-language processing, but has been used for many different purposes (esp. for programming artificial intelligence). • The programmer writes a "database" of "facts" and "rules"; e.g.: • The user then supplies a "goal" which the system attempts toprove(using resolution and backtracking); e.g., witch(girl). %- RULES ---------- witch(X) :- burns(X) , female(X). burns(X) :- wooden(X). wooden(X) :- floats(X). floats(X) :- sameweight(X,Y) , floats(Y). %- FACTS ---------- female(girl). floats(duck). sameweight(girl,duck).

  49. Undecidability • Consider "The Book-of-all-Books": • This book contains the titles of all books that do not have a self-reference(i.e. don't contain their title inside) • Finitely many books; i.e.: • We can sit down & figure out whether to include or not... • Q: What about "The Book-of-all-Books"; • Should it be included or not? • "Self-referential paradox"(many guises): • e.g. "Thissentence is false" "The Bible" "War and Peace" "ProgrammingLanguages, An Interp.-Based Approach" ... The Book-of-all-Books  

  50. Undecidability (of Termination) • Assume termination is decidable (in Java); • i.e.  some program, halts: PROG  BOOL • Q: Does P0loop or terminate...? :) • Hence: "Termination is undecidable" • ...for WHILE, Java, C, Lambda Calculus, Prolog, ... boolhalts(prog p) { ... } -- P0.prg -- prog p0 = read_program("P0.prg"); if (halts(p0) == "halts") loop(); elsehalt();

More Related