簡體   English   中英

在Prolog中遞歸合並列表

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM