在 Prolog 中获取 "real" prefixes/suffixes/infixes
Get "real" prefixes/suffixes/infixes in Prolog
prefix/suffix 的 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]
这是我的问题:我想要一个 "real" 前缀。因此,前缀不能为空,其后的部分也不能为空。
所以查询 prefix(X,[a,b,c,d]).
的结果应该是
X=[a];X=[a,b];X=[a,b,c]
就是这样。
不幸的是,标准内置前缀谓词的真正优点是,它可以使用附加的终止,即append([],Y,Y).
所以很容易知道什么时候停止,一个一个地挑选列表直到列表为空。
我的终止意味着:如果列表中只剩下一个元素,则停止。
我该怎么做?
我天真的结果是:
prefix(P,L):-
length(P,1),append(P,E,L),E/=[].
虽然这感觉不对。我在工作,所以我还没有检查这是否真的有效,但它应该:
有没有更方便的方法呢?
后缀也是如此,这将更加困难,因为您没有办法像头部一样具体地处理尾部,我想我只是颠倒整个事情,然后在其上调用前缀。
中缀只是两个的组合。
希望大家明白我的意思。感谢您的输入!
tl;dr: 如何写一个谓词 prefix/2 只过滤真正的前缀,所以前缀本身不能为空,它后面的列表也不能为空。
对于真正的前缀,你可以这样尝试:
list_prefix(List, [H|T]) :-
append([H|T], [_|_], List).
这只是说第一个参数必须至少有一个元素,列表的其余部分必须至少有一个元素。
并按照@false 的建议使其更明确:
list_real_prefix(List, Prefix) :-
Prefix = [_|_],
Rest = [_|_],
append(Prefix, Rest, List).
"real" 后缀将完全相同:
list_real_suffix(List, Suffix) :-
Front = [_|_],
Suffix = [_|_],
append(Front, Suffix, List).
你也可以为此使用一个 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).
prefix/suffix 的 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]
这是我的问题:我想要一个 "real" 前缀。因此,前缀不能为空,其后的部分也不能为空。
所以查询 prefix(X,[a,b,c,d]).
的结果应该是
X=[a];X=[a,b];X=[a,b,c]
就是这样。
不幸的是,标准内置前缀谓词的真正优点是,它可以使用附加的终止,即append([],Y,Y).
所以很容易知道什么时候停止,一个一个地挑选列表直到列表为空。
我的终止意味着:如果列表中只剩下一个元素,则停止。 我该怎么做?
我天真的结果是:
prefix(P,L):-
length(P,1),append(P,E,L),E/=[].
虽然这感觉不对。我在工作,所以我还没有检查这是否真的有效,但它应该:
有没有更方便的方法呢? 后缀也是如此,这将更加困难,因为您没有办法像头部一样具体地处理尾部,我想我只是颠倒整个事情,然后在其上调用前缀。
中缀只是两个的组合。
希望大家明白我的意思。感谢您的输入! tl;dr: 如何写一个谓词 prefix/2 只过滤真正的前缀,所以前缀本身不能为空,它后面的列表也不能为空。
对于真正的前缀,你可以这样尝试:
list_prefix(List, [H|T]) :-
append([H|T], [_|_], List).
这只是说第一个参数必须至少有一个元素,列表的其余部分必须至少有一个元素。
并按照@false 的建议使其更明确:
list_real_prefix(List, Prefix) :-
Prefix = [_|_],
Rest = [_|_],
append(Prefix, Rest, List).
"real" 后缀将完全相同:
list_real_suffix(List, Suffix) :-
Front = [_|_],
Suffix = [_|_],
append(Front, Suffix, List).
你也可以为此使用一个 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).