模拟运行中状态,比较关键的是delay的模拟
同时还有对VAR的模拟 (对所有可能出现状态的模拟、对保持和变化两种状态的模拟,排除不会出现的情况)
为了模拟运行中的状态,需要提取VAR和delay的信息,上次主要是提取VAR,这次是提取了delay和其相关的VAR
利用了Nusmv的步长特性(next语句的特点),step1 = 0: capability.var 能保证 capability.var在第一次next中不变。第一次next中step变为1,所以第二次next中 capability.var 可以正常变化。可以让nusmv状态转换变得更有序。步长变量也可用于比如出现某个状态,让step变化,作状态调整。
MODULE main
VAR
step1:{0,1};
capability.var:{state1,state2,state3};
ASSIGN
init(step1):= 0;
next(step1):= 1;
next(capability.var):=
case
step1 = 0: capability.var;
TRUE: state3;
esac;
不init三类变量 ,模拟了所有可能出现的状态,包括变化状态和不变状态
capability保持不变(capability.var==lastvar),变化(capability.var!=lastvar)
代入现有规则看是否符合实际运行状态,如:bulb检测到有人移动,会on而不是off,有人移动和bulb on捆绑 ;如果smartplug等于off,那么连接smartplug 的设备一定是off,smartplug的开关状态和连接设备的开关状态绑定。所以python要提取出连smartplug的设备和类似情况
在smv中可以如下实现,未涉及timer应该在delay前进行:
对于smartplug
switch({on,off}属性)
smart.plug = off & step = :off
对于bulb这类
switch(bulb)
TAP前半部分 & step:off
capability.var、capability.lastvar需要在前两个next保持不变,为了避免变化而引起的其它变量改变,加入如下规则可实现
step1 = 0: capability.var;
step2 = 0: capability.var;
TAP前半部分有timer作条件,VAR的修正是否在delay后执行,如何执行
oven heat且smoke!= detected:650
TAP规则里的隐含意义
以iotinspector.smv为例,该smv中有60个VAR,根据上面对VAR的分类,实际设备capability相关的有60 / 3 = 20个
设备的capability的取值范围假设为10,那么该capability对应的上一状态的取值范围也为10,delay也假设取值范围为10
那么总共需要探索30的20次方,不现实
Nusmv里有现成的next,最好在Nusmv里实现
delay的修正在第一个next。如果runin在第一个next就修正的话,会导致多倒计时,所以runin要等delay一个Next,在第二个next进行修正。step2在step1变了之后再变,可以保证状态两次不变
delay的取值:只有0和上界值。0代表不工作(包括结束);上界值代表刚开始
runind的取值。1,介于1和上界值,上界值。 1代表不工作(包括结束);介于1和上界值代表正在运行(其中上界值-2是个specification条件);上界值代表刚开始
runin参与实际的判断而不是delay,所以主要是修正runin
所以next(delay)为
MODULE RUNIN(delay)
VAR
timer:0..500;
ASSIGN
init(timer):=0;
next(timer):=
case
delay=0:0;
timer=0 & delay>0: delay;
timer>0 & delay>0: timer - 1;
TRUE: timer;
esac;
MODULE main
VAR
step1:{0,1};
step2:{0,2};
capability.var:{state1,state2,state3};
capability.lastvar:{state1,state2,state3};
delay:0..500;
runin_delay: RUNIN(delay);
ASSIGN
init(step1):= 0;
next(step1):= 1;
init(step2):= 0;
next(step2):=
case
step1 = 0: step2;
step1 = 1: 2;
esac;
next(capability.var):=
case
step1 = 0: capability.var;
step2 = 0: capability.var;
TRUE: state3;
esac;
next(capability.lastvar):=
case
step1 = 0: capability.lastvar;
step2 = 0: capability.lastvar;
TRUE:capability.var;
init(delay): 0;
next(delay):=
case
step1 = 0 & capability.var=state1 & capability.var!=capability.lastvar: 400;
step1 = 0 & capability.var=state1 & capability.var==capability.lastvar: 398;
step2 = 0: delay;
capability.var=state1 & capability.var!=capability.lastvar: 400;
runin_delay.timer=1: 0;
TRUE: delay;
esac;
如下的运行和结束不好区分:
step1 = 0 & capability.var=state1 & capability.var==capability.lastvar: 398;
step1 = 0 & capability.var=state1 & capability.var==capability.lastvar: 1;
可能的解决方法:通过python外部枚举后写入smv,枚举范围2的9次方:512,可行