需要完整的输出列表

时间:2017-12-18 09:02:11

标签: prolog

以下是我提出的代码。但是,这里有两个问题。 首先,只显示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

2 个答案:

答案 0 :(得分:0)

您需要允许Prolog 回溯以获取所有解决方案。谓词的问题在于它可以在回溯之前执行递归调用。此外,对于下一个菜单提示,您继续递归一个级别,这可能不是一个好习惯,因为它会响应用户输入而不断消耗更多堆栈。

这是另一种方法,使用repeat/0谓词和fail/0repeat/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), nltime(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.