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
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.