重复
repeat/0
被简单地定义为:
repeat.
repeat :- repeat.
或者,等价地说:
repeat :- true
为了重复执行,您需要通过失败返回到
repeat
调用,可以通过
fail
显式或通过另一个失败的谓词(请参见上面链接中的示例)来实现。
...
repeat,
...,
fail.
如果你想退出重复模式,你可以(而且应该)剪切决策树中的 !
,这样你就不会有悬空的 repeat
选择点。
如果没有这么做,解释器仍然有可能回溯到 repeat
。
注意: !/0
的规则可以在这里找到。
示例
对于你的示例来说,也就是说(顺便说一句,我使用 writeln
):
test :-
nl,
writeln('Welcome.'),
repeat,
writeln('Print this message again? (yes/no)'),
read(Ans),nl,
(Ans == yes ->
writeln('You selected yes.'),
fail
; writeln('You selected no.'),
!
).
其他备注
请注意,OP使用了原子,而字符串已经足够。实际上,原子(单引号)被哈希并且更适用于符号推理,而字符串(双引号)没有内部化,并且更适合显示信息。
在同样的精神下,阅读时我宁愿使用 read_string(end_of_line,_,S)
,它可以读取到行尾并返回一个字符串。对于 read/1
,我必须使用 Ctrl+D 关闭输入流,这很麻烦。
此外,我们完全可以摆脱 ->
:
test :-
nl,
writeln("Welcome."),
repeat,
writeln("Print this message again? (yes/no)"),
read_string(end_of_line,_,Ans),
nl,
write("You selected "),
write(Ans),
writeln("."),
Ans == "no",
!.
移除
->
可能会引起争议,因为其他人认为应该考虑更多情况。这是原理:由于原始问题似乎是关于
repeat
的作业,有关处理
yes
、
no
和错误输入的部分似乎未经明确规定,而且实际上并不重要。我保留了原始语义,并合并了
yes
和错误输入的情况:毕竟,当用户说“是”时会发生什么?我们会重复,就像当用户输入意外的内容时一样。唯一不重复的情况是当
Ans == no
时。
现在,如果我们想改变原始代码的行为,以明确检查所有可能的输入类型,下面是一种尝试:
test :-
nl,
writeln("Welcome."),
repeat,
writeln("Print this 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).
fail
和!
将会交换位置,以及不同的子项也会被交换。理解Prolog评估工作原理可能需要一些时间。尝试使用break
命令逐步执行程序。使用不同的例子,不要犹豫去尝试。 - coredump