prolog tricks

56
Modern Programming Lang uages 1 Prolog Tricks

Upload: oliver-nichols

Post on 01-Jan-2016

98 views

Category:

Documents


0 download

DESCRIPTION

Prolog Tricks. Outline. 20.6 The Lighter Side of Prolog 22.2 Arithmetic in Prolog 22.3 Problem Space Search: 8 Queens 22.4 Farewell To Prolog. Quoted Atoms As Strings. Any string of characters enclosed in single quotes is a term In fact, Prolog treats it as an atom: - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Prolog Tricks

Modern Programming Languages 1

Prolog Tricks

Page 2: Prolog Tricks

Modern Programming Languages 2

Outline

20.6 The Lighter Side of Prolog 22.2 Arithmetic in Prolog 22.3 Problem Space Search: 8 Queens 22.4 Farewell To Prolog

Page 3: Prolog Tricks

Modern Programming Languages 3

Quoted Atoms As Strings

Any string of characters enclosed in single quotes is a term

In fact, Prolog treats it as an atom:– 'abc' is the same atom as abc– 'hello world' and 'Hello world' are

atoms too Quoted strings can use \n, \t, \', \\

Page 4: Prolog Tricks

Modern Programming Languages 4

Input and Output

Simple term input and output. Also the predicate nl: equivalent to write('\n')

?- write('Hello world').

Hello world

Yes?- read(X).| hello.

X = hello

Yes

Page 5: Prolog Tricks

Modern Programming Languages 5

Debugging With write

p :- append(X,Y,[1,2]), write(X), write(' '), write(Y), write('\n'), X=Y.

?- p.[] [1, 2][1] [2][1, 2] []

No

Page 6: Prolog Tricks

Modern Programming Languages 6

The assert Predicate

Adds a fact to the database (at the end)

?- parent(joe,mary).

No?- assert(parent(joe,mary)).

Yes?- parent(joe,mary).

Yes

Page 7: Prolog Tricks

Modern Programming Languages 7

The retract Predicate

Removes the first clause in the database that unifies with the parameter

Also retractall to remove all matches

?- parent(joe,mary).

Yes?- retract(parent(joe,mary)).

Yes?- parent(joe,mary).

No

Page 8: Prolog Tricks

Modern Programming Languages 8

Dangerous Curves Ahead

A very dirty trick: self-modifying code Not safe, not declarative, not efficient—but can be

tempting, as the next example shows Best to use them only for facts, only for predicates

not otherwise defined by the program, and only where the clause order is not important

Note: if a predicate was compiled by consult, SWI-Prolog will not permit its definition to be changed by assert or retract

Page 9: Prolog Tricks

Modern Programming Languages 9

An Adventure Game

Prolog comments– /* to */, like Java– Also, % to end of line

/* This is a little adventure game. There are three entities: you, a treasure, and an ogre. There are six places: a valley, a path, a cliff, a fork, a maze, and a mountaintop. Your goal is to get the treasure without being killed first.*/

Page 10: Prolog Tricks

Modern Programming Languages 10

/* First, text descriptions of all the places in the game.*/description(valley, 'You are in a pleasant valley, with a trail ahead.').description(path, 'You are on a path, with ravines on both sides.').description(cliff, 'You are teetering on the edge of a cliff.').description(fork, 'You are at a fork in the path.').description(maze(_), 'You are in a maze of twisty trails, all alike.').description(mountaintop, 'You are on the mountaintop.').

Page 11: Prolog Tricks

Modern Programming Languages 11

/* report prints the description of your current location.*/report :- at(you,X), description(X,Y), write(Y), nl.

Page 12: Prolog Tricks

Modern Programming Languages 12

?- assert(at(you,cliff)).

Yes?- report.You are teetering on the edge of a cliff.

Yes?- retract(at(you,cliff)).

Yes?- assert(at(you,valley)).

Yes?- report.You are in a pleasant valley, with a trail ahead.

Yes

Page 13: Prolog Tricks

Modern Programming Languages 13

