谓词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 .