33
1 CS 385 Fall 2006 Chapter 15 Introduction to PROLOG

1 CS 385 Fall 2006 Chapter 15 Introduction to PROLOG

Embed Size (px)

Citation preview

1

CS 385 Fall 2006Chapter 15

Introduction to PROLOG

2

PROLOG

A logic programming language (based on first order predicate calculus)

• declarative semantics* – father(bob,ted). // the meaning is in the set of clauses and is

– father(ted, mary). // independent of the way PROLOG executes them

• built-in unification

Syntax

Predicate Calculus Prolog P not P

P Q P, Q

P Q P; Q

P → Q Q :- P

P ≡ Q P = Q

* These would mean the same if they were reordered

3

Syntax (cont)

Variables begin with uppercase.

Predicate Calculus Prolog X person(X) → mortal(X) mortal(X) :- person(X).

X isa(X, bird) → flies(X) flies(X) :- isa(X, bird).

AND: flies(X) :- isa(X, bird), not is(X, emu).

flies(X) :- isa(X, bird), not flightless(X).

flightless(emu).

flightless(ostrich).

OR: happy(X) :- healthy(X); wise(X).

Better (separate predicates): happy(X) :- healthy(X).

happy(X) :- wise(X).

4

AMZI Environment

Download from 385 site

Current version at amzi.com: more elaborate than needed.

Apologies to Mac friends

Listener: an interactive environment for developing a set of

predicates posing queries to be resolved by unification

Help on 385 site

5

Recursion

1. predecessor(X, Z):- parent(X, Z).

2. predecessor(X, Z):- parent(X, Y), predecessor(Y, Z).

3. parent(ann, bob).

4. parent(bob, connie).

How conclude predecessor(ann, connie)?unify rhs of 1 and 3 to conclude

5. predecessor(ann, bob)unify rhs 2 with 4 and 5 to conclude

6. predecessor(ann, connie).

Typical query: predecessor(ann, X).

6

family2.pro

Given predicates for parent and female:parent(pam, bob).

female(pam).

How would we describe mother?mother(X, Y) :-

parent(X, Y),

female(X).

Sister?sister(X, Y) :-

parent(Z, X),

parent(Z, Y),

female(X),

not(X = Y).

7

Comparison

FEATURE C++ PROLOG

Language model: procedural programming

object-oriented

logic programming

Data types: integer, float, array, struct, pointer

atom, predicate, list

Data manipulation: assignment

parameter passing

variable binding through unification

Program control: sequence, branch, loop, recursion

pattern-directed search

Program structure: block rules and facts in a database

Variable scoping: global and nested local scopes

confined to a single rule or fact

8

Definitions

predecessor is a predicate of arity 2

parent is a predicate of arity 2

predecessor has 2 clauses. They are rules.

parent has 3 clauses. They are facts.

predecessor(X, Z):- parent(X, Z).

predecessor(X, Z):- parent(X, Y), predecessor(Y, Z).

parent(ann, bob).

parent(bob, connie).

parent(joe, sue).

9

Commands

• assert add a predicate

• retract remove a predicate

• consult load a file into the database

• read to terminal

• write to terminal

• see file input (later, maybe)

• tell file output (later, maybe)

• listing list current database

Good resource: Adventure in Prolog in the PROLOG documentation

10

Lists in PROLOG

The major way to represent dataenclosed by brackets

list elements separated by commas

list elements can be lists.

E.g:[ ]

[liz]

[liz, pat, bob]

[liz, pat, [bob, harry]]

Lists have a head and a tail: [X|Y]

E.g. [liz, pat, bob]X = liz //an atom

y = [pat, bob] //a list

11

Lists (cont)

member(X, [X|T]). (1)

member(X,[Y|T]) :- member(X,T). (2)

Trace member(b, [a,b,c]).

call (1). {b/X, [a, b, c]/[X|T] } fail since b ≠a

call (2).

member(X, [X|T]) unifies to member(b, [a,b,c]) with {b/X, a/Y, [b,c]/T}

member(b, [a,b,c])? implied by lhs member(b, [b,c])

member(b, [b,c])?

call (1)

X = b, [X|T] = [b, c].

yes to call (1) since b = b.

yes to call (2)

12

Short Version member(b, [a,b,c])

call (1). {b/X, [a, b, c]/[X|T] } fail since b ≠a

call (2).

member(X, [X|T]) unifies to member(b, [a,b,c]) with {b/X, a/Y, [b,c]/T}

