80
1 Module 5 Prolog

B.tech CS S8 Artificial Intelligence Notes Module 5

Embed Size (px)

DESCRIPTION

B.tech CS S8 Artificial Intelligence Notes Module 5

Citation preview

Page 1: B.tech CS S8 Artificial Intelligence Notes Module 5

1

Module 5

Prolog

Page 2: B.tech CS S8 Artificial Intelligence Notes Module 5

2

Page 3: B.tech CS S8 Artificial Intelligence Notes Module 5

3

Page 4: B.tech CS S8 Artificial Intelligence Notes Module 5

4

Page 5: B.tech CS S8 Artificial Intelligence Notes Module 5

5

Page 6: B.tech CS S8 Artificial Intelligence Notes Module 5

6

Page 7: B.tech CS S8 Artificial Intelligence Notes Module 5

7

Page 8: B.tech CS S8 Artificial Intelligence Notes Module 5

8

Page 9: B.tech CS S8 Artificial Intelligence Notes Module 5

9

Page 10: B.tech CS S8 Artificial Intelligence Notes Module 5

10

Page 11: B.tech CS S8 Artificial Intelligence Notes Module 5

11

Page 12: B.tech CS S8 Artificial Intelligence Notes Module 5

12

Page 13: B.tech CS S8 Artificial Intelligence Notes Module 5

13

Page 14: B.tech CS S8 Artificial Intelligence Notes Module 5

14

Page 15: B.tech CS S8 Artificial Intelligence Notes Module 5

15

Page 16: B.tech CS S8 Artificial Intelligence Notes Module 5

16

Page 17: B.tech CS S8 Artificial Intelligence Notes Module 5

17

Page 18: B.tech CS S8 Artificial Intelligence Notes Module 5

18

Page 19: B.tech CS S8 Artificial Intelligence Notes Module 5

19

Page 20: B.tech CS S8 Artificial Intelligence Notes Module 5

20

Page 21: B.tech CS S8 Artificial Intelligence Notes Module 5

21

Page 22: B.tech CS S8 Artificial Intelligence Notes Module 5

22

Page 23: B.tech CS S8 Artificial Intelligence Notes Module 5

23

Page 24: B.tech CS S8 Artificial Intelligence Notes Module 5

24

Page 25: B.tech CS S8 Artificial Intelligence Notes Module 5

25

Page 26: B.tech CS S8 Artificial Intelligence Notes Module 5

26

Page 27: B.tech CS S8 Artificial Intelligence Notes Module 5

27

Page 28: B.tech CS S8 Artificial Intelligence Notes Module 5

28

Page 29: B.tech CS S8 Artificial Intelligence Notes Module 5

29

Page 30: B.tech CS S8 Artificial Intelligence Notes Module 5

30

Page 31: B.tech CS S8 Artificial Intelligence Notes Module 5

31

Page 32: B.tech CS S8 Artificial Intelligence Notes Module 5

32

Page 33: B.tech CS S8 Artificial Intelligence Notes Module 5

33

Page 34: B.tech CS S8 Artificial Intelligence Notes Module 5

34

Page 35: B.tech CS S8 Artificial Intelligence Notes Module 5

35

Page 36: B.tech CS S8 Artificial Intelligence Notes Module 5

36

Page 37: B.tech CS S8 Artificial Intelligence Notes Module 5

37

Page 38: B.tech CS S8 Artificial Intelligence Notes Module 5

38

Page 39: B.tech CS S8 Artificial Intelligence Notes Module 5

39

Page 40: B.tech CS S8 Artificial Intelligence Notes Module 5

40

Page 41: B.tech CS S8 Artificial Intelligence Notes Module 5

41

Abstract Data Types (ADTs) in Prolog

%%%%%%%%%%%%%%%%%%% stack operations %%%%%%%%%%%%%%%

% These predicates give a simple, list based implementation of stacks

% empty stack generates/tests an empty stack

% BUILT IN TO SWI PROLOG

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

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

empty_stack([]).

% member_stack tests if an element is a member of a stack

member_stack(E, S) :- member(E, S).

% stack performs the push, pop and peek operations

% to push an element onto the stack

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

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

% To pop an element from the stack

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

% Top = a, Rest = [b,c]

% To peek at the top element on the stack

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

% Top = a

stack(E, S, [E|S]).

Page 42: B.tech CS S8 Artificial Intelligence Notes Module 5

42

%%%%%%%%%%%%%%%%%%%% queue operation %%%%%%%%%%%%%%

