如何在prolog中打印多个答案

时间:2011-05-14 11:47:28

标签: prolog

问题是我必须打印所有最小的开始,然后最小主要然后最小甜点。 我写了这个

starter( greenSalad,10).
starter( seserSalad,20).
starter( tomatoSalad,10).
main( chicken,40).
main( pizza,30).
main( pasta,30).
dessert( raspberryCake,30).
dessert( fruitCake,20).
dessert( applepie,20).

min(Head,Tail,Head):- Head<Tail.
min(Head,Tail,Tail):- Tail<Head.
findmin([Only], Only).
findmin([Head|Tail], Minimum) :- findmin(Tail, TailMin), Minimum is
min(Head, TailMin).


**findMeal**2:-findall(Sp,starter(_,Sp),SList),findmin(SList,Spm),printStarter2(Spm),
    findall(Mp,main(_,Mp),MList),findmin(MList,Mpm),printMain2(Mpm),
    findall(Dp,dessert(_,Dp),DList),findmin(DList,Dpm),printDessert2(Dpm).


printStarter2(Spm):-starter(S,Spm),write(S),nl,fail.
printMain2(Mpm):-main(M,Mpm),write(M),nl,fail.
printDessert2(Dpm):-dessert(D,Dpm),write(D),nl,fail.

问题是:这给了所有最小的开始,然后在没有给出最低主要和甜点的情况下停止

1 个答案:

答案 0 :(得分:1)

Prolog按照条款出现的顺序测试谓词。它确实可以使条件成立。当它试图证明findMeal时,它证明了findall / 3,它总是证明是真的,但是做了必要的统一,即。 SList在此之后受到约束。

然后它证明了findmin / 2,它将Spm与10统一,并留下选择点。它到达printStarter2,它试图证明它,所以它打印greensaled并失败(在子句末尾的fail / 0)。它可以追溯到选择点并将Spm与'next'10(来自tomatoSalad)统一起来。推理引擎再次进入printStarter,打印并再次失败。由于没有更多的选择点,并且最后一个选择点失败,谓词无法生成,因此推理引擎停止并打印“失败”。

如果你想修复它,让它打印所有最低限度的食物,将findMeal谓词分成三个条款:

findMeal :- findall(Sp,starter(_,Sp),SList),findmin(SList,Spm),printStarter2(Spm).
findMeal :- findall(Mp,main(_,Mp),MList),findmin(MList,Mpm),printMain2(Mpm).
findMeal :- findall(Dp,dessert(_,Dp),DList),findmin(DList,Dpm),printDessert2(Dpm).

这将强制推理引擎在证明谓词开始时创建选择点。在上述相同的场景之后,第一个谓词将失败,但推理引擎将有更多的选择点 - 下一个findMeal子句,依此类推。

此外,您可能还想添加一个findMeal子句,一个空子句:

findMeal.

因此,在前三个条款失败后,谓词将被证明是正确的。