Prolog - 使用术语表示和访问复杂的嵌套数据

Cro*_*ess 6 nested prolog data-structures

my_computer([
    case([
        motherboard([board(plastic),ports(metal),slots(plastic),capacitors(plastic)]),
        power_supply_unit([casing(metal),cables(plastic),connectors(plastic),capacitors(plastic),fan(plastic),transformer(metal)]),
        central_processing_unit([board(plastic),fan(plastic),heatsink(metal)]),
        random_access_memory([board(plastic)]),
        graphics_processing_unit([board(plastic),ports(metal),capacitors(plastic),fan(plastic),heatsink(metal)])
    ]),
    monitor([
        lcd_screen(plastic),inverter(plastic),frame(plastic)
    ]),
    keyboard([
        key(plastic),frame(plastic),cable(plastic)
    ]),
    mouse([
        key(plastic),wheel(plastic),casing(plastic),cable(plastic)
    ])
]).
Run Code Online (Sandbox Code Playgroud)

我应该怎么做才能运行类似monitor(X).motherboard(X)提供一层或多层(子)材料的问题(就像my_computer(X).那样做)?

下面的代码对于提出这样的问题会更有用吗?关于一层子材料的问题很容易通过这种方式回答.

my_computer([case,monitor,keyboard,mouse]).
    case([motherboard,power_supply_unit,central_processing_unit,random_access_memory,graphics_processing_unit]).
        motherboard([board,ports,slots,capacitors]).
        power_supply_unit([casing,cables,connectors,capacitors,fan,transformer]).
        central_processing_unit([board,fan,heatsink]).
        random_access_memory([board]).
        graphics_processing_unit([board,ports,capacitors,fan,heatsink]).
    monitor([lcd_screen,inverter,frame]).
    keyboard(keys,frame,cable).
    mouse([keys,wheel,casing,cable]).
Run Code Online (Sandbox Code Playgroud)

lur*_*ker 4

对你的问题的简短回答是:

monitor(X) :-
    my_computer([_, monitor(X), _, _]).
Run Code Online (Sandbox Code Playgroud)

类似地,对于keyboardormouse等​​,这motherboard将是更深的一层:

motherboard(X) :-
    my_computer([case([motherboard(X), _, _, _, _), _, _, _]).
Run Code Online (Sandbox Code Playgroud)

这些谓词当然采用固定的结构。如果您想要它更通用一点,您可以对嵌入函子( 、 等)进行更精细的“狩猎monitormotherboard

根据您更广泛的应用程序目标,我不清楚这是否是数据的最佳表示。现在已经足够了,但上下文可能希望将其带向不同的方向。


这是另一种方法,将数据视为暗示树关系的单个事实。基本上只是has关系。将“重要”事实分为material(Item, Type)

item(my_computer, case).
item(my_computer, monitor).
item(my_computer, keyboard).
item(my_computer, mouse).

item(case, motherboard).
item(case, power_supply_unit).
item(case, central_processing_unit).
item(case, random_access_memory).
item(case, graphics_processing_unit).

item(motherboard, board).
item(motherboard, ports).
item(motherboard, slots).
item(motherboard, capacitors).

item(power_supply_unit, casing).
item(power_supply_unit, cable).
item(power_supply_unit, connectors).
item(power_supply_unit, capacitors).
item(power_supply_unit, fan).
item(power_supply_unit, transformer).

item(central_processing_unit, board).
item(central_processing_unit, fan).
item(central_processing_unit, heatsink).

item(random_access_memory, board).

item(graphics_processing_unit, board).
item(graphics_processing_unit, ports).
item(graphics_processing_unit, capacitors).
item(graphics_processing_unit, fan).
item(graphics_processing_unit, heatsink).

item(monitor, lcd_screen).
item(monitor, inverter).
item(monitor, frame).

item(keyboard, key).
item(keyboard, frame).
item(keyboard, cable).

item(mouse, key).
item(mouse, wheel).
item(mouse, casing).
item(mouse, cable).

material(board, plastic).
material(slots, plastic).
material(capacitors, plastic).
material(ports, metal).
material(casing, metal).
material(cable, plastic).
material(connectors, plastic).
material(fan, plastic).
material(heatsink, metal).
material(lcd_screen, plastic).
material(inverter, plastic).
material(frame, plastic).
material(key, plastic).
material(cable, plastic).
Run Code Online (Sandbox Code Playgroud)

然后,您可以定义一个谓词来生成您想要的任何级别的树。这是一个以术语(而不是列表)形式执行此操作的示例:

structure(Item, Structure) :-
    (   item(Item, _)
    ->  findall(T, (item(Item, R), structure(R, T)), Rs),
        Structure =.. [Item |Rs]
    ;   Structure = Item
    ).
Run Code Online (Sandbox Code Playgroud)

那么:

:- structure(case, S).
S = case(motherboard(board,ports,slots,capacitors),
         power_supply_unit(casing,cable,connectors,capacitors,fan,transformer),
         central_processing_unit(board,fan,heatsink),
         random_access_memory(board),
         graphics_processing_unit(board,ports,capacitors,fan,heatsink)
        )
Run Code Online (Sandbox Code Playgroud)

这可以很容易地更改为以列表形式提供结果。例如,这里有一个谓词,它采用上述事实并给出您最初在问题中提出的形式:

structure(Item, Tree) :-
    (   item(Item, _)
    ->  findall(T, (item(Item, R), structure(R, T)), Rs),
        Tree =.. [Item, Rs]
    ;   material(Item, Material),
        Tree =.. [Item, Material]
    ).
Run Code Online (Sandbox Code Playgroud)

对于谓词来说, 变成item了一个微不足道的结果where_used(Item, Parent)

where_used(Item, Parent) :-
    item(Parent, Item).
Run Code Online (Sandbox Code Playgroud)

同样,这完全取决于您想要如何使用和管理数据。