前缀/后缀的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,所以前缀本身不能为空,后面的列表也不能为空。
答案 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).