% These predicates give a simple, list based implementation of FIFO queues

% empty queue generates/tests an empty queue

empty_queue([]).

% member_queue tests if an element is a member of a queue

member_queue(E, S) :- member(E, S).

% add_to_queue adds a new element to the back of the queue

add_to_queue(E, [], [E]).

add_to_queue(E, [H|T], [H|Tnew]) :- add_to_queue(E, T, Tnew).

% remove_from_queue removes the next element from the queue

% Note that it can also be used to examine that element

% without removing it

remove_from_queue(E, [E|T], T).

append_queue(First, Second, Concatenation) :-

append(First, Second, Concatenation).

%%%%%%%%%%%%%%%%%%%% set operations %%%%%%%%%%%%%%%

% These predicates give a simple, list based implementation of sets

% empty_set tests/generates an empty set.

empty_set([]).

member_set(E, S) :- member(E, S).

% add_to_set adds a new member to a set, allowing each element

% to appear only once

add_to_set(X, S, S) :- member(X, S), !.

add_to_set(X, S, [X|S]).

remove_from_set(E, [], []).

Page 43: B.tech CS S8 Artificial Intelligence Notes Module 5

43

remove_from_set(E, [E|T], T) :- !.

remove_from_set(E, [H|T], [H|T_new]) :-

remove_from_set(E, T, T_new), !.

% BUILT IN TO SWI PROLOG

/*

union([], S, S).

union([H|T], S, S_new) :-

union(T, S, S2),

add_to_set(H, S2, S_new).

intersection([], _, []).

intersection([H|T], S, [H|S_new]) :-

member_set(H, S),

intersection(T, S, S_new),!.

intersection([_|T], S, S_new) :-

intersection(T, S, S_new),!.

*/

set_diff([], _, []).

set_diff([H|T], S, T_new) :-

member_set(H, S),

set_diff(T, S, T_new),!.

set_diff([H|T], S, [H|T_new]) :-

set_diff(T, S, T_new), !.

subset([], _).

subset([H|T], S) :-

member_set(H, S),

subset(T, S).

equal_set(S1, S2) :-

subset(S1, S2), subset(S2, S1).

%%%%%%%%%%%%%%%%% priority queue operations %%%%%%%%%%

% These predicates provide a simple list based implementation of a priority queue.

% They assume a definition of precedes for the objects being handled

empty_sort_queue([]).

member_sort_queue(E, S) :- member(E, S).

insert_sort_queue(State, [], [State]).

Page 44: B.tech CS S8 Artificial Intelligence Notes Module 5

44

insert_sort_queue(State, [H | T], [State, H | T]) :-

precedes(State, H).

insert_sort_queue(State, [H|T], [H | T_new]) :-

insert_sort_queue(State, T, T_new).

remove_sort_queue(First, [First|Rest], Rest).

Semantic Nets and Frames in Prolog

Page 45: B.tech CS S8 Artificial Intelligence Notes Module 5

45

Page 46: B.tech CS S8 Artificial Intelligence Notes Module 5

46

Page 47: B.tech CS S8 Artificial Intelligence Notes Module 5

47

Page 48: B.tech CS S8 Artificial Intelligence Notes Module 5

48

Page 49: B.tech CS S8 Artificial Intelligence Notes Module 5

49

Page 50: B.tech CS S8 Artificial Intelligence Notes Module 5

50

Page 51: B.tech CS S8 Artificial Intelligence Notes Module 5

51

Page 52: B.tech CS S8 Artificial Intelligence Notes Module 5

52

Page 53: B.tech CS S8 Artificial Intelligence Notes Module 5

53

Page 54: B.tech CS S8 Artificial Intelligence Notes Module 5

54

Page 55: B.tech CS S8 Artificial Intelligence Notes Module 5

55

Page 56: B.tech CS S8 Artificial Intelligence Notes Module 5

56

Page 57: B.tech CS S8 Artificial Intelligence Notes Module 5

57

Page 58: B.tech CS S8 Artificial Intelligence Notes Module 5

58

Page 59: B.tech CS S8 Artificial Intelligence Notes Module 5

59

Page 60: B.tech CS S8 Artificial Intelligence Notes Module 5

60

Page 61: B.tech CS S8 Artificial Intelligence Notes Module 5

61

Page 62: B.tech CS S8 Artificial Intelligence Notes Module 5

62

Page 63: B.tech CS S8 Artificial Intelligence Notes Module 5

63

Page 64: B.tech CS S8 Artificial Intelligence Notes Module 5

