根据参数值选择术语

时间:2014-09-25 09:28:45

标签: list prolog compare

我想比较两个列表中的值以找出哪个值较小,但是因为我对Prolog有点新,我在处理这个问题时遇到了一些麻烦。

我试图通过比较两个列表中的数值(每个列表的最后一个元素)来检查apple是否比cracker便宜:

product(I):-
        I = [_,_,_],
        cheaper(item(apple,fruit,1),item(cracker,biscuit,4)).

如何设计程序?

2 个答案:

答案 0 :(得分:1)

我不确切知道I = [_,_,_]应该做什么,但你不需要它。相反,只需:

?- cheaper(item(apple,fruit,1), item(cracker,biscuit,4), Cheaper).
Cheaper = item(apple, fruit, 1).

?- cheaper(item(cracker,biscuit,4), item(apple,fruit,1), Cheaper).
Cheaper = item(apple, fruit, 1).

这两个项目来自另一个问题,但你应该知道比我更好。

你只需要统一每个术语的第三个参数,并进行比较:

cheaper(item(I1, K1, P1), item(I2, K2, P2), item(I, K, P)) :-
    (   P1 =< P2
    ->  I = I1, K = K1, P = P1
    ;   I = I2, K = K2, P = P2
    ).

或者,如果你更愿意这样做:

cheaper(I1, I2, Cheaper) :-
    price(I1, P1), price(I2, P2),
    (   P1 =< P2
    ->  Cheaper = I1
    ;   Cheaper = I2
    ).
price(item(_, _, P), P).

帮助谓词price/3是一个从复合词中仅提取所需参数的好方法的示例。您甚至可以将其称为item_price/2,如果需要,还可以定义item_name/2item_kind/2。或者使用library(record)。或者,如果您使用SWI-Prolog,请使用dicts

答案 1 :(得分:0)

不使用if语句和OR的替代方法。

cheaper(item(Name1, _, Price1), item(Name2, _, Price2), Cheapest):- 
    Price1 < Price2,
    Cheapest = Name1.
cheaper(item(Name1, _, Price1), item(Name2, _, Price2), Cheapest):- 
    Price2 < Price1,
    Cheapest = Name2.

因此它对价格进行了两次单独检查。地球上为什么有人认为这有用?那么当价格相同时会发生什么?规则是否应该随意选择第一项或第二项?或者最好还是返回no,两者都不比另一个便宜(如上所述)。或者,如果它们的价格相同,那么返回两个项目会更好(见下文)。这样你的调用规则就可以尝试第二个项目,如果第一个项目由于某种原因无法工作。

cheaper(item(Name1, _, Price1), item(Name2, _, Price2), Cheapest):- 
    Price1 =< Price2,
    Cheapest = Name1.
cheaper(item(Name1, _, Price1), item(Name2, _, Price2), Cheapest):- 
    Price2 =< Price1,
    Cheapest = Name2.

| ?- cheaper(item(apple,fruit,10), item(cucumber,veg,10), Result).
Result = apple ? ;
Result = cucumber ? ;
no
| ?- cheaper(item(chocolate,candy,10), item(cucumber,veg,10), Result), 
     low_calories(Result).
Result = cucumber ? ;
no