我離開舊的答案,因爲它留下一些地方考慮(和問題是關於執行的只是空的動作)。只需提供一個全面實施過:
:- 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