member(b, [a,b,c])? implied by lhs member(b, [b,c])

member(b, [b,c])?

call (1)

X = b, [X|T] = [b, c].

yes to call (1) since b = b.

yes to call (2)

call (1). fail since b ≠a

call (2). b=X, a=Y, [b,c]=T

member(b, [b,c])?

call (1)

X = b, [X|T] = [b, c].

yes to call (1) since b = b.

yes to call (2)

member(X, [X|T]). (1)member(X,[Y|T]) :- member(X,T). (2)

13

Debugger member(b, [a,b,c])

call (1). fail since b ≠a

call (2). b=X, a=Y, [b,c]=T

member(b, [b,c])?

call (1)

X = b, [X|T] = [b, c].

yes to call (1) since b = b.

yes to call (2)

(only tracks paths followed)

CALL:(2) member / 2

b

[a,b,c]

CALL:(1) member / 2

b

[b,c]

EXIT: member / 2

b

[b,c]

EXIT: member / 2

b

[a,b,c]member(X, [X|T]). (1)member(X,[Y|T]) :- member(X,T). (2)

14

With the debugger and a driver

test1:- member(b, [a, b, c]).

member(X, [X|T]).

member(X,[Y|T]) :- member(X,T).

(1) test1:

(1) member(b, [b|T])?

no

