Prolog 中的前缀

Prefix in Prolog

我是 Prolog 的新手。 我对谓词前缀有疑问,但有点不同。

我想得到一个列表的前缀,但是直到一个元素 列表可以有重复元素。

一个例子:

prefix(Element, List, Prefix)
prefix(c, [a,b,c,d,e,f], [a, b])

不包含该元素。

目前我只有这个

prefix(X, [X|T], []).
prefix(X, [Y|T], [Y|Z]):-
    prefix(X, T, Z).

但是不行。

L = [a,b,c] ? prefix(b, L, Prefix).

no
?- 

谢谢

这是一个使用定从句文法的解决方案 and the non-terminal all_seq//2

prefix(X, Xs, Ys) :-
   phrase( ( all_seq(dif(X), Ys), [X], ... ), Xs).

... --> [] | [_], ... .

所以语法(在 phrase/2 内)是:

There is 1. an initial sequence Ys with all elements different to X, followed by 2. X, followed by 3. anything.

仍然有一个缺点,使用 DCG 时经常会出现这种情况:实施并不像它可能的那样确定,因此留下了多余的选择点。

prefix(X,[X|T],[]).
prefix(X,[Y|T],Z) :- prefix(X,T,M)  , Z = [Y|M].

输出:

?- L = [a,b,c,d,e,f] , prefix(d,L,G).
L = [a, b, c, d, e, f],
G = [a, b, c] .

?- L = [a,b,c,d,e,f] , prefix(e,L,G).
L = [a, b, c, d, e, f],
G = [a, b, c, d] .

编辑 #1
原始代码有效,使用 (,) 而不是 (?) 如下。

prefix(X,[X|T],[]).
prefix(X,[Y|T],[Y|Z]) :- prefix(X,T,Z).

输出:

?- prefix(d , [a,b,c,d,e] , G).
G = [a, b, c]
?- L = [a,b,c] , prefix(b, L, Prefix).
L = [a, b, c],
Prefix = [a] .

编辑#2 正如评论中提到的用户 false,我可以确认你是对的,但在我的解决方案中,我假设列表包含唯一元素:
prefix(d,[d,d],[d]) 成功 - 它应该会失败,

使用 dif/2,您可以明确声明对于 Element 之前的任何成员 XX \== Element:

prefix(Element, [Element|_], []).
prefix(Element, [Head|List], [Head|Prefix]) :-
    dif(Element, Head),
    prefix(Element, List, Prefix).

或者同样,因为我想在我的答案的第一次迭代中使用 append/3

prefix(Element, List, Prefix) :-
    append(Prefix, [Element|_Suffix], List),
    maplist(dif(Element), Prefix).

后缀基本相同:

suffix(Element, List, Suffix) :-
    append(_Prefix, [Element|Suffix], List),
    maplist(dif(Element), Suffix).

如果你不想使用maplist(dif(Element), List):

all_dif(_, []).
all_dif(X, [H|T]) :- dif(X, H), all_dif(X, T).