我是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
?-
由于
答案 0 :(得分:3)
使用dif/2
,您可以明确说明X
之前的任何成员Element
,X \== 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).
答案 1 :(得分:2)
以下是使用Definite Clause Grammars dcg和非终端all_seq//2
的解决方案:
prefix(X, Xs, Ys) :-
phrase( ( all_seq(dif(X), Ys), [X], ... ), Xs).
... --> [] | [_], ... .
所以语法(在phrase/2
内)读取:
有 1.初始序列
Ys
,所有元素与X
不同,后跟2.X
,后跟3.任何内容。
还有一个缺点,在使用DCG时经常出现这样的情况:实现并不像它可能的那样确定,因此留下了多余的选择点。
答案 2 :(得分:0)
prefix(X,[X|T],[]).
prefix(X,[Y|T],Z) :- prefix(X,T,M) , Z = [Y|M].
输出:
? - L = [a,b,c,d,e,f],前缀(d,L,G)。
L = [a,b,c,d,e,f],
G = [a, b,c]。? - L = [a,b,c,d,e,f],前缀(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).
输出:
? - 前缀(d,[a,b,c,d,e],G)。
G = [a,b,c]
? - L = [a,b,c],前缀(b,L,前缀)。
L = [a,b,c],
前缀= [a]。
编辑#2
作为评论中提到的用户false,我可以确认您是对的,但在我的解决方案中,我认为该列表包含唯一的元素:
prefix(d,[d,d],[d])
成功 - 它应该失败,