List 有极限的子序列
这是我的问题: 编写一个过程List 有极限的子序列,list,debugging,prolog,dcg,subsequence,List,Debugging,Prolog,Dcg,Subsequence,这是我的问题: 编写一个过程distance(List,Nemptylist,SubList)/3,检查SubList 是列表的子列表,项目之间的距离不超过N约束(N 实现为Nemptylist–一个N匿名变量列表)。假设列表 是完全实例化的。重复答案是允许的,只要他们的数量是有限的 例如,对于N=2: ?- distance( [a,t,d,r,a,n,c,b,c] , [_,_], [a,b,c] ). true ?- distance( [m,a,t,d,r,b,c,t] , [_,_]
distance(List,Nemptylist,SubList)/3
,检查SubList
是列表
的子列表,项目之间的距离不超过N
约束(N
实现为Nemptylist
–一个N
匿名变量列表)。假设列表
是完全实例化的。重复答案是允许的,只要他们的数量是有限的
例如,对于N
=2:
?- distance( [a,t,d,r,a,n,c,b,c] , [_,_], [a,b,c] ).
true
?- distance( [m,a,t,d,r,b,c,t] , [_,_] , [a,b,c] ).
false
?- distance([a, t, d, r, a, n, c, b], [_, _], [a, b, c]).
false
?- distance([c, c, c, a, c, c, c], [_, _], [a]).
true.
我已经坐了几个小时,试图解决这个问题,并最终给出了一些例子
上面的工作,但后来我运行了一些测试,他们失败了
我目前的解决方案如下:
distance( L1 , L2 , [X] ) :-
member(X,L1) .
distance( L1 , L2 , [H|T] ) :-
distance(L1,L2,T) ,
append(Y,Z,L2) ,
T=[Hs|Ts] ,
append([H],Y,W) ,
append(W,[Hs],R) ,
sublist(R,L1) .
prefix(X,L) :- append(X, _, L).
suffix(X,L) :- append(_, X, L).
sublist(X,L) :- suffix(S,L) , prefix(X,S) .
当我尝试运行此测试时:
distance( [r,a,n,c,b,c],[],X) .
由于超出运行时错误,它失败
我调试了几个小时,真的很累。请帮我完成这项糟糕的任务。以下是一个逐步解决方案,从一个不完整的定义开始:
distance_tentative(Xs, _Ys, Zs) :-
phrase(( ..., seq(Zs), ... ), Xs).
... --> [] | [_], ... .
seq([]) --> [].
seq([E|Es]) --> [E], seq(Es).
这个解决方案太专业化了,因为它只描述而不描述。子序列是:
subseq([]) --> [].
subseq([E|Es]) --> [E], subseq(Es).
subseq(Es) --> [_], subseq(Es).
现在,我们想限制中介无关元素的数量。也就是说,我们希望将最后一条规则的应用限制在此列表参数的长度LN
subseq_n([], _) --> [].
subseq_n([E|Es], LN) --> [E], subseq_n(Es, LN).
subseq_n(Es, [_|LN]) --> [_], subseq_n(Es, LN).
也许最后一条规则应该改为:
subseq_n(Es, [E|LN]) --> [E], subseq_n(Es, LN).
我怀疑问题陈述的翻译有问题。无论如何,现在我们有:
distance(Xs, Ys, Zs) :-
phrase(( ..., subseq_n(Zs, Ys), ... ), Xs).
有很多多余的答案,但你说这是可以的
优化
在第一个…
和子q\u n//2
的第一个元素开始之间存在大量冗余,即模糊性;类似地,在结尾处的subseq\u n//2
和…
之间。此外,如果Zs
为空,一个答案就足够了。简短的
distance(_Xs, _Ys, []).
distance(Xs, Ys, [Z|Zs]) :-
phrase( ( ..., [Z], rsubseq_n(Zs, Ys), ... ), Xs).
rsubseq_n([], _) --> [].
rsubseq_n([E|Es], Ys) --> [E], rsubseq_n(Es, Ys).
rsubseq_n([E|Es], [_|Ys]) --> [_], rsubseq_n([E|Es], Ys).
请注意,“距离列表”现在仅在子序列中使用
该程序具有非常有利的终止特性:
因此,只有知道第一个参数才能使谓词终止
编辑:您的问题陈述不明确,其中距离N
适用于:
。。。约束项之间的距离不超过N
这可能意味着总编辑距离不超过N,或每个连续对之间的距离。因此,假设每个连续对之间的距离意味着:
distanceII(_Xs, _Ys, []).
distanceII(Xs, Ys, [Z|Zs]) :-
phrase( ( ..., [Z], rsubseq_d(Zs, Ys), ... ), Xs).
rsubseq_d([], _) --> [].
rsubseq_d([E|Es],Max) -->
maxseq(Max),
[E],
rsubseq_d(Es, Max).
maxseq(_) --> [].
maxseq([_|Es]) --> [_], maxseq(Es).
我认为您的实施存在两个主要问题:
NEmptyList
中的元素与子列表(R,L1)
中的列表中的元素统一起来。未来的子列表
目标可能会失败,因为NEmptyList
不会与列表中的任何N
连续元素统一。如果您想使用append(这是可以的),您应该每次构建一个新的长度列表,最多N
(见下文)
列表中相同的唯一序列验证子列表中的不同序列。要演示这一点,请尝试以下解决方案:
?- distance([a,a],[],[a,a,a,a,a,a]).
true ;
true ;
false.
distance(_, _, []).
distance(List, NEmpty, Sublist):-
append(_, Right, List), % The first element can be anywhere in the list
distance2(Right, NEmpty, Sublist).
distance2([X|_], _, [X]).
distance2(List, NEmpty, [X|Sublist]):-
length(NEmpty, N),
between(0, N, N1),
length(AtMostNEmpty, N1), % Make a different list each time of length <N
append([X|AtMostNEmpty], Right, List),
distance2(Right, NEmpty, Sublist).
?- distance([a,a],[],[a,a,a,a,a,a]).
true ;
true ;
false.
distance(_, _, []).
distance(List, NEmpty, Sublist):-
append(_, Right, List), % The first element can be anywhere in the list
distance2(Right, NEmpty, Sublist).
distance2([X|_], _, [X]).
distance2(List, NEmpty, [X|Sublist]):-
length(NEmpty, N),
between(0, N, N1),
length(AtMostNEmpty, N1), % Make a different list each time of length <N
append([X|AtMostNEmpty], Right, List),
distance2(Right, NEmpty, Sublist).
距离(,,[])。
距离(列表、NEmpty、子列表):-
追加(\右,列表),%第一个元素可以在列表中的任何位置
距离2(右,NEmpty,子列表)。
距离2([X | X],[ux])。
距离2(列表,NEmpty,[X|子列表]:-
长度(NEmpty,N),
在(0,N,N1)之间,
长度(AtMostNEmpty,N1),%在每次长度时制作不同的列表