我正在为大学考试学习 Prolog,但我在这个练习中遇到了问题:
not_member(X,L)如果元素X不属于列表,则实现为 TRUE的谓词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).
Run Code Online (Sandbox Code Playgroud)
此代码适用于数字列表,如以下查询所示:
2 ?- not_member(4, [1,2,3]).
true.
3 ?- not_member(1, [1,2,3]).
false.
Run Code Online (Sandbox Code Playgroud)
但是,对于包含一些非数字元素的列表,它不起作用并报告错误:
4 ?- not_member(a, [a,b,c]).
ERROR: =\=/2: Arithmetic: `a/0' is not a function
Run Code Online (Sandbox Code Playgroud)
为什么?
让我们检查文档!
(=\=)/2是算术运算符。
+Expr1 =\= +Expr2 如果表达式 Expr1 的计算结果不等于 Expr2,则为真。
您必须使用(\=)/2来比较两个通用术语:
not_member(_, []) :- !.
not_member(X, [Head|Tail]) :-
X \= Head,
not_member(X, Tail).
Run Code Online (Sandbox Code Playgroud)
和:
?- not_member(d, [a,b,c]).
true.
Run Code Online (Sandbox Code Playgroud)
使用prolog-dif获得符合逻辑的答案——适用于地面和非地面情况!
就像在这个答案中一样,我们定义non_member(E,Xs)为maplist(dif(E),Xs)。
让我们把maplist(dif(E),Xs)和not_member(E,Xs) 通过@Haile到测试!
?- not_member (E,[1,2,3])。 假的。%错了!“E=4”呢? ?- maplist(dif(E),[1,2,3])。 差异(E,1),差异(E,2),差异(E,3)。未决目标的成功百分比
是否坚定?(有关此重要问题的更多信息,请阅读 此、此、此和此答案。)
?- E=d, not_member (E,[a,b,c])。 E = d。 ?- not_member (E,[a,b,c]), E=d。 假的。%不坚定 ?- E=d, maplist(dif(E),[a,b,c])。 E = d。 ?- maplist(dif(E),[a,b,c]), E=d。% 坚定 E = d。
让我们不要忘记最一般的用途!
?- not_member (E,Xs)。 Xs = []。%一很多的解决方案是失踪了! ?- 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) ...
| 归档时间: |
|
| 查看次数: |
7352 次 |
| 最近记录: |