Prolog Recursion Pepper Major portions credited to Blackburn
Prolog Recursion Pepper Major portions credited to : Blackburn, Patrick, Johan Bos and Kristina Striegnitz. Learn Prolog Now. London: College Publications, 2006. (ISBN 9781904987178) Also available at http: //www. learnprolognow. org
A rule with that calls itself is_digesting(X, Y) : - just_ate(X, Y). is_digesting(X, Y) : just_ate(X, Z), is_digesting(Z, Y). • 2 rules – You are digesting what you just ate – You are digesting whatever you ate just ate • And so on until you come to an animal that did not just eat something.
Use in a query just_ate(mosquito, blood(john)). just_ate(frog, mosquito). just_ate(stork, frog). just_ate(person, cow). just_ate(cow, frog). is_digesting(person, X)"? Please answer 'y' or 'n'? yes X = cow ; X = frog ; X = mosquito ; X = blood(john) ;
Construction is_digesting(X, Y) : - just_ate(X, Y). is_digesting(X, Y) : just_ate(X, Z), is_digesting(Z, Y). • Base case: – Does not use its own predicate. • Recursive rule: – Handles one case, – Recurses over the rest of the cases.
Proof Is_digesting(person, A). • What just_ate fact has person on the left side, then the right side can be X. : look for just_ate(person, A). Look for just_ate(X, Z), is_digesting(Z, Y). if just_ate (person, _1) and (_1, A) so (person, cow) and (cow, frog) match so A = frog
Recursion of descendants • facts: child(anne, bridget). child(bridget, caroline). child(caroline, donna). child(donna, emily). Find descendants: - not far enough descend(X, Y) : - child(X, Y). descend(X, Y) : - child(X, Z), child(Z, Y).
Recursion Analysis • Base case: – Does not use its own predicate. – If y is a child of x, y descends from x – descend(X, Y) : - child(X, Y). • Recursive rule: – Handles one case, – Recurses over the rest of the cases. – If y is a child of a descendant of x, then y is a descendant of x – descend(X, Y) : - child (I, Y), descend(X, I)
Exercise graph • Connected points edge(a, b). edge(b, c). edge(b, d). edge(b, e). edge(d, e). edge(y, x). edge(x, z). What points can you reach from a particular point? Assumes no circular connections. connected(a, X). connected (X, z).
Accumulate text • Without Accumulation: – descend(X, Y) : - child(X, Y). – descend(X, Y) : - child (I, Y), descend(X, I) • With Accumulation: – descend(X, Y, childrel(X, Y)): - child(X, Y). – descend(X, Y, childrel(X, I, L)): - child(X, I), descend(I, Y, L). • Query: descend 2(anne, donna, X). X = parent. Child(anne, bridget, parent. Child(bridget, caroline, parent. Child(caroline, donna))) ;
Exercise Walk the Graph • Given a list of edges • Show the path that connects from one edge to another • connected. Path(a, e, X). • Should give: X = go(a, b, go(b, e)) ; X = go(a, b, go(b, d, go(d, e))) ;
Adding Numbers • adder(X, Y, Z): - Z is X + Y. – 10 ? - adder(1, 2, X). – X = 3. – 11 ? - adder(X, 2, 3). – ERROR: is/2: Arguments are not sufficiently instantiated
Random Numbers • random/3 – given a range of numbers as the first 2 arguments, a random number starting from the first number but not including the last number. (for dice 1, 7) • makeroll(X) : - random(1, 7, X). • adder(X, Y, Z): - Z is X + Y. • throw 2(Z) : - makeroll( X), makeroll( Y), Z is X + Y. • You can add writeln(Z).
Count Recursive Attempts • Need one variable to initialize to 0 when you start. • When you recurse, add 1 to the variable you initialized to 0 • When you are done, add 1 to the accumulated list. • Example throw. Until_11(Count, Final. Count): - Final. Count is Count + 1, throw 2(11). throw. Until_11(Count, Final. Count): - throw 2(Y), Z is Count + 1, Y = 11 throw. Until_11(Z, Final. Count). • Example query: throw. Until_11(0, X).
Exercise Count Edge Walk Recursions Count the number of possible steps between two points. • count. Connections(a, e, 0, X). • X = 2 ; • X = 3 ;
Recursion Summary • • • How to declare a recursive rule How to pair the recursive rule with a base case How prolog proof leads to recursion No base case – endless recursion Random Counting recursive steps
- Slides: 15