/* These connect predicates establish the map. The meaning of connect(X,Dir,Y) is that if you are at X and you move in direction Dir, you get to Y. Recognized directions are forward, right and left.*/connect(valley,forward,path).connect(path,right,cliff).connect(path,left,cliff).connect(path,forward,fork).connect(fork,left,maze(0)).connect(fork,right,mountaintop).connect(maze(0),left,maze(1)).connect(maze(1),right,maze(2)).connect(maze(2),left,fork).connect(maze(0),right,maze(3)).connect(maze(_),_,maze(0)).

Page 14: Prolog Tricks

Modern Programming Languages 14

/* move(Dir) moves you in direction Dir, then prints the description of your new location.*/move(Dir) :- at(you,Loc), connect(Loc,Dir,Next), retract(at(you,Loc)), assert(at(you,Next)), report./* But if the argument was not a legal direction, print an error message and don't move.*/move(_) :- write('That is not a legal move.\n'), report.

Page 15: Prolog Tricks

Modern Programming Languages 15

/* Shorthand for moves.*/forward :- move(forward).left :- move(left).right :- move(right).

Page 16: Prolog Tricks

Modern Programming Languages 16

?- assert(at(you,valley)).

Yes?- forward.You are on a path, with ravines on both sides.

Yes?- forward.You are at a fork in the path.

Yes?- forward.That is not a legal move.You are at a fork in the path.

Yes

Page 17: Prolog Tricks

Modern Programming Languages 17

/* If you and the ogre are at the same place, it kills you.*/ogre :- at(ogre,Loc), at(you,Loc), write('An ogre sucks your brain out through\n'), write('your eyesockets, and you die.\n'), retract(at(you,Loc)), assert(at(you,done))./* But if you and the ogre are not in the same place, nothing happens.*/ogre.

Page 18: Prolog Tricks

Modern Programming Languages 18

/* If you and the treasure are at the same place, you win.*/treasure :- at(treasure,Loc), at(you,Loc), write('There is a treasure here.\n'), write('Congratulations, you win!\n'), retract(at(you,Loc)), assert(at(you,done))./* But if you and the treasure are not in the same place, nothing happens.*/treasure.

Page 19: Prolog Tricks

Modern Programming Languages 19

/* If you are at the cliff, you fall off and die.*/cliff :- at(you,cliff), write('You fall off and die.\n'), retract(at(you,cliff)), assert(at(you,done))./* But if you are not at the cliff nothing happens.*/cliff.

Page 20: Prolog Tricks

Modern Programming Languages 20

/* Main loop. Stop if player won or lost.*/main :- at(you,done), write('Thanks for playing.\n')./* Main loop. Not done, so get a move from the user and make it. Then run all our special behaviors. Then repeat.*/main :- write('\nNext move -- '), read(Move), call(Move), ogre, treasure, cliff, main.

The predefined predicate call(X) tries to prove X as a goal term.

Page 21: Prolog Tricks

Modern Programming Languages 21

/* This is the starting point for the game. We assert the initial conditions, print an initial report, then start the main loop.*/go :- retractall(at(_,_)), % clean up from previous runs assert(at(you,valley)), assert(at(ogre,maze(3))), assert(at(treasure,mountaintop)), write('This is an adventure game. \n'), write('Legal moves are left, right or forward.\n'), write('End each move with a period.\n\n'), report, main.

Page 22: Prolog Tricks

Modern Programming Languages 22

?- go.This is an adventure game. Legal moves are left, right or forward.End each move with a period.

You are in a pleasant valley, with a trail ahead.

Next move -- forward.You are on a path, with ravines on both sides.

Next move -- forward.You are at a fork in the path.

Next move -- right.You are on the mountaintop.There is a treasure here.Congratulations, you win!Thanks for playing.

Yes

Page 23: Prolog Tricks

Modern Programming Languages 23

Outline

20.6 The Lighter Side of Prolog 22.2 Arithmetic in Prolog 22.3 Problem Space Search: 8 Queens 22.4 Farewell To Prolog

Page 24: Prolog Tricks

Modern Programming Languages 24

Unevaluated Terms

Prolog operators allow terms to be written more concisely, but are not evaluated

These are all the same Prolog term:

That term does not unify with 7

+(1,*(2,3))1+ *(2,3)+(1,2*3)(1+(2*3))1+2*3

Page 25: Prolog Tricks

Modern Programming Languages 25

