Prolog:找到供应所有零件的供应商

时间:2014-01-20 05:11:03

标签: prolog

我是Prolog的新手。这是我的事实。

part_cost(部分,供应商)

part_cost(top_tube ,cinelli).
part_cost(top_tube ,columbus).
part_cost(down_tube ,columbus).
part_cost(head_tube ,cinelli).
part_cost(head_tube ,columbus).
part_cost(seat_mast ,cinelli).
part_cost(seat_mast ,columbus).

我想找一家供应各种零件的供应商,实际上是哥伦布。

我不知道如何用Prolog语言说“全部”。

感谢任何帮助。

更新

谢谢@Ankur和@Sergey Dymchenko。你的清单方法激励着我!我可以写规则:

supplyAllParts(Supplier, []):-true.

supplyAllParts(Supplier, [Part|PartRest]) :- 
    part_cost(Part, Supplier, _, _),
    supplyAllParts(Supplier, PartRest).

并通过

调用它
?- supplyAllParts(S,[top_tube, down_tube, head_tube, seat_mast]).
S = columbus.

现在Prolog可以从事实中动态查找零件清单([top_tube,down_tube,head_tube,seat_mast])而不是我手动提供它吗?

3 个答案:

答案 0 :(得分:1)

首先,您可能需要手动定义“所有部分”的概念,因为可能存在某种“bottom_super_gravitsapa”,没有人拥有:

% store in sorted order, to compare with setof results later
sort([top_tube, down_tube, head_tube, seat_mast], AllParts)

要获取每个供应商的所有零件清单,我们可以使用setof/3

?- setof(Part, part_cost(Part, Supplier), Parts).
setof(Part, part_cost(Part, Supplier), Parts).
Supplier = cinelli
Parts = [head_tube,seat_mast,top_tube] ?;
Supplier = columbus
Parts = [down_tube,head_tube,seat_mast,top_tube]
yes

现在只需添加一个条件,即特定供应商的零件清单和AllParts是相同的:

Parts == AllParts

如果您不想手动定义AllParts并假设每个可能的部件都有供应商,您可以使用另一个setof从主setof之前的事实中获取AllParts。 / p>

答案 1 :(得分:1)

all在任何一种语言中都是一个大词,它意味着变化如此......在地球上,在Prolog我们有findall / 3家族,它输出一个列表我们指示从成功的查询中提取的所有模式。然后进一步处理输出列表...但对于您的情况,库(aggregate)更方便:

supplies_all(Supplier) :-
    aggregate(max(N,S), count_part_cost(S,N), max(_, Supplier)).

count_part_cost(S,N) :-
    aggregate(count, P^part_cost(P,S), N).

我使用了服务谓词count_part_cost / 2,只是为了保持主要的清晰... 如果您尝试“内联”它们,请注意变量的使用。研究变量量化,直到你对它感到满意为止。

编辑正如谢尔盖所​​说,我的代码不正确。以下是我更合适的定义:

supplies_all(Supplier) :-
    setof(P, S^part_cost(P,S), Ps),
    setof(P, part_cost(P,Supplier), Ps).

我认为它突出了我上面推荐的关于研究变量量化的建议......

编辑另一种可能的定义,成本更低,但有多余的多重解决方案(好吧,我们已经设定了...)

supplies_all(Supplier) :-
    % peek any Supplier from catalog
    part_cost(_,Supplier),
    % check it has all parts available
    forall(part_cost(P,_), part_cost(P,Supplier)).

答案 2 :(得分:1)

supplies([],_).
supplies([H|T],S) :- part_cost(H,S), supplies(T,S).

| ?- setof(P,S^part_cost(P,S),R), supplies(R,Supplier).

R = [down_tube,head_tube,seat_mast,top_tube]
Supplier = columbus