List 多个列表的组合-Prolog

List 多个列表的组合-Prolog,list,prolog,List,Prolog,我需要在列表中找到这些组合。例如,给出以下列表 List = [[1, 2], [1, 2, 3]] 这些应该是输出 Comb = [[1,1],[1,2],[1,3],[2,1],[2,2],[2,3]] 另一个例子: List = [[1,2],[1,2],[1,2,3]] Comb = [[1,1,1],[1,1,2],[1,1,3],[1,2,1],[1,2,2],[1,2,3]....etc] 我知道如何对包含两个子列表的列表执行此操作,但它需要对任意数量的子列表执行此操作 我

我需要在列表中找到这些组合。例如,给出以下列表

List = [[1, 2], [1, 2, 3]]
这些应该是输出

Comb = [[1,1],[1,2],[1,3],[2,1],[2,2],[2,3]]
另一个例子:

List = [[1,2],[1,2],[1,2,3]]

Comb = [[1,1,1],[1,1,2],[1,1,3],[1,2,1],[1,2,2],[1,2,3]....etc]
我知道如何对包含两个子列表的列表执行此操作,但它需要对任意数量的子列表执行此操作


我不熟悉Prolog,请帮忙。

为了完整起见,这里是我的评论版本的扩充版。注
nilmemberd\u t/2
的灵感来源于

上面的版本显示,在我的评论回复中“仅”缺少第一个子句。也许更简短一些:

nilmemberd([[]|_]).
nilmemberd([[_|_]|Nils]) :-
   nilmemberd(Nils).

这应该适用于无约束的开场白。使用约束条件时,必须重新考虑bagof/3,因为复制约束条件是一个定义不清的地形。

这里有一种使用
maplist/3
append/2
的方法:

list_comb([], [[]]). list_comb([Xs|Xss], Ess) :- Xs = [_|_], list_comb(Xss, Ess0), maplist(aux_x_comb(Ess0), Xs, Esss1), append(Esss1, Ess). aux_x_comb(Ess0, X, Ess1) :- maplist(head_tail_list(X), Ess0, Ess1). head_tail_list(X, Xs, [X|Xs]).
这就是它的工作原理! 作为一个例子,考虑这些目标:

  • list_comb([[a,b],[f,g],[x,y,z]],Ess)

  • list_comb([[f,g],[x,y,z]],Ess0)

