Title: CSE 337 Concepts of Programming Languages
1CSE 337 Concepts of Programming Languages
- Logic Programming II
- (More about Prolog)
2Outline
- Unification in Prolog
- Lists
- Numeric computation in Prolog
- Solving the 8-queens problem
3Unification
- Unification is the process of matching to make
statement identical. - Variables that are set equal to patterns are said
to be instantiated.
4The Predicate
- The goal (X,Y) succeeds if and only if X and Y
can be unified - Since is an operator, it can be and usually is
written like this
?- (parent(mohamed,ibrahim),parent(mohamed,X)).X
ibrahim Yes
?- parent(mohamed, ibrahim)parent(mohamed,X).X
ibrahim Yes
5Unification in Prolog
- A constant unifies only with itself.
- A variable unifies with anything and become
instantiated to that thing. - A structured term unifies with another term only
if it has the same function/predicate name and
same number of arguments, and the arguments can
be unified recursively.
6Examples
?- me me. ?- me you. ?- me X. ?- you
Y. ?- X Y. ?- f(X) g(X). ?- f(a,g(x))
f(Y,X). ?- f(a,g(X)) f(Y,g(b)).
7Lists in Prolog
- A bit like ML lists
- The atom represents the empty list
- A predicate . corresponds to MLs operator
8List Notation
- ML-style notation for lists
- These are just abbreviations for the underlying
term using the . Predicate - Prolog usually displays lists in this notation
9Example
?- X .(1,.(2,.(3,))).X 1, 2, 3 Yes?-
.(X,Y) 1,2,3.X 1Y 2, 3 Yes
10List Notation With Tail
- Last in a list can be the symbol followed by a
final term for the tail of the list - Useful in patterns 1,2X unifies with any list
that starts with 1,2 and binds X to the tail
?- 1,2X 1,2,3,4,5.X 3, 4, 5 Yes
11The append Predicate
?- append(1,2,3,4,Z).Z 1, 2, 3, 4 Yes
- Predefined append(X,Y,Z) succeeds if and only if
Z is the result of appending the list Y onto the
end of the list X
12Not Just A Function
?- append(X,3,4,1,2,3,4).X 1, 2 Yes
- append can be used with any pattern of
instantiation (that is, with variables in any
positions)
13Not Just A Function
?- append(X,Y,1,2,3).X Y 1, 2, 3
X 1Y 2, 3 X 1, 2Y 3 X
1, 2, 3Y No
14An Implementation
append(, B, B).append(HeadTailA, B,
HeadTailC) - append(TailA, B, TailC).
15Other Predefined List Predicates
- All flexible, like append
- Queries can contain variables anywhere
16Using select
?- select(2,1,2,3,Z).Z 1, 3 No?-
select(2,Y,1,3).Y 2, 1, 3 Y 1, 2,
3 Y 1, 3, 2 No
17The reverse Predicate
?- reverse(1,2,3,4,Y).Y 4, 3, 2, 1 No
- Predefined reverse(X,Y) unifies Y with the
reverse of the list X
18An Implementation
reverse(,).reverse(HeadTail,X) -
reverse(Tail,Y), append(Y,Head,X).
19The Anonymous Variable
- The variable _ is an anonymous variable
- Every occurrence is bound independently of every
other occurrence - In effect, much like MLs _ it matches any term
without introducing bindings
20Example
tailof(.(_,A),A).
- This tailof(X,Y) succeeds when X is a non-empty
list and Y is the tail of that list - Dont use this, even though it works
tailof(.(Head,A),A).
21The not Predicate
?- member(1,1,2,3).Yes?- not(member(4,1,2,3
)).Yes
22Example
sibling(X,Y) - not(XY), parent(P,X),
parent(P,Y).
?- sibling(ibrahim,fatma).Yes?-
sibling(ibrahim,ibrahim).No?-
sibling(X,Y).No
23Outline
- Unification in Prolog
- Lists
- Numeric computation in Prolog
- Solving the 8-queens problem
24Real Values And Integers
?- X is 1/2.X 0.5 Yes?- X is 1.0/2.0.X
0.5 Yes?- X is 2/1.X 2 Yes?- X is
2.0/1.0.X 2Yes
There are two numeric types integer and
real. Most of the evaluable predicates are
overloaded for all combinations. Prolog is
dynamically typed the types are used at runtime
to resolve the overloading. But note that the
goal 22.0 would fail.
25Comparisons
- Numeric comparison operators lt, gt, lt, gt,
, \ - To solve a numeric comparison goal, Prolog
evaluates both sides and compares the results
numerically - So both sides must be fully instantiated
26Comparisons
?- 12 lt 12.No?- 1lt2.Yes?-
12gt13.No?- X is 1-3, Y is 0-2, X Y.X
-2Y -2 Yes
27Equalities In Prolog
- We have used three different but related equality
operators - X is Y evaluates Y and unifies the result with X
3 is 12 succeeds, but 12 is 3 fails - X Y unifies X and Y, with no evaluation both 3
12 and 12 3 fail - X Y evaluates both and compares both 3
12 and 12 3 succeed - Any evaluated term must be fully instantiated
28Example mylength
mylength(,0).mylength(_Tail, Len) -
mylength(Tail, TailLen), Len is TailLen 1.
?- mylength(a,b,c,X).X 3 Yes?-
mylength(X,3).X _G266, _G269, _G272 Yes
29Counterexample mylength
mylength(,0).mylength(_Tail, Len) -
mylength(Tail, TailLen), Len TailLen 1.
?- mylength(1,2,3,4,5,X).X 011111 Yes
30Example sum
sum(,0).sum(HeadTail,X) -
sum(Tail,TailSum), X is Head TailSum.
?- sum(1,2,3,X).X 6 Yes?-
sum(1,2.5,3,X).X 6.5Yes
31Example factorial
factorial(X,1) - X 1.factorial(X,Fact)
- X gt 1, NewX is X - 1, factorial(NewX,NF),
Fact is X NF.
?- factorial(5,X).X 120 Yes?-
factorial(20,X).X 2.4329e018 Yes?-
factorial(-2,X).No
32Outline
- Unification in Prolog
- Lists
- Numeric computation in Prolog
- Solving the 8-queens problem
33The 8-Queens Problem
- Chess background
- Played on an 8-by-8 grid
- Queen can move any number of spaces vertically,
horizontally or diagonally - Two queens are in check if they are in the same
row, column or diagonal, so that one could move
to the others square - The problem place 8 queens on an empty chess
board so that no queen is in check
34Representation
- We could represent a queen in column 2, row 5
with the term queen(2,5) - But it will be more readable if we use something
more compact - Since there will be no other piecesno pawn(X,Y)
or king(X,Y)we will just use a term of the form
X/Y - (We wont evaluate it as a quotient)
35Example
- A chessboard configuration is just a list of
queens - This one is 2/5,3/7,6/1
36/ nocheck(X/Y,L) takes a queen X/Y and a list
of queens. We succeed if and only if the X/Y
queen holds none of the others in
check./nocheck(_, ).nocheck(X/Y, X1/Y1
Rest) - X \ X1, Y \ Y1, abs(Y1-Y) \
abs(X1-X), nocheck(X/Y, Rest).
37/ legal(L) succeeds if L is a legal placement
of queens all coordinates in range and no
queen in check./legal().legal(X/Y
Rest) - legal(Rest), member(X,1,2,3,4,5,6,7
,8), member(Y,1,2,3,4,5,6,7,8),
nocheck(X/Y, Rest).
38Adequate
- This is already enough to solve the problem the
query legal(X) will find all legal configurations
?- legal(X).X X 1/1 X 1/2
X 1/3
398-Queens Solution
- Of course that will take too long it finds all
64 solutions with one queen, then starts on those
with two, and so on - To make it concentrate right away on eight
queens, we can give a different query
?- X _,_,_,_,_,_,_,_, legal(X).X 8/4,
7/2, 6/7, 5/3, 4/6, 3/8, 2/5, 1/1 Yes
40Example
- Our 8-queens solution
- 8/4, 7/2, 6/7, 5/3, 4/6, 3/8, 2/5, 1/1
41Room For Improvement
- Slow
- Finds trivial permutations after the first
?- X _,_,_,_,_,_,_,_, legal(X).X 8/4,
7/2, 6/7, 5/3, 4/6, 3/8, 2/5, 1/1 X 7/2,
8/4, 6/7, 5/3, 4/6, 3/8, 2/5, 1/1 X 8/4,
6/7, 7/2, 5/3, 4/6, 3/8, 2/5, 1/1 X 6/7,
8/4, 7/2, 5/3, 4/6, 3/8, 2/5, 1/1
42An Improvement
- Clearly every solution has 1 queen in each column
- So every solution can be written in a fixed
order, like this X1/_,2/_,3/_,4/_,5/_,6/_,7/_,
8/_ - Starting with a goal term of that form will
restrict the search (speeding it up) and avoid
those trivial permutations
43/ eightqueens(X) succeeds if X is a legal
placement of eight queens, listed in order of
their X coordinates./eightqueens(X) - X
1/_,2/_,3/_,4/_,5/_,6/_,7/_,8/_, legal(X).
44Improved 8-Queens Solution
- Now much faster
- Does not bother with permutations
?- eightqueens(X).X 1/4, 2/2, 3/7, 4/3, 5/6,
6/8, 7/5, 8/1 X 1/5, 2/2, 3/4, 4/7, 5/3,
6/8, 7/6, 8/1
45An Experiment
legal().legal(X/Y Rest) - legal(Rest),
member(X,1,2,3,4,5,6,7,8),
member(Y,1,2,3,4,5,6,7,8), nocheck(X/Y,
Rest).
- Fails arguments not sufficiently instantiated
- The member condition does not just test in-range
coordinates it generates them
46Another Experiment
legal().legal(X/Y Rest) -
member(X,1,2,3,4,5,6,7,8),
member(Y,1,2,3,4,5,6,7,8), nocheck(X/Y,
Rest), legal(Rest). formerly the first
condition
- Fails arguments not sufficiently instantiated
- The legal(Rest) condition must come first,
because it generates the partial solution tested
by nocheck