相关页面
反库所Anti-places/限定库所limit places,
队列Queues/堆栈stacks
引言
CPN Tools 并不直接支持禁止弧. 但是它可以模拟禁止弧的行为.至少有两种方法可以达到这个目的.
一种方法是使用列表lists. 这种方法有些麻烦,
但是可以用于所有情况. 禁止弧的模拟也可以使用反库所anti-places.
这种方法较为简单,
但是它只能用于跟禁止弧相连的库所的令牌数量是有限的情况下.
示例
这个网络模型是一个简单的生产者/消费者系统.
生产者 (没有详细建模)
发送包到网络上.
如果消费者准备好, 那么它就能接收包,
并处理包,然后处于准备好状态 (蓝色环). 如果网络上没有包,
消费者就可以进入休眠状态, 然后被唤醒 (褐色环).
问题出现在“网络上没有包”的情况下.
这可以使用禁止弧 (加粗红色弧)来建模. 哎,CPN Tools
并不支持 ...
使用列表Lists
一种方法是使用列表lists来克服 CPN
Tools不支持禁止弧这一不足.
要模拟禁止弧,主要需要将颜色类型比如从`T'改变为
`list T', 将所有的输入弧 (对库所而言) 加进列表中,
而且所有的输出弧必须从列表中移出一个随机元素 (并将列表返回库所).
原来的禁止弧就变成了一个双向弧, 它移走 (再加入) 空列表.
上面的例子做了这样的改变后,
结果变为:
声明的改变
- 添加颜色类型 "PACKAGESs", 定义为 "list PACKAGE".
- 创建新类型PACKAGEs的两个变量, "ps" 和 "rest".
- 添加一个新函数 "pick", 它在给定的列表下,
从列表中返回一个随机元素及相应的列表剩余部分(如果这个随机元素存在的话).
如果这个随机元素不存在,就返回 NONE.
这个函数可以用于所有类型,
所以如果你需要用列表lists创建禁止弧,
你可以直接复制这个函数.
相关库所的改变
- 将库所的颜色类型从 "PACKAGE" 改为 "PACKAGEs".
- 库所的初始标识变为一个令牌的列表;
在本例中最初的初始标识是空标识, 这里用空列表"[]"来代替.
假如最初的初始标识是 "1`1++2`4", 就要将其改变为 "[1, 4, 4]".
输入弧
输入弧要像对堆栈stack一样来处理.
- 将弧的注入式从 "p" 改为 "p::ps", 其中 "p"
属于类型 "PACKAGE" , "ps" 属于类型 "PACKAGEs"
- 添加一个相反方向的新弧, 其注入式为 "ps"
输出弧
输出弧相对于队列或堆栈要复杂一些,
因为本例必须要选择一个随机元素.
- 将原来的输出弧的注入式从 "p" 改为 "ps"
(也既是说选择所有的元素,而不是选择一个任意元素)
- 加入一个新弧, 它简单的将 "rest" 送回该库所.
这个变量属于类型 "PACKAGEs", 也就是,
它和输入弧的注入式是相同的.
现在出现两个问题: 我们先前使用的变量 "p"
不在被设定一个特定值,而且新引进的变量 "rest"
也不被设定为特定值.
这时我们选择在输出变迁的警卫函数中设定两个变量的值.
- 将变迁的警卫函数改为 "[SOME (p, rest) = pick ps]".
变迁要被触发的话, 必须保证这个警卫函数的值为 true.
首先, "pick" 函数一定要返回 "SOME <something>",
而不能是 "NONE", 所以如果 "ps"
是空列表的话, 就不可能满足警卫函数的值为 true. 其次,
我们将变量 "p" 的值设为"pick"函数返回值的第一个元素,
它是 "ps"列表中的一个随机元素, 并将变量 "rest"的值设为"ps"列表的剩余元素.
禁止弧
最后我们必须在禁止弧上输入一个正确的注入式.
- 在禁止弧上输入注入式 "[]"
- 将禁止弧改成一个双向弧
这样连接于禁止弧上的变迁就只有当其输入库所是空列表时才能触发,
这正是禁止弧预期的行为.
使用反库所
基于列表的禁止弧解决办法较为复杂,
而且在有些情况下并不需要使用列表.
如果相关库所的令牌数量只能是1的话,添加一个反库所anti-place
并加入一个双向弧(它从反库所中移走并加入反库所所有的令牌),
会使禁止弧的实现更容易一些.
在上面的例子中,
我们可以看到网络中至多有 4 个令牌,
所以反库所方法可以使用在这个例子. 反库所加入之后,我们可以得到:
首先我们发现对相关库所的任意绑定值,在这个例子中,绑定值为 5.
(同样可以选择 4, 7, 或 1000000 等等).
添加一个反库所,
并将这个库所变为一个有限容量的库所,
关于有限容量的库所请参见 here.
现在就很容易地添加禁止弧:
- 添加一条弧从反库所到变迁
- 添加弧注入式 "5`e", 其中 "5"
就是上面所选择的限制值.
如果这个库所先前就有绑定值,
那么添加的反库所并不改变它的行为,
而且这个构造也是正确的.
实例
这篇文档所描述的模型可以被下载: