我创建了以下脚本,然而,它引发了一个错误,即使从我的观点来看它是完全正确的。可能是什么原因呢?
remove_repeats([],[]).
remove_repeats([X],[X]).
remove_repeats([X,X],[X]).
remove_repeats([X,Y],[X,Y]):-X=\=Y.
remove_repeats([H,H|T],R):-remove_repeats([H|T],R).
remove_repeats([H1,H2|T],R):- H1=\=H2, remove_repeats([H2|T],Z), R=[H1|Z].
当我按照以下方式运行时:
remove_repeats([a,b,b,c,c,c,c,c,d],Result).
它引发了以下错误:
ERROR: =\=/2 :Arithmetic: 'a=0' is not a function
答案 0 :(得分:1)
给出的错误确实有原因。 :)
=\=/2
是一个算术运算符,用于比较两个算术表达式的值是否相等,如果它们不相等则产生成功(true)。如果您尝试在非数字术语上使用它,则会产生错误。
如果要检查术语是否相同,可以使用\==
。例如,
?- a \== b.
true.
?- X \== a.
true.
如果你想检查"不能统一"你会使用\=
:
?- a \= b.
true.
?- X \= a. % X could be unified with 'a' to make them equal
false.
这本身会使你的谓词工作,虽然它确实找到了不止一次的解决方案:
?- remove_repeats([a,b,b,c,c,c,c,c,d], Result).
Result = [a, b, c, d] ;
Result = [a, b, c, d] ;
false.
?-
虽然逻辑中没有错误,本身,但可以进行一些清理。
remove_repeats([], []).
remove_repeats([X], [X]).
remove_repeats([X,X], [X]).
remove_repeats([X,Y], [X,Y]) :- X \= Y.
remove_repeats([H,H|T], R) :- remove_repeats([H|T], R).
remove_repeats([H1,H2|T], R) :-
H1 \= H2,
remove_repeats([H2|T], Z),
R = [H1|Z].
条款remove_repeats([X,X], [X]).
是多余的,因为它已由remove_repeats([H,H|T], R) ...
后跟remove_repeats([X], [X])
处理。此外,条款remove_repeats([X,Y], [X,Y]) :- X \= Y.
也是多余的,因为它将由remove_repeats([H1,H2|T], R) ...
和remove_repeats([X], [X]).
处理。然后我们可以通过将R
统一到条款的头部来结束最后一个条款:
remove_repeats([], []).
remove_repeats([X], [X]).
remove_repeats([H,H|T], R) :- remove_repeats([H|T], R).
remove_repeats([H1,H2|T], [H1|Z]) :-
H1 \= H2,
remove_repeats([H2|T], Z).
摆脱冗余规则也消除了多余的结果,因为解决方案不会有多种方法来满足规则:
?- remove_repeats([a,b,b,c,c,c,c,c,d], Result).
Result = [a, b, c, d] ;
false.
?-
<小时/> 修改
正如@false在评论中指出的那样,如果您正在使用SWI Prolog,那么您可以使用dif/2
谓词来代替=\=/2
。因此,上述H1 \= H2
将是dif(H1, H2)
。