在Prolog中获取“真实”前缀/后缀/中缀

时间:2016-10-13 08:45:21

标签: list recursion prolog append prefix

前缀/后缀的Prolog表示法非常简单: 它几乎把所有的工作都放在了追加上。 对于那些不知道的人:

prefix(P,L):-append(P,_,L).
suffix(S,L):-append(_,S,L).

现在这意味着prefix(X,[a,b,c,d]).的结果 将是:X=[];X=[a];X=[a,b];X=[a,b,c];X=[a,b,c,d]

这是我的问题:我想要一个“真正的”前缀。因此,前缀不能为空,后面的部分也不能为空。 因此查询prefix(X,[a,b,c,d]).的结果应为

X=[a];X=[a,b];X=[a,b,c]

就是这样。

不幸的是,标准内置前缀谓词的真正优点是,它可以使用append的终止,即append([],Y,Y). 因此,很容易知道何时停止,逐个选择列表,直到列表为空。

我的终止意味着:如果列表中只剩下一个元素,请停止。 我该怎么做?

我天真的结果将是:

prefix(P,L):-
length(P,1),append(P,E,L),E/=[].

但这感觉不对。我在工作,所以我没有检查这是否真的有效,但它应该:

还有更方便的方法吗? 同样适用于后缀,这将更加困难,因为你没有办法像尾部那样特定地修改Tail,我想我只是反转整个事情然后在它上面调用前缀。

Infix只是两个人的组合。

我希望很清楚我的意思。感谢您的输入! tl; dr:如何写一个只过滤实际前缀的谓词前缀/ 2,所以前缀本身不能为空,后面的列表也不能为空。

2 个答案:

答案 0 :(得分:4)

对于真实前缀,您可以尝试这样做:

list_prefix(List, [H|T]) :-
    append([H|T], [_|_], List).

这只是说第一个参数必须至少有一个元素,列表的其余部分必须至少有一个元素。

遵循@false的建议,使其更明确:

list_real_prefix(List, Prefix) :-
    Prefix = [_|_],
    Rest = [_|_],
    append(Prefix, Rest, List).

“真实”后缀将完全相同:

list_real_suffix(List, Suffix) :-
    Front = [_|_],
    Suffix = [_|_],
    append(Front, Suffix, List).

答案 1 :(得分:4)

您也可以使用DCG,这是描述性的:

list_prefix(P) --> non_empty_seq(P), non_empty_seq(_).
non_empty_seq([X]) --> [X].
non_empty_seq([X|Xs]) --> [X], non_empty_seq(Xs).

| ?- phrase(list_pref(P), [a,b,c,d]).

P = [a] ? a

P = [a,b]

P = [a,b,c]

no
| ?-

您可以类似地定义后缀:

list_suffix(S) --> non_empty_seq(_), non_empty_seq(S).