prolog rozszerzenie - lublinkft.umcs.lublin.pl/mgozdz/prolog2-wyklad.pdf · marek góźdź...
TRANSCRIPT
Prologrozszerzenie
semestr zimowy 2018/2019
wersja z dnia: 21 stycznia 2019
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 1 / 177
Literatura
W.F. Clocksin, C.S. Mellish, Prolog. Programowanie, Helion(dostępne np. w druku na żądanie, ok. 40 zł)
D. Diaz, GNU Prologhttp://www.gprolog.org/manual/gprolog.pdf
A. Niederliński, A Gentle Guide to Constraint Logic Programming viaECLiPSehttp://www.anclp.pl
Poziom rozszerzonypaździernik: 08, 22listopad: 05, 26grudzień: 10styczeń: 07, 21luty: 04
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 2 / 177
Foundations Logic
Boolean algebra consists of the set
A = {0, 1}
with addition and multiplication defined as (a ∈ A)
0 + a = a 0 · a = 01 + a = 1 1 · a = a
Negation is defined as
a+ a = 1
a · a = 0¯a = a
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 3 / 177
Foundations Logic
Correspondence with the language of logic
0 FALSE
1 TRUE
a+ b a OR b
a · b a AND b
x NOT x
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 4 / 177
Foundations Logic
The algebra features:
Associativity x+ (y + z) = (x+ y) + z
Associativity x · (y · z) = (x · y) · zCommutativity x+ y = y + x
Commutativity x · y = y · xDistributivity x · (y + z) = (x · y) + (x · z)Distributivity x+ (y · z) = (x+ y) · (x+ z)Identity x+ 0 = x
Identity x · 1 = x
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 5 / 177
Foundations Logic
The algebra features continued:
Idempotence x+ x = x
Idempotence x · x = xAnnihilator x · 0 = 0Annihilator x+ 1 = 1
Absorption x · (x+ y) = xAbsorption x+ (x · y) = xComplementation x+ x = 1
Complementation x · x = 0de Morgan’s Law x+ y = x · yde Morgan’s Law x · y = x+ y
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 6 / 177
Foundations Functions and relations
Functions vs. relationsWhat is the difference between a function and a relation?
FunctionA function f : X → f(X) maps each member of X onto exactly onemember of f(X). If additionally each member of f(X) is inverse-mappedto exactly one member of X the function f is invertible, so that f−1 exists.
RelationA relation f : X → f(X) maps each member of X onto f(X). In generalrelations are not invertible. Every function is a relation, but in general arelation is not a function.
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 7 / 177
Programming Basics
ProgrammingA minimal programming language consists of
data structures, variables
IF ... THEN ... statement
loop statement
Prolog has variables and IF statements. Loops are realized automatically(internal implementation) and are not declared explicitly.
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 8 / 177
Programming Imperative and declarative paradigm
Two main paradigms in programming languagesimperative vs. declarative
1 In the imperative paradigm, the method of solving a problem mustbe directly programmed. Examples: C (plain), fortran (plain), pascal(plain), C++ (object), java (object)...
2 In the declarative paradigm, we define facts (data) and methods ofmanipulation of these facts, and then ask questions. The computeranswers the question within declared rules. Example: prolog (logic),clojure (functional), lisp (multi), haskell (functional)...
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 9 / 177
Programming Imperative and declarative paradigm
Example in a imperative language fortran77
1 function silnia(x)2 integer silnia , x, tmp3 tmp=14 if (x.eq.1) then5 silnia =16 else7 do 10 i=1,x8 tmp=tmp*i9 10 continue10 silnia=tmp11 end if12 end function
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 10 / 177
Programming Imperative and declarative paradigm
Example in declarative languages – haskell: functional programming
1 silnia :: Integer -> Integer2 silnia 0 = 13 silnia x = x * silnia (x-1)
Example in declarative languages – prolog: programming in logic
1 silnia (0,1).2 silnia(N,F) :-3 N>0,4 N1 is N-1,5 silnia(N1 ,F1),6 F is N * F1.
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 11 / 177
Prolog Basics
Types of predicatesPredicate defines a relation between its arguments:
unconditional relation is a prolog statement/fact
1 predicate(arg1 ,arg2).
conditional relation usually makes sense only if variables appear inthe definition – prolog rule
1 wife_candidate(X) :- smart(X),2 beautiful(X),3 younger_than(X ,30).
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 12 / 177
Prolog Basics
Prolog rules have the formHEAD — IF — CONDITION(S)
1 siostra(malgosia ,X) :- brat(X,malgosia),2 kobieta(malgosia ).
try to find X from HEAD using known facts
pick the first possible X
check if this X fullfils the conjunction of conditions
if yes, ask the user if another solution is needed
try to find another X in the database that satisfies HEAD andCONDITIONS...
...and so on, until user satisfied or no more possibilities remain
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 13 / 177
Prolog Basics
Matching of terms – two terms match, if
they are identicalor
they can be made identical by variable instantiation
1 | ?- 2=2.2 yes3
4 | ?- X=2.5 X = 26 yes7
8 | ?- pred(a,b,3)= pred(a,X,Y).9 X = b10 Y = 311 yes
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 14 / 177
Prolog Basics
Technically, matching is realized during the operation of unification ofterms. The functor = is an infix operator which tries to unify its left andright argument.Unification is discussed in detail during the basic course.
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 15 / 177
Prolog Basics
Anonymous variable
denoted by an underscore
every occurence of represents a different variable
unimportant for the logic of the program
singleton variables should be represented by
1 | ?- consult(user).2 compiling user for byte code ...3 pred(X,Y,Z) :- X>0.4 user :1: warning: singleton variables [Y,Z] for pred/35 pred(X,_,_) :- X>0.6
7 user compiled , 3 lines read - 277 bytes written , 848005 ms8
9 (1 ms) yes10
11 | ?- pred(a,b,3)= pred(_,X,_).12 X = b13 yes
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 16 / 177
Prolog Basics
Matching to uninstantiated or anonymous variable is always possible:
1 | ?- pred(Y) = X. % in SWI prolog:2 X = pred(Y) % X = pred(_G98)3 (1 ms) yes % Y = _G984
5 | ?- pred(_) = X.6 X = pred(_)7 yes
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 17 / 177
Prolog Basics
SUMMARY
properties of Boolean algebra
functions and relations
imperative vs. declarative programming
minimal programming language
terms, predicates, clauses
basic term matching, anonymous variable
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 18 / 177
Prolog Functors and operators
OperatorsOperators may have three different syntax types
infix operator, like in 25.5 / 4, 9 - 7
1 | ?- X is 6+3.2 X = 93 yes
prefix operator, like in -5, \+ predicate(term). and
1 | ?- X is +(6 ,3).2 X = 93 yes
postfix (suffix) operator, like the factorial in mathematics: 5!GNU Prolog has no predefined postfix operators.
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 19 / 177
Prolog Functors and operators
Operators and predicates may play the role of functors, which are used tobuild compound terms. Operators may be defined using the predicate (see:Manual p.112-114)
op(Priority, OpSpecifier, Operator)
Priority is a number from 0 (delete the definition) to 1 (executefirst), to 1200 (execute last), telling in which order the operatorsshould be executed.
OpSpecifier type (prefix, postfix, infix), associativity (yes, no, left,right).
Operator name or list of names
Examples:: is 600 xfy, i.e., a right-associative infix operator of priority 600+ is 500 yfx, i.e., a left-associative infix operator of priority 500+ is 200 fy, i.e., an associative prefix operator of priority 200
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 20 / 177
Prolog Functors and operators
OpSpecifier type associativity examples
yfx infix left-associative + - *xfy infix right-associative ,xfx infix non-associative = is < (no nesting)fy prefix associativefx prefix non-associative - (no --1)yf postfix associativexf postfix non-associative
f – the operatorx – non-associative sidey – associative side
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 21 / 177
Prolog Functors and operators
Example: an infix operator that reverses a list.The file op.pro contains:
1 :- op(200,yfx ,rev).2 X rev Y :- reverse(X,Y).
Prolog console:
1 | ?- [’op.pro’].2 compiling /home/marek/op.pro for byte code ...3 /home/marek/op.pro compiled , 3 lines read -4 256 bytes written , 4 ms5
6 yes7
8 | ?- X=[1,2,3], X rev Y.9 X = [1,2,3]10 Y = [3,2,1]11 yes
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 22 / 177
Prolog Functors and operators
You can check the properties of an operator using current op
1 | ?- current_op(P,S,+).2
3 P = 2004 S = fy ? ;5
6 P = 5007 S = yfx8
9 yes
1 | ?- current_op(P,S,rev).2
3 P = 2004 S = yfx5
6 yes
1 | ?- current_op (500,S,X).2
3 S = yfx4 X = (\/) ? a5
6 S = yfx7 X = (+)8
9 S = yfx10 X = (-)11
12 S = yfx13 X = (/\)14
15 (2 ms) no
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 23 / 177
Prolog Functors and operators
More about the priority.
The priority is sometimes called precedence. The lower the priority,the stronger is the binding of the operator.
The priority of a term is equal to the priority of its principal functor.
The principal functor of the term means the last operation to beexecuted, or the outermost one in the prefix notation.
If the principal functor isn’t an operator or the term is enclosed inparenthesis, then the priority is set to 0.
Examples:3+5 has priority 500sqrt(3+5) has priority 0(3+5) has priority 0dragon has priority 0
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 24 / 177
Prolog Functors and operators
More about the associativity. Consider the term: 15-10-5.It is not clear for the computer how to treat such nested expressions:
15-(10-5)=15-5=10 if the operator - were right-associative (withthe specifier xfy)
(15-10)-5=5-5=0 if the operator - were left-associative (withspecifier yfx)
One solution is to forbid such syntax (no chains allowed) and force theuser to use parenthesis explicitly. Another solution is to define associativityfor the operators.
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 25 / 177
Prolog Functors and operators
Internally, the infix operators are represented in the unambiguous prefixnotation, so the R-associative case is transformed into -(15,-(10,5)),while the L-associative case is transformed into -(-(15,10),5).The operator - is L-associative in prolog, so the mathematics workscorrectly.
1 | ?- current_op(X,Y,-).2 X = 2003 Y = fy ? ;4
5 X = 5006 Y = yfx
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 26 / 177
Prolog Functors and operators
Example: operators and natural languages
1 :- op(300,xfx ,is_smaller_than ).2
3 smaller(ant ,snail).4 smaller(snail ,mouse).5 smaller(mouse ,cat).6 smaller(cat ,dog).7 smaller(dog ,horse).8 smaller(horse ,elephant ).9 smaller(elephant ,dragon ).10
11 is_smaller_than(X,Y) :- smaller(X,Y) ;12 (smaller(X,Z),13 is_smaller_than(Z,Y)).
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 27 / 177
Prolog Functors and operators
With the new operator, ’English’ statements can be evaluated as true orfalse. Prolog ’understands’ only these words, which have been defined inthe database.
1 | ?- ant is_smaller_than dragon.2 true ? ;3 no4
5 | ?- horse is_smaller_than dragon.6 true ? ;7 no8
9 | ?- horse is_smaller_than cat.10 no
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 28 / 177
Prolog Term types
Term typesChecking term types allows to control user input.Example:
1 dodaj(X,Y) :- Y is X+1.
1 | ?- dodaj(4,X).2 X = 53 yes4
5 | ?- dodaj(abc ,X).6 uncaught exception:7 error(type_error(evaluable ,abc/0),(is)/2)
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 29 / 177
Prolog Term types
Modify the definition by including term type control
1 dodaj(X,Y) :- number(X), Y is X+1.
1 | ?- dodaj(abc ,X).2 no
More verbatim version:
1 dodaj(X,Y) :-2 (number(X), Y is X+1) ;3 (\+ number(X),4 write(’Pierwszy argument musi byc liczba ’)).
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 30 / 177
Prolog Term types
The predicates true/0 and fail/0 (false/0) have logical value true andfalse.The predicate false/0 is not a part of the ISO’95 standard, has beenadded in 2012 as an extension. New GNU Prolog (ver.1.4+) supports both.How to define these predicates? Easy! For example:
1 true :- 1=1.2 false :- 1=0.
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 31 / 177
Prolog Term types
The predicate \+
means “is not provable”
expression \+ term is true if term fails
negation by failure
often used where logical NOT needed
1 | ?- true.2 yes3
4 | ?- \+ true.5 no
1 | ?- false.2 no3
4 | ?- \+ false.5 yes
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 32 / 177
Prolog Term types
The implication operator ->/2 acts as if--then, so
1 X -> Y.
works this way:
if X succeeds, then remove all choice-points created for X and executeY
if X fails, the whole expression fails
The construction
1 X -> Y ; Z.
works as if X -- then Y -- else Z statement.
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 33 / 177
Prolog Term types
Returning to the example with term type control
1 dodaj(X,Y) :- number(X) -> Y is X+1 ;2 write(’Pierwszy argument musi byc3 liczba ’).
1 | ?- dodaj(4,X).2 X = 53 yes4
5 | ?- dodaj(abc ,X).6 Pierwszy argument musi byc liczba7 yes
Notice: the final communicate from the system is yes in both cases. Why?
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 34 / 177
Prolog Term types
The definition of neg/1 which works like \+ can have the followingstructure:
using the if–then–else construction
1 neg(T) :- (T -> fail ; true).
using the cut operator
1 neg(T) :- T, !, fail.2 neg(_).
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 35 / 177
Prolog Arithmetics
ArithmeticsAs you have seen, the functors = and == cannot be used for arithmetics.
1 | ?- X=2+3.2 X = 2+33 yes4
5 | ?- X==2+3.6 no
prolog understands 2+3 as a term ready for evaluation in terms oflogical true/false
to change the evaluation into mathematical mode, use the functoris
1 | ?- X is 2+32 X = 53 yes
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 36 / 177
Prolog Arithmetics
The functor =:= (and comparison functors similarly)
assumes mathematical evaluation of its left and right argument
answers if the resulting numbers are the same
1 | ?- 2^3 =:= sqrt (64).2 yes
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 37 / 177
Prolog Arithmetics
Negation and inequality may be logically interchangable
1 | ?- \+(2^3+1 =:= sqrt (64)).2 yes3
4 | ?- 2^3+1 =\= sqrt (64).5 yes
...but (warning!)
prolog doesn’t care about the exact numbers
the true/false value is important
1 | ?- \+(2^3+10 =:= sqrt (64)).2 yes
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 38 / 177
Prolog Arithmetics
SUMMARY
new operators can be definedI prefix, infix, suffixI priorityI associativity
operators as elements of ’natural’ languages
true, false (fail)
unprovable \+
if–then (X->Y), if–then–else (X->Y;Z)
numbers (arithmetics) vs. true/false (logic)
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 39 / 177
Prolog Finding solutions and prolog programs
It is easy to badly define recurence relations. Consider the followingexample:
1 smaller(pocket ,suitcase ).2 smaller(suitcase ,backpack ).3 smaller(backpack ,box).4 smaller(box ,wardrobe ).5
6 smaller(X,Y) :- smaller(X,Z), smaller(Z,Y).
One would think, that this definition builds the whole chain of “beingsmaller” objects, so
1 | ?- smaller(A,B).
should return all pairs, like (pocket,suitcase), (pocket,backpack)etc. (This is wrong!)
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 40 / 177
Prolog Finding solutions and prolog programs
However,...
1 | ?- smaller(A,B).2
3 A = pocket4 B = suitcase ? a5
6 A = suitcase7 B = backpack8
9 A = backpack10 B = box11
12 A = box13 B = wardrobe14
15 A = pocket16 B = backpack
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 41 / 177
Prolog Finding solutions and prolog programs
17 A = pocket18 B = box19
20 A = pocket21 B = wardrobe22 Redo: smaller(pocket ,wardrobe) ?23 Redo: smaller(suitcase ,wardrobe) ?24 Redo: smaller(backpack ,wardrobe) ?25 Redo: smaller(box ,wardrobe) ?26 Call: smaller(box ,_249) ?27 Exit: smaller(box ,wardrobe) ?28 Call: smaller(wardrobe ,_24) ?29 Call: smaller(wardrobe ,_298) ?30 Call: smaller(wardrobe ,_322) ?31 Call: smaller(wardrobe ,_346) ?
at the end an infinite loop starts...
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 42 / 177
Prolog Finding solutions and prolog programs
The first 4 solutions are taken directly from the database.
To obtain solution (pocket,backpack) the transitional rule is used:smaller(X,Z), smaller(Z,Y)
To obtain solution (pocket,box) the rule is used twice, as thesmaller(X,Z) term is expanded tosmaller(X,Z) :- smaller(X,ZZ), smaller(ZZ,Z)
Similarly prolog arrives at (pocket,wardrobe)
Tries to continue in this fashion, expanding the first term of thedefinition, but since the first argument is now wardrobe, the termcannot be satisfied. So the expansion continues until out of memory.
Notice that other solutions, like the “2nd order” (suitcase,box),do not appear at all.
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 43 / 177
Prolog Finding solutions and prolog programs
The problem stems from the fact, that the rule smaller(X,Y) invokesitself without any control, which leads to infinite non-terminating loop.
Question: homeworkHow to correct the code/ write a new one, so that
all pairs (solutions) will be recognized
and the program termination point will be well defined?
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 44 / 177
Prolog Finding solutions and prolog programs
Decission trees
decission trees help to describe decission making criteria
they are quite often binary trees, i.e., only two branches come outfrom each node (like for simple yes/no decissions)
usualy a more complicated tree can be transformed to binary form
sometimes loops/jumps appear inside the tree
the leaves contain the final yes/no decission
the same information (decission process) may be encoded in manydifferent ways
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 45 / 177
Prolog Finding solutions and prolog programs
Example: Donuts’ quality control (1)
ROUNDyes / \ no/ REJECT
BROWNyes / \ noOK \
TOPPINGyes / \ noOK REJECT
1 quality(donut(R,B,_),ok) :- R=y, B=y.2 quality(donut(R,B,T),ok) :- R=y, B=n, T=y.3 quality(donut(R,_,_),no) :- R=n.4 quality(donut(R,B,T),no) :- R=y, B=n, T=n.5 quality(donut(_,_,_),no).
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 46 / 177
Prolog Finding solutions and prolog programs
Example: Donuts’ quality control (2)
SHAPEround / \ *
/ REJECTCOLOR
brown / \ *OK \
TOPPINGyes / \ noOK REJECT
Being smart, one can encode the whole tree in one line:
1 quality(round ,C,T) :- C=brown , !; T=yes.
where true/fail of this predicate is equivalent to OK/REJECT from the tree.
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 47 / 177
Prolog Finding solutions and prolog programs
The cut predicate !.
prolog consults the same lines of the program many times
it is often not needed, like in
1 parents(mother ,father ,kid).2 (...)3 is_father(X) :- parents(_,X,_), !.
we are interested if X is father, not how many kids he has. Duringbacktracking other possibilities beyond the first will not be considered
the use of ! may be tricky: it may make your program work, or it maybreak it
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 48 / 177
Prolog Finding solutions and prolog programs
(GNU Prolog Manual, sect. 7.2.1)“!/0 always succeeds with the side-effect of removing all choice-pointscreated since the invocation of the predicate activating it.”
This means that the cut predicate always succeeds and (pick one)
removes all choice points connected with the current set of goalsin other words
freezes (or “cuts off”) the choices made thus far, if they lead to avalid solutionin other words
divides the current set of goals into its left and right part andexecutes them separately (left first, if success the choices are set onceand for all, right part afterwards – if right part fails, no returning tothe left part but everything fails)
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 49 / 177
Prolog Finding solutions and prolog programs
Example: the order of resolution without cut.Consider a simple program:
1 x(1).2 x(10).3 x(100).4 y(2).5 y(20).6 y(200).7
8 liczba(A,B) :- x(A), y(B).
The resolution of liczba(A,B) is performed according to the scheme:Solve x(A) (first candidate A=1)Assuming A=1 solve y(B) (first candidate B=2)Assuming A=1 solve y(B) (second candidate B=20) etc.Solve x(A) (second candidate A=10)Assuming A=10 solve y(B) (first candidate B=2) etc.etc.
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 50 / 177
Prolog Finding solutions and prolog programs
The query and answers:
1 | ?- liczba(X,Y).2
3 X = 1 | X = 10 | X = 1004 Y = 2 ? a | Y = 2 | Y = 25 | |6 X = 1 | X = 10 | X = 1007 Y = 20 | Y = 20 | Y = 208 | |9 X = 1 | X = 10 | X = 10010 Y = 200 | Y = 200 | Y = 20011 | |12 | | (1 ms) yes
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 51 / 177
Prolog Finding solutions and prolog programs
Example: the order of resolution with a cut.Consider a simple program:
1 x(1).2 x(10).3 x(100).4 y(2).5 y(20).6 y(200).7
8 liczba(A,B) :- x(A), !, y(B).
The resolution of liczba(A,B) is performed according to the scheme:Solve x(A) (first candidate A=1)Solve ! – success, freeze the choice A=1Solve y(B) (first candidate B=2)Solve y(B) (second candidate B=20)Solve y(B) (third candidate B=200)Finish
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 52 / 177
Prolog Finding solutions and prolog programs
The query and answers:
1 | ?- liczba(X,Y).2
3 X = 14 Y = 2 ? a5
6 X = 17 Y = 208
9 X = 110 Y = 20011
12 yes
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 53 / 177
Prolog Finding solutions and prolog programs
Example: be careful with the cut!
1 x(1).2 x(10).3 x(100).4 y(10 ,2).5 y(10 ,20).6 y(10 ,200).7
8 liczba(A,B) :- x(A), !, y(A,B).
1 | ?- liczba(X,Y).2
3 no
Even though 3 valid solutions exist, prolog cannot find any of them.
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 54 / 177
Prolog Finding solutions and prolog programs
Example: cut in the database
1 x(1).2 x(10).3 y(2) :- !.4 y(20).5 y(200).6
7 liczba(A,B) :- x(A), y(B).
1 | ?- liczba(X,Y).2
3 X = 14 Y = 2 ? a5
6 X = 107 Y = 28 (1 ms) yes
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 55 / 177
Prolog Finding solutions and prolog programs
Example: cut in this definition is necessary
1 maximum(X,Y,X) :- X>Y.2 maximum(_,X,X).3
4 | ?- maximum(4,5,X).5 X = 56 yes7
8 | ?- maximum(5,4,X).9 X = 5 a10 X = 411 yes
1 maximum(X,Y,X) :- X>Y,!.2 maximum(_,X,X).3
4 | ?- maximum(4,5,X).5 X = 56 yes7
8 | ?- maximum(5,4,X).9 X = 510 yes
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 56 / 177
Prolog Database manipulation
Database manipulationIt is possible to manipulate the database from the console or from theinside of the program. This allows to work with a dynamical database,which is modified as the result of the execution of the program.Example: The prolog program sells something (internet shop with avirtual advisor) and the database must be modified according to theavailability of the goods.Example: The prolog program interpretes the current weather and theforecast advising the best time to take a hike. These data is updatedcontinually via internet.
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 57 / 177
Prolog Database manipulation
These predicates insert Clause in the database:
asserta(Clause).assertz(Clause).
1 | ?- asserta(p(0)).2 yes3
4 | ?- asserta(p(-1)), assertz(p(1)).5 yes
asserta/1 adds its argument at the beginning of the database.assertz/1 adds the Clause at the end of the database.
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 58 / 177
Prolog Database manipulation
listing/0 shows the actual declarations:
1 | ?- listing.2 % file: user_input3 p(-1).4 p(0).5 p(1).6 yes7
8 | ?- p(X).9 X = -1 ? a10 X = 011 X = 112 yes
Notice the order of the declarations.
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 59 / 177
Prolog Database manipulation
It is also possible to insert rules, instead of facts, to the database, but theymust be additionally enclosed in parenthesis asserta((head :- rule)).Notice: no dot at the end of the rule!1 | ?- asserta (( parent(X) :- mother(X,_) ; father(X,_))).2 yes3
4 | ?- listing.5 % file: user_input6
7 parent(A) :-8 ( mother(A, _)9 ; father(A, _)10 ).11
12 p(-1).13 p(0).14 p(1).15 yes
Notice, that the new definition appears at the beginning.
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 60 / 177
Prolog Database manipulation
To remove something from the database, use
retract(Clause).retractall(Clause).
1 | ?- retract (( parent(X) :- mother(X,_) ; father(X,_))).2 yes3
4 | ?- retractall(p(_)).5 yes6
7 | ?- listing.8 % file: user_input9
10 yes
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 61 / 177
Prolog Database manipulation
SUMMARY
be careful with the recurencedecission trees, binary trees – the basics of an “inteligent” system
I different representation of the same dataI different prolog programs describing the sameI → think and plan before programmingthe cut predicate !/0
dynamical database
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 62 / 177
Prolog More about graphs
More about graphs: graphs vs. treesConsider the family tree
Durin|NainII|
-------------------------------| |DainI Borin| |
-------------------------- || | | |Thror Fror Gror Farin| | || | ----------------| | | |ThrainII Nain Fundin Groin| | | |------------------ | ------- ------| | | | | | | |ThorinII Frerin Dis DainII Balin Dwalin Gloin Oin
| |---------- || | |Fili Kili Gimli
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 63 / 177
Prolog More about graphs
The database is constructed in a minimalistic way:
1 son_of(nain2 ,durin).2 son_of(dain1 ,nain2).3 son_of(thror ,dain1).4 son_of(fror ,dain1).5 son_of(gror ,dain1).6 son_of(thrain2 ,thror).7 son_of(thorin2 ,thrain2 ).8 son_of(frerin ,thrain2 ).9 son_of(dis ,thrain2 ).10 son_of(fili ,dis).11 son_of(kili ,dis).
12 son_of(nain ,gror).13 son_of(dain2 ,nain).14 son_of(borin ,nain2).15 son_of(farin ,borin).16 son_of(fundin ,farin).17 son_of(balin ,fundin ).18 son_of(dwalin ,fundin ).19 son_of(groin ,farin).20 son_of(gloin ,groin).21 son_of(oin ,groin).22 son_of(gimli ,gloin).
The predicate son of/2 defines the nearest neighbors and their mutualposition within the tree (here interpreted as being older and younger, i.e.,being higher and lower on the tree).
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 64 / 177
Prolog More about graphs
Some possible (simple) definitions without recurence:
1 father_of(F,S) :- son_of(S,F).
1 gfather_of(GF,GS) :- son_of(GS,F), son_of(F,GF).
1 ggfather_of(GGF ,GGS) :- gfather_of(GGF ,GS),2 son_of(GGS ,GS).
1 brothers(B1,B2) :- father_of(F,B1),2 father_of(F,B2),3 \+(B1=B2).
1 uncle_of(U,N) :- brothers(U,F), father_of(F,N).
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 65 / 177
Prolog More about graphs
Define the ancestor as anybody from your birthline older than you. Thisincludes Durin and Nain II as common ancestors for all dwarfs in this tree.
1 ancestor_of(A,D) :- father_of(A,D);2 father_of(A,X),3 ancestor_of(X,D).
Notice, that this definition does not count uncles (brothers of father), theirancestors and the children of their ancestors. However, this is a much morecomplicated problem:
it would require to move horizontally across the tree (brothers)
it would require to move down the tree (using a separate branch) butnot deeper than the starting point
thus a counter of up and down steps is necessary
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 66 / 177
Prolog More about graphs
Now, cousins are all members of your birthline, so all descendants ofDain I are cousins, and all descendants of Borin are cousins. First guess:
1 cousins(X,Y) :-2 (ancestor_of(borin ,X), ancestor_of(borin ,Y));3 (ancestor_of(dain1 ,X), ancestor_of(dain1 ,Y)).
This implementation doesn’t include Borin and Dain I as anybody’scousins. It also permits to be your own cousin. A better version:
1 cousins(borin ,X) :- ancestor_of(borin ,X).2 cousins(X,borin) :- ancestor_of(borin ,X).3 cousins(dain1 ,X) :- ancestor_of(dain1 ,X).4 cousins(X,dain1) :- ancestor_of(dain1 ,X).5 cousins(X,Y) :-6 ( ancestor_of(borin ,X),7 ancestor_of(borin ,Y), \+(X=Y)) ;8 ( ancestor_of(dain1 ,X),9 ancestor_of(dain1 ,Y), \+(X=Y)) .
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 67 / 177
Prolog More about graphs
Consider the graph [Clocksin, Mellish, chapter 7 ]
a
b
gh
d
f
e
c
Database describing the graph:
1 arc(a,b).2 arc(a,e).3 arc(b,c).4 arc(b,f).5 arc(e,d).6 arc(e,f).7 arc(f,c).8 arc(g,d).9 arc(g,h).10 arc(h,f).
this is not a tree, it’s a graphpaths are unidirectionalno loops present (acyclic graph)
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 68 / 177
Prolog More about graphs
The simplest engine to travel along the graph has the form:
1 path(X,X).2 path(X,Y) :- arc(X,Z), path(Z,Y).
the first condition says, that there’s always a zero path
the 2nd condition defines transitional rule to find paths of length 1hop or more
for 1 hop (nearest neighbors) the rule says:path(X,Y) :- arc(X,Y), path(Y,Y).with arc(X,Y) being present in the database. This is why we neededthe 1st definition
this solution works fine, but has limitations
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 69 / 177
Prolog More about graphs
Examples:
1 ?- path(a,a).2 true ? ;3 no4
5 | ?- path(a,c).6 true ? ;7 true ? ;8 true ? ;9 (1 ms) no
1 | ?- path(a,X).2 X = a ? ;3 X = b ? ;4 X = c ? ;5 X = f ? ;6 X = c ? ;7 X = e ? ;8 X = d ? ;9 X = f ? ;10 X = c ? ;11 (1 ms) no
the path along the graph is not shown
what are the multiple solutions? (difference between X=c in lines 4, 6,10?)
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 70 / 177
Prolog More about graphs
Some feedback from the program is desirable:
path between the endpoints should be shown
correct order of nodes (directional graph)
intermediate results which fail should not be visible
1 path(X,X,L) :- reverse(L,L1), write(L1).2 path(X,Y,L) :- arc(X,Z),3 (\+ member(Z,L) -> L1=[Z|L]),4 path(Z,Y,L1).
Notice:
reverse(list,list) reverses a list
member(term,list) checks if term is on the list
list L stores the path; subsequent nodes are added at the beginning,so reverse is needed at the end
\+member(Z,L) assures that only new nodes Z will be added to thelist, creating a new list L1
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 71 / 177
Prolog More about graphs
What should be L?Maybe an unknown variable:
1 | ?- path(a,c,L).2 no3
4 | ?- path(a,a,L).5 _236 true ? ;7 no
Doesn’t work at all.
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 72 / 177
Prolog More about graphs
Maybe empty list:
1 | ?- path(a,c,[]).2 [b,c]3 true ? ;4
5 [b,f,c]6 true ? ;7
8 [e,d,a,b,c]9 true ? ;10 (...)
The list does not contain the starting node.
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 73 / 177
Prolog More about graphs
Add the starting node to the initial list:
1 | ?- path(a,a,[a]).2 [a]3 true ? ;4 no5
6 | ?- path(a,c,[a]).7 [a,b,c]8 true ? ;9
10 [a,b,f,c]11 true ? ;12
13 [a,e,f,c]14 true ? ;15 no
1 | ?- path(a,X,[a]).2 [a]3 X = a ? ;4
5 [a,b]6 X = b ? ;7
8 [a,b,c]9 X = c ? ;10
11 [a,b,f]12 X = f ? ;13
14 [a,b,f,c]15 X = c ? ; (...)
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 74 / 177
Prolog More about graphs
The solution is still not elegant. The user is interested in the endpointsonly, but has to declare the list which stores the results.Introduce a wrapper :
1 road(X,Y) :- path(X,Y,[X]).
Now:
1 | ?- road(a,c).2 [a,b,c]3 true ? ;4
5 [a,b,f,c]6 true ? ;7
8 [a,e,f,c]9 true ? ;10 no
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 75 / 177
Prolog More about graphs
Consider now the graph
a
b
gh
d
f
e
c
Database describing the graph:
1 arc(a,b).2 arc(a,e).3 arc(b,c).4 arc(b,f).5 arc(e,d).6 arc(e,f).7 arc(f,c).8 arc(g,d).9 arc(g,h).10 arc(h,f).11 arc(d,a). % new entry
paths are unidirectionalone loop present (cyclic graph)
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 76 / 177
Prolog More about graphs
Our previous definitions work (almost) fine in this case:
1 | ?- road(a,d).2 [a,e,d]3 true ? ;4 no5
6 | ?- road(a,a).7 [a]8 true ? ;9 no
but the loop is not detected properly.
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 77 / 177
Prolog More about graphs
The reason is the definition of path/3:
1 path(X,X,L) :- reverse(L,L1), write(L1).2 path(X,Y,L) :- arc(X,Z),3 (\+ member(Z,L) -> L1=[Z|L]),4 path(Z,Y,L1).
in which \+member(Z,L) disallows to return to the same point. Thesimplest way out is to exclude the starting point from the list:
1 loop(X) :- path(X,X ,[]).2
3 | ?- loop(a).4 []5 true ? ;6
7 [e,d,a]8 true ? ;9 no
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 78 / 177
Prolog More about graphs
Let us detect all the loops in the graph:
1 | ?- loop(X).2 [] % the empty loop3 true ? ;4
5 [e,d,a] % a -> e -> d -> a6 X = a ? ;7
8 [d,a,e] % e -> d -> a -> e9 X = e ? ;10
11 [a,e,d] % d -> a -> e -> d12 X = d ? ;13 no
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 79 / 177
Prolog More about graphs
Consider now the graph:
a
b
gh
d
f
e
c
4
1
2
3
2
1
5
7
2
3
Database describing the graph:
1 arc(a,b,1).2 arc(a,e,2).3 arc(b,c,2).4 arc(b,f,7).5 arc(e,d,4).6 arc(e,f,2).7 arc(f,c,3).8 arc(g,d,3).9 arc(g,h,5).10 arc(h,f,1).
model of a road map
paths are bidirectional
this can be included explicitly in tha database or in the definitions(preferred method in most cases)
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 80 / 177
Prolog More about graphs
Add road length counting and bidirectionality:
1 road(X,Y) :- path(X,Y,[X],0).2
3 path(X,X,L,S) :- write(L), nl ,4 write(’Droga: ’), write(S).5 path(X,Y,L,S) :- (arc(X,Z,D); arc(Z,X,D)),6 (\+ member(Z,L) ->7 append(L,[Z],L1), S1 is S+D),8 path(Z,Y,L1 ,S1).
line 1: [X] needed for the starting point to appear on the path list
line 1: 0 (zero) means the initial distance
line 5: (arc(X,Z,D); arc(Z,X,D)) assures bidirectionality
line 7: S1 is S+D increases the distance by the length of the path
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 81 / 177
Prolog More about graphs
Example:
1 | ?- road(c,a).2 [c,b,f,e,a]3 Droga: 134 true ? ;5
6 [c,b,f,h,g,d,e,a]7 Droga: 248 true ? ;9
10 [c,b,a]11 Droga: 312 true ? ;
13 [c,f,b,a]14 Droga: 1115 true ? ;16
17 [c,f,e,a]18 Droga: 719 true ? ;20
21 [c,f,h,g,d,e,a]22 Droga: 1823 true ? ;24 no
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 82 / 177
Prolog More about graphs
HomeworkProblem: Write two prolog programs which will find the shortest pathbetween two nodes of a bidirectional graph. “The shortest path” means:
a) the smallest number of intermediate nodes
b) the shortest distance (with distances assigned to each connection)
Deadline: 10.XII.2018
Delivery: please send me your programs (database + definitions) [email protected]
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 83 / 177
Prolog More about graphs
Modified blackjack (21) game. Rules:
use cards with values 1–10 points
start with 2 random cards
each turn you may either draw next card or finish
the number of points should be as close to 21 as possible but if itexceeds 21 you loose immediately
These rules, and rules of most other games, are often depicted by boxdiagrams (flowcharts). The flowcharts encode decission making processes,rules, and can be almost directly converted into computer programs.
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 84 / 177
Prolog More about graphs
The flowchart for this game
Draw another card?
Draw 2 cards
Draw one card
Sum of points (S)
Your score: 21−SLoose the game
Is (S>21)?
yes
no
yes no
Identify on the diagram:input and output datamain part of the programloopuser input (game decissions)game rules
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 85 / 177
Prolog More about graphs
The sketch of a prolog program which leads this game for one player:1 play :- start(S), loop(’i’,S,S1), sum_list(S1 ,Sum), result(Sum).2
3 start(S) :- draw_card(C1), draw_card(C2), S=[C1 ,C2].4
5 % initial state of the loop and decission if finish the game6 loop(’i’,S,S1) :- sum_list(S,Score), write(’Your score is: ’),7 write(Score), write(’Draw a card (y/n)?’),8 read(Decission), loop(Decission ,S,S1).9
10 % leaving the loop11 loop(’n’,S,S1) :- S1 = S.12
13 % next round of the loop14 loop(’y’,S,S1) :- draw_card(C), SN = .(C,S), loop(’i’,SN ,S1).15
16 % final result of the game17 result(Sum) :- ... .18
19 % random card20 draw_card(C) :- ... .
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 86 / 177
Prolog More about graphs
The main and most complicated part of the game code is the loop
the ’i’ mode handles the initial state of the play, when two cards arerevealed, and player’s decissions
the ’n’ mode finishes the loop and updates the final list of player’scards (S1)
the ’y’ mode draws next card and updates the player’s temporarycard list (S)
We need two lists, S and S1, because last two predicates of play need tobe called with the final content of the player’s hand. S is updated internallyinside the loop, but on the level of play it has still the initial value!
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 87 / 177
Prolog More about graphs
Flowcharts are quite universal:
decission making processes
resolution
‘pseudo-inteligent’ behavior ofan automaton
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 88 / 177
Prolog More about graphs
Example of an actual game – all rules on one graph
Turn Begins
Turn Ends
1Open the
Door
Take 1 Dungeon / Station Card, Face UP
Is it a...MONSTER?
Is it a CURSEor a TRAP?
Place card into handOR put card into playright now.
Trap takes effect...on YOU! Right now!Aren’t you lucky?
2Look forTrouble
Have you aMonster card in
your hand?
Play the Monster Cardfrom your hand to thetable.
3Loot the
Room
Combat
Take one Dungeon /Station card face DOWN and place it in your hand OR put it into play right now.
4Charity
Have youmore than 5 cards
in your hand?
Areyou Lowest
Level or tied forLowest level?
Discard excess cards.
Give excess cards toLiving Characters withLowest Level (or tiedfor Lowest Level.)
Compare TOTAL levelsof ALL Monsters to total of your Level & bonuses (plus your Helper’s Level & bonuses, too.)
Can you beatthe monster?
Somethingchanged duringthe 2.6 second
pause?
Must youRun Away?
Persuade someone tohelp you. Pick just one Helper. Choose wisely.
Runnersmust roll 1d foreach monster.
Bad Stuff happens...Maybe Multiple BadStuff!
Runner escapes!You killed the monster.Increase your level(s);Take the Treasure face DOWN (face UP if youhad a Helper.)
Go To4
Charity
Y
Y
Y
YY
Y
Y
Y
N N
N
N
N
N
N
N
MUNCHKIN, Mostly On One Page
Do you wantto fight this
monster?
Y
N
4 orless
5 or more
THINGS TO DO WHEN YOU’RE DEAD-- Keep your Level, Race & Class-- Lay out your hand, face up, next to your other cards in play.-- In level order (high to low), each living character gets to take one card.-- Discard any leftovers.-- You live again at the beginning of the next player’s turn.-- Just before the beginning of your next turn, draw 2 Treasure Cards and 2 Dungeon / Station Cards, face DOWN. Put any of these into play as you will.
TRADE YOUR STUFF with other players anytime you or they are not in combat; you can only trade with cards that are in play.SELL YOUR STUFF only during your turn when you are not in combat. You can sell from what’s in play and/or from your hand.
YOU CAN CARRY IN PLAY1 Headgear1 Footgear1 Armor2 1-Hand Items1 2-Hand Item1 Big or Complex Item1 SidekickItems in play which cannot be carried should be turned sideways.
WHEN TO PLAY...CURSES: any time, even during combat.POTIONS: during any combat, from cards in play or in hand.TREASURES, RACE, CLASS: Play these as you acquire them or from your hand on your turn.
RULES EVEN MUNCHKINS NEED TO HEEDYou have to kill a monster to get your 10th Level (and win!). Cards overrides rules (and this chart!). Once combat starts you cannot change what you are carrying in play (but you can discard your Race or Class.) Only the cards in play (displayed in front of you) count for trading, bribery, combat, etc. Once a card is in play you can’t pull it back into your hand -- you can only trade, sell or discard it.
Created for yourMunchkinly pleasure
by Bob Portnell
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 89 / 177
Prolog More about graphs
SUMMARY
not all graphs are trees, all trees are graphs
graphs: acyclic or cyclic
graphs: unidirectional vs. bidirectional
flowcharts
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 90 / 177
Prolog Lists
append(L1,L2,M) creates a new list M=L1+L2
1 | ?- L1=[a,b,c], L2=[d,e,f], append(L1,L2,M)2
3 L1 = [a,b,c]4 L2 = [d,e,f]5 M = [a,b,c,d,e,f]6
7 yes
How does it (possibly) work?
decomposes one list (L1 or L2) into separate elements
adds the elements on the beginning or end of the other list
unifies the outcome with the last argument M
uses recurence to work through the whole list
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 91 / 177
Prolog Lists
Problem: Define concat/3 that works like append/3.Strategy 1
remove the first element from L2
add it to the end of L1
repeat until L2=[]
unify the outcome with M
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 92 / 177
Prolog Lists
Solution 1.1
1 concat(L,[],L).2 concat(L1,L2,M) :- L2=[E|R], Z=[L1|E],3 concat(Z,R,M).4 | ?- L1=[a,b,c], L2=[d,e,f], concat(L1,L2,M).5
6 L1 = [a,b,c]7 L2 = [d,e,f]8 M = [[[[a,b,c]|d]|e]|f] ? ;9
10 no
the result isn’t constructed correctly
the appended elements are not treated as separate terms
observe: the head is a term, but the tail must be a list
in line 2: E is the head of L2 and the tail of Z
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 93 / 177
Prolog Lists
Solution 1.2
1 concat(L,[],L).2 concat(L1,L2,M) :- L2=[E|R], Z=[L1|[E]],3 concat(Z,R,M).4 | ?- L1=[a,b,c], L2=[d,e,f], concat(L1,L2,M).5
6 L1 = [a,b,c]7 L2 = [d,e,f]8 M = [[[[a,b,c],d],e],f] ? ;9
10 no
the result is a nested list
one may introduce a predicate which ‘flattens’ lists and obtain thecorrect result...
... or use the 2nd strategy
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 94 / 177
Prolog Lists
The conclusion:
we don’t know how to correctly append an element at the end of alist,
we cannot use the built-in predicate append,
we don’t want to use the built-in predicate reverse,
so we need append to define our concat, which makes no sense.
Homework: Define the predicate flat/2 which will flatten nested lists.
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 95 / 177
Prolog Lists
Strategy 2
remove the last element from L1
add it to the beginning of L2
repeat until L1=[]
unify the outcome with M
Problem: how to remove the last element from the list?The possible ways out are
reverse the list and take its head (not elegant, we don’t want to dothat, besides – requires to use reverse)
cut the head until the last element is reached and then “gobackwards” using the heads in the reversed order
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 96 / 177
Prolog Lists
Solution 2
1 concat ([],L,L).2 concat(L1,L2,M) :- L1=[P|K],3 concat(K,L2,Z),4 M=[P|Z].5 | ?- L1=[a,b,c], L2=[d,e,f], concat(L1,L2,M).6
7 L1 = [a,b,c]8 L2 = [d,e,f]9 M = [a,b,c,d,e,f] ? ;10
11 no
Let’s analyze the code...
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 97 / 177
Prolog Lists
Strategy 1
easier to understand the recurence
outcome only approximately correct (needs “flattening”)
Strategy 2
less obvious, because to take the last element, one has to go throughthe whole list starting from the beginning
the outcome is correct
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 98 / 177
Prolog Lists
reverse(LM,ML) is true if ML is the reversed list LM
1 | ?- reverse ([a,b,c],[c,b,a]).2 yes3
4 | ?- reverse ([a,b,c,d],X).5 X = [d,c,b,a]6 yes7
8 | ?- reverse(X,[a,b,c,d]).9 X = [d,c,b,a]10 yes
How is it defined?
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 99 / 177
Prolog Lists
Problem: build our own implementation of reverse/2.Strategy
remove the head of the input list
add it at the beginning of the output list
Notice, that in this problem we do not have the problem of appendingsomething to the output list!Complications
we have one input list – transfer it to the initially uninstantiatedoutput
we have both lists instantiated – compare them, if one is the reverseof the other
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 100 / 177
Prolog Lists
Implementation 1 (not correct)
1 odwroc(_ ,[]).2 odwroc(X,[G|O]) :- append(L,[G],X), odwroc(L,O).
Let’s analyze the code...
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 101 / 177
Prolog Lists
1 ?- odwroc(X,[a,b,c,d]).2 X = [d,c,b,a] ? ;3 X = [_,d,c,b,a] ? ;4 X = [_,_,d,c,b,a] ? ;5 X = [_,_,_,d,c,b,a] ? ;6 X = [_,_,_,_,d,c,b,a] ? ;7 X = [_,_,_,_,_,d,c,b,a] ? ;8 X = [_,_,_,_,_,_,d,c,b,a] ?9 Prolog interruption (h for help) ? a10 execution aborted11 | ?- odwroc ([a,b,c,d],X).12 X = [] ? ;13 X = [d] ? ;14 X = [d,c] ? ;15 X = [d,c,b] ? ;16 X = [d,c,b,a] ? ;17 (1 ms) no
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 102 / 177
Prolog Lists
Implementation 2 (still not correct)
1 odwroc ([] ,[]).2 odwroc(X,[G|O]) :- append(L,[G],X), odwroc(L,O).
1 | ?- odwroc(X,[a,b,c,d]).2 X = [d,c,b,a] ? ;3 ^C4 Prolog interruption (h for help) ? a5 execution aborted6
7 | ?- odwroc ([a,b,c,d],X).8 X = [d,c,b,a] ? ;9 no
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 103 / 177
Prolog Lists
Hmmmm... the naive approach is not acceptable
the code has problem with termination
it behaves differently depending on the variable placement
it builds the solution and accepts all intermediate states
Try to use an accumulator:
this is a variable, which is neither the input, nor the output
it stores intermediate results
it is updated during recursion
it should be unified with the output at the end of recursion
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 104 / 177
Prolog Lists
Implementation 3 (almost there)
1 odwroc ([],A,X) :- X=A.2 odwroc ([G|O],A,X) :- append ([G],A,T),3 odwroc(O,T,X).
1 | ?- odwroc ([a,b,c,d],[],X).2 X = [d,c,b,a]3 yes4
5 | ?- odwroc(X,[],[a,b,c,d]).6 X = [d,c,b,a] ? ;7 Fatal Error: global stack overflow
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 105 / 177
Prolog Lists
Implementation 4 (the correct one!)
1 odwroc ([],X,X) :- !.2 odwroc ([G|O],A,X) :- append ([G],A,T),3 odwroc(O,T,X).
1 | ?- odwroc ([a,b,c,d],[],X).2 X = [d,c,b,a]3 yes4
5 | ?- odwroc(X,[],[a,b,c,d]).6 X = [d,c,b,a] ? ;7 yes
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 106 / 177
Prolog Lists
The last solution works OK, except that it requires 3 arguments not 2, butthis is easy to correct by defining a wrapper.
1 my_reverse(L,M) :- odwroc(L,[],M).
Observe:
our definitions have (mostly) two lines
the second line is the “engine” of the predicate
the first line is the termination condition (and it must be defined inthis order!)
the termination doesn’t necessarily finishes the code
in odwroc it plays the role of a “turning point” (the program stopsthe decomposition of the list)
past that point the program starts to build the solution from the datagathered during the recurence
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 107 / 177
Prolog Lists
SUMMARY
structure of a recurence definitionI the main “engine” of the predicateI the termination condition for the recurence placed before the engine inthe definition
decomposition of a list from the first to the last entry
decomposition of a list from the last to the first entry
don’t forget about the cut predicate !
accumulators allow to transfer intermediate data through therecurence to the output variable
hiding accumulators from the user using wrappers
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 108 / 177
Prolog Lists
Problem: build our own implementation of select/3, which removes oneoccurence of a given term from a list.usun(T,M,L)T – term to be removed from MM – input listL – output listStrategy:
compare T with elements of list M
if different, append the element to list L
if the same, ignore it and copy the remaining (not yet analyzed) partof M to list Lwe have to deal with two distinct situations1 T is a member of M:→ on the beginning of list M→ not on the beginning of list M
2 T is not a member of M
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 109 / 177
Prolog Lists
What we need:
a predicate that will analyze the list until the term T is found in it
the case when T is not on the list must be taken into account
a predicate that will duplicate a list (copying)
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 110 / 177
Prolog Lists
Implementation 1: let us start with the following code
1 kopiuj ([] ,[]) :- !.2 kopiuj ([G|O],[A|B]) :- G=A, kopiuj(O,B).3
4 usun(T,[G|O],L) :- T=G, kopiuj(O,L), !.5 usun(T,[G|O],[A|B]) :- T\=G, A=G, usun(T,O,B).
1 | ?- usun(2,[a,b,4,2,6,c],L).2 L = [a,b,4,6,c]3 yes4
5 | ?- usun(x,[a,b,4,2,6,c],L).6 (1 ms) no
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 111 / 177
Prolog Lists
Issues with this implementation:1 doesn’t handle properly the case when term is not on the list2 removes only the first occurence of the term, not single occurences asselect does
3 is not elegant and far from optimal
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 112 / 177
Prolog Lists
Implementation 2: fixing issue 1 – T is not on the list M
1 kopiuj ([] ,[]) :- !.2 kopiuj ([G|O],[A|B]) :- G=A, kopiuj(O,B).3
4 usun(T,M,L) :- \+ member(T,M), kopiuj(M,L), !.5 usun(T,[G|O],L) :- T=G, kopiuj(O,L), !.6 usun(T,[G|O],[A|B]) :- T\=G, A=G, usun(T,O,B).
1 | ?- usun(2,[a,b,4,2,6,c],L).2 L = [a,b,4,6,c]3 yes4
5 | ?- usun(x,[a,b,4,2,6,c],L).6 L = [a,b,4,2,6,c]7 yes
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 113 / 177
Prolog Lists
Implementation 3: fixing issue 3 – optimizationThe folllowing codes are equivalent:
1 % old version2 kopiuj ([] ,[]) :- !.3 kopiuj ([G|O],[A|B]) :- G=A, kopiuj(O,B).4
5 usun(T,M,L) :- \+ member(T,M), kopiuj(M,L), !.6 usun(T,[G|O],L) :- T=G, kopiuj(O,L), !.7 usun(T,[G|O],[A|B]) :- T\=G, A=G, usun(T,O,B).
1 % new version2 usun(T,L,L) :- \+ member(T,M), !.3 usun(T,[T|L],L) :- !.4 usun(T,[G|O],[G|B]) :- T\=G, usun(T,O,B).
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 114 / 177
Prolog Lists
However, this implementation is still not perfect, as it removes only thefirst occurence of the term T from the list.
1 | ?- usun(a,[a,1,a,3,a,6,a,a,a,8],X).2 X = [1,a,3,a,6,a,a,a,8] ? ;3 no
while
1 | ?- select(a,[a,1,a,3,a,6,a,a,a,8],X).2 X = [1,a,3,a,6,a,a,a,8] ? ;3 X = [a,1,3,a,6,a,a,a,8] ? ;4 X = [a,1,a,3,6,a,a,a,8] ? ;5 X = [a,1,a,3,a,6,a,a,8] ? ;6 X = [a,1,a,3,a,6,a,a,8] ? ;7 X = [a,1,a,3,a,6,a,a,8] ? ;8 no
You will fix that during the laboratories...
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 115 / 177
Prolog Some advanced topics: recurence
Advanced topics: recurenceRecurence – two approaches:
top-down – starts from the original problem, decomposing it intosimpler sub-problems until trivial facts (from the database) emerge
bottom-up – starts with known rules and uses them on simplestobjects to construct the original problem; in this approachaccumulators are often used; these funtions are usually faster than thetop-bottom implementations
Our test exampleThe Fibonacci sequence
0, 1,→ 1, 2, 3, 5, 8, 13, 21, 34, ..., 6765 (20th place) , ...
is generated from two first numbers 0, 1 (sometimes 1, 1) by a recurenceformula
fn = fn−1 + fn−2, n > 2
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 116 / 177
Prolog Some advanced topics: recurence
The top-down definition
1 fib(N,0) :- N =:= 0.2 fib(N,1) :- N =:= 1 ; N =:= 2.3 fib(N,X) :- N1 is N-1, fib(N1 ,Y),4 N2 is N-2, fib(N2 ,Z), X is Y+Z.
we start from N and go down (N1 is N-1, N2 is N-2) until N=0
simplest/special cases at the beginning to define the first elements ofthe sequence (termination of the recurence)
general case (recurence) at the end
result (X is Y+Z) is computed after the recurence finishes
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 117 / 177
Prolog Some advanced topics: recurence
Equivalent top-down definition after some reorganization of the code
1 fib(0,0).2 fib(1,1).3 fib(N,X) :- fib(N-1,Y), fib(N-2,Z), X is Y+Z.
Homework: Correct the termination issue of this predicate.
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 118 / 177
Prolog Some advanced topics: recurence
The bottom-up definition
1 fibonacci(N,X) :- fib(0,0,1,N,X).2
3 fib(N,X,_,N,X).4 fib(N1 ,X1 ,X2 ,N,X) :- N1 <N, N2 is N1+1,5 X3 is X1+X2 ,6 fib(N2 ,X2 ,X3 ,N,X).
line 1: wrapper
line 3: termination condition
lines 4-6: N, N1, N2 – number elements in the sequence
lines 4-6: X1, X2, X3 – elements in the sequence
N1, X1, X2 – accumulators
notice that the (intermediate) result (X3 is X1+X2) is obtainedbefore fib is called
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 119 / 177
Prolog Some advanced topics: recurence
Some remarks:
the top-down definitions are ‘simpler’, more straightforward, andshorter
the bottom-up definition is more complex; uses 3 accumulators and awrapper
the top-down definitions invoke fib twice, so the computationalcomplexity is like 2R, where R is the number of recurences(exponential)
the bottom-up definition invokes fib once, so the computationalcomplexity is like R, where R is the number of recurences (linear)
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 120 / 177
Prolog Some advanced topics: recurence
Example 2The factorial function
n! = 1 · 2 · · · · · n
The top-down definition
1 fact (0,1).2 fact(N,F):- N>0, N1 is N-1,3 fact(N1 ,F1), F is N*F1.
The bottom-up definition
1 fact(N,F) :- fact(0,1,N,F).2
3 fact(N,F,N,F).4 fact(N1 ,F1 ,N,F):- N1 <N, N2 is N1+1,5 F2 is N2*F1 , fact(N2 ,F2 ,N,F).
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 121 / 177
Prolog Some advanced topics: recurence
Summary: directions of reasoningBottom-up
forward reasoning
start from facts
use rules to prove the query (B)
may create many true statements that are not connected to theactual query
Example: A is true, the rule (A :- B.) exists, infer that B is trueTop-down
used by prolog
backward reasoning
start from the query (A)
use rules in reverse to prove the query is equivalent to somecombination of facts
may be slow, exploring lines of reasoning that fail
Example: the rule (A :- B.) exists, to prove A prove BMarek Góźdź (2018/2019) PROLOG 21 stycznia 2019 122 / 177
Prolog Some advanced topics: recurence
Examples (from the lecture by A.Bonner, Univ. Toronto):Example 1:
1 p(X,Y,Z) :- q(X), q(Y), q(Z).2 q(a1).3 q(a2).4 ...5 q(an).
bottom-up approach will create n3 facts of the form p(ai,aj,ak)
Example 2:
1 p(f(x)) :- p(x).2 p(a).
bottom-up approach will create infinitely many facts of the formp(f(a)), p(f(f(a))), p(f(f(f(a))))...
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 123 / 177
Prolog Some advanced topics: recurence
Example 3:
1 A :- B.2 B :- C.
top-down approach will fail to prove A:goal A → goal B → goal C → unable to prove ⇒ FAIL to prove A
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 124 / 177
Prolog Some advanced topics: recurence
Example 4:
1 A :- B1, B2.2 B1 :- C1 , C2.3 B2 :- C3 , C4.4 C1.5 C2.6 C3.7 C4.
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 125 / 177
Prolog Some advanced topics: recurence
Example 5:
1 A :- B1.2 A :- B2.3 B1 :- C1.4 B1 :- C2.5 B2 :- C3.6 B2 :- C4.7 C4.
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 126 / 177
Prolog Some advanced topics: recurence
SUMMARY
always try to keep your code simple and compact
forward reasoning (bottom-up)
backward reasoning (top-down)both directions of reasoning lead to different recurence definitions,including their
I numerical complexity (speed)I order of function calls
both reasonings are logically equivalent
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 127 / 177
Prolog Some advanced topics: FDS
Advanced topics: Finite Domain Solver (FDS)
this system is present in the GNU prolog implementation (see: GNUProlog Manual, chapter 9)
SWI prolog has a similar module called clpfd: Constraint LogicProgramming over Finite Domains with different syntax
FDS allows for constraining the possible solutions to certain values orsets only
saves lots of time if programmed correctly
allows, e.g., for solving equations with one or more unknowns
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 128 / 177
Prolog Some advanced topics: FDS
Finite Domain variablescompatible with regular prolog integersinitial range is 0 ... fd_max_integer
1 | ?- fd_max_integer(X).2 X = 268435455
Domain sizethe domain has to be constrained as soon as possible due to limitedpossible size (overflow error), eg.,
I Z=X*Y, X<100, Y<40 creates first the domain for Z of the sizefd_max_integer×fd_max_integer which is huge and may fail
I X<100, Y<40, Z=X*Y first constraints the domains of X and Y, andthen creates the domain for Z of the size 100×40
interval representation – the domain has the form of a continuousrange; additional constraints can be added on the ends of the rangeonlysparse representation – the domain is not continuous so all possiblevalues are stored in a vector (of max length vector_max=127, can beadjusted by fd_set_vector_max/1)
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 129 / 177
Prolog Some advanced topics: FDS
Setting the domain.fd_domain/3 – sets the domain to an interval; works for single variableand for list of variables
1 | ?- fd_domain(X,0 ,4).2 X = _#0(0..4)
1 | ?- fd_domain ([X,Y,Z],0,4).2 X = _#0(0..4)3 Y = _#18(0..4)4 Z = _#36(0..4)
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 130 / 177
Prolog Some advanced topics: FDS
fd_domain/2 – sets the domain to a list of possible values
1 | ?- fd_domain(X,[1 ,3 ,5]).2 X = _#2(1:3:5)
1 | ?- fd_domain ([X,Y],[1,3,5]).2 X = _#2(1:3:5)3 Y = _#34(1:3:5)
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 131 / 177
Prolog Some advanced topics: FDS
Domain and variable information.fd_min/2, fd_max/2 – the min and max values allowed for the variable
1 | ?- fd_domain(X,[1,3,5]), fd_min(X,MIN),2 fd_max(X,MAX).3 MIN = 14 MAX = 55 X = _#2(1:3:5)
fd_size/2 – the size of the domain
1 | ?- fd_domain(X,13,24), fd_size(X,N).2 N = 123 X = _#0(13..24)
1 | ?- fd_domain(X,[13 ,24]) , fd_size(X,N).2 N = 23 X = _#2(13:24)
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 132 / 177
Prolog Some advanced topics: FDS
fd_dom/2 – lists the current domain of a variable
1 | ?- fd_domain(X,13,24), fd_dom(X,N).2 N = [13 ,14 ,15 ,16 ,17 ,18 ,19 ,20 ,21 ,22 ,23 ,24]3 X = _#0(13..24)
1 | ?- fd_domain(X,[13 ,24]) , fd_dom(X,N).2 N = [13 ,24]3 X = _#2(13:24)
fd_has_vector(X) – is the domain of X in sparse representation?fd_use_vector(X) – enforces the sparse representation of the X’s domain
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 133 / 177
Prolog Some advanced topics: FDS
Arithmetics.
Partial arithmetic constraintsConstraints FD expression X to be...
X #= Y equal to...X #\= Y not equal to...X #< Y less than...X #=< Y not greater than...X #> Y greater than...X #>= Y not smaller than...
... FD expression Y.
These operators impose constraints on the hash-side (X in my example) toreduce its domain. Only the bounds of the domain are updated (fasterversion, less accurate in some cases).
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 134 / 177
Prolog Some advanced topics: FDS
There are double-hash operators (#=#, #=<#, etc.) which update the wholedomain (slower version, more accurate).
fd_prime(X) – constraints X to be a prime number within thevector_max range; forces sparse representation of X’s domain
1 | ?- fd_prime(X).2 X = _#1(2..3:5:7:11:13:17:19:23:29:31:37:41:43:3 47:53:59:61:67:71:73:79:83:89:97:101:4 103:107:109:113:127@)
fd_not_prime(X) – constraints X to be anything but a prime numberwithin the vector_max range; forces sparse representation of X’s domain
1 | ?- fd_not_prime(X).2 X = _#1(0..1:4:6:8..10:12:14..16:18:20..22:24..28:3 30:32..36:38..40:42:44..46:48..52:54..58:60:62..66:4 68..70:72:74..78:80..82:84..88:90..96:98..100:102:5 104..106:108:110..112:114..126@)
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 135 / 177
Prolog Some advanced topics: FDS
Boolean algebra (logic).
Logic operatorsConstraints FD boolean expression X
#\ X NOT XX #<=> Y X equivalent to YX #\<=> Y X NOT equivalent to YX ## Y X XOR Y is trueX #==> Y X implies YX #\==> Y X NOT implies YX #/\ Y X AND Y is trueX #\/\ Y X AND Y is falseX #\/ Y X OR Y is trueX #\\/ Y X OR Y is false
where Y is also a FD boolean expression.
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 136 / 177
Prolog Some advanced topics: FDS
Examples: Negation
1 | ?- #\ X #<=> 1.2 X = 0
Equivalent, not equivalent
1 | ?- X=1, Y #<=> X, Z #\<=> Y.2 X = 13 Y = 14 Z = 0
XOR (addition modulo 2)
1 | ?- X=1, Y=0, X##Y.2 X = 13 Y = 04 yes5
6 | ?- X=1, Y=1, X##Y.7 no % remember definition!
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 137 / 177
Prolog Some advanced topics: FDS
fd_labeling(X) – a special directive which forces prolog to work onvalues of X, not just an abstract representation of the domain; X may bealso a list of FD variablesCompare:
1 | ?- fd_prime(X).2 X = _#1(2..3:5:7:11:13:17:19:23:29:31:37:41:43:3 47:53:59:61:67:71:73:79:83:89:97:101:4 103:107:109:113:127@)
1 | ?- fd_prime(X), fd_labeling(X).2 X = 2 ? ;3 X = 3 ? ;4 X = 5 ? ;5 X = 7 ? ;6 X = 11 ? ;7 X = 13 ?8 Prolog interruption (h for help) ? a9 execution aborted
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 138 / 177
Prolog Some advanced topics: FDS
Important:
Until fd_labeling is used, prolog tries not to instantiate variables aslong as it is possible. Giving the solution in the most general form,using the ranges of domains, is often not useful.
Using fd_labeling sets prolog in a mode, where actual values (fromthe domain) of the variables are being substituted and thecomputation is performed on them.
So, whenever you are using the FDS and want some definite answers,you must “fd label” the variables.
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 139 / 177
Prolog Some advanced topics: FDS
Cheking the de Morgan’s Law
1 | ?- (#\(X #/\ Y)) #<=> ((#\ X) #\/ (#\ Y)).2 X = _#18(0..1)3 Y = _#36(0..1)4 yes
1 | ?- (#\(X #/\ Y)) #<=> ((#\ X) #\/ (#\ Y)),2 fd_labeling ([X,Y]).3
4 X = 0 | X = 15 Y = 0 ? ; | Y = 0 ? ;6 |7 X = 0 | X = 18 Y = 1 ? ; | Y = 19 | yes
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 140 / 177
Prolog Some advanced topics: FDS
From the domains to values: domains only
1 | ?- fd_domain ([X,Y],1,3), Y #< X.2 X = _#0(2..3)3 Y = _#18(1..2)4 yes
From the domains to values: one variable labeled
1 | ?- fd_domain ([X,Y],1,3), Y #< X,2 fd_labeling(X).3 X = 24 Y = 1 ? ;5
6 X = 37 Y = _#18(1..2)8 (1 ms) yes
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 141 / 177
Prolog Some advanced topics: FDS
From the domains to values: both variables labeled
1 | ?- fd_domain ([X,Y],1,3), Y #< X,2 fd_labeling ([X,Y]).3 X = 24 Y = 1 ? ;5
6 X = 37 Y = 1 ? ;8
9 X = 310 Y = 211 yes
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 142 / 177
Prolog Some advanced topics: FDS
FDS for lists.
fd_element(N,L,X) – constraints X to be equal to the N-th element ofthe list LExample:
1 | ?- L=[2,4,6,8], fd_element (4,L,X).2 L = [2,4,6,8]3 X = 8
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 143 / 177
Prolog Some advanced topics: FDS
fd_all_different(L) – assures that all FD variables constituting the listL take different values; very useful, allows not to use the slow predicatepermutation/2Example:
1 | ?- fd_domain ([X,Y,Z],5,8), L=[X,Y,Z],2 X#<Y, Y#<Z,3 fd_all_different(L), fd_labeling ([X,Y,Z]).4
5 L = [5,6,7] | L = [5,7,8]6 X = 5 | X = 57 Y = 6 | Y = 78 Z = 7 ? ; | Z = 8 ? ;9 |10 L = [5,6,8] | L = [6,7,8]11 X = 5 | X = 612 Y = 6 | Y = 713 Z = 8 ? ; | Z = 814 | yes
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 144 / 177
Prolog Some advanced topics: FDS
Applying constraints may lead to two cases:
fully constrained – set of constraints narrows the possible solutionsto only one; if this solution lies within the imposed domain(s) thecase is solved
partially constrained – the constraints narrow the possible solutionsto a region/set; those which agree with the range of the imposeddomain(s) are valid
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 145 / 177
Prolog Some advanced topics: FDS
Example: Solve the equation 2 + x = 4. This is a fully constrained case.
1 | ?- 2+X #= 4.2 X = 23 yes
Notice, that:
the operators =, ==, =:= will not do the trick
operator #= indicates that the L-hand side and R-hand side should beequal
prolog seeks for values of variables to fulfill the equation
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 146 / 177
Prolog Some advanced topics: FDS
Example: Solve the inequality 2 + x < 4. This is a partially constrainedcase.
1 | ?- 2+X #=< 4.2 X = _#2(0..2)3 yes
prolog gave the correct range of solutions < 0, 2 > but not definitevalues
prolog assumed silently that X > 0 – that’s the lower bound of thedefault domain
prolog must be forced to browse through that set of would-besolutions and pick the correct values (not all of them or not allcombinations of them must be correct!)
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 147 / 177
Prolog Some advanced topics: FDS
1 | ?- 2+X #=< 4, fd_labeling(X).2 X = 0 ? ;3 X = 1 ? ;4 X = 25 yes
the fd_labeling(X) sets X to values from the range of solutions
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 148 / 177
Prolog Some advanced topics: FDS
Example: (konkurs Świetlik dla klas 3, 2009) Two eggs and a cup of flourweigh 30 dag, while 3 eggs and two cups of flour weigh 54 dag. What isthe weight of 1 egg and two cups of flour?
1 | ?- 2*E+F #= 30, 3*E+2*F #= 54, X is E+2*F.2 E = 6 % 1 egg3 F = 18 % 1 cup of flour4 X = 42 % the result5 yes
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 149 / 177
Prolog Some advanced topics: FDS
Example: Predicate between/3 – generates a sequence of backtrackingchoices instantiating the counterBasic usage:
1 | ?- between(3,5,X).2 X = 3 ? a3 X = 44 X = 55 yes
Implementation of this predicate is pretty easy using FDS.
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 150 / 177
Prolog Some advanced topics: FDS
Problem: use FDS to implement between/3.Strategy: obvious, isn’t it?Solution:
1 pomiedzy(X,I,J) :- I #=< X, X #=< J,2 fd_labeling(X).
1 | ?- pomiedzy(X,3 ,5).2 X = 3 ? a3 X = 44 X = 55 yes
Even more elegantly:
1 pomiedzy(X,I,J) :- fd_domain(X,I,J),2 fd_labeling(X).
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 151 / 177
Prolog Some advanced topics: FDS
Example: In the following riddle each letter codes a different number0...9. Solve the equation:
D O N A L D+ G E R A L D-----------= R O B E R T
Strategy:
we have 10 different letters, so all ten numbers 0...9 will be used
the letters are: A,B,D,E,G,L,N,O,R,T
D + D = T
L + L = R (mod 10)
A + A = E (mod 10)
etc.
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 152 / 177
Prolog Some advanced topics: FDS
Solution 1:
1 reb(A,B,D,E,G,L,N,O,R,T) :-2 X=[A,B,D,E,G,L,N,O,R,T],3 L=[1,2,3,4,5,6,7,8,9,0], permutation(X,L),4 (D*100000+O*10000+N*1000+A*100+L*10+D) +5 (G*100000+E*10000+R*1000+A*100+L*10+D) #=6 (R*100000+O*10000+B*1000+E*100+R*10+T).
This solution is slow because it uses the slow predicate permutation/2.In this case the permutation is done once, so it’s not a big deal, but... seesudoku.
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 153 / 177
Prolog Some advanced topics: FDS
Solution 2:
1 reb(A,B,D,E,G,L,N,O,R,T) :-2 X=[A,B,D,E,G,L,N,O,R,T],3 fd_domain(X,0,9),4 fd_all_different(X),5 fd_labeling(X),6 (D*100000+O*10000+N*1000+A*100+L*10+D) +7 (G*100000+E*10000+R*1000+A*100+L*10+D) #=8 (R*100000+O*10000+B*1000+E*100+R*10+T).
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 154 / 177
Prolog Some advanced topics: FDS
1 ?- reb(A,B,D,E,G,L,N,O,R,T).2 A = 43 B = 34 D = 55 E = 96 G = 17 L = 88 N = 69 O = 210 R = 711 T = 0 ?12 (2333 ms) yes
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 155 / 177
Prolog Some advanced topics: FDS
Example: The magic square 3x3 using FDS.
1 kwadrat(S,X) :-2 S=[E11 ,E12 ,E13 ,E21 ,E22 ,E23 ,E31 ,E32 ,E33],3 fd_domain(S,1,9),4 fd_all_different(S),5 fd_labeling(S),6 sum_list ([E11 ,E12 ,E13],X),7 sum_list ([E21 ,E22 ,E23],X),8 sum_list ([E31 ,E32 ,E33],X),9 sum_list ([E11 ,E21 ,E31],X),10 sum_list ([E12 ,E22 ,E32],X),11 sum_list ([E13 ,E23 ,E33],X),12 sum_list ([E11 ,E22 ,E33],X),13 sum_list ([E13 ,E22 ,E31],X).
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 156 / 177
Prolog Some advanced topics: FDS
SUMMARY
Finite Domain Solver FDS allows to impose constraints on thevariablesthe basic constraint: fd_domain
I continuous – interval representationI discontinuous – sparse representation
arithmetics – equations and inequalitites
logic – all basic logic operations (AND, OR, NOT, XOR, implication,equivalency)working out the solutions: fd_labeling
I fully constrained casesI partially constrained cases
FD lists – avoid permutation, use fd_all_different
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 157 / 177
Prolog Summary
A comprehensive summary
Additional features of prolog
based on Boolean algebra
uses relations rather than functions, which makes backtrackingpossible
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 158 / 177
Prolog Summary
Operators
infix, prefix, postfix
priority 0 (delete), 1 (execute first) ... 1200 (execute last)
associativity (fy, xfx...)
Declaration in two steps:
predicate op/3 introduces the operator and its specification
the actual definition, i.e., how the operator works
Example: operator which works like member/2
1 :- op(500,xfy ,belongs_to ).2 X belongs_to [X|_].3 X belongs_to [_|L] :- X belongs_to L.
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 159 / 177
Prolog Summary
Is the associativity important?For the infix expression 15-10-5
the right-associativity (xfy) means, that it is converted to the prefixform
-(15,-(10,5)).with right-grouping of the arguments
the left-associativity (yfx) means, that it is converted to the prefix form-(-(15,10),5)).
with left-grouping of the arguments
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 160 / 177
Prolog Summary
A useful construction is the implication X -> Y; Z. It can be used asa conditional statement:
If X then Y; otherwise Z.This compact definition
1 double(X,Y) :-2 number(X) -> Y is X*2 ;3 (number(Y) -> X is Y*2 ; write(’error ’)).
is equivalent to
1 double(X,Y) :- number(X), Y is X*2.2 double(X,Y) :- number(Y), X is Y*2.3 double(X,Y) :- \+ number(X), \+ number(Y),4 write(’error ’).
Don’t use this construction too much!
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 161 / 177
Prolog Summary
Backtracking: the way of finding multiple solutions
performed always for (half-)open queries| ?- likes(marry,X).| ?- likes(X,Y).
the database is consulted many times
markers are used to mark the place in database, where prolog finishedthe last read
temporary variables are automatically created by the system to storeintermediate results
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 162 / 177
Prolog Summary
The operator which allows you to stop backtracking at some point is thecut !/0. It always succeeds and (pick one)
removes all choice points connected with the current set of goalsin other words
freezes (or “cuts off”) the choices made thus far, if they lead to avalid solutionin other words
divides the current set of goals into its left and right part andexecutes them separately (left first, if success the choices are set onceand for all, right part afterwards – if right part fails, no returning tothe left part but everything fails)
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 163 / 177
Prolog Summary
Cut is often used to finish the recurence correctly:
1 ost([X],X).2 ost([_|T],X) :- ost(T,X).3
4 | ?- ost([1,2,3],X).5 X = 3 ? ;6 no
1 ost([X],X) :- !.2 ost([_|T],X) :- ost(T,X).3
4 | ?- ost([1,2,3],X).5 X = 36 yes
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 164 / 177
Prolog Summary
Example: getting rid of multiple solutions (incorrect!)
1 nieje(wieprzowina ,ala).2 nieje(wolowina ,ala).3 nieje(cielecina ,ala).4 nieje(wedlina ,ala).5 nieje(drob ,ala).6 nieje(ryby ,ala).7 nieje(owoce ,kasia ).8 nieje(ryby ,kasia ).9 nieje(kasza ,kasia ).10 nieje(jogurt ,jan).11 nieje(wieprzowina ,jan).12
13 semi -wege(X) :- L=[ wieprzowina ,wolowina ,cielecina ,14 wedlina ,drob ,ryby],15 member(P,L), nieje(P,X).
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 165 / 177
Prolog Summary
Answers:
1 | ?- semi -wege(ala).2 true ? ;3 true ? ;4 true ? ;5 true ? ;6 true ? ;7 true ? ;8 no
1 | ?- semi -wege(X).2 X = ala ? a3 X = jan4 X = ala5 X = ala6 X = ala7 X = ala8 X = ala9 X = kasia10 yes
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 166 / 177
Prolog Summary
Changing the definition by adding cut at the end:
1 semi -wege(X) :- L=[ wieprzowina ,wolowina ,cielecina ,2 wedlina ,drob ,ryby],3 member(P,L), nieje(P,X), !.
Answers:
1 | ?- semi -wege(ala).2 yes
1 | ?- semi -wege(X).2 X = ala3 yes
Only the first solution (ala) is found in the second case! Cut should notbe used like this, unless you really know what you are doing.
Cut prevents from backtracking and finding any other solution. Not fromfinding the same solution multiple times.
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 167 / 177
Prolog Summary
A better version – still not perfect
1 vege([],Out ,Out).2 vege(L,Acc ,Out) :-3 L=[P|T], nieje(P,X),4 (\+ member(X,Acc) -> A=[X|Acc]; A=Acc),5 vege(T,A,Out).
1 | ?- vege([wedlina ,ryby ,wieprzowina ,drob],[],X).2 X = [ala] ? a3 X = [jan ,ala]4 X = [kasia ,ala]5 X = [jan ,kasia ,ala]6 no
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 168 / 177
Prolog Summary
A special unassigned variable is the accumulator
temporary variable
stores intermediate results during recurence (loop)
usually unified with the output variable at the end
Compare (from the book of Clocksin & Mellish)
1 dlugoscL ([] ,0).2 dlugoscL ([H|T],N) :- dlugoscL(T,N1), N is N1+1.
1 dlugoscL ([],A,A).2 dlugoscL ([H|T],A,N) :- A1 is A+1,3 dlugoscL(T,A1,N).
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 169 / 177
Prolog Summary
You can scan a list element by element in two ways.Forward scanning:
1 scanF ([]) :- !.2 scanF ([H|T]) :- write(H), nl , scanF(T).
Backwards scanning:
1 scanB ([]) :- !.2 scanB ([H|T]) :- scanB(T), write(H), nl.
even though there is and AND on the right-hand side of thedefinitions, the order matters
in scanF you perform some operations on H, discard it and go forwardin the recurence
in scanB you decompose the whole list first and perform someoperations on the elements in the reversed order
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 170 / 177
Prolog Summary
Forward scanning:
1 | ?- scanF ([1 ,2 ,3]).2 13 24 35
6 yes
top-down approach
you take the top element (first, uppermost) from the stack and dosomething with it
discard the element
proceed with the new uppermost
until the stack is empty
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 171 / 177
Prolog Summary
Backwards scanning:
1 | ?- scanB ([1 ,2 ,3]).2 33 24 15
6 yes
bottom-up approach
you take the last element (deepest) from the stack and do somethingwith it
discard the element
proceed with the new lowest
until the stack is empty
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 172 / 177
Prolog Summary
Database manipulation
asserta(likes(marry,john)).
assertz((dislikes(X,Y) :- \+likes(X,Y))).
retract(predicate(constant)).
retractall(likes(_,_)).
Homework: use the database, to prepare an alternative version of thevege predicate. The information that a person has been checked should bestored as a statement in the database.
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 173 / 177
Prolog Summary
Trees and graphs.
decission (binary) trees – each node (except the lowest ones) has twomutually exclusive paths to its children; the state of the whole treecan be described by one predicatecar(0,1,1,1,0,1).where the six positions may indicate: diesel (no), turbo (yes), metaliccolor (yes), AC (yes), wifi (no), insurance (yes).
acyclic graphs – connections do not form loops; each node isrepresented by a constant, each connection is a binary relation(commutative – bidirectional graph, or not – unidirectional graph)
cyclic graphs – loops are allowed; extra attention must be paid tocontrol, that your solutions will not cycle forever among the samevalues
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 174 / 177
Prolog Summary
Example (already shown previously)
a
b
gh
d
f
e
c
4
1
2
3
2
1
5
7
2
3
1 arc(a,b,1).2 arc(a,e,2).3 arc(b,c,2).4 arc(b,f,7).5 arc(e,d,4).6 arc(e,f,2).7 arc(f,c,3).8 arc(g,d,3).9 arc(g,h,5).10 arc(h,f,1).
1 road(X,Y) :- path(X,Y,[X],0).2
3 path(X,X,L,S) :- write(L), nl ,4 write(’Droga: ’), write(S).5 path(X,Y,L,S) :- (arc(X,Z,D); arc(Z,X,D)),6 (\+ member(Z,L) ->7 append(L,[Z],L1), S1 is S+D),8 path(Z,Y,L1 ,S1).
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 175 / 177
Prolog Summary
Finite Domain Solver
If you want to set constraints on the values of the elements use the FDSsystem. The domains are computed and updated first, before actual valuesfor the FD variables are looked for.Basic predicates:
fd_domain(L,min,max).
fd_all_different(L).
don’t forget about fd_labeling(L).
hash operators, like #=
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 176 / 177
Prolog Summary
Marek Góźdź (2018/2019) PROLOG 21 stycznia 2019 177 / 177