Evaluating Expressions

The predefined predicate is can be used to evaluate a term that is a numeric expression

is(X,Y) evaluates the term Y and unifies X with the resulting atom

It is usually used as an operator

?- X is 1+2*3.

X = 7

Yes

Page 26: Prolog Tricks

Modern Programming Languages 26

Instantiation Is Required?- Y=X+2, X=1.

Y = 1+2X = 1

Yes?- Y is X+2, X=1.ERROR: Arguments are not sufficiently instantiated?- X=1, Y is X+2.

X = 1Y = 3

Yes

Page 27: Prolog Tricks

Modern Programming Languages 27

Evaluable Predicates

For X is Y, the predicates that appear in Y have to be evaluable predicates

This includes things like the predefined operators +, -, * and /

There are also other predefined evaluable predicates, like abs(Z) and sqrt(Z)

Page 28: Prolog Tricks

Modern Programming Languages 28

Real 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 2=2.0 would fail.

Page 29: Prolog Tricks

Modern Programming Languages 29

Comparisons

Numeric comparison operators: <, >, =<, >=, =:=, =\=

To solve a numeric comparison goal, Prolog evaluates both sides and compares the results numerically

So both sides must be fully instantiated

Page 30: Prolog Tricks

Modern Programming Languages 30

Comparisons?- 1+2 < 1*2.

No?- 1<2.

Yes?- 1+2>=1+3.

No?- X is 1-3, Y is 0-2, X =:= Y.

X = -2Y = -2

Yes

Page 31: Prolog Tricks

Modern Programming Languages 31

Equalities In Prolog

We have used three different but related equality operators:– X is Y evaluates Y and unifies the result with X:

3 is 1+2 succeeds, but 1+2 is 3 fails– X = Y unifies X and Y, with no evaluation: both 3 = 1+2 and 1+2 = 3 fail

– X =:= Y evaluates both and compares: both 3 =:= 1+2 and 1+2 =:= 3 succeed

Any evaluated term must be fully instantiated

Page 32: Prolog Tricks

Modern Programming Languages 32

