How to go back to "repeat" in Prolog? -
is possible go repeat in prolog without calling function (predicat) , without making new function?
i have following code
test :- nl, write('welcome.'),nl, repeat, write('print message again? (yes/no)'),nl, read(ans),nl, ( ans == yes -> write('you selected yes.'), nl ; write('you selected no.') ). the current output is
welcome. print message again? (yes/no) yes. selected yes. true. program end.
the output want
welcome. print message again? (yes/no) yes. selected yes. print message again? (yes/no) no. program ends.
the easy output way want avoid (i don't want output. don't want shows welcome multiple of times):
welcome. print message again? (yes/no) yes. welcome. selected yes. print message again? (yes/no) no. program ends.
repeat
repeat/0 simply defined as:
repeat. repeat :- repeat. or, equivalently:
repeat :- true ; repeat. in order repeat, need backtrack repeat call failing, either explicitely fail or through failing predicate (see example in above link).
... repeat, ..., fail. once want exit repeating pattern, can (and should) cut ! decision tree don't have dangling repeat choice point. if don't, interpreter still have possibility backtrack repeat later.
nb: rules !/0 can found here.
example
for example specifically, means (btw, use writeln):
test :- nl, writeln('welcome.'), repeat, writeln('print message again? (yes/no)'), read(ans),nl, (ans == yes -> writeln('you selected yes.'), fail % backtrack repeat ; writeln('you selected no.'), ! % cut, won't backtrack repeat anymore ). other remarks
notice op used atoms, whereas strings sufficient. indeed, atoms (single-quotes) hashed , prefered symbolic reasoning, whereas strings (double-quotes) not interned , more adequate displaying messages.
in same spirit, when reading, i'd rather use read_string(end_of_line,_,s), reads up-to end of line , returns string. read/1, had close input stream ctrl+d, annoying.
also, can rid of -> completely:
test :- nl, writeln("welcome."), repeat, writeln("print message again? (yes/no)"), read_string(end_of_line,_,ans), nl, write("you selected "), write(ans), writeln("."), ans == "no", % otherwise, repeat !. removing -> might controversial seeing how other people argue having more cases. here rationale: since original question seems homework repeat, parts handling yes, no , bad inputs explicitely seems underspecified, , frankly, not relevant. kept original semantics , merged yes , bad-input cases: after all, happens when user says yes? repeat, when user types unexpected input. case not repeat when ans == no.
now, if want change behavior of original code in order explicitely check possible kind of inputs, here attempt:
test :- nl, writeln("welcome."), repeat, writeln("print message again? (yes/no)"), read_string(end_of_line,_,ans), nl, (memberchk(ans,["yes","no"]) -> write("you selected "), write(ans), writeln("."), ans == "no", ! ; writeln("bad input" : ans), fail).
Comments
Post a Comment