[英]Combine list recursively in Prolog
我已經在Prolog中做到了
contains(psu,[fan,cable,transformer]).
contains(screen,[panel,cable,psu]).
contains(fan,[plastic,cable,copper]).
contains(cable,[copper,plastic]).
contains(transformer,[wire,core]).
contains(wire,[copper,plastic]).
contains(panel,[glass,polarizingfilter,liquidcrystals]).
我想問一個問題componentsOf(X)
,其中它返回列表中X
所有組件和子組件
componentsOf(psu)
[fan,cable,transformer,plastic,copper,wire,core]
我嘗試通過每次都添加列表並最后使用sort/2
來制作列表,但沒有用。 有什么幫助嗎?
您可以通過以下方式使用findall/3
:
solve(L1,L2,L3):-
findall(X,contains(X,_),L1),
findall(X,contains(_,X),L2),
findall([X,Y],contains(X,Y),L3).
查詢:
?- solve(L1,L2,L3).
L1 = [psu, screen, fan, cable, transformer, wire, panel],
L2 = [[fan, cable, transformer], [panel, cable, psu], [plastic, cable, copper], [copper, plastic], [wire, core], [copper, plastic], [glass, polarizingfilter, liquidcrystals]],
L3 = [[psu, [fan, cable, transformer]], [screen, [panel, cable, psu]], [fan, [plastic, cable, copper]], [cable, [copper, plastic]], [transformer, [wire, core]], [wire, [copper, plastic]], [panel, [glass, polarizingfilter, liquidcrystals]]]
在L1
您將獲得所有組件;在L2
您將獲得所有子組件;在L3
您將獲得包含組件和子組件的列表。
SWI-Prolog的圖書館ordset是您的朋友:
componentsOf(Obj, Components) :-
components_([Obj], Comps),
ord_subtract(Comps, [Obj], Components).
components_(Lst, Out) :-
% change setof with findall because setof fails when L is empty
findall(X, (member(Y, Lst), contains(Y, X)), L),
flatten([Lst | L], FlatL),
list_to_ord_set(FlatL, SetL),
ord_intersection(Lst, SetL, Intersection, Difference),
( Difference = []
-> Out = Intersection
; components_(Difference, Out1),
ord_union(Out1, SetL, Out)).
范例:
?- componentsOf(psu, Out).
Out = [cable, copper, core, fan, plastic, transformer, wire].
編輯我用findall更改setof :
?- componentsOf(screen, X).
X = [cable, copper, core, fan, glass, liquidcrystals, panel, plastic, polarizingfilter|...].
在這里,您可以看到一個可行的解決方案,例如定點迭代。
components(SoFar, Cs) :-
setof(P, C^L^
((member(C,SoFar),contains(C,L),member(P,L))
;member(P,SoFar)), Ts),
( Ts = SoFar -> Cs = Ts ; components(Ts, Cs) ).
part_components(P, Cs) :-
% corrected to exclude P from Cs
% components([P], Cs).
contains(P, Ps),
components(Ps, Cs).
緊湊,但效率不高... OTOH,它產生可讀的(很好的,已排序的)答案:
?- part_components(screen,R).
R = [cable, copper, core, fan, glass, liquidcrystals, panel, plastic, polarizingfilter, psu, transformer, wire]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.