Prolog101(12)

谓词repeat,相当于循环,根据最后一句语句判断是否退出循环。

sayhi:-
write('What is your name?'),
read(X),write('Hi '),write(X).

sayhito(X):-
write('Hi '),write(X).
do(sayhito(X)):-sayhito(X),!. 

loop_test:-
repeat, 
write('Enter command (end to exit): '), 
read(X), 
write(">>"), 
write(X), 
nl, 
X=end. 

用纯逻辑方法改写一下nani的例子

% a nonassertive version of nani search  

nani :- 
write('Welcome to Nani Search'), 
nl, 
initial_state(State), 
control_loop(State). 

control_loop(State) :- 
end_condition(State). 
control_loop(State) :- 
repeat, 
write('> '), 
read(X), 
constraint(State, X), 
do(State, NewState, X), 
control_loop(NewState). 

% initial dynamic state  
initial_state([ 
here(kitchen), 
have([]), 
location([ 
kitchen/apple, 
kitchen/broccoli, 
office/desk, 
office/flashlight, 
cellar/nani ]), 
status([ 
flashlight/off, 
game/on]) ]). 

% static state  
rooms([office, kitchen, cellar]). 
doors([office/kitchen, cellar/kitchen]). 

connect(X,Y) :- 
doors(DoorList), 
member(X/Y, DoorList). 
connect(X,Y) :- 
doors(DoorList), 
member(Y/X, DoorList). 

% list utilities  
member(X,[X|Y]). 
member(X,[Y|Z]) :- member(X,Z). 

delete(X, [], []). 
delete(X, [X|T], T). 
delete(X, [H|T], [H|Z]) :- delete(X, T, Z). 

% state manipulation utilities
get_state(State, here, X) :- 
member(here(X), State). 
get_state(State, have, X) :- 
member(have(Haves), State), 
member(X, Haves). 
get_state(State, location, Loc/X) :- 
member(location(Locs), State), 
member(Loc/X, Locs). 
get_state(State, status, Thing/Stat) :- 
member(status(Stats), State), 
member(Thing/Stat, Stats). 

del_state(OldState, [location(NewLocs) | Temp], location, Loc/X):- 
delete(location(Locs), OldState, Temp), 
delete(Loc/X, Locs, NewLocs). 

add_state(OldState, [here(X)|Temp], here, X) :- 
delete(here(_), OldState, Temp). 
add_state(OldState, [have([X|Haves])|Temp], have, X) :- 
delete(have(Haves), OldState, Temp). 
add_state(OldState, [status([Thing/Stat|TempStats])|Temp], status, Thing/Stat) :- 
delete(status(Stats), OldState, Temp), 
delete(Thing/_, Stats, TempStats). 

% end condition  
end_condition(State) :- 
get_state(State, have, nani), 
write('You win'). 

end_condition(State) :- 
get_state(State, status, game/off), 
write('quitter'). 

% constraints and puzzles together  
constraint(State, goto(cellar)) :- 
!, can_go_cellar(State). 
constraint(State, goto(X)) :- 
!, can_go(State, X). 
constraint(State, take(X)) :- 
!, can_take(State, X). 
constraint(State, turn_on(X)) :- 
!, can_turn_on(State, X). 
constraint(_, _). 

can_go(State,X) :- 
get_state(State, here, H), 

connect(X,H). 
can_go(_, X) :- 
write('You can''t get there from here'), 
nl, fail. 

can_go_cellar(State) :- 
can_go(State, cellar), 
!, cellar_puzzle(State). 

cellar_puzzle(State) :- 
get_state(State, have, flashlight), 
get_state(State, status, flashlight/on). 
cellar_puzzle(_) :- 
write('It''s dark in the cellar'), 
nl, fail. 

can_take(State, X) :- 
get_state(State, here, H), 
get_state(State, location, H/X). 
can_take(State, X) :- 
write('it is not here'), 
nl, fail. 

can_turn_on(State, X) :- 
get_state(State, have, X). 
can_turn_on(_, X) :- 
write('You don''t have it'), 
nl, fail. 

% commands  
do(Old, New, goto(X)) :- goto(Old, New, X), !. 
do(Old, New, take(X)) :- take(Old, New, X), !. 
do(Old, New, turn_on(X)) :- turn_on(Old, New, X), !. 
do(State, State, look) :- look(State), !. 
do(Old, New, quit) :- quit(Old, New). 
do(State, State, _) :- 
write('illegal command'), nl. 

look(State) :- 
get_state(State, here, H), 
write('You are in  '), write(H), nl, 
write('You can see'), list_things(State, H), nl,
write('You have'), list_bag(State, H), nl,
write('You can go'), list_rooms(H), nl. 

list_things(State, H) :- 
get_state(State, location, H/X), 
tab(2), write(X), 
fail. 
list_things(_, _). 

list_rooms(H) :- 
connect(X,H),tab(2),write(X),fail.
list_rooms(_).

list_bag(State, H) :- 
get_state(State, have, X), 
tab(2), write(X), 
fail. 
list_bag(_, _). 

goto(Old, New, X) :- 
add_state(Old, New, here, X), 
look(New). 

take(Old, New, X) :- 
get_state(Old, here, H), 
del_state(Old, Temp, location, H/X), 
add_state(Temp, New, have, X). 

turn_on(Old, New, X) :- 
add_state(Old, New, status, X/on). 

quit(Old, New) :- 
add_state(Old, New, status, game/off).

试一下

?- nani().
Welcome to Nani Search
> look.
You are in  kitchen
You can see  apple  broccoli
You have
You can go  office  cellar
> |: take(apple).
> |: take(broccoli).
> |: goto(office).
You are in  office
You can see  desk  flashlight
You have  broccoli  apple
You can go  kitchen
> |: take(desk).
> |: take(flashlight).
> |: goto(kitchen).
You are in  kitchen
You can see
You have  flashlight  desk  broccoli  apple
You can go  office  cellar
> |turn_on(flashlight).
> |: goto(cellar).
You are in  cellar
You can see  nani
You have  flashlight  desk  broccoli  apple
You can go  kitchen
> |: take(nani).
You win
true .

Leave a Reply

Your email address will not be published. Required fields are marked *

*