根据规则限制Prolog解决方案

时间:2015-10-04 13:52:11

标签: prolog

我有一个Prolog程序,说明人们是否喜欢各种类型的水果:

likes(alice,apple).
likes(bob,peach).
likes(bob,pear).

有许多这类水果可供选择:

count(apple,1).
count(peach,2).
count(pear,6).

如果用户喜欢水果并且有足够的水果可供用户使用,那么每个水果都可以使用:

can_eat(Person,Fruit) :- likes(Person, Fruit),
    count(Fruit,N),
    N > 0.

所以你可以这样做:

?- can_eat(X,Y).
X = bob,
Y = apple ;  <-- single apple
X = bob,
Y = peach ;
X = alice,
Y = apple.  <-- single apple, again

?- can_eat(alice,X).
X = apple. <-- Alice has apple

?- can_eat(bob,X).
X = apple ; <-- Bob has apple
X = peach.

Alice和Bob都被允许使用苹果,但只有一个苹果。我如何告诉Prolog只允许Alice或Bob获得苹果,而不是两者。我想我需要一种方法来跟踪Prolog给我的解决方案留下的苹果数量。

2 个答案:

答案 0 :(得分:1)

您可以表示可用水果的集合,并根据人们执行的操作使关系更新。例如,can_eat(Person, Fruit, Env) Env包含(Fruit, Count)对的New_Env内的某些内容。

更新后的环境(Fruit, X)基于旧版(Fruit, Y),对于某些旧版YX - 1Y #= X - 1Y #>= 0。您可以使用clpfdjulia> using Plots; scatter(rand(10,3), c=[:green,:red,:blue]) 和{{1}}表示此关系。

答案 1 :(得分:0)

首先,你应该发布你的确切数据库,因为现在bob不喜欢苹果。所以我们得到

compile("com.github.deano2390:MaterialShowcaseView:1.0.5@aar") {
    exclude group: 'com.android.support', module:'appcompat-v7'
}
compile 'com.android.support:appcompat-v7:23.0.1'

无论如何,只要can_eat / 2参数是 atomic ,就无法解决您的问题。所需的解释意味着国家的变化,一项任务。

例如

?- setof(F-P, can_eat(F,P), L).
L = [alice-apple, bob-peach, bob-pear].

产生一个长解决方案列表,正好

can_eat(A) :-
    findall(F-N, count(F, N), L),
    assign(L, A).

assign(L, [P-Fruit|As]) :-
    likes(P, Fruit),
    select(Fruit-N, L, R),
    N > 0, M is N-1,
    assign([Fruit-M|R], As).
assign(_, []).