我在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
但是没有用。有什么帮助吗?
答案 0 :(得分:0)
您可以这样使用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
中获得包含组件和子组件的列表。
答案 1 :(得分:0)
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|...].
答案 2 :(得分:0)
Here你可以看到一个有效的解决方案,即固定点迭代的例子。
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]