Example: mylengthmylength([],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

Page 33: Prolog Tricks

Modern Programming Languages 33

Counterexample: mylengthmylength([],0).mylength([_|Tail], Len) :- mylength(Tail, TailLen), Len = TailLen + 1.

?- mylength([1,2,3,4,5],X).

X = 0+1+1+1+1+1

Yes

Page 34: Prolog Tricks

Modern Programming Languages 34

Example: sumsum([],0).sum([Head|Tail],X) :- sum(Tail,TailSum), X is Head + TailSum.

?- sum([1,2,3],X).

X = 6

Yes?- sum([1,2.5,3],X).

X = 6.5

Yes

Page 35: Prolog Tricks

Modern Programming Languages 35

Example: gcd

gcd(X,Y,Z) :- X =:= Y, Z is X.gcd(X,Y,Denom) :- X < Y, NewY is Y - X, gcd(X,NewY,Denom).gcd(X,Y,Denom) :- X > Y, NewX is X - Y, gcd(NewX,Y,Denom).

Note: not just

gcd(X,X,X)

Page 36: Prolog Tricks

Modern Programming Languages 36

The gcd Predicate At Work

?- gcd(5,5,X).X = 5 Yes?- gcd(12,21,X).X = 3 Yes?- gcd(91,105,X).X = 7 Yes?- gcd(91,X,7).ERROR: Arguments are not sufficiently instantiated

Page 37: Prolog Tricks

Modern Programming Languages 37

Example: factorialfactorial(X,1) :- X =:= 1.factorial(X,Fact) :- X > 1, NewX is X - 1, factorial(NewX,NF), Fact is X * NF.

?- factorial(5,X).X = 120 Yes?- factorial(20,X).X = 2.4329e+018 Yes?- factorial(-2,X).No

Page 38: Prolog Tricks

Modern Programming Languages 38

Outline

20.6 The Lighter Side of Prolog 22.2 Arithmetic in Prolog 22.3 Problem Space Search: 8 Queens 22.4 Farewell To Prolog

Page 39: Prolog Tricks

Modern Programming Languages 39

The 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 other’s square

The problem: place 8 queens on an empty chess board so that no queen is in check

Page 40: Prolog Tricks

Modern Programming Languages 40

Representation

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 pieces—no pawn(X,Y) or king(X,Y)—we will just use a term of the form X/Y

(We won’t evaluate it as a quotient)

Page 41: Prolog Tricks

Modern Programming Languages 41

Example

A chessboard configuration is just a list of queens

This one is [2/5,3/7,6/1]

8

7

6

5

4

3

2

1

2 1 4 3 6 5 8 7

Q

Q

Q

Page 42: Prolog Tricks

Modern Programming Languages 42

/* 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).

Page 43: Prolog Tricks

Modern Programming Languages 43

/* 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).

Page 44: Prolog Tricks

Modern Programming Languages 44

Adequate

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]

Page 45: Prolog Tricks

Modern Programming Languages 45

8-Queens Solution

Of course that will take too long: it finds all 64 legal 1-queens solutions, then starts on the 2-queens solutions, and so on

To make it concentrate right away on 8-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

Page 46: Prolog Tricks

Modern Programming Languages 46

Example

Our 8-queens solution [8/4, 7/2, 6/7, 5/3, 4/6, 3/8, 2/5, 1/1]

8

7

6

5

4

3

2

1

2 1 4 3 6 5 8 7

Q

Q

Q

Q

Q

Q

Q

Q

Page 47: Prolog Tricks

Modern Programming Languages 47

Room 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]

Page 48: Prolog Tricks

Modern Programming Languages 48

An Improvement

Clearly every solution has 1 queen in each column

So every solution can be written in a fixed order, like this:

X=[1/_,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

Page 49: Prolog Tricks

Modern Programming Languages 49

/* 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).

Page 50: Prolog Tricks

Modern Programming Languages 50

nocheck(_, []).nocheck(X/Y, [X1/Y1 | Rest]) :- % X =\= X1, assume the X's are distinct Y =\= Y1, abs(Y1-Y) =\= abs(X1-X), nocheck(X/Y, Rest).

legal([]).legal([X/Y | Rest]) :- legal(Rest), % member(X,[1,2,3,4,5,6,7,8]), assume X in range member(Y,[1,2,3,4,5,6,7,8]), nocheck(X/Y, Rest).

Since all X-coordinates are already known to be in range and distinct, these can be optimized a little

Page 51: Prolog Tricks

Modern Programming Languages 51

Improved 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] ;

Page 52: Prolog Tricks

Modern Programming Languages 52

An Experiment

Fails: “arguments not sufficiently instantiated”

The member condition does not just test in-range coordinates; it generates them

legal([]).legal([X/Y | Rest]) :- legal(Rest), % member(X,[1,2,3,4,5,6,7,8]), assume X in range 1=<Y, Y=<8, % was member(Y,[1,2,3,4,5,6,7,8]), nocheck(X/Y, Rest).

Page 53: Prolog Tricks

Modern Programming Languages 53

Another Experiment

Fails: “arguments not sufficiently instantiated”

The legal(Rest) condition must come first, because it generates the partial solution tested by nocheck

legal([]).legal([X/Y | Rest]) :- % member(X,[1,2,3,4,5,6,7,8]), assume X in range member(Y,[1,2,3,4,5,6,7,8]), nocheck(X/Y, Rest), legal(Rest). % formerly the first condition

Page 54: Prolog Tricks

Modern Programming Languages 54

Outline

20.6 The Lighter Side of Prolog 22.2 Arithmetic in Prolog 22.3 Problem Space Search: 8 Queens 22.4 Farewell To Prolog

Page 55: Prolog Tricks

Modern Programming Languages 55

Parts We Skipped The cut (!)

– A goal that always succeeds, but only once– Used to control backtracking

Exception handling– System-generated or user-generated exceptions– throw and catch predicates

The API– A small ISO API; most systems provide more– Many public Prolog libraries: network and file

I/O, graphical user interfaces, etc.

Page 56: Prolog Tricks

Modern Programming Languages 56

A Small Language

We did not have to skip as much of Prolog as we did of ML and Java

Prolog is a small language Yet it is powerful and not easy to master The most important things we skipped are

the techniques Prolog programmers use to get the most out of it