64

Page 65: B.tech CS S8 Artificial Intelligence Notes Module 5

65

Page 66: B.tech CS S8 Artificial Intelligence Notes Module 5

66

Page 67: B.tech CS S8 Artificial Intelligence Notes Module 5

67

Page 68: B.tech CS S8 Artificial Intelligence Notes Module 5

68

Alternative search strategies

Basic depth first search algorithm

go(Start, Goal) :-

empty_stack(Empty_been_list),

stack(Start, Empty_been_list, Been_list),

path(Start, Goal, Been_list).

% path implements a depth first search in PROLOG

% Current state = goal, print out been list

path(Goal, Goal, Been_list) :-

reverse_print_stack(Been_list).

path(State, Goal, Been_list) :-

mov(State, Next),

% not(unsafe(Next)),

not(member_stack(Next, Been_list)),

stack(Next, Been_list, New_been_list),

path(Next, Goal, New_been_list), !.

reverse_print_stack(S) :-

empty_stack(S).

reverse_print_stack(S) :-

stack(E, Rest, S),

reverse_print_stack(Rest),

write(E), nl.

Breadth first search algorithm

state_record(State, Parent, [State, Parent]).

go(Start, Goal) :-

empty_queue(Empty_open),

state_record(Start, nil, State),

add_to_queue(State, Empty_open, Open),

empty_set(Closed),

path(Open, Closed, Goal).

path(Open,_,_) :- empty_queue(Open),

write('graph searched, no solution found').

path(Open, Closed, Goal) :-

remove_from_queue(Next_record, Open, _),

Page 69: B.tech CS S8 Artificial Intelligence Notes Module 5

69

state_record(State, _, Next_record),

State = Goal,

write('Solution path is: '), nl,

printsolution(Next_record, Closed).

path(Open, Closed, Goal) :-

remove_from_queue(Next_record, Open, Rest_of_open),

(bagof(Child, moves(Next_record, Open, Closed, Child), Children);

Children = []),

add_list_to_queue(Children, Rest_of_open, New_open),

add_to_set(Next_record, Closed, New_closed),

path(New_open, New_closed, Goal),!.

moves(State_record, Open, Closed, Child_record) :-

state_record(State, _, State_record),

mov(State, Next),

% not (unsafe(Next)),

state_record(Next, _, Test),

not(member_queue(Test, Open)),

not(member_set(Test, Closed)),

state_record(Next, State, Child_record).

printsolution(State_record, _):-

state_record(State,nil, State_record),

write(State), nl.

printsolution(State_record, Closed) :-

state_record(State, Parent, State_record),

state_record(Parent, Grand_parent, Parent_record),

member(Parent_record, Closed),

printsolution(Parent_record, Closed),

write(State), nl.

add_list_to_queue([], Queue, Queue).

add_list_to_queue([H|T], Queue, New_queue) :-

add_to_queue(H, Queue, Temp_queue),

add_list_to_queue(T, Temp_queue, New_queue).

Best first search algorithm

%%%%% operations for state records %%%%%%%

% These predicates define state records as an adt

% A state is just a [State, Parent, G_value, H_value, F_value] tuple.

% Note that this predicate is both a generator and

% a destructor of records, depending on what is bound

Page 70: B.tech CS S8 Artificial Intelligence Notes Module 5

70

% precedes is required by the priority queue algorithms

state_record(State, Parent, G, H, F, [State, Parent, G, H, F]).

precedes([_,_,_,_,F1], [_,_,_,_,F2]) :- F1 =< F2.

% go initializes Open and Closed and calls path

go(Start, Goal) :-

empty_set(Closed),

empty_sort_queue(Empty_open),

heuristic(Start, Goal, H),

state_record(Start, nil, 0, H, H, First_record),

insert_sort_queue(First_record, Empty_open, Open),

path(Open,Closed, Goal).

% Path performs a best first search,

% maintaining Open as a priority queue, and Closed as a set.

% Open is empty; no solution found

path(Open,_,_) :-

empty_sort_queue(Open),

write("graph searched, no solution found").

% The next record is a goal

% Print out the list of visited states

path(Open, Closed, Goal) :-

remove_sort_queue(First_record, Open, _),

state_record(State, _, _, _, _, First_record),

State = Goal,

write('Solution path is: '), nl,

printsolution(First_record, Closed).

% The next record is not equal to the goal

% Generate its children, add to open and continue

% Note that bagof in AAIS prolog fails if its goal fails,

% I needed to use the or to make it return an empty list in this case

