我有一个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给我的解决方案留下的苹果数量。
答案 0 :(得分:1)
您可以表示可用水果的集合,并根据人们执行的操作使关系更新。例如,can_eat(Person, Fruit, Env)
Env
包含(Fruit, Count)
对的New_Env
内的某些内容。
更新后的环境(Fruit, X)
基于旧版(Fruit, Y)
,对于某些旧版Y
,X - 1
项Y #= X - 1
为Y #>= 0
。您可以使用clpfd,julia> 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(_, []).