我是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").
输出是第二个字符串。 为什么第一个不像那样?
修改
经过进一步测试后,我发现这种奇怪的行为只发生在从该自定义方法中读取列表时,并且只有在读取多个列表时才会发生。
答案 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的一个很好的信息来源,其中回溯用树形图解释。