Prolog:失败的语句执行两次

时间:2015-09-24 14:27:36

标签: prolog

我是Prolog的初学者(使用SWI-Prolog),我遇到以下问题:

我的规则定义如下:

start:-
   write("Enter first list: "), read_list(List1), 
   write("Enter second list: "), read_list(List2), 
   equal_length(List1, List2), 
   compare(List1, List2, Alike),
   write(" The lists are "), write(Alike).

start:- write("The lists should have the same length!!").

这就是我阅读清单的方式:

read_list([H|T]):- read(H), H\=[], read_list(T).
read_list([]).

比较是一组将比较列表的规则,但它永远不会执行,我甚至为此替换了它:

compare(_, _, "the same").

这就是equal_length的样子:

equal_length([_|T1], [_|T2]):- equal_length(T1, T2).
equal_length([], []).

因此,当列表长度不同时,它会失败。 问题是,当启动失败时,它会再次执行第一次出现(List1和List2已绑定)!

我尝试过这样简单的东西:

hi:- 1>2, write("Nonsense").
hi:- write("Of course it doesn't work").

输出是第二个字符串。 为什么第一个不像那样?

修改

经过进一步测试后,我发现这种奇怪的行为只发生在从该自定义方法中读取列表时,并且只有在读取多个列表时才会发生。

1 个答案:

答案 0 :(得分:1)

您的代码存在的问题是缺乏回溯管理。当您的语句失败时,Prolog将尝试为满足equal_length的列表获取新值。 以下是使用!运算符处理回溯的示例:

start:-
      read_list_data( List1, List2 ),
      equal_length(List1, List2),
      compare2(List1, List2, Alike),
      write( List1 ), nl,
      write(" The lists are "),
      write(Alike).

start:- write("The lists should have the same length!!").

read_list([H|T]):- read(H),
      H\=[],
      read_list(T).
read_list([]).

compare2(_, _, 'the same').

equal_length([_|T1], [_|T2]):- equal_length(T1, T2).
equal_length([], []).

read_list_data( List1, List2 ) :-
      write("Enter first list: "),
      read_list(List1),
      write("Enter second list: "),
      read_list(List2),
      !.

<强>阐释:

!标记通过让Prolog知道它必须承诺到目前为止做出的选择(即保留列表的值)来避免回溯意外行为。 我找到了关于这个here的一个很好的信息来源,其中回溯用树形图解释。