path(Open, Closed, Goal) :-

remove_sort_queue(First_record, Open, Rest_of_open),

bagof(Child, moves(First_record, Open, Closed, Child, Goal), Children),

insert_list(Children, Rest_of_open, New_open),

add_to_set(First_record, Closed, New_closed),

path(New_open, New_closed, Goal),!.

Page 71: B.tech CS S8 Artificial Intelligence Notes Module 5

71

% moves generates all children of a state that are not already on open or closed. The only

% wierd thing here is the construction of a state record, test, that has unbound variables in

% all positions except the state. It is used to see if the next state matches something

% already on open or closed, irrespective of that states parent or other attributes Also,I've

% commented out unsafe since the way I've coded the water jugs problem I don't really

% need it.

moves(State_record, Open, Closed,Child, Goal) :-

state_record(State, _, G, _,_, State_record),

mov(State, Next),

% not(unsafe(Next)),

state_record(Next, _, _, _, _, Test),

not(member_sort_queue(Test, Open)),

not(member_set(Test, Closed)),

G_new is G + 1,

heuristic(Next, Goal, H),

F is G_new + H,

state_record(Next, State, G_new, H, F, Child).

%insert_list inserts a list of states obtained from a call to

% bagof and inserts them in a priotrity queue, one at a time

insert_list([], L, L).

insert_list([State | Tail], L, New_L) :-

insert_sort_queue(State, L, L2),

insert_list(Tail, L2, New_L).

% Printsolution prints out the solution path by tracing

% back through the states on closed using parent links.

printsolution(Next_record, _):-

state_record(State, nil, _, _,_, Next_record),

write(State), nl.

printsolution(Next_record, Closed) :-

state_record(State, Parent, _, _,_, Next_record),

state_record(Parent, Grand_parent, _, _, _, Parent_record),

member_set(Parent_record, Closed),

printsolution(Parent_record, Closed),

write(State), nl.

Meta-interpreters in Prolog

Meta-programming, is programming where we treat programs as data. This is

easy in Prolog, as Prolog programs are just Prolog terms. Programs can also be

Page 72: B.tech CS S8 Artificial Intelligence Notes Module 5

72

considered as input data for other programs. Prolog programs are sequences of prolog

terms, so prolog programs easily serve as input data. A prolog meta-interpreter uses

program data as a basis for additional computations. In this section, several prolog meta-

interpreters are discussed that modify the computation of prolog goals.

Because it is possible to directly access program code in Prolog, it is easy to write

interpreter of Prolog in Prolog. Such interpreter is called a meta-interpreter. Meta-

interpreters are usually used to add some extra features to Prolog, e.g., to change build-in

negation as failure to constructive negation. The meta-level constructs, especially

‘clause’, is very useful in building meta interpreters, i.e., Prolog interpreters in Prolog.

The key idea is in defining a predicate, called ‘solve(G)’ which solves goal G with

respect to a program P.

The simplest Prolog meta-interpreter is a following program:

solve(Goal):-call(Goal).

However, there is not advantage of using such meta-intepreter as it immediately

calls Prolog interpreter. Much more popular is "vanilla" meta-interpreter that uses

Prolog's build-in unification but enables access to search engine which can be easily

