为什么prolog中的这一行会返回false?

时间:2016-11-20 15:18:36

标签: list prolog

我正在尝试编写一个Prolog代码,但我不能让它返回true。我试图找到一个列表,其中所有元素都包含在另外两个列表中。例如,所有列表A元素都在B和C列表中找到,而不是在一起。 我的Prolog代码是:

member(X, [X|_]).   
member(X, [_|T]) :-
    member(X, T).

first([H0|T0], [H0|T1], A) :-
    member(H0, A),
    first(T0, [H0|T1], A).
first([H0|T0], [_|T1], A) :-
    first([H0|T0], T1, A).

如果元素在列表中,则成员谓词返回true。谓词'first'我试图使用成员谓词在C列表中找到A和B的匹配元素。如果我找到了,那么在第一个列表中进一步比较并将其第一个元素与第二个列表元素进行比较,如果我匹配,我会检查是否可以在第三个列表中找到它。我希望它能做到这一点,但是当我跑步时

?- first([4, 6, 4], [4, 5, 6, 4], [1, 2, 4, 6]).

它给出了错误,我无法弄清楚为什么。这似乎是一个简单的注意错误,但我无法理解它。

2 个答案:

答案 0 :(得分:1)

我对prolog一无所知,但就像我之前被逻辑错误所困扰的每个人一样。 (=

正如我所评论的那样,你似乎缺少first([], _, _)的基本情况。一个例子:

first([4], [4], [4]) :-
    member(4, [4]), // quite true
    first([], [4], [4]). // No matching rule, as all those assume an existing head in the first argument

答案 1 :(得分:0)

我不确定我理解你的问题,但请允许我尝试进一步指定你的谓词 first / 3

first(+L, +L1, +L2)
  succeeds if every element of L is found either in L1 or in L2.

如果这是您正在寻找的,那么:

first([], _, _).
first([E|L], L1, L2) :-
  (member(E, L1); member(E, L2)),
  first(L, L1, L2).

成功的例子:

first([1, 2, 3], [1, 2, 3], [1, 2]).
first([1], [1, 2, 3], [1, 2]).
first([1, 2, 3], [1, 2, 3], []).

faiure的例子:

first([1, 2, 3, 5], [1, 2, 3], [1, 2]).
first([7], [1, 2, 3], [1, 2]).
first([1, 2, 3], [], []).