gpt4 book ai didi

prolog - 制定效果公理

转载 作者:行者123 更新时间:2023-12-04 02:07:00 25 4
gpt4 key购买 nike

如何使用谓词 contains(b,l,t) 正确编写 empty(b,t)-action 的效果公理 如果桶 b 在时间 t 装有 l 升水,则谓词计算 True 。

empty(b,t):在时间 t 完全清空桶 b。转移效果在时间 t+1 可见

transfer(b,b',t):将尽可能多的水从桶 b 转移到桶 b',而不会从时间 t 开始溢出任何水。转移的影响在时间 t+1 是可见的。

桶 1 装满水,容量为 7 升。桶 2 是空的,容量为 3 升。目标状态是 b2 包含 1 升水。

我会说正确的解决方案是:

to any b,t,l( empty(b,t) -> contains(b,l,t))

例如,这是正确的还是我应该将升数设置为 l= 5 ?

最佳答案

对于这个问题,不需要明确的时间,所以我们将历史表示为一个 Action 列表。另一方面,您需要明确表示系统的状态,即三个桶的当前内容。原因是 Prolog 数据结构(即术语)一旦创建就无法更改。由于有很多无意义的术语,最好先通过 is_type/1 谓词定义数据类型。因为您将在某个时候使用算术(当您将水从一个桶倒到另一个桶时),所以我将使用算术约束而不是古老的 is/2 谓词。

:- use_module(library(clpfd)).

首先我们声明有 3 个桶,分别由原子 b1、b2 和 b3 表示:
is_bucket(b1).
is_bucket(b2).
is_bucket(b3).

然后我们需要定义我们的状态。我们只使用一个术语 buckets/3,其中第一个参数保存 b1 的容量,其他两个参数也是如此。
is_state(buckets(X,Y,Z)) :-
% each bucket contains at least 0 liters
[X,Y,Z] ins 0 .. sup.

所有容器可能不会变成负数,因此我们将它们的域设置为从零到(正)无穷大的范围。

现在什么是行动?到目前为止,您描述了清空和倾倒:
is_action(empty(B)) :-
is_bucket(B).
is_action(pour(From, To)) :-
is_bucket(From),
is_bucket(To).

要清空一个桶,我们只需要知道是哪一个。如果我们从一个倒水到另一个,我们需要描述两者。由于我们已经有一个描述桶的谓词,我们可以将规则表述为“如果 FromTo 是桶,那么 pour(From, To) 是一个 Action 。

现在我们需要解释一个 Action 如何转换一个状态。这是旧状态和新状态之间的关系,因为我们想知道会发生什么,还有历史。
% initial state
state_goesto_action(buckets(7,5,3), buckets(7,5,3), []).

初始状态的转换不会改变任何东西,并且有一个空的历史记录( [])。
% state transitions for moving
state_goesto_action(buckets(X,Y,Z), buckets(0,Y,Z), [empty(b1) | History]) :-
state_goesto_action(_S0, buckets(X,Y,Z), History).

这条规则可以理解为“如果我们有一个 Action 来自某个状态 _S0 导致状态 buckets(X,Y,Z) 和一些 History ,那么我们接下来可以执行 empty(b1) Action ,我们将到达状态 buckets(0,Y,Z)”换句话说,状态被更新, Action 被添加到历史中。对称规则适用于其他桶:
state_goesto_action(buckets(X,Y,Z), buckets(X,0,Z), [empty(b2) | History]) :-
state_goesto_action(_S0, buckets(X,Y,Z), History).
state_goesto_action(buckets(X,Y,Z), buckets(X,Y,0), [empty(b3) | History]) :-
state_goesto_action(_S0, buckets(X,Y,Z), History).

我们如何检查这是否有意义?让我们看看长度为 2 的历史:
?- state_goesto_action(_,S1,[H1,H2]).
S1 = buckets(0, 3, 5),
H1 = H2, H2 = empty(b1) .

很好,如果两个操作都是 empty(b1) ,则第一个存储桶为空,其他存储桶保持不变。让我们看看进一步的解决方案:
S1 = buckets(0, 0, 5),
H1 = empty(b1),
H2 = empty(b2) ;

S1 = buckets(0, 3, 0),
H1 = empty(b1),
H2 = empty(b3) ;

S1 = buckets(0, 0, 5),
H1 = empty(b2),
H2 = empty(b1) ;

S1 = buckets(7, 0, 5),
H1 = H2, H2 = empty(b2) ;

S1 = buckets(7, 0, 0),
H1 = empty(b2),
H2 = empty(b3) ;

S1 = buckets(0, 3, 0),
H1 = empty(b3),
H2 = empty(b1) ;

S1 = buckets(7, 0, 0),
H1 = empty(b3),
H2 = empty(b2) ;

S1 = buckets(7, 3, 0),
H1 = H2, H2 = empty(b3).

看起来我们得到了清空桶的所有可能性(仅此而已:-))。现在您需要添加从一个桶倒到另一个桶的规则。祝你好运!

(编辑:错别字,第二条规则中的错误)

关于prolog - 制定效果公理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38689589/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com