modified (e.g., it is possible to change the order of goals' execution)

solve(true).

solve((A,B)):-

solve(A),solve(B).

solve(A):-

clause(A,B),solve(B).

Note, that vanilla meta-interpreter uses build-in predicate clause(H,B) which finds

a clause in Prolog program with head that unifies with H and body B (if there is no body,

then Body=true). The modified vanilla meta-interpreter can be used to compute "proof"

of the computation:

solve(true, fact).

solve((A,B),(ProofA, ProofB)):-

solve(A, ProofA),solve(B, ProofB).

solve(A, A-ProofB):-

clause(A,B),solve(B, ProofB).

It is also possible to write a meta-interpreter that uses list of goals instead of

traditional conjunction of goals. In some cases, this could be more natural as one does not

need to traverse the structure of goal each time a primitive goal is being found.

solve([]).

solve([A|T]):-

clause(A,B),

Page 73: B.tech CS S8 Artificial Intelligence Notes Module 5

73

add_to_list(B,T,NT),

solve(NT).

A clause such as: gp(X, Y) :- p(X, Z) , p(Z, Y). can be interpreted as data, where

:- and , are just infix binary constructors. Also

father(bob,mark). is represented as:

father(bob,mark) :- true.

Consider the following query

?- solve(gp(bob,sue), Proof).

Proof = (gp(bob,sue) :-

(p(bob,mary) :-

(m(bob,mary) :- true)),

(p(mary,sue) :-

(m(mary,sue) :- true)))

?- why(gp(bob,sue)).

gp(bob,sue) is true

because p(bob,mary) is true

because m(bob,mary) is true

because p(mary,sue) is true

because m(mary,sue) is true

yes

A Simple Meta-interpreter

solve(true) :-!.

solve(not A) :- not(solve(A)).

solve((A,B)) :- !,solve(A), solve(B).

solve(A) :- clause(A,B), solve(B).

p(X,Y) :- q(X), r(Y).

q(X) :- s(X).

r(X) :- t(X).

s(a).

t(b).

t(c).

Given below can be used as test cases for above meta-interpreter

test1 :- solve(p(a,b)).

test2 :- solve(p(X,Y)).

test3 :- solve(p(f,g)).

Page 74: B.tech CS S8 Artificial Intelligence Notes Module 5

74

Meta-interpreter with user interaction

solve(true) :-!.

solve(not A) :- not(solve(A)).

solve((A,B)) :- !,solve(A), solve(B).

solve(A) :- clause(A,B), solve(B).

solve(A) :- askuser(A).

askuser(A):- write(A),

write('? Enter true if the goal is true, false otherwise'),

nl, read(true).

p(X,Y) :- q(X), r(Y).

q(X) :- s(X).

r(X) :- t(X).

s(a).

t(b).

t(c).

Given below can be used as test cases for above meta-interpreter

test1 :- solve(p(a,b)).

test2 :- solve(p(X,Y)).

test3 :- solve(p(f,g)).

Previous University questions

4-mark questions

1. What is matching?

2. What are abstract data types?

3. With an example, explain how facts are represented in prolog?

4. Explain how frames can be represented in prolog?

5. Explain the use of assert and been predicate in prolog?

Answer:

Predicates

Clauses with the same clause name, the same number of arguments and defined in

the same module are combined in the database and form the definition of a predicate.

The common clause name is called the predicate name or functor of the predicate. The

number of arguments is the arity. For example, the predicate fac/2 is defined by the

collection of all clauses with the clause head fac(Arg1,Arg2), where Arg1 and Arg2 may

be any terms.

Page 75: B.tech CS S8 Artificial Intelligence Notes Module 5

75

The separate clauses of a predicate are connected by disjunction, i.e. by inclusive

OR. Clauses with the same clause name but a different number of arguments belong to

different predicates. Likewise, clauses which have the same clause name and the same

arity but are associated with different modules belong to different predicates.

The Prolog predicate concept can be compared to the subprogram concept in

conventional programming languages; we therefore also speak of "calling" a predicate in

Prolog. The predicate concept ensures a high degree of modularity in Prolog programs

and thereby supports structured programming.

Only predicates whose clauses have been included in the database with consult/1,

reconsult/1 or with an assert predicate can be modified, i.e. clauses can be added (assert

predicates) or removed (retract predicates), individual predicates can be deleted

(abolish/1) or replaced (reconsult/1). Assert is used to add a new predicate to the current

database. Been predicate is used to record previously visited states and avoid loops.

The clauses of these predicates can be output with listing/0/1 and analyzed with

clause predicates. Note however that to do so you must call the Prolog system with the -

debug option.

Compiled predicates

IF/Prolog offers a number of ways of compiling user-defined predicates and

including them in the database. This can be done by the system's incremental compiler by

using the assert and consult predicates. In addition, predicate definitions stored in files

can be compiled by the predicate compile/1 or the external compiler (procmp command).

Predicates compiled with consult/1, reconsult/1, compile/1 or procmp are

normally no longer modifiable. However, you can inform the compiler with the

dynamic/1 directive that certain predicates are to remain modifiable. Predicates which

you have generated with assert predicates or which you have declared as modifiable with

other compilation methods are compiled only to the extent where the compilation is

reversible, i.e. where decompilation is possible.

Whenever references are made in this manual to compiled predicates they should

be taken to mean predicates which cannot be decompiled. These can no longer be

modified by simply adding or removing clauses.

12-mark questions

1) Explain how recursive search is carried out in prolog with an example?

2) Write notes on:

a. Meta predicates

b. Meta interpreters

3) Brief on the concept of matching and evaluation in prolog with example?

Page 76: B.tech CS S8 Artificial Intelligence Notes Module 5

76

4) With example explain how to represent semantic nets in prolog?

