需要完整的输出列表

问题描述 投票:0回答:2

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

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

这是另一种方法,使用repeat/0谓词和fail/0repeat/0只是成功,允许在回溯过程中重新查询解决方案。 fail/0总是失败,这迫使回溯。这是一种连续重复循环的常用方法,适用于菜单上的循环。我还调整了nl/0的使用量以使输出更整洁,我重命名为time/2,因为它太过通用了,并且可能会与系统谓词冲突。

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'), ...

如您所见,输入无法识别的内容只是重新提示。为了使其更完整,您可以添加被识别为“完全”的原子,如果您获得数据库中不存在的输入,则可以编写诊断消息。这对学习来说是一个很好的练习。


0
投票

第二个问题:

menu1 :- 
  write('Input time'),nl,
  read(Y),nl,
  ( time(Y,X) ->
    write(X),nl
  ; write('bad input'),nl ),
  menu1.
© www.soinside.com 2019 - 2024. All rights reserved.