【问题标题】:Implement a Prolog predicate that say if an element belong to a list. Problems with not numerical lists实现一个 Prolog 谓词来判断一个元素是否属于一个列表。非数字列表的问题
【发布时间】:2013-04-07 17:05:18
【问题描述】:

我正在为大学考试学习 Prolog,但我在这个练习中遇到了问题:

如果元素X 不属于列表L,则实现谓词not_member(X,L) 为TRUE。

如果我的推理是正确的,我已经找到了解决方案:

% 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

为什么?

【问题讨论】:

    标签: prolog prolog-dif


    【解决方案1】:

    让我们检查一下文档!

    (=\=)/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.
    

    【讨论】:

    • 好的,tnx 这么多。只有一点澄清:你为什么使用:not_member(, []) :- !。而是:not_member(, [])。究竟是什么意思! ? Tnx
    • (不详细解释)是剪辑。它可以防止回溯,但这不是强制性的。在这种情况下,可以使用它,因为一旦在 not_member(_, []) 上统一成功。我们不需要检查其他“解决方案”,因此我们“剪切”prolog 搜索树并停止 che 计算。
    【解决方案2】:

    使用 获得合乎逻辑的答案—— 地面 非地面情况!

    就像in this answer 一样,我们将non_member(E,Xs) 定义为maplist(dif(E),Xs)

    让我们测试一下maplist(dif(E),Xs)<i>not_member</i>(E,Xs) by @Haile

    ?- not_member(E,[1,2,3])。 错误。 % 错了! `E=4` 呢? ?- maplist(dif(E),[1,2,3])。 差(E,1),差(E,2),差(E,3)。未决目标的成功百分比

    它坚定吗? (有关此重要问题的更多信息,请阅读 thisthisthisthis 回答。)

    ?- 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] , 差异 (E,_A) ; Xs = [_A,_B] ,差异(E,_A),差异(E,_B) ; Xs = [_A,_B,_C],差异(E,_A),差异(E,_B),差异(E,_C) ...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-04
      • 1970-01-01
      • 1970-01-01
      • 2018-09-29
      • 1970-01-01
      相关资源
      最近更新 更多