Outline for today Logic Programming Lecture 3: Recursion, lists, and data structures • Recursion • • proof search behavior practical concerns • List processing • Programming with terms as data structures James Cheney Recursion (mostly) • Nothing to it? ancestor(X,Y) :- parent(X,Y). ancestor(X,Y) :- parent(X,Z), not Turing-complete ancestor(Z,Y). can't define transitive closure • October 3, 2011 Recursion (1) • So far we've used nonrecursive rules • These are limited: • • Logic Programming • Just use recursively defined predicate as a e.g. ancestor goal. • Easy, right? James Cheney Logic Programming October 3, 2011 James Cheney Logic Programming October 3, 2011 • Depth first search, revisited Prolog tries rules depth-first in program order • • no matter what • Rule order can matter. ancestor2(X,Y) :- parent(X,Z), Even if there is an "obvious" solution using later clauses! p :- p. • Recursion (2) ancestor2(Z,Y). ancestor2(X,Y) :- parent(X,Y). This may be less efficient (tries to find longest path first) p. This may also loop unnecessarily (if parent were cyclic). will always loop on first rule. Heuristic: write base case rules first. James Cheney Logic Programming October 3, 2011 Rule order matters parent(a,b). parent(b,c). October 3, 2011 Rule order matters parent(a,b) ancestor(a,b) parent(a,Z),ancestor(Z,b) Z = b ancestor(b,b) Logic Programming parent(a,b). parent(b,a). ancestor(a,b) parent(a,Z),ancestor(Z,b) James Cheney Z = b ancestor(b,b) done parent(b,W),ancestor(W,b) W = a ancestor(a,b) ... James Cheney Logic Programming October 3, 2011 James Cheney Logic Programming October 3, 2011 Recursion (3) • Goal order matters parent(a,b). parent(b,c). Goal order can matter. ancestor(a,b) ancestor3(X,Y) :- parent(X,Y). ancestor3(X,Y) :- ancestor3(Z,Y), parent(a,b) parent(X,Z). done ancestor(Z,b),parent(a,Z) This will list all solutions, then loop. Z = a parent(a,a) James Cheney Logic Programming ancestor(W,b), parent(Z,W), parent(a,Z) parent(Z,b), parent(a,Z) October 3, 2011 Recursion (4) James Cheney ... Logic Programming ... October 3, 2011 Goal order matters • Goal order can matter. ancestor(X,Y) ancestor4(X,Y) :- ancestor4(Z,Y), ancestor(X,Z), parent(Z,Y) parent(X,Z). ancestor(X,W), parent(W,Z), parent(Z,Y) ancestor4(X,Y) :- parent(X,Y). This will always loop! ancestor(X,V), parent(V,W), parent(W,Z), parent(Z,Y) Heuristic: try non-recursive goals first. ancestor(X,U), parent(U,V), parent(V,W), parent(W,Z), parent(Z,Y) ... James Cheney Logic Programming October 3, 2011 James Cheney Logic Programming October 3, 2011 Recursion and terms • Terms can be arbitrarily nested • Example: unary natural numbers • Example: addition add(z,N,N). add(s(N),M,s(P)) :- add(N,M,P). nat(z). nat(s(N)) :- nat(N). • To do interesting things we need recursion James Cheney Addition and subtraction Logic Programming October 3, 2011 • Can run in reverse to find all M,N with M+N=P • Can use to define leq leq(M,N) :- add(M,_,N). James Cheney Multiplication Logic Programming October 3, 2011 List processing • Can multiply two numbers: • Recall built-in list syntax multiply(z,N,z). list([]). multiply(s(N),M,P) :- list([X|L]) :- list(L). multiply(N,M,Q), add(M,Q,P). square(M) :- multiply(N,N,M). • Example: list append append([],L,L). append([X|L],M,[X|N]) :- append(L,M,N). James Cheney Logic Programming October 3, 2011 James Cheney Logic Programming October 3, 2011 Append in action Mode annotations • Forward direction • ?- append([1,2],[3,4],X). • Backward direction • ?- append(X,Y,[1,2,3,4]). • James Cheney Logic Programming October 3, 2011 Notation append(+,+,-) • Similarly, append(-,-,+) • • "?" annotation means either + or - James Cheney Logic Programming October 3, 2011 List processing(3) • Removing an element of a list remove(X,[X|L],L). mem(X,[X|_]). remove(X,[Y|L],[Y|M]) :- remove(X,L,M). mem(X,[_|L]) :- mem(X,L). • "if you call append with last argument ground then it will make the first two arguments ground" Not "code", but often used in documentation List processing (2) • When is something a member of a list? "if you call append with first two arguments ground then it will make the third argument ground" • Typical mode Typical modes remove(+,+,-) mem(+,+) mem(-,+) James Cheney Logic Programming October 3, 2011 James Cheney Logic Programming October 3, 2011 List processing (4) • Zip, or "pairing" corresponding elements of two lists List flattening • zip([],[],[]). Write flatten predicate flatten/2 • • Given a list of (lists of ..) lists Produces a list containing all elements in order zip([X|L],[Y|M],[(X,Y)|N]) :- zip(L,M,N). • Typical modes: zip(+,+,-). zip(-,-,+). % "unzip" James Cheney Logic Programming October 3, 2011 James Cheney List flattening • • We can use terms to define data structures pb([entry(james,'123-4567'),...]) Given a list of (lists of ..) lists Produces a list containing all elements in order • and operations on them pb_lookup(pb(B),P,N) :- flatten([],[]). member(entry(P,N),B). flatten([X|L],M) :- flatten(X,Y1), We can't fill this in yet! (more next week) flatten(L,Y2), pb_insert(pb(B),P,N,pb([entry(P,N)|B])). append(Y1,Y2,M). pb_remove(pb(B),P,pb(B2)) :remove(entry(P,_),B,B2). flatten(X,[X]) :- ???. James Cheney October 3, 2011 Records/structs Write flatten predicate flatten/2 • • Logic Programming Logic Programming October 3, 2011 James Cheney Logic Programming October 3, 2011 Trees Tree membership • We can define (binary) trees with data: • Define membership in tree tree(leaf). mem_tree(X,node(X,T,U)). tree(node(X,T,U)) :- tree(T), tree(U). mem_tree(X,node(Y,T,U)) :mem_tree(X,T) ; mem_tree(X,U). James Cheney Logic Programming October 3, 2011 James Cheney Logic Programming Preorder traversal • preorder(node(X,T,U),[X|N]) :preorder(T,L), append(L,M,N). What happens if we run this in reverse? Logic Programming • • • Expression evaluation • Learn Prolog Now, ch. 3-4 I/O "Cut" (pruning proof search) • Further reading: preorder(U,M), James Cheney Next time • Nonlogical features Define preorder preorder(leaf,[]). • October 3, 2011 October 3, 2011 James Cheney Logic Programming October 3, 2011
© Copyright 2026 Paperzz