5) Explain various alternative search strategies?

6) Describe how recursive search is used on prolog to solve 3 x 3 knight’s problem?

Answer:

A knight can move two squares either horizontally or vertically followed by one

square in an orthogonal direction as long as it does not move off the board. The

attempt is to find a series of legal moves in which the knight lands on each square of

the chessboard exactly once.

% 3x3 knight's tour

:- dynamic been/1.

path(Z,Z).

path(A,C):- move(A,B), not(been(B)), assert(been(B)), path(B,C).

% initial call is path2(A,B,[A])

path2(Z,Z,Been).

path2(A,C,Been):- move(A,B), not member(B,Been), path2(B,C,[B|Been]).

% initial call is path3(A,B,[A]) AT MOST ONE SOLUTION

path3(Z,Z,Been).

path3(A,C,Been):- move(A,B), not member(B,Been), path3(B,C,[B|Been]),!.

move(1,6).

move(1,8).

move(2,7).

move(2,9).

move(3,4).

move(3,8).

move(4,3).

1 2 3

4 5 6

7 8 9

Page 77: B.tech CS S8 Artificial Intelligence Notes Module 5

77

move(4,9).

move(6,7).

move(6,1).

move(7,6).

move(7,2).

move(8,3).

move(8,1).

move(9,4).

move(9,2).

7) Write the prolog code for the wolf, goat, and cabbage problem.

Answer:

This is an example of a production system in Prolog. A farmer with his wolf, goat,

and cabbage come to the edge of a river they wish to cross. There is a boat at the

river's edge, but, of course, only the farmer can row. The boat also can carry only two

things (including the rower) at a time. Devise a sequence of crossings of the river so

that all four arrive safely on the other side of the river. Remembering that If the wolf

is ever left alone with the goat, the wolf will eat the goat. Similarly, if the goat is left

alone with the cabbage, the goat will eat the cabbage.

/*

* This is the code for the Farmer, Wolf, Goat and Cabbage Problem

* using the ADT Stack.

*

* Run this code by giving PROLOG a "go" goal.

* For example, to find a path from the west bank to the east bank,

* give PROLOG the query:

*

* go(state(w,w,w,w), state(e,e,e,e)).

*/

:- [adts]. /* consults (reconsults) file containing the

various ADTs (Stack, Queue, etc.) */

go(Start,Goal) :-

empty_stack(Empty_been_stack),

stack(Start,Empty_been_stack,Been_stack),

path(Start,Goal,Been_stack).

/*

* Path predicates

*/

path(Goal,Goal,Been_stack) :-

Page 78: B.tech CS S8 Artificial Intelligence Notes Module 5

78

write('Solution Path Is:' ), nl,

reverse_print_stack(Been_stack).

path(State,Goal,Been_stack) :-

move(State,Next_state),

not(member_stack(Next_state,Been_stack)),

stack(Next_state,Been_stack,New_been_stack),

path(Next_state,Goal,New_been_stack),!.

/*

* Move predicates

*/

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]).

move(state(X,W,X,C), state(Y,W,Y,C))

:- opp(X,Y), not(unsafe(state(Y,W,Y,C))),

writelist(['try farmer takes goat',Y,W,Y,C]).

move(state(X,W,G,X), state(Y,W,G,Y))

:- opp(X,Y), not(unsafe(state(Y,W,G,Y))),

writelist(['try farmer takes cabbage',Y,W,G,Y]).

move(state(X,W,G,C), state(Y,W,G,C))

:- opp(X,Y), not(unsafe(state(Y,W,G,C))),

writelist(['try farmer takes self',Y,W,G,C]).

move(state(F,W,G,C), state(F,W,G,C))

:- writelist([' BACKTRACK from:',F,W,G,C]), fail.

/*

* Unsafe predicates

*/

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

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

/*

* Definitions of writelist, and opp.

*/

writelist([]) :- nl.

Page 79: B.tech CS S8 Artificial Intelligence Notes Module 5

79

writelist([H|T]):- print(H), tab(1), /* "tab(n)" skips n spaces. */

writelist(T).

opp(e,w).

opp(w,e).

reverse_print_stack(S) :-

empty_stack(S).

reverse_print_stack(S) :-

stack(E, Rest, S),

reverse_print_stack(Rest),

write(E), nl.

Artificial Intelligence 19

Sample crossing for

FWGC problem

Page 80: B.tech CS S8 Artificial Intelligence Notes Module 5

80

Artificial Intelligence 20

State Space Representation of FWGC problem