我离开旧的答案,因为它留下一些地方考虑(和问题是关于执行的只是空的动作)。只需提供一个全面实施过:
:- use_module(library(clpfd)).
bucket_capacity(b1,7).
bucket_capacity(b2,3).
bucket_capacity(b3,5).
% projections to a single bucket
state_bucket_value(buckets(X, _, _),b1,X).
state_bucket_value(buckets(_, Y, _),b2,Y).
state_bucket_value(buckets(_, _, Z),b3,Z).
% state update relation by a single bucket
state_updated_bucket_value(buckets(_, Y, Z), buckets(X0, Y, Z), b1, X0).
state_updated_bucket_value(buckets(X, _, Z), buckets(X, Y0, Z), b2, Y0).
state_updated_bucket_value(buckets(X, Y, _), buckets(X, Y, Z0), b3, Z0).
% initial state
state_goesto_action(S0, S0, []) :-
S0 = buckets(X,Y,Z),
bucket_capacity(b1,X),
bucket_capacity(b2,Y),
bucket_capacity(b3,Z).
% state transition for emptying
state_goesto_action(S1, S2, [empty(Bucket) | History]) :-
state_updated_bucket_value(S1, S2, Bucket, 0),
state_goesto_action(_S0, S1, History).
% state transition for pouring
state_goesto_action(S1, S3, [pour(From,To) | History]) :-
bucket_capacity(b1,Max),
state_bucket_value(S1,From,X),
state_bucket_value(S1,To,Y),
From0 #= min(X+Y, Max),
To0 #= max(X-Y, 0),
state_updated_bucket_value(S1, S2, From, From0),
state_updated_bucket_value(S2, S3, To, To0),
state_goesto_action(_S0, S1, History).
为了找到答案,如果我们能找到恰好与一个升斗,我们可以公平地枚举所有的历史:
?- length(L,_), state_bucket_value(S,_,1), state_goesto_action(_, S, L).
L = [pour(b1, b3), pour(b1, b2), empty(b1), pour(b1, b3)],
S = buckets(5, 0, 1) ;
L = [pour(b1, b3), pour(b1, b2), pour(b1, b1), pour(b1, b3)],
S = buckets(5, 0, 1) ;
L = [pour(b1, b3), pour(b1, b2), pour(b2, b1), empty(b1)],
S = buckets(7, 0, 1) ;
L = [pour(b1, b3), pour(b1, b2), pour(b2, b1), pour(b1, b1)],
[...].
而只是为了检查谓语是可逆的:
?- L = [pour(b1, b3), pour(b1, b2), empty(b1), pour(b1, b3)], state_goesto_action(_, S, L).
L = [pour(b1, b3), pour(b1, b2), empty(b1), pour(b1, b3)],
S = buckets(5, 0, 1) ;
false.
编辑:删除域名的限制,加快计算(我们先从一个固定的状态,这样的限制将永远是地面,可以在不labeli传播NG)。
至少对于Prolog来说,你的问题没有意义。尝试用编程语言来形式化,以获得线索。 – CapelliC
也许你应该先解释一下,b,t和l代表什么,规则应该做什么。假设t是一个时间点,b代表一个桶,l代表一个水量(单位为升),你声明:“如果在某点t,任何桶都是空的,那么任何桶都有任意数量的水”。但是你的公理的一个例子是“在时间t,如果桶b是空的,那么桶b包含100升水。”这是一个矛盾。既然矛盾的公理证明了什么,你就不应该使用它们。 –
@ CapelliC @ lambda.xy.x更新了问题以便更好地理解。 – Mensch