chapter 5. programming techniques - software …...chapter 5: programming techniques and application...
TRANSCRIPT
„Advanced Logic Programming“
Summer semester 2016 R O O T S
– –
Chapter 5. Programming Techniques
Ensuring termination
Programming with lists
Accumulators
Generate and Test
Symbolic Term Manipulation
Knowledge Representation: Terms versus Facts
Preventing Backtracking: Cuts
Recursion versus Backtracking
Updated: June 22, 2016
Updated page 5-69 to 5-72
Chapter 5: Programming Techniques and Application Examples
R O O T S
How to Write Terminating Predicates
Order of goals and clauses
Recursion and cyclic predicate definitions
Recursion and cycles in the data
Recursion and “growing” function terms
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-3 R O O T S
“?-p.” loops infinitely
Program
Trace
“?-p.” succeeds infinitely
Program
Trace
Order of Clauses in Predicate Definition
p :- q. % 1
p :- r. % 2
q :- p. % 3
r. % 4
p :- r. % 1
p :- q. % 2
q :- p. % 3
r. % 4
?- p.
... nothing happens
...
?- p.
true ;
true ;
...
r.
p.
q.
In spite of
same
model:
Strategy 1: Non-recursive clauses first!
Ensure termination of recursive definitions by moving non-recursive clauses before
recursive ones.
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-4 R O O T S
?-p(X) loops infinitely
after succeeding twice
Program
Trace
?-p succeeds twice
Program
Trace
Order of Literals in Clause Body
In spite of
same
model:
Strategy 2: Non-recursive literals first!
Ensure termination of recursive definitions by moving non-recursive calls before recursive ones.
p(0).
p(X) :- p(Y), a(X,Y).
a(1,0).
p(0).
p(X) :- a(X,Y), p(Y).
a(1,0).
?- p(X).
X = 0 ;
X = 1 ;
ERROR: Out of local stack
?- p(X).
X = 0 ;
X = 1 ;
false.
p(0).
p(1).
a(1,0).
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-5 R O O T S
Given: The following floor plan
A possible Prolog representation:
… or its graph representation
… for a directed graph
Cycles in the data (1)
a b c
d e f
a b c
d e f
door(a,b).
door(b,c).
door(b,d).
door(c,e).
a b c
d e f
door(c,f).
door(d,e).
door(e,f).
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-6 R O O T S
Cycles in the data (2)
Question: How to represent symmetry of doors?
1. Attempt: Recursive definition
2. Attempt: Split definition into two predicates
a b c
d e f
door(a,b).
door(b,c).
door(b,d).
door(c,e).
door(X, Y) :- door(Y, X).
connected(X, Y) :- door(X, Y).
connected(Y, X) :- door(X, Y).
door(c,f).
door(d,e).
door(e,f).
X Y
door
door
a b c
d e f
X Y
connected
door
X Y
connected
door
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-7 R O O T S
Cycles in the data (3)
Question: Is there a path from room X to room Y?
1. Attempt:
Declaratively OK, but will loop on cycles induced by definition of
connected/2!
Derives the same facts infinitely often:
a b c
d e f
connected(X, Y) :- door(X, Y).
connected(X, Y) :- door(Y, X).
path(X, Y) :- connected(X, Y).
path(X, Y) :- connected(X, Z), path(Z, Y).
?- path(X,Y).
X = a, Y = b ;
...
X = a, Y = b ;
...
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-8 R O O T S
Cycles in the data (4)
Question: Is there a path from room X to room Y?
2. Attempt: Avoid looping through cycles in data by “remembering”
Remember each visited room in additional list parameter
a b c
d e f
path(X, Y) :- path(X, Y, [X]). % remember start node
path(X, Y, Visited) :- connected(X, Y).
path(X, Y, Visited) :- connected(X, Z),
not( member(Z, Visited) ),
path(Z, Y, [Z|Visited]).
connected(X, Y) :- door(X, Y).
connected(X, Y) :- door(Y, X).
Strategy 3: Keep track of visited elements!If the data can contain cycles, don’t follow paths starting at already visited elements..
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-9 R O O T S
Divergent Construction of Terms
The definition of length/2:
Tracing an invocation of 'length' with input on first argument:
/**
* The predicate length(List, Int) suceeds iff Arg2 is
* the number of elements in the list Arg1.
*/
length([ ],0).
length([X|Xs],N) :- length(Xs,N1), N is N11.
?- length([1,2],N).
Call length([2],N1)
Call length([],N2)
Exit lenght([],0)
Creep N2 = 0
Creep N1 is N2+1
Creep N is N1+1
N=2
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-10 R O O T S
Divergent Construction of Terms
The definition of length/2:
An invocation of 'length/2' without input on any argument:
The constructed terms diverge: They get bigger and bigger, infinitely!
?- length(X,N).
X=[], N=0 ;
X=[G100], N=1 ;
X=[G102, G101], N=2 ;
... produces infinitely many results ...
/**
* The predicate length(List, Int) suceeds iff Arg2 is
* the number of elements in the list Arg1.
*/
length([ ],0).
length([X|Xs],N) :- length(Xs,N1), N is N11.
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-11 R O O T S
Divergent Construction of Terms
The properly documented definition of length/2:
%% length(+List, ?Length) is det
%% length(?List, +Length) is det
%% length(-List, -Length) is nondet (divergent)
%
% The predicate length(List, Int) suceeds iff Arg2 is
% the number of elements in the list Arg1.
length([ ],0).
length([X|Xs],N) :- length(Xs,N1), N is N11.
Strategy 4: Document invocation modes!Document explicitly each invocation mode in which the predicate’s result diverge.
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-12 R O O T S
Prolog Termination Guide!
To avoid Prolog predicates looping infinitely make sure that
1. there is a matching non-recursive clause before a recursive one,
2. there is a non-recursive literal before a recursive invocation,
3. there are no cycles in the data traversed by a recursive definition
either cycles in the data itself
or cycles introduced by rules
or the cycles are dealt with by explicit bookkeeping in the recursive
predicate and
4. invocation modes leading to divergent construction of terms are
properly documented
we just saw an example (the length/2 predicate)
they might be useful in generate-and-test applications
it is the responsibility of the caller to avoid them in other cases
Chapter 5: Programming Techniques and Application Examples
R O O T S
Recursive Programming with Lists
List notation revisited
Recursive list processing
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-14 R O O T S
Lists in Prolog
Prolog lists may be heterogeneous: They may contain elements of
different „types“
Example: Homogeneous lists
Example: Homogeneous only at the top level
Example: Fully heterogeneous
[1, 2, 3] List of integers
['a', 'b', 'c'] List of characters
[ ] Empty list
[[1,2], [ ], [5]] List of integer lists
[[1,2], 'a', 3] List, atom and integer
[[1,2], [ ], ['a']] List of lists but the element types differ
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-15 R O O T S
List are Binary Trees Encoded as Terms (1)
Internally, lists are binary trees represented as binary terms
whose functor is the reserved atom dot '.'
whose left-hand-side is a list element (the head) and
whose right-hand-side is another list (the tail) – it can be the empty list []
[1 , 2 , 3] =
.
.
.
1
2
3 []
Head
Tail
=
Head
.(1, .(2, .(3, [] ) ) )
Note that any non-empty tail
is itself a list with a head and
a tail…
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-16 R O O T S
Accessing Head and Tail
Notation [ Head | Tail ]
The portion on the left of the | symbol are the initial element(s) of the list
On the right is the remaining tail of the list.
Note that a variable head or tail can be “completed” by unification
?- [1,2,3,4]=[H|T].
?- [1,2,3,4]=[H1,H2|T].
?- [1,2,3,4]=[_,_,H|_].
?- [1,2,3,4]=[_,_,_,_|T].
?- []=[H|T].
?- [1,2,3,4]=[_,_,_,_,_|T].
H=1, T=[2,3,4]
H1=1, H2=2, T=[3,4]
H=3
???
???
???
?- X=[Y,2,3,4], Y=1.
?- T=[2,3,4], X=[1|T].
X=[1,2,3,4], Y=1
???
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-17 R O O T S
Length of a List
Naïve version of “length/2” predicate:
Derivation steps:
length([H|T],N) :- length(T,N1), N is N11.
length([ ],0).
length([a, b, c],N). N is 2+1
H = a, T = [b, c]
length([b, c],N1). N1 is 1+1
H = b, T = [c]
length([c],N11). N11 is 0+1
H = c, T = []
length([],N111).
N111=0
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-20 R O O T S
Concatenating Lists
Predicate definition
Execution trace for ?- append([a, b], [c, d], X).
The result is the composition s1s2s3 = s3(s2s1) = (s3s2)s1 restricted to the binding for X
{ X [a| [b| [c, d]]] }
According to slides 15 and 16 this is equivalent to
{ X [a, b, c, d] }
/**
* The predicate append(L1, L2, L12) suceeds iff Arg3 is
* the list that results from concatenating Arg2 and Arg1.
*/
append([], L, L).
append([H|T], L, [H|TL]) :- append(T, L, TL).
?- append([a, b], [c, d], X).
-> append([b], [c, d], TL1]).
-> append([], [c, d], TL2).
-> true
sss
s1 = {H1a, T1[b], L1[c,d], X[H1|TL1]}
s2 = {H2b, T2[], L2[c,d], TL1[H2|TL2]}
s3 = {L3[c,d], TL2 L3}
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-21 R O O T S
Testing List Membership (1)
Predicate definition:
Execution trace excerpt
/**
* The predicate member(Elem, List) suceeds iff Arg1 is an element
* of the list Arg2 or unifiable with an element of Arg2.
*/
member(H, [H|_]).
member(E, [_|T]) :- member(E, T).
?- member(2,[12, 2, 2, 3]).
Call member(2, [12, 2, 2, 3]).
Exit member(2, [12, 2, 2, 3]).
true ;
Redo member(2, [12, 2, 2, 3]).
Call member(2, [2, 2, 3]).
Exit member(2, [2, 2, 3]).
true ;
Redo member(2, [2, 2, 3]).
Call member(2, [2, 3]).
Exit member(2, [2, 3]).
true ;
...
backtracking inititated by entering ;
backtracking inititated by entering ;
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-22 R O O T S
Testing List Membership (2)
The member/2 predicate can be used in many differen “input modes”:
?- member(a, [a,b,c,d]).
?- member(X, [a,b,c,d]).
Is a an element of [a,b,c,d]?
Which elements does [a,b,c,d] have?
?- member(a, List). Which lists contain the element a?
?- member(X, List). Any element of any list!
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-23 R O O T S
Accessing List Elements
First element of a list
Last element of a list:
N th element of a list:
first([X|_],X).
last([X],X).
last([_|Xs],X) :- last(Xs,X).
nth(1,[X|_],X).
nth(N,[_|Xs],X) :- N1 is N-1, nth(N1,Xs,X).
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-24 R O O T S
Splitting Lists
/**
* The split/4 predicate succeeds if
* Arg3 is a list that contains all elements of Arg2
* that are smaller than Arg1
* and
* Arg4 is a list that contains all elements of Arg2
* that are bigger or equal to Arg1
*/
split(_, [], [], []).
split(E, [H|T], [H|S], B):- H < E, split(E,T,S,B).
split(E, [H|T], S , [H|B]):- H >= E, split(E,T,S,B).
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-25 R O O T S
Sorting Lists
Naïve test for list membership via member/3 has linear complexity: O(n)
But if lists are sorted, membership testing is faster on the average
So sorting is very useful
Quicksort-Algorithm in Prolog
/**
* quicksort/2 suceeds if the second argument is a sorted
* version of the list in the first argument. Duplicates
* are kept.
*/
quicksort([], []).
quicksort([Head|Tail], Sorted) :-
split(Head,Tail,Smaller,Bigger),
quicksort(Smaller,SmallerSorted),
quicksort(Bigger,BiggerSorted),
append(SmallerSorted,[Head|BiggerSorted], Sorted).
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-26 R O O T S
Doing Something with all Elements
Sum of list elements:
Normal Execution:
Goals with illegal modes or type errors:
sum([],0).
sum([H| T], S) :- sum(T, ST), S is ST+H.
?- sum([12, 4], X).
Call sum([4], ST])
Call sum([],ST1) Exit sum([],0)
Call S is 4+0 Exit 4 is 4+0
Call X is 12+4 Exit 16 is 12+4
?- sum(X,3).
ERROR: is/2: Arguments are not sufficiently instantiated
?- sum(X,Y).
X = [],
Y = 0 ;
ERROR: is/2: Arguments are not sufficiently instantiated
?- sum([1,2,a],Res).
ERROR: is/2: Arithmetic: `a/0' is not a function
Chapter 5: Programming Techniques and Application Examples
R O O T S
Accumulators
Efficiency of tail recursion
Using accumulators for tail recursion
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-28 R O O T S
Accumulators (1)
Naïve version of “length” predicate:
Draback: No efficient „tail recursion“
length([H|T],N) :- length(T,N1), N is N11.
length([ ],0).
length([a, b, c],N). N is 2+1
H = a, T = [b, c]
length([b, c],N1). N1 is 1+1
H = b, T = [c]
length([c],N11). N11 is 0+1
H = c, T = []
length([],N111).
N111=0
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-29 R O O T S
Accumulators (2)
Idea
Enable tail recursion by doing computations before the recursive call
Pass the computation result as an additional parameter
An accumulator is a parameter that stores intermediate results.
Length computation with accumulator
In the last recursion step the accumulated result becomes the final
result
No need for any subsequent computations
No need to keep previous recursive invocations on the stack
length_acc(L,N) :- len_acc(L,0,N). % initialisation
len_acc([H|T], A, N) :- A1 is A+1,len_acc(T, A1, N).
len_acc([], A, A).
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-30 R O O T S
Accumulators (3)
Trace:
In the last recursion step the accumulated result becomes the final result!
length_acc([a, b, c],0,N). N=3
H = a, T = [b, c]
A1= 1
length_acc([b, c],1,N). N=3
H = b, T = [c]
A1= 2
length_acc([c],2,N). N=3
H = c, T = []
A1= 3
length_acc([],3,N).
N = 3
length_acc(L,N) :- len_acc(L,0,N).
len_acc([H|T], A, N) :- A1 is A+1, len_acc(T, A1, N).
len_acc([], A, A).
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-31 R O O T S
Accumulators (4)
Reversing lists without accumulator:
Reversing lists using an accumulator:
No need for calling append/3 at all!
No need to traverse the list again in each recursion level
% The predicate (?L, ?UL) suceeds if L is and UL contain the same elements in reversed order.
reverse([], []).
reverse([Head| Tail], RListe) :-
reverse(Tail, RTail), % Reverse rest of list
append(RTail,[Head],RList). % Append head to reversed list
reverse(L, RL) :- reverse(L, [], RL). % initialisation
reverse([], RL, RL). % RL is the reversed list
reverse([Head| Tail], PreviousRL, RL) :-
reverse(Tail, [Head| PreviousRL], RL). % Add head to result
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-32 R O O T S
Accumulators (5)
?- reverse([1,2,3], RL).
call: reverse([1,2,3], RL).
call: reverse([1, 2, 3], [], RL)
call: reverse([2, 3], [1], RL)
call: reverse([3], [2, 1], RL)
call: reverse([], [3, 2, 1], RL)
exit: reverse([], [3, 2, 1], [3, 2, 1])
exit: reverse([3], [2, 1], [3, 2, 1])
exit: reverse([2, 3], [1], [3, 2, 1])
exit: reverse([1, 2, 3], [], [3, 2, 1])
exit: reverse([1, 2, 3], [3, 2, 1])
RL = [3, 2, 1]
yes
RL = [3, 2, 1]
reverse(L, RL) :- reverse(L, [], RL).
reverse([], RL, RL).
reverse([Head| Tail], PreviousRL, RL) :-
reverse(Tail, [Head| PreviousRL], RL). % Add
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-34 R O O T S
Homework (Exam training)
Draw the full derivation trees for the exmples shown on the previous
slides.
See previous chapter if you do not remember how to draw derivation trees.
For each each of the programs that had no example traces, make up
your own small sample query and draw its derivation tree.
Check your results by running the same queries in the graphical debugger
of SWI-Prolog / the PDT and comparing each derivation step with your
tree.
Chapter 5: Programming Techniques and Application Examples
R O O T S
Data Representation via Terms and Symbolic Term Manipulation
Representation of arithmetic expressions
Symbolic differentiation
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-36 R O O T S
Mathematical Laws for Differentiation
dx
dg
dx
df
dx
gfd
)(
dx
dfg
dx
dgf
dx
fgd**
)*(
2
**)/(
g
dx
dgfg
dx
df
dx
gfd
dx
dffc
dx
fd cc
1*)(
dx
dff
dx
fd 1)(ln
dx
dfc
dx
fcd*
)*(
dx
dg
dx
df
dx
gfd
)(
1dx
dx
0dx
dc
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-37 R O O T S
Expression Prolog Term
Representation of Expressions as Terms
constant c
variable x
f +g
f - g
f * g
f / g
f c
ln f
k(c)
x
F+G
F-G
F*G
F/G
exp(F,k(c))
ln(F)
The function 2x2 + ln x is represented as k(2)*exp(x,k(2))+ ln(x)
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-38 R O O T S
Mathematical Law Prolog Clause
Representation of Laws by Clauses
0dx
dcdx(k(C), k(0)).
1dx
dxdx(x, k(1)).
dx(k(C)*F, k(C)*DF) :-
dx(F, DF).dx
dfc
dx
fcd*
)*(
dx
dg
dx
df
dx
gfd
)( dx(F+G, DF+DG) :-
dx(F, DF), dx(G, DG).
dx(F-G, DF-DG) :-
dx(F, DF), dx(G, DG).dx
dg
dx
df
dx
gfd
)(
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-39 R O O T S
Mathematical Law Prolog Clause
Representation of Laws by Clauses
dx
dfg
dx
dgf
dx
fgd**
)*( dx(G*F, F*DG+G*DF) :-
dx(F, DF), dx(G, DG).
2
**)/(
g
dx
dgfg
dx
df
dx
gfd
dx(G/F,(DF*G-F*DG)/exp(G,k(2))) :-
dx(F, DF), dx(G, DG).
dx
dffc
dx
fd cc
1*)(
dx(exp(F,k(C)),k(C)*exp(F,k(C-1))*DF) :-
dx(F, DF).
dx
dff
dx
fd 1)(ln dx(ln(F), exp(F,k(-1))*DF) :-
dx(F, DF).
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-40 R O O T S
Differentiation of an Expression
Math
Prolog
Homework: Implement simplification of expressions:
?- dx( k(2)*exp(x,k(2))+ln(x), Diff).
Diff = k(2)*(k(2)*exp(x,k(2-1))*k(1))+exp(x,k(-1))*k(1)
2x2 + ln x 2*2x2-1 *1 + x -1 * 1
2*2x2-1 *1 + x -1 * 1 4x + x -1
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-41 R O O T S
Remember!
The rule heads provide the most specific structures to which they are
applicable. For instance
instead of
This makes the program more efficient: Selection of inapplicable rules
is prevented already during unification of clause heads
The body makes statements about subterms
Statements on complex term are broken down into statement on subterms
Result term is constructed from subterms
dx(F+G,DF+DG) :- dx(F,DF), dx(G,DG).
dx(F,DF) :- F=F1+G1, dx(F1,DF1), dx(G1,DG1), DF=DF1+DG1.
Chapter 5: Programming Techniques and Application Examples
R O O T S
Data Representation via Facts
Finding Paths
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-43 R O O T S
Given: The following maze … or its graph abstraction
Knowledge Representation: Terms versus Clauses
a b c
d e f
a b c
d e f
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-44 R O O T S
Knowledge Representation: Terms versus Clauses (2)
Alternative representations
1. List
Drawback: Sequential list traversal, each time we want to test whether
there is a door
2. Set of facts
The maze is not represented by a single Prolog term
… but as knowledge about its structure.
[door(a,b), door(b,c), door(b,d), door(c,e),
door(c,f), door(d,e), door(e,f)]
door(a,b). door(c,f).
door(b,c). door(d,e).
door(b,d). door(e,f).
door(c,e).
a b c
d e f
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-45 R O O T S
Term representation
Need to write accessor
predicates
member(door(c,X), [...])
Search might take long
linear list traversal
Update is simulated by a
modified copy of the term
Homework: Implement
replace(L1,+Eold,+Enew,L2)
No side-effects
Clause Representation
Direct access: just write a goal
for the predicate
door(c,X)
Search more efficient
first argument indexing
Update using builtin predicates
for database manipulation
assert/1 adds clauses
retract/1 deletes clauses
Homework: Implement
replace(+Eold,+Enew)
Side-effects
Need to cleanup!
Knowledge Representation: Terms versus Clauses (3)
reverse([], RL, RL).
reverse([Head| Tail], PreviousRL, RL) :-
reverse(Tail, [Head| PreviousRL], RL).
a b c
d e f
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-46 R O O T S
Knowledge Representation: Terms versus Clauses (3)
1 ?- listing.
Yes
2 ?- assert(p(1)).
Yes
3 ?- assert(p(1)).
Yes
4 ?- assert(p(2)).
Yes
5 ?- listing.
:- dynamic p/1.
p(1).
p(1).
p(2).
Yes
6 ?- p(X).
X = 1 ;
X = 1 ;
X = 2
7 ?- retract(p(1)).
Yes
8 ?- p(X).
X = 1 ;
X = 2
9 ?- retract(p(_)).
More? ;
Yes
10 ?- listing(p).
Yes
shows all clauses
shows all clauses
of p
a b c
d e f
Add the clause p(1).
Add the clause p(1).
Add the clause p(2).
Delete a clause
whose head unifies
with p(1)
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-47 R O O T S
Recall: Dealing with cycles
Question: Is there a path from room X to room Y?
2. Attempt: Avoid looping through cycles in data by “remembering”
Remember visited rooms in additional list parameter
Never visit the same node twice
Linear time test for membership
a b c
d e f
path(X, Y) :- path(X, Y, [X]). % remember start node
path(X, Y, Visited) :- connected(X, Y).
path(X, Y, Visited) :- connected(X, Z),
not( member(Z, Visited) ),
path(Z, Y, [Z|Visited]).
connected(X, Y) :- door(X, Y).
connected(X, Y) :- door(Y, X).
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-48 R O O T S
Dealing with Cycles byRemembering Facts
Question: Is there a path from room X to room Y?
3. Attempt: Avoid looping through cycles by “remembering” facts
Remember visited rooms in dynamically created facts
Never visit the same node twice
Constant time test for membership
a b c
d e f
path(X, Y) :- assert(visited(X)), % remember start node
path__(X, Y).
path__(X, Y) :- connected(X, Y).
path__(X, Y) :- connected(X, Z),
not(visited(Z)), % stop at visited node
assert(visited(Z)), % remember next node
path__(Z, Y).
connected(X, Y) :- door(X, Y).
connected(X, Y) :- door(Y, X).
‘assert’ adds a clause
at run-time
Constant time check due to
first argument indexing
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-49 R O O T S
Dealing with Cycles byRemembering Facts (cont.)
Cleanup necessary!
visited/1 facts must be cleared before starting a new path computation!
Integrate this into the top-level path/2 predicate
Cleanup before, not after!
Enforce correct start state and leave debug info behind after the end
a b c
d e f
path(X, Y) :-
assert(visited(X)), % remember start node
path__(X, Y).
path__(X, Y) :- connected(X, Y).
path__(X, Y) :- connected(X, Z),
not(visited(Z)), % stop at visited node
assert(visited(Z)), % remember next node
path__(Z, Y).
retractall(visited(_)),
retract all clauses whose
head unifies with visited(_)
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-50 R O O T S
Homework (Exam training)
Check your understanding of the path computation by stating whether the
the following claims are true or false. Justify your opinion:
a) The path/2 predicate yields an infinite set of answers.
b) The path/2 predicate yields only non-cyclic paths.
Depending on your answer to b) modify the path/2 predicate so that it will
c) also return cyclic paths (if it now does only return acyclic ones)
or
d) not return cyclic paths (if it now returns them)
Then discuss your opinion about a), b) and solution to c), d) with at least 2
colleagues who developed their answers independently!
This is the most important training for an oral exam!!!
Chapter 5: Programming Techniques and Application Examples
R O O T S
Generate and Test
Example: Map coloring
Generate and test
When to use and when to avoid
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-52 R O O T S
Generate and Test (1)
Principle
Generate: Enumerate search space
Test whether we have a solution
Example: Map coloring
N countries
M < N colors
Neighboring countries must
have different colors
1
2 34
5 6
solution(X) :-
possibleSolution(X),
correctSolution(X).
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-53 R O O T S
Generate and Test (2): Map Coloring
color(red). color(yellow).
color(green). color(blue).
different(red, yellow). different(red, green).
different(red, blue). different(yellow, red).
different(yellow, green). different(yellow, blue).
different(green, red). different(green, yellow).
different(green, blue). different(blue, red).
different(blue, yellow). different(blue, green).
correctColoring(L1,L2,L3,L4,L5,L6) :-
different(L1,L2), different(L1,L3), different(L1,L5),
different(L1,L6), different(L2,L3), different(L2,L5),
different(L3,L4), different(L3,L5), different(L3,L6),
different(L4,L6), different(L5,L6).
coloring(L1,L2,L3,L4,L5,L6) :-
color(L1),color(L2),color(L3),color(L4),color(L5),color(L6),
correctColoring(L1,L2,L3,L4,L5,L6).
1
2 34
5 6
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-54 R O O T S
Generate and Test (3)
Recomended use
Small search space
No idea how to create candidates more systematically
Risks
Search space might be very big
Long time wasted generating useless candidates
Better
Test as soon as possible
Combine creation of candidates and test
Example: Map coloring
No need to enumerate colors separately
… since they are enumerated already by
the “different/2” predicate.
1
2 34
5 6
sort(UL, SL) :-
permute(UL, SL),
sorted(SL).
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-55 R O O T S
Generate and Test (4): Optimizations
different(red, yellow). different(red, green).
different(red, blue). different(yellow, red).
different(yellow, green). different(yellow, blue).
different(green, red). different(green, yellow).
different(green, blue). different(blue, red).
different(blue, yellow). different(blue, green).
coloring(L1,L2,L3,L4,L5,L6) :-
different(L1,L2), different(L1,L3), different(L1,L5), different(L1,L6),
different(L2,L3), different(L2,L5),
different(L3,L4), different(L3,L5), different(L3,L6),
different(L4,L6),
different(L5,L6).
1
2 34
5 6
coloring(L1,L2,L3,L4,L5,L6) :-
different(L1,L2), different(L1,L3), different(L2,L3), % L3 available
different(L1,L5), different(L2,L5), different(L3,L5), % L5 available
different(L1,L6), different(L5,L6), different(L3,L6), % L6 available
different(L3,L4), different(L4,L6). % L4 available
1. Eliminate color/1. Variables are bound to proper color values by different/2:
2. Test as soon as data is available to prevent exploring impossible combinations:
Chapter 5: Programming Techniques and Application Examples
R O O T S
Stoping backtracking: The cut
The cut
Good uses of the cut
Dangerous uses of the cut
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-58 R O O T S
The "Cut"-Operator (1)
Prolog remembers choice points if there are still alternative clauses to
be tried This can be quite expensive...
Remembering the choice point
Going back to the choice point
Trying the clause at the choice point
What if all this is known in advance to be useless?
The cut operator
prevents exploration of parts of the search space by deleting choice points
can reduce runtime and storage costs
can lead to incomplete answer sets
!
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-59 R O O T S
The "Cut"-Operator (2)
The cut operator only has an operational semantics
It succeeds exactly once, leaving no choice points
It deletes any choice points for goals to its left
It deletes any choice point for the predicate in which it occurs
Example:
When the above cut is executed it deletes all choice points for
q(X)
p(X)
As a consequence, if s(X) cannot be proven with the substitution produced
by q(X) then
there will be no backtracking to q(X)
there will be no backtracking to the second clause of p/1
thus the call to p/1 will fail
p(X) :- q(X), !, s(X).
p(X) :- r(X).
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-60 R O O T S
Use of the Cut 1. Mark Disjoint Cases
Example: The predicate max/3 succeeds if the third argument is the
maximum of the first two
Observation
The two clauses express disjoint cases
If the first clause succeeded the second will fail
Use of cut
Use it to say “If you got here there is no point in going to the next clause”:
With the cut, the test in the second clause is redundant Delete it!
max(X,Y,Y):- X =< Y.
max(X,Y,X):- X > Y.
max(X,Y,Y):- X =< Y, !.
max(X,Y,X):- X > Y.
max(X,Y,Y):- X =< Y, !.
max(X,Y,X).
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-61 R O O T S
set/2 without cut
contains redundant membership
tests
much more expensive than the
redundant “>” test on the
previous slide
set/2 with cut
membership is tested only
once
second clause is reached only
if test in first clause has failed
Use of the Cut 2. Eliminate Redundant Tests
set([], []).
set([Head| Tail], Set) :-
member(Head, Tail),
set(Tail, Set).
set([Head| Tail], [Head| Set]) :-
\+ member(Head, Tail),
set(Tail, Set).
set([], []).
set([Head| Tail], Set) :-
member(Head, Tail),
!,
set(Tail, Set).
set([Head| Tail], [Head| Set]) :-
set(Tail, Set).
Example: set/2 succeeds if argument 2 a duplicate-free copy of
argument 1
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-62 R O O T S
Principle: A total predicate succeeds for every input
Example: Term simplification should always succeed, yielding the
original term if no simplification rule is applicable
Rules for specific cases come first
Rule capturing other cases comes last (“catch all”)
s-(k(A),k(B),k(C)) :-
!,
C is A-B.
s-(F,G,SF-SG) :-
s(F,SF),
s(F,SG).
Use of the Cut 3. Define Total Relations
s(F+G, S) :- !, s+(F,G,S).
s(F-G, S) :- !, s-(F,G,S).
s(F*G, S) :- !, s*(F,G,S).
s(F/G, S) :- !, s/(F,G,S).
s(exp(F,G), S) :- !, se(F,G,S).
s(ln(F), S) :- !, sl(F,S).
s(F, F). % catch all
s+(k(A),k(B),k(C)) :-
!,
C is A+B.
s+(F,G,SF+SG) :-
s(F,SF),
s(F,SG).
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-63 R O O T S
Homework (Exam training)
Check your understanding of the simplification predicate by:
a) Completing the definition of s-, s*, s/, se, sl following the principle
illustrated by s+
b) Running the resulting program on some simple inputs
Think first about suitable test cases and corresponding inputs
c) Observing what is still missing / incomplete
d) Completing at least one of the missing features
Then discuss your solution with 2 colleagues who developed their
answers independently!
Getting the program more complete / correct is important for your own
understanding
Discussing your solution with others is the most important training for
the oral exam!!!
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-64 R O O T S
Use of the Cut 4. Conditionals
The cut can be used to implement conditional branching
behaves as
Prolog offers a convenient short hand notation for this:
Example
Remember: The „test“ goal before „->“ does not backtrack!
If it fails the „elsepart“ after „;“ is executed
If it succeeds the „thenpart“ before „;“ is executed
The „thenpart“ and the „elsepart“ can backtrack but not the test!
p :- test , !, thenpart .
p :- elsepart.
if test then thenpart else elsepart
p :- test -> thenpart ; elsepart.
max(X, Y, Z) :- (X > Y) -> Z = X ; Z = Y.
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-65 R O O T S
Use of the Cut 4. Conditionals (cont)
What if we want the test part to backtrack?
Prolog offers a special predicate for this: The „soft cut“ *->
If test succeeds at least once, p behaves like „test, thenpart“
Put differently, if thenpart fails, p backtracks to test but not to
elsepart
Allows to say: „If there is no single way to satisfy test(X) then do
elsepart, otherwise try thenpart for all ways to satisfy test(X).
Example
p :- test(X) *-> thenpart(X) ; elsepart.
p :- test(X) *-> thenpart(X) ; elsepart.
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-66 R O O T S
Use of the Cut 5. Modelling Exceptions
Principle
Put the exception rules at the start, the general ones at the end
After each exception test add cut and fail
Example
“Except for ‘Big Kahuna Burgers’,Vincent enjoys any burger.”
enjoys(vincent,X):- bigKahunaBurger(X), !, fail.
enjoys(vincent,X):- burger(X).
burger(X):- bigMac(X).
burger(X):- bigKahunaBurger(X).
burger(X):- whopper(X).
bigMac(a).
bigMac(b).
whopper(c).
bigKahunaBurger(d).
?- enjoys(vincent,d).
no
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-67 R O O T S
The "Cut"-Operator Negation
The „cut„ and „fail“ predicates can be used together to implement
„Negation by failure“
call(X) suceeds, if the goal X is provable.
It is an example of a meta-predicate (a predicate that takes other
predicates as parameters).
fail is a built-in predicate that always fails
not(X) :- call(X), !, fail.
not(X).
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-68 R O O T S
Good uses of the Cut Summary
The cut can make Prolog programs more efficient and concise.
It can be used to
1. Mark disjoint cases
2. Eliminat redundant tests
3. Define total relations concisely („Catch all“)
4. Express if – then – else
5. Express exceptions
6. Terminate backtracking-based loops gracefully
See next section („Using backtracking for iteration“)
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-69 R O O T S
Green "Cut" – Red "Cut"
Same predicate, different uses
Green "Cut" eliminates infinite resolution paths and failing paths.
Red "Cut" eliminates successful resolution paths
?- none(X)
?- ab(X),!, X=b
!!
test(X):- none(X).
test(X):- one(X).
none(X):- ab(X), !, X=b.
none(c).
ab(a).
ab(b).
one(d).
Eliminated
by the cut
one#1
{xd}
?- test(X)
!, a=b
a=b
?- one(X)
fail
truetrue
b=b
true
Color indicates the selected goal and the substitution computed by its resolution.
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-70 R O O T S
Example: Cut-free code
p(X):- a(X).
p(X):-
b(X),c(X), d(X),e(X).
p(X):- f(X).
a(1).
b(1). b(2).
c(1). c(2).
d(2).
e(2).
f(3).
?- p(X).
X=1;
X=2;
X=3;
no
?- a(X).
?- d(2), e(2).
?- e(2).
?- d(1), e(1).
?- c(1),d(1),e(1). ?- c(2),d(2),e(2).
?- b(X),c(X),d(X),e(X).
{X1} {X1} {X2}
fail
{X3}
Color indicates the selected goal and the variables binding computed by its resolution.
There is no choicepoint for ?- c(1) due to indexing (there is no other clause that could
unify with the goal c(1) ).
?- p(X).
?- f(X).
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-71 R O O T S
Example: The same code with a red cut
p(X):- a(X).
p(X):-
b(X),c(X),!,d(X),e(X).
p(X):- f(X).
a(1).
b(1). b(2).
c(1). c(2).
d(2).
e(2).
f(3).
?- p(X).
X=1;
no
?- p(X).
?- a(X).
?- !,d(1), e(1).
?- c(1),!,d(1),e(1).
{X1} {X1}
Color indicates the selected goal and the variables binding computed by its resolution.
There is no choicepoint for ?- c(1) since there is no other clause that could unify with
the goal c(1).
?- b(X),c(X),!,d(X),e(X).
?- d(1), e(1).
fail
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-72 R O O T S
Red Cuts can be hard to detect
Take care: Adding cuts without proper consideration can change the
meanig of a predicate in a non obvious way!
Good append/3
Bad append/3
Can you explain the difference?
Tip: Compare the resolution of the goal ?- append(L1,L2, [a,b]) with each
of the two versions of append/3.
append([], L, L).
append([Head| Tail], L, [Head| TailL]) :-
append(Tail, L, TailL).
append([], L, L) :- !.
append([Head| Tail], L, [Head| TailL]) :-
append(Tail, L, TailL).
Chapter 5: Programming Techniques and Application Examples
R O O T S
Using Backtracking for Iteration
Iteration via Recursion
Iteration via Backtracking
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-74 R O O T S74
Iteration via Recursion
Many powerful applications (already shown)
Processing of nested terms and, in particular, lists
Traversal of graphs espressed as facts (connected rooms example)
reverse(L, RL) :- reverse(L, [], RL). % initialisation
reverse([], RL, RL). % RL is the reversed list
reverse([Head| Tail], PreviousRL, RL) :-
reverse(Tail, [Head| PreviousRL], RL). % Add head to result
path(X, Y) :- connected(X, Y).
path(X, Y) :- connected(X, Z),
path(Z, Y).
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-75 R O O T S75
Iteration via Recursion: Limitations
Sample scenario
Recursive reading and processing of terms from a file
Risk of stack overflow
Stack grows for each read term
File size often much bigger than stack size
Recursive solution would lead to stack overflow
processFile(...) :-
read(X),
( not(X==end_of_file),
process(X),
processFile(...) % stack grows for each term read
; true
).
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-76 R O O T S
Iteration via Backtracking
Principle
The “driver” can be any nondeterministic predicate
The “trigger” can be any predicate that fails when the loop should go on
and succeeds otherwise
repeat/0
built-in predicate that always succeeds
often used as “driver”
fail/0
built-in predicate that always fails
often used as “trigger”
backtracking_based_iteration:-
driver, % non-deterministic
action, % deterministic loop body
trigger. % fails to force backtrackingfailu
re
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-77 R O O T S
Iteration via Backtracking: Scenariosa) „Nondeterministic driver and fail“
Loops can be “driven” by a nondeterministic predicate
The loop is repeated as often as the “driver” succeeds
The final clause succeeds when the driver fails
It ensures that predicate/… succeeds
It can hold some final “post-action” that succeeds
See next slide for an example (cache_internal_packages)
predicate(…) :-
get_item(…), % nondeterministic „driver“
action(…), % deterministic loop body
fail. % triggers backtracking
predicate(…) :-
postaction(…). % cleanup, completion message, …
failu
re
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-78 R O O T S
Iteration via Backtracking: Idiomsa) „Nondeterministic driver and fail“
Prolog idiom for “Foreach Item do Action”
Example: Caching computation results
78
cache_internal_packages :-
packageT(Id,Name), % for each package
not(external_package(Id)), % test its status
assert(internal_package(Id,Name)), % store result
fail. % force backtracking
cache_internal_packages :-
writeln('Caching completed'). % postaction
failu
re
foreach_do_idiom(…) :-
get_item(…), % nondeterministic „driver“
processing(…), % deterministic loop body
fail. % triggers backtracking
predicate(…) :-
postaction(…). % cleanup, completion message, …
failu
re
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-79 R O O T S
Iteration via Backtracking: Idiomsb) „repeat and test“
Prolog idiom for “repeat Action until Condition”
Example: Simple file processing
79
processFile :-
repeat, % backtracking driver
read(X), % deterministic: read a term
process(X), % deterministic: side-effect
X==end_of_file, % force backtracking or terminate
!. % cut choicepoints of repeat/0
failu
resu
cc.
repeat_until_loop_idiom :-
repeat, % backtracking driver
action(…), % deterministic: side-effect
condition(…), % force backtracking or terminate
!, % cut choicepoints of repeat/0
... % possibly do sth. after the loop
failu
resu
cc.
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-80 R O O T S
Iteration via Backtracking: Scenariosb) Repeat and test (cont)
More general schema
predicate(…) :-
initialize(…),
repeat,
get_next(…), % deterministic
process(…), % deterministic
!. % prevent backtracking to second
% clause of process/… after the
% first one suceeded
process(…) :-
is_last_item(…),
process_last_item(…).
process(…) :-
process_normal_item(…),
fail.
successful end
trigger backtracking
succeeds infinitely
More examples in next chapter (section on file IO)
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-81 R O O T S
Homework (Exam training)
Connect each pair of related terms on the next page by a line
Each term can be related to different other terms
Label each connection by a reason (keyword or slide number)
Compare your resulting mind map to one of a colleague
Discuss the differences
Agree on a joint mind map
© 2009-2016 Dr. G. Kniesel Course „Advanced Logic Progrmming“ (ALP) Page 5-82 R O O T S
Summary
Termination
Clause order
Literal order
Cycle detection
Diverging modes
Lists Notation
Recursion
Efficiency
Accumulators CutArgument
indexing
Tail recursion
Term based programming
Fact based programming
Generate and Test
Green cut Red cut
Iteration
Backtracking
Driver
Danger