第三个例子DieHarder
本例子主要介绍TLA+是如何进行输入的。
在上一个例子中,严格限制了big桶为5升,small桶为3升,目标是4升。如果需要将big桶与small桶的大小根据输入不同,则只需要利用CONSTANT来定义big,small桶的大小即可。
------------------------------ MODULE DieHarder -------------------------------
EXTENDS Naturals
CONSTANT BIG,SMALL,GOAL \* 增加CONSTANT 常量作为输入,并将下面用到的3,4,5进行替换即可
VARIABLES big, small
TypeOK == small \in 0..SMALL /\ big \in 0..BIG
Init == big = 0 /\ small = 0
FillSmallJug == small' = SMALL /\ big' = big
\* 这里用 small',big'表示变更后的状态,=左边不能使用small,big这样的原变量
FillBigJug == big' = BIG /\ small' = small \* 逻辑同上
EmptySmallJug == small' = 0 /\ big' = big \* 逻辑同上
EmptyBigJug == big' = 0 /\ small' = small \* 逻辑同上
Min(m,n) == IF m < n THEN m ELSE n \* 定义一个取小函数
SmallToBig == big' = Min(big + small, BIG) /\ small' = small - (big' - big)
\* small桶倒入big桶时,有可能溢出,因此需要判断一下
\* 对于big桶,if small+big < BIG,THEN big' = big + small ELSE BIG
\* 对于small桶,剩余水为减去倒入到big桶的量(big'-big),即 small' = small - (big'-big)
BigToSmall == small' = Min(big + small, SMALL) /\ big' = big - (small' - small) \* 逻辑同上
Next == \/ FillSmallJug
\/ FillBigJug
\/ EmptySmallJug
\/ EmptyBigJug
\/ SmallToBig
\/ BigToSmall
==================================================================
Check & Run
当定义了CONSTANT常量时,则需要在Model Overview页面的 what is the model中定义常量的值。
其他的设置不变,运行后,可以看到Error-trace中达成目标的过程。
每次运行都可以根据需要修改CONSTANT的值,如果设置的值不合理,比如BIG=4,SMALL=2,GOAL=3则不可能达成目标,也就不会有Error-trace的输出。