我正在学习Prolog的大学考试,我对这个练习有问题:
如果元素
not_member(X,L)
不属于列表X
,则实现谓词L
为真。
如果我的推理是正确的,我找到了一个解决方案:
% FACT (BASE CASE): It is TRUE that X is not in the list if the list is empty.
not_member(_,[]).
% RULE (GENERAL CASE): If the list is non-empty, I can divide it in its Head
% element and the sublist Tail. X does not belong to the list if it is different
% from the current Head element and if it does not belong to the sublist Tail.
not_member(X,[Head|Tail]) :-
X =\= Head,
not_member(X,Tail).
此代码适用于数字列表,如以下查询所示:
2 ?- not_member(4, [1,2,3]).
true.
3 ?- not_member(1, [1,2,3]).
false.
但是,列表中包含一些非数字元素, 它不起作用并报告错误:
4 ?- not_member(a, [a,b,c]).
ERROR: =\=/2: Arithmetic: `a/0' is not a function
为什么?
答案 0 :(得分:4)
让我们查看文档!
(=\=)/2是算术运算符。
+ Expr1 = \ = + Expr2 如果表达式Expr1的计算结果与Expr2不相等,则为真。
您必须使用(\=)/2来比较两个通用术语:
not_member(_, []) :- !.
not_member(X, [Head|Tail]) :-
X \= Head,
not_member(X, Tail).
和
?- not_member(d, [a,b,c]).
true.
答案 1 :(得分:2)
使用prolog-dif获取逻辑上合理的答案 -
与in this answer一样,我们将 我们让 坚定吗? (有关此重要问题的更多信息,请阅读
this,this,this和this回答。) 让我们不要忘记最常用的用途!non_member(E,Xs)
定义为maplist(dif(E),Xs)
。maplist(dif(E),Xs)
和not_member(E,Xs)
by @Haile参与测试!?- not_member(E,[1,2,3]).
false. % wrong! What about `E=4`?
?- maplist(dif(E),[1,2,3]).
dif(E,1), dif(E,2), dif(E,3). % success with pending goals
?- E=d, not_member(E,[a,b,c]).
E = d.
?- not_member(E,[a,b,c]), E=d.
false. % not steadfast
?- E=d, maplist(dif(E),[a,b,c]).
E = d.
?- maplist(dif(E),[a,b,c]), E=d. % steadfast
E = d.
?- not_member(E,Xs).
Xs = []. % a lot of solutions are missing!
?- maplist(dif(E),Xs).
Xs = []
; Xs = [_A] , dif(E,_A)
; Xs = [_A,_B] , dif(E,_A), dif(E,_B)
; Xs = [_A,_B,_C], dif(E,_A), dif(E,_B), dif(E,_C)
...