List 序言:删除所有连续整数子列表

List 序言:删除所有连续整数子列表,list,prolog,sublist,meta-predicate,List,Prolog,Sublist,Meta Predicate,所以我遇到了这个序言问题: 给定一个线性数字列表,删除所有连续值序列 例如,remove([1,2,4,6,7,8,10],L)将产生L=[4,10] 我成功地编写了以下代码: consecutive(N,P):- N is P-1. removeS([],[]). removeS([H],[H]). removeS([H1,H2],[]):- consecutive(H1,H2). removeS([H1,H2|T],[H1|L]):- not(consecutiv

所以我遇到了这个序言问题:

给定一个线性数字列表,删除所有连续值序列

例如,
remove([1,2,4,6,7,8,10],L)
将产生
L=[4,10]

我成功地编写了以下代码:

consecutive(N,P):-
    N is P-1.

removeS([],[]).
removeS([H],[H]).

removeS([H1,H2],[]):-
    consecutive(H1,H2).
removeS([H1,H2|T],[H1|L]):-
    not(consecutive(H1,H2)),
    removeS([H2|T],L).
removeS([H1,H2,H3|T],L):-
    consecutive(H1,H2),
    not(consecutive(H2,H3)),
    removeS([H3|T],L).
removeS([H1,H2,H3|T],L):-
    consecutive(H1,H2),
    consecutive(H2,H3),
    removeS([H3|T],L).
它几乎适用于以下情况:

removeS([1,2,3,4,5,2,3,4,5,6,7,9,11],R). -->  R = [5, 9, 11];
Here only 9 and 11 should be displayed

removeS([3,2,1,2,3,4,5,2,3,4,5,6,7,9,11],R). --> R = [3, 2, 5, 9, 11];
Here only 3,2,9,11 should appear in R
这是因为它在计算下一步时考虑了递增序列的最后一个数


我在这里做错了什么?

你做的事情没有必要那么笼统(而且更复杂)

?- removeS([1,2,3],R).
R = [3] ;
false.
我引入了一个服务谓词,它“吃掉”所有连续词,并简化了逻辑,使其仅在出现两个连续词时启动,我有:

?- removeS([3,2,1,2,3,4,5,2,3,4,5,6,7,9,11],L).
L = [3, 2, 9, 11].
编辑

这是我的定义。切割可以被移除,正如你所做的那样,否定了替代方案,但我认为这只会使整体变得混乱。或者,简单地说,放下它,用once/1包装/2 top call

removeS([],[]).
removeS([A,B|T],L):- succ(A,B), eat(A,[B|T],R), !, removeS(R, L).
removeS([A|B],[A|L]) :- removeS(B,L).

eat(A,[B|T],R) :- succ(A,B), eat(B,T,R).
eat(_,T,T).
在这个答案中,我们结合使用两个s

基于、和,我们定义:

consecutives_removed(Xss, Zs) :-
   split_if_adj(z_nonsucc_t, Xss, Yss),
   tfilter(\[_|Xs]^(Xs=[]), Yss, Zss),
   append(Zss, Zs).
示例查询(由OP给出):


这是一个很好的尝试!它没有给出您想要的答案的原因是最后一个子句的最后一行。如果
连续(H2,H3)
成功,则您不希望
删除([H3 | t],L)
,因为您不想计数
H3
。你只需要
删除(T,L)。
@潜伏者:在应用你的“更正”后,我得到(如预期的那样)
?-删除([1,2,3,4],L)。L=[4]
。你有不同的结果吗?我坚持认为缺少的是泛化…@我没有测试那个案例。我的“纠正”是必要的,但还不够。谓词显然需要更多的东西才能使其正确。我并没有声称这是一个完整的解决方案。这只是我发现的东西。我认为您的答案是在重构方向上的改进。我只是在寻找一个补丁(部分地回答了“我所拥有的东西有什么问题?”):)@潜伏者:这种方法在逻辑上是有缺陷的:删除N个连续的元素会删除检查以下元素所需的“前瞻性”!我避免发布完整的代码(5行!),希望Eugen(我同意他的是一个很好的尝试)能够对发现合适的解决方案感兴趣。尽管OP最初的方法在逻辑上并没有完全的缺陷(我提出了一个类似的、可行的解决方案),但您的解决方案更干净、更紧凑(+1)。
consecutives_removed(Xss, Zs) :-
   split_if_adj(z_nonsucc_t, Xss, Yss),
   tfilter(\[_|Xs]^(Xs=[]), Yss, Zss),
   append(Zss, Zs).
?- consecutives_removed([1,2,4,6,7,8,10], Xs).
Xs = [4,10].

?- consecutives_removed([1,2,3,4,5,2,3,4,5,6,7,9,11], Xs).
Xs = [9,11].

?- consecutives_removed([3,2,1,2,3,4,5,2,3,4,5,6,7,9,11], Xs).
Xs = [3,2,9,11].