Nusmv模拟物联网TAP规则运行状态

前言

模拟运行中状态,比较关键的是delay的模拟

同时还有对VAR的模拟 (对所有可能出现状态的模拟、对保持和变化两种状态的模拟,排除不会出现的情况)

为了模拟运行中的状态,需要提取VAR和delay的信息,上次主要是提取VAR,这次是提取了delay和其相关的VAR

提出一个关键概念:步长变量step

引入1个步长变量step1,可以保证状态一次不变

利用了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;

一、模拟VAR

某个设备capability相关的VAR有3类:

  1. 设备的capability
  2. 该capability对应的上一状态
  3. 该capability对应的delay

对所有可能出现状态的模拟

不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规则里的隐含意义

二、模拟delay

方式一:Nusmv中VAR和delay init为所有取值范围 (不可行)

缺点1:会出现没有的状态,或者直接冲突的状态

缺点2:需要探索的空间太多

以iotinspector.smv为例,该smv中有60个VAR,根据上面对VAR的分类,实际设备capability相关的有60 / 3 = 20个
设备的capability的取值范围假设为10,那么该capability对应的上一状态的取值范围也为10,delay也假设取值范围为10
那么总共需要探索30的20次方,不现实

方式二:Python外部做判断、模拟 (不可行)

缺点:如果不在Nusmv里实现,判断的逻辑不好处理

Nusmv里有现成的next,最好在Nusmv里实现

方式三:引入步长变量,用于稳定状态、辅助修正

为了正确模拟运行,需要引入2个步长变量,保证状态两次不变以辅助修正

引入2个步长变量的原因:

delay的修正在第一个next。如果runin在第一个next就修正的话,会导致多倒计时,所以runin要等delay一个Next,在第二个next进行修正。step2在step1变了之后再变,可以保证状态两次不变

delay的nusmv编写

init(delay) = 0

delay的取值:只有0和上界值。0代表不工作(包括结束);上界值代表刚开始

next(delay)的编写

runind的取值。1,介于1和上界值,上界值。 1代表不工作(包括结束);介于1和上界值代表正在运行(其中上界值-2是个specification条件);上界值代表刚开始

runin参与实际的判断而不是delay,所以主要是修正runin

所以next(delay)为

  1. step1 = 0 & 满足条件(通常为变化):上界(刚开始)
  2. 之前出现过那个条件,如果状态为满足条件的保持:上界-2,或者python随机一个介于上下界的值
  3. 如果状态为保持,且为结束态: 1;因为是否结束是以runin作判断,所以确保runin=1
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,可行

你可能感兴趣的:(物联网,IoT,安全,物联网,交互,安全,系统安全,web安全)