(2) member[b, [b, c]

(1) member(b, [b |[c]])

yes

yes

yes

CALL:(1) test1 / 0

CALL:(2) member / 2

b

[a,b,c]

CALL:(1) member / 2

b

[b,c]

EXIT: member / 2

b

[b,c]

EXIT: member / 2

b

[a,b,c]

EXIT: test1 / 0

15

With the Clauses Reversed

member(X,[Y|T]) :- member(X,T). (1)

member(X, [X|T]). (2)

(1) member(b, [a,b,c])?

(1) member[b, [b, c]

(1) member(b, [c])

(1) member(b, [ ])

fail (can't apply rule 1 or 2)

fail (and can't apply rule 1 0r 2)

(2) member(b, [b|[c]]) succeeds

16

Other Commands

test1:- member(b, [a, b, c]). //to save typing

write(X) //writes X to the screen

nl //writes a newline

Example:writelist([ ]).

writelist(H|T) :- write(H), nl, writelist(T).

How would you reverse a list?reverse_writelist([ ]).

reverse_writelist(H|T) :-

reverse_writelist(T), nl, write(H).

17

Recursive Search: the knights tour

Can a knight (chess) visit each square on a board once?

Board and legal moves:move(1,6)

move(1,8)

move(2,7)

move(2,9)

...

move(9,2)

Is there a path from one square to another?path(Z,Z).

path(X,Y):- move(X,W), path(W,Y).

knight0.pro

Try path(1,2).

1 2 3

4 5 6

7 8 9

18

Trace path(1,2)

move(1,6)

try path(6,2)

move(6,7)

try path(7,2)

move(7,6)

try path(6,2).

Whoops.

Resolution (knight1.pro):path(X,Y):- move(X,W), not(been(W)), assert(been(W)), path(W,Y).

But this adds been(6) to the database.

Try path(1,6) twice.

19

New definition:

path(Z,Z,L).

path(X,Y,L):-

move(X,Z), not(member(Z, L), path(Z, Y, [Z|L]).

Trace path(1,7, [1]).

Text has a longer one. Try yourself.

How does the result get printed?

20

Prolog, Take 2

What have we done so far– simple logical inference (am I my own grandfather?)

– production systems e.g. knight’s tour and tea ceremony

There are many other ways to control the search – cut (!) to prevent backtracking beyond a certain point

– could bog down here

21

Cut!

A goal with no arguments that– succeeds the first time encountered

– fails each other time

family3.pro:

grandparent(X, Y) :- // all possible pairs

parent(X, Z), parent(Z, Y).

grandparent(X, Y) :- // X =pam, Z = pat

parent(X, Z), !, // X =pam, Z = pat

parent(Z, Y).

grandparent(X, Y) :- // X= pam, Z = ann

parent(X, Z),

parent(Z, Y), !.

22

ADT Stack

stack(Top, Stack, [Top|Stack])To push an element onto the stack, specify Top and Rest and use S

?- stack(a, [b, c, d], S).

returns S = [a, b, c, d]

To pop an element from the stack specify S and use Top and Rest

?- stack(Top, Rest, [a, b, c, d]).

returns Top = a

Rest = [b,c,d]

To peek at the top element on the stack:

?- stack(Top, _, [a, b, c, d]).

returns Top = a

Exercise: build functions for write_bottom and to test whether the top element is repeated in the stack.

23

The farmer, wolf, cabbage, and goat

Problem:They are all on one side of the river

The wolf will eat the goat

The goat will eat the cabbage

The boat carries two things at once

Objective: get them all across the river safely

The state: state(F,W,G,C)

F,W,G,C = e or w.

Where is the boat? (with the farmer)

Start state: state (w,w,w,w)

Goal state: state (e, e, e, e )

24

Figure 14.1: Sample crossings for the farmer, wolf, goat, and cabbage problem.

25

State Space Graph:

start: (w, w, w, w)

(e, e, w, w) (e, w, e, w) (e, w, w, e) (e, w, w, w)

(w, w, e, w) (w, w, w, e) (w, e, w, w)

goal: (e, e, e, e)

(underline = unsafe)

26

How to do this in Prolog?

Ideas we want to capture:

1. move (state1, state2)– the farmer will be on opposite sides in state1 and 2

– state 2 needs to be safe

2. unsafe:– wolf and goat are together without the farmer

– goat and cabbage are together without the farmer

3. opposite sides:– opp(e,w).

– opp(w,e).

unsafe(state(X, Y, Y, C):- opp(X,Y).

unsafe(state(X, W, Y, Y):- opp(X,Y). % much easier than with the graph

27

Prolog

Generate rules for moving the farmer/wolf/goat/cabbage

E.g. the farmer moves the wolf:move(state(X,X,G,C), state(Y,Y,G,C)):-

opp(X,Y),

not(unsafe(state(Y,Y,G,C))),

writelist(['try farmer takes wolf ', Y, Y, G, C]), nl.

How do we find a path through the graph?

Keep track of where you have been ona stack, Been_stack (text)

a list (simpler version)

Backtracking: pop from the stack

remove 1st element on list

28

Search Strategies (15.4)

Depth first searchtext uses a stack

alternate: a (closed) list

the open list is handled by PROLOG backtracking

Breadth first searchwhat's different?

a queue

add all children to the queue when a move is made

Best first searcha priority queue

29

Missionaries and Cannibals

Three missionaries and three cannibals come to a river.

They wish to cross.

There is a boat that will hold only two.

Any of the group is able to row.

If there are more missionaries than cannibals on any side of the river, the cannibals will be converted.

Get all people across the river with no conversions.

States?

state(M, C, B)

Safe?

safe(state(M, C, 0)) :- M =<C.

safe(state(M, 0, 0)).?

30

NLP (15.9 )

sentence(Start, End):-

nounphrase(Start, Rest),

verbphrase(Rest, End).

Tested by

utterance(X):- sentence(X, [ ]).

This works by

examining the first part of the sentence

trying to make a nounphrase from pieces of it

passing the rest to make a verbphrase.

expecting End to be empty when done

utterance([man, bites]):

sentence([ man, bites],[]) % Start = [man, bites]

nounphrase(Start, Rest), % Start = [man], Rest = [bites]

verbphrase(Rest, End). % Rest = [bites], End = []

31

Using nounphrase

sentence(Start, End):- %1

nounphrase(Start, Rest), %2

verbphrase(Rest, End).

nounphrase([Noun|End], End) :- %3

noun(Noun).

noun(man). %4

verb(bites) %5

sentence([ man, bites], [ ]) %1 Start = [man, bites]

nounphrase( [man, bites], ??) %2 Start = [man, bites] Rest=??

nounphrase( [man | bites], bites) %3 Start = [man, bites] →[Noun|End] = [man | bites]

noun(man) %4 [End]→[bites]

verbphrase([bites], [ ]) % ... suceeds because of verb(bites)

32

More NLP

Try: utterance([dog, bites, X]).% will give all possible ways to finish it.

utterance(X). % will give all possible sentences.

Curiosity: test2:-utterance([dog, X]). % returns yes

utterance([dog, X]) % returns values for X

33

Context-free versus Context-sensitive

Context free the rules do not depend on the rest of the sentence

Context sensitiveto account for noun-verb agreement.

(noun singular ↔ verb singular).

add singular or plural to each noun and verb.

require that the nounphrase and verbphrase agree.

see nlpcs.pro.