以下是我提出的代码。但是,这里有两个问题。 首先,只显示X的第一个值,即1.然后,如果Y为假,则不会跳回menu1。 希望能得到一些帮助。
time(office_hour,1).
time(office_hour,2).
menu1 :-
write('Input time'),nl,
read(Y),nl,time(Y,X),nl,write(X),nl,menu1.
这是该场景的示例。如下所示,仅显示值1。如何显示值2? Sry我只是个新手
?-menu1.
Input time
office_hour.
1.
Input time
答案 0 :(得分:0)
您需要允许Prolog 回溯以获取所有解决方案。谓词的问题在于它可以在回溯之前执行递归调用。此外,对于下一个菜单提示,您继续递归一个级别,这可能不是一个好习惯,因为它会响应用户输入而不断消耗更多堆栈。
这是另一种方法,使用repeat/0
谓词和fail/0
。 repeat/0
只是成功,允许在回溯过程中重新查询解决方案。并且fail/0
总是失败,这迫使回溯。这是进行连续重复循环的常用方法,适用于在菜单上循环。我还稍微调整了nl/0
用法以使输出更整洁,并且我重命名为time/2
,因为它太过通用了,并且可能会与系统谓词冲突。 / p>
item_time(office_hour,1).
item_time(office_hour,2).
menu1 :-
repeat,
nl, write('Input time'), nl,
read(Y),
item_time(Y, X),
write(X), nl,
fail.
这将产生:
| ?- menu1.
Input time
office_hour.
1
2
Input time
foo.
Input time
...
这里发生的事情是fail/0
会导致谓词子句回溯到write(X), nl
和time(Y, X)
,这将提出替代解决方案,成功解决这些问题,以及然后再次前进到write(X), nl
。如果time(Y, X)
找不到更多解决方案,那么它最终会失败并且该子句会一直回溯到repeat/0
调用,这总是成功。这导致执行再次向前移动到nl, write('Input time'), ...
。
正如您所看到的,输入无法识别的内容只会重新提示。为了使这更完整,你可以添加被识别为"相当"如果您获得数据库中不存在的输入,则可以编写诊断消息。这对学习来说是一个很好的练习。
答案 1 :(得分:0)
第二个问题:
menu1 :-
write('Input time'),nl,
read(Y),nl,
( time(Y,X) ->
write(X),nl
; write('bad input'),nl ),
menu1.