You are on page 1of 15

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:
descend2(anne,donna,X).
X = parentChild(anne, bridget, parentChild(bridget, caroline,
parentChild(caroline, donna))) ;
Exercise Walk the Graph
• Given a list of edges
• Show the path that connects from one edge
to another
• connectedPath(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.
• throw2(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
throwUntil_11(Count, FinalCount):-
FinalCount is Count + 1, throw2(11).
throwUntil_11(Count, FinalCount):-
throw2(Y), Z is Count + 1, Y \= 11
throwUntil_11(Z, FinalCount).
• Example query: throwUntil_11(0,X).
Exercise Count Edge Walk
Recursions
Count the number of possible steps between
two points.

•countConnections(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

You might also like