2014-09-25 58 views
0

我想比较两个列表中的值来找出哪一个具有较小的值,但是因为我对Prolog有点新,所以我有一些麻烦提出了一个合适的过程处理这个。根据参数值选择词条

我想检查是否apple是两个列表进行比较的数值(每个列表的最后一个元素)比cracker便宜:

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

应该如何的程序设计?

+0

什么是产品规则?它是不完整的(没有以句点('.'))结束,似乎只检查'I'是否是一个包含三个元素的列表。 – Dunes 2014-09-25 09:43:54

回答

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

+0

奇怪的是? - 产品(I).'在苹果应该比饼干便宜时返回false。 – Alpine 2014-09-25 09:56:58

+0

解决了,谢谢! – Alpine 2014-09-25 10:39:33

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 
+0

'<='是我的复制和粘贴错误。编写代码并在获取输出时将其复制到序言中,并忘记将更正复制回去(我正在使用SICStus)。为什么这个实现不稳定?只有排序算法要求另一个比较答案 - 第一个(顶部)规则将始终首先尝试,第二个规则不应该。出于提高效率的目的,一旦列表排序,您就可以在排序算法中执行一次裁减。 – Dunes 2014-09-25 15:45:25