List prolog-数组的子序列-每个结果仅一次

List prolog-数组的子序列-每个结果仅一次,list,prolog,List,Prolog,在这里,您可以看到我的实现: subsequence([], _). subsequence([H1|T1], [H1|T2]) :- subsequence(T1, T2). subsequence(L1, [_|T2]) :- subsequence(L1, T2). 比如说, ?- subsequence(X, [1,2]). X = [] ; X = [1] ; X = [1, 2] ; X = [1] ; X = [] ; X = [2] ; X = [] ; 这个结果通

在这里,您可以看到我的实现:

subsequence([], _).   
subsequence([H1|T1], [H1|T2]) :- subsequence(T1, T2).
subsequence(L1, [_|T2]) :- subsequence(L1, T2).
比如说,

?- subsequence(X, [1,2]).
X = [] ;
X = [1] ;
X = [1, 2] ;
X = [1] ;
X = [] ;
X = [2] ;
X = [] ;  
这个结果通常是可以的,但是我想得到这样的结果:

39 ?- subsequence(X, [1,2]).
X = [] ;
X = [1] ;
X = [1, 2] ;
X = [2] ;
(顺序无关紧要)

正如你所看到的,我的目标是消除重复。怎么做?我试图分析计算树——我确实设法重新构造了这个结果。然而,我仍然不能消除重复的。(这棵树帮不了我)

当第一个参数为
[]
时,由于
子序列/2
的子句不是互斥的,因此存在重复的解决方案。
子序列([],X)
可以通过多种方式获得成功。它匹配谓词的第一个和第三个子句,或通过谓词的第一个和第三个子句成功

您可以修改第三个子句,以避免
[]
是第一个参数的情况,从而使这些子句在这种情况下相互排斥:

subsequence([], _).   
subsequence([X|T1], [X|T2]) :- subsequence(T1, T2).
subsequence([X|T1], [_|T2]) :- subsequence([X|T1], T2).
这将产生:

| ?- subsequence(X, [1,2]).

X = [] ? a

X = [1]

X = [1,2]

X = [2]

no
| ?-

实现上述目的的另一种方法是将第三个谓词子句(保留上面的前两个)定义为:


修改第一条就足够了。[]的子序列应该是[],而不是“任何”


谢谢你的回答。然而,您似乎对另一种方式很好奇,但它不起作用。@HaskellFun“另一种方式”仅是我所说的
子序列/2
的第3条的替代品。你还需要前两个条款。当我运行它时,它运行良好。确保包含
子序列/2
的所有三个子句。换句话说,您仍然需要
子序列([],124;)。
子序列([X|T1],[X|T2]):-子序列(T1,T2)。
作为前两个子句。是的。简单地说,您可以用更优雅的方式检查列表是否为空。我还好吗?@HaskellFun无论哪种方式都可以
subsequence(L, [_|T]) :-
    L = [_|_],    % L is a list with at least one element
    subsequence(L, T).
subsequence([], []).   
subsequence([H1|T1], [H1|T2]) :- subsequence(T1, T2).
subsequence(L1, [_|T2]) :- subsequence(L1, T2).