我们如何从
Ess0
Ess

  • 我们看看问题的答案 后一个问题:

    ?- list_comb([[f,g],[x,y,z]], Ess0). Ess0 = [[f,x],[f,y],[f,z], [g,x],[g,y],[g,z]].

  • 。。。然后对
    b
    执行相同的操作

    maplist(aux\u x\u comb)
    帮助我们处理所有项目:

    ?映射列表(辅助x梳([[f,x],[f,y],[f,z], [g,x],[g,y],[g,z]]), [a,b],X)。 X=[[a,f,X],[a,f,y],[a,f,z], [a,g,x],[a,g,y],[a,g,z], [b,f,x],[b,f,y],[b,f,z], [b,g,x],[b,g,y],[b,g,z]]

  • 要从列表列表获取列表,请使用
    append/2


  • 我希望这个解释更容易理解而不是混淆:)

    是@false方法的一个转折点:

    %list\u梳(++LL,-Ess)
    列表(LL、Ess):-
    is_列表(LL),
    地图列表(is_列表,LL),
    findall(Es,地图列表(成员,Es,LL),Ess)。
    
    测试:

    41?-list_梳([1,2],[1],[1]],X)。
    X=[[1,1,1],[2,1,1]]。
    42?-list_comb([[1,2],[1],[1,2,3]],X)。
    X=[[1,1,1],[1,1,2],[1,1,3],[2,1,1],[2,1,2],[2,1,3]。
    43?-list_comb([[1,2],[1,2,3]],X)。
    X=[]。
    44?-list_comb([[1,2],t[1,2,3]],X)。
    错。
    45?-列表_梳(t,X)。
    错。
    

    这个答案是为了“一个考虑到
    Ess
    ”的纯解决方案”而提供的赏金。 这里我们这样概括:

    list\u crossproduct/2
    通过早期关联
    Xs
    Ess
    来实现双向性

    ?- list_comb(Xs, [[1,2,3],[1,2,4],[1,2,5]]). nontermination % BAD! ?- list_crossproduct(Xs, [[1,2,3],[1,2,4],[1,2,5]]). Xs = [[1],[2],[3,4,5]] % this now works, too ; false.
    List=[[1,2],[1,2],[1,2,3]],bagof(Es,maplist(member,Es,List),Ess)。
    @GuyCoder:您的解决方案是什么样子的?@GuyCoder:任何基于本身不太符合要求的系统的扩展肯定都是相当可疑的。如果遇到困难,你必须查阅下面的扩展序言。@GuyCoder:那么你认为这对OP来说容易吗?@GuyCoder:提醒一下:你提供了一笔交易。我完成了我的任务。@rep:你是说你有资格获得承诺的赏金?不!但我想我应该发布一个lambda变体作为单独的答案。(只有4个有趣的,不值得赏金)大概,你做了所有这些,而不是仅仅使用
    findall
    而不是
    bagof
    ,以避免
    findall(Es,maplist(member,Es,[[1,2],t[1]])。
    错误地成功而不是失败。但是你的版本同样错误地在
    [[1,2],[1],[1],[1]
    上成功了
    [[1,1],[1],[1]
    ,但是
    findall
    正确地(在本例中)成功了
    []
    @Will:
    bagof/3
    正确地处理变量,而
    findall/3
    像mad一样复制它们
    Ess
    对终止没有影响-至少在某些情况下,通过排除变量,谓词变成函数程序的模式-但没有la…-er-非严格性。有趣的是:最好使用
    nilmemberd(Xs)
    而不是
    member([],Xs)
    。 ?- list_comb([[f,g],[x,y,z]], Ess0). Ess0 = [[f,x],[f,y],[f,z], [g,x],[g,y],[g,z]]. ?- maplist(head_tail_list(a), [[f,x],[f,y],[f,z], [g,x],[g,y],[g,z]], X). X = [[a,f,x],[a,f,y],[a,f,z], [a,g,x],[a,g,y],[a,g,z]]. ?- maplist(aux_x_comb([[f,x],[f,y],[f,z], [g,x],[g,y],[g,z]]), [a,b], X). X = [[[a,f,x],[a,f,y],[a,f,z], [a,g,x],[a,g,y],[a,g,z]], [[b,f,x],[b,f,y],[b,f,z], [b,g,x],[b,g,y],[b,g,z]]].
    list_crossproduct(Xs, []) :-
       member([], Xs).
    list_crossproduct(Xs, Ess) :-
       Ess = [E0|_],
       same_length(E0, Xs),
       maplist(maybelonger_than(Ess), Xs),
       list_comb(Xs, Ess).
    
    maybelonger_than(Xs, Ys) :-
       maybeshorter_than(Ys, Xs).
    
    maybeshorter_than([], _).
    maybeshorter_than([_|Xs], [_|Ys]) :-
       maybeshorter_than(Xs, Ys).
    
    ?- list_comb(Xs, [[1,2,3],[1,2,4],[1,2,5]]). nontermination % BAD! ?- list_crossproduct(Xs, [[1,2,3],[1,2,4],[1,2,5]]). Xs = [[1],[2],[3,4,5]] % this now works, too ; false.
    ?- list_crossproduct(Xs, [[1,2,3],[1,2,4],[1,2,5],X,Y,Z]).
       X = [1,2,_A],
       Y = [1,2,_B],
       Z = [1,2,_C], Xs = [[1],[2],[3,4,5,_A,_B,_C]]
    ;  X = [1,_A,3],
       Y = [1,_A,4],
       Z = [1,_A,5], Xs = [[1],[2,_A],[3,4,5]]
    ;  X = [_A,2,3],
       Y = [_A,2,4],
       Z = [_A,2,5], Xs = [[1,_A],[2],[3,4,5]]
    ;  false.