状态机smv & 线性时序逻辑(LTL) & 分支时序逻辑(CTL)

系统结构 smv_parser,对smv_parser的结果进行分析

突发性wet,比如水泼了

  -> State: 33.7 <-
    homePresentState = present
    runinfan12.timer = 1
    runinfan27.timer = 2
    runinfan61.timer = 3
    runinalarm.timer = 3
  -> State: 33.8 <-
    homewater.waterSensor.water = wet
    fan.switchCap.switch = off
    runinfan12.timer = 0
    delayfan12 = 0
    runinfan27.timer = 1
    runinfan61.timer = 2
    runinalarm.timer = 2
  -> State: 33.9 <-
    homePresent.presenceSensor.presence = not_present
    homewater.waterSensor.water = dry
    fan.switchCap.switch = on
    homewaterState = wet
    runinfan27.timer = 0
    delayfan27 = 0
    runinfan61.timer = 1
    runinalarm.timer = 1

对目前状态机的更改问题

实际的运行状态 ⊆ 目前的状态机
1.补全了next
2.加入了对smoke、alarm
如果不加,判断条件就不能是smoke只能是runinfan61.timer=1 & fan.switchCap.switch=on
3.case顺序调换,delay是肯定调后的,状态中runin的调后目前不确定

调换后delayfan修正了,runin虽然没修正但也正常

  -> State: 1.22 <-
    homePresent.presenceSensor.presence = present
    homewater.waterSensor.water = wet
    fan.switchCap.switch = off
    runinfan12.timer = 1
    runinfan27.timer = 0
    delayfan27 = 0
    runinfan61.timer = 2
  -> State: 1.23 <-
    homePresent.presenceSensor.presence = not_present
    homewater.waterSensor.water = dry
    fan.switchCap.switch = on
    homePresentState = present
    homewaterState = wet
    runinfan12.timer = 0
    delayfan27 = 4
    runinfan61.timer = 1
  -> State: 1.24 <-
    fan.switchCap.switch = off
    homePresentState = not_present
    homewaterState = dry
    runinfan12.timer = 4
    runinfan27.timer = 4
    runinfan61.timer = 0
    delayfan61 = 0

问题:hold / is true

LTL和CTL的选择问题

快是因为复杂度原因
CTL property不能用LTL替换,比如某些情况是子树,包含多个路径
EF AG这种分析包含多个路径的子树的,只能用CTL,如果最简单的ltl逻辑enough for our purpose,只用ltl就行了
在这里插入图片描述


维基上更清楚
https://en.wikipedia.org/wiki/Linear_temporal_logic#Weak_until_and_strong_release

G ((runinfan61.timer = 2 & fan.switchCap.switch = off) -> !( F (runinfan61.timer = 2 & fan.switchCap.switch = on)))

G ((runinfan61.timer = 2 & fan.switchCap.switch = off) -> F (runinfan61.timer = 1 & fan.switchCap.switch = on)),只要找到F不为(runinfan61.timer = 1 & fan.switchCap.switch = on)的就是false,并不能满足我们的需求
!(上式)会出现timer=2并且为on

G,F限制区间问题,read always followed by green or yellow
G(color.red->X(color.green 或 yellow)) ->有当前、未来一步和未来之意?

p->q等价于非p或q
φ ↔ ψ ≡ (φ → ψ) ∧ ( ψ → φ)
->和->F有区别
一个判断当前和后续,一个只判断未后续状态
!一般用于取具体的例子

!G不等于G!
G! (runinfan61.timer=2 & fan.switchCap.switch = off) 全局的每一个状态存在! (runinfan61.timer=2 & fan.switchCap.switch = off)
等价于 !F(runinfan61.timer=2 & fan.switchCap.switch = off)


AutoTap : If @raining while @ rain.off and window.open , then window.close
check_ltlspec -p “G((weather.rain=raining)->!F(window.switch=close))” 基于下一步才变

– Loop starts here
-> State: 1.1 <-
window.switch = open
weather.rain = raining
rain.config = raining
-> State: 1.2 <-
bounded model check就可以避开初始冲突

Trace Type: Counterexample
-> State: 1.1 <-
window.switch = open
weather.rain = not_raining
-> State: 1.2 <-
weather.rain = raining
– Loop starts here
-> State: 1.3 <-
weather.rain = not_raining
-> State: 1.4 <-

Trace Type: Counterexample
-> State: 3.1 <-
window.switch = open
weather.rain = not_raining
step = 1
-> State: 3.2 <-
weather.rain = raining
step = 2
-> State: 3.3 <-
window.switch = close
step = 3
– Loop starts here
-> State: 3.4 <-
window.switch = open
-> State: 3.5 <-
window.switch = close
-> State: 3.6 <-
window.switch = open

MODULE main
  VAR
    window.switch:{open, close, uncertain};
    weather.rain:{raining,not_raining};

  ASSIGN
    init(weather.rain):=not_raining;
	
	--防止第一次,对没有TAP规则的要注意单独处理一下
    --init(window.switch):=close;
    next(window.switch):=window.switch;

5种数排列120种

MODULE main
  VAR
    window.switch:{open, close, uncertain};
    weather.rain:{raining,not_raining};
    step:1..3;
    --rain.config:{raining,not_raining};


  ASSIGN
    init(weather.rain):=not_raining;
    next(weather.rain):=
        case
            step = 2:raining;
            TRUE:{raining,not_raining};
    esac;

    init(step):=1;
    next(step):=
       case
           step != 3: step+1;
           TRUE:step;
    esac;

    init(window.switch):=open;
    next(window.switch):=
        case
            step = 1:open;
            weather.rain = raining:{open, close, uncertain};
            TRUE: window.switch;
        esac union
        case
            step = 1:open;
            weather.rain = not_raining:{open, close, uncertain};
            TRUE: window.switch;
        esac;

--check_ltlspec -p "G((weather.rain=raining)->!F(window.switch=close))"
MODULE main
  VAR
    window.switch:{open, close, uncertain};
    weather.rain:{raining,not_raining};


  ASSIGN
    init(weather.rain):=not_raining;
    next(weather.rain):=
        case
            TRUE:{raining,not_raining};
    esac;

    init(window.switch):=open;
    next(window.switch):=
        case
            weather.rain = raining:close;
            TRUE: window.switch;
        esac;



MODULE main
  VAR
    window.switch:{open, close, uncertain};
    window.switch_old:{open, close, uncertain};
    window.certain:boolean;
    temperature:0..10;
    humidity:10..20;
    flag_open:0..1;
    flag_close:0..1;


  ASSIGN
    init(temperature) := 5;
    init(humidity) := 10;

    init(window.switch) := close;
    next(window.switch):=
      case
        next(flag_open)=1 & next(flag_close)=1:uncertain;
        temperature < 5: close;
        TRUE:window.switch;
      esac union
      case
        next(flag_open)=1 & next(flag_close)=1:uncertain;
        humidity > 15 : open;
        TRUE:window.switch;
      esac;

    init(window.switch_old) := close;
    next(window.switch_old) := window.switch;

    init(flag_open) := 0;
    next(flag_open):=
      case
        temperature < 5: 1;
        TRUE:0;
      esac;

    init(flag_close) := 0;
    next(flag_close):=
      case
        humidity > 15: 1;
        TRUE:0;
      esac;


    init(window.certain) := TRUE;
    next(window.certain):=
      case
        next(flag_open) = 1 & next(flag_close) = 1: FALSE;
        TRUE:TRUE;
      esac;

-- check_ltlspec -p "G(window.certain=TRUE)"
该路径没有LOOPS
Trace Type: Counterexample
  -- Loop starts here
  -> State: 1.1 <-
    window.switch = close
    window.switch_old = close
    window.certain = TRUE
    temperature = 5
    humidity = 10
    flag_open = 0
    flag_close = 0
  -> State: 1.2 <-
    temperature = 3
    humidity = 17
  -> State: 1.3 <-
    window.switch = uncertain
    window.certain = FALSE
    temperature = 0
    humidity = 10
    flag_open = 1
    flag_close = 1
  -> State: 1.4 <-
    window.switch = close
    window.switch_old = uncertain
    window.certain = TRUE
    temperature = 7
    humidity = 13
    flag_close = 0
  -> State: 1.5 <-
    window.switch_old = close
    temperature = 5
    humidity = 10
    flag_open = 0
MODULE main
  VAR
    window.switch:{open, close, uncertain};
    window.switch_old:{open, close, uncertain};
    window.certain:boolean;
    temperature:0..10;
    t1:0..10;
    humidity:10..20;
    h1:10..20;
    flag_open:0..1;
    flag_close:0..1;
    step:1..3;


  ASSIGN
    init(temperature) := 5;
    next(temperature):=
      case
        step = 1: 3;
        TRUE:0..10;
      esac;

    init(humidity) := 10;
    next(humidity):=
      case
        step = 1: 17;
        TRUE:10..20;
      esac;
    
    --等于配置初始值
    init(t1) := 5;
    --第一次变化之后保持不变,防止生成过多无效空间
    next(t1):=
      case
        step = 1: 1..10;
        TRUE:t1;
      esac;    

    init(h1) := 15;  
    next(h1):=
      case
        step = 1: 10..19;
        TRUE:h1;
      esac;   

    init(step):=1;
    next(step):=
       case
           step != 3: step+1;
           TRUE:step;
    esac;

    init(window.switch) := close;
    next(window.switch):=
      case
        next(flag_open)=1 & next(flag_close)=1:uncertain;
        temperature < t1: close;
        TRUE:window.switch;
      esac union
      case
        next(flag_open)=1 & next(flag_close)=1:uncertain;
        humidity > h1: open;
        TRUE:window.switch;
      esac;

    init(window.switch_old) := close;
    next(window.switch_old) := window.switch;

    init(flag_open) := 0;
    next(flag_open):=
      case
        temperature < t1: 1;
        TRUE:0;
      esac;

    init(flag_close) := 0;
    next(flag_close):=
      case
        humidity > h1: 1;
        TRUE:0;
      esac;

    init(window.certain) := TRUE;
    next(window.certain):=
      case
        next(flag_open) = 1 & next(flag_close) = 1: FALSE;
        TRUE:TRUE;
      esac;

-- check_ltlspec -p "G(window.certain=TRUE)"
Trace Type: Counterexample
  -> State: 1.1 <-
    window.switch = close
    window.switch_old = close
    window.certain = TRUE
    temperature = 5
    t1 = 5
    humidity = 10
    h1 = 15
    flag_open = 0
    flag_close = 0
    step = 1
  -> State: 1.2 <-
    temperature = 3
    t1 = 1
    humidity = 17
    h1 = 11
    step = 2
  -- Loop starts here
  -> State: 1.3 <-
    temperature = 0
    humidity = 10
    flag_close = 1
    step = 3
  -> State: 1.4 <-
    temperature = 1
    humidity = 12
    flag_open = 1
    flag_close = 0
  -> State: 1.5 <-
    temperature = 0
    humidity = 10
    flag_open = 0
    flag_close = 1


在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
反例
在这里插入图片描述

一、线性时序逻辑(LTL)

在这里插入图片描述

X,U是temporal operator,不指precise time
W(weak until) (ψ U φ) ∨ G ψ 多了个G ψ
F sometimes
FG infinitely often
Realse ψ R φ。φ保持为真,直到ψ变为真(包括为真的地方)。如果ψ不会为真,则φ一直为真

the syntax of LTL
之前都是看the first letter就行
X可以看the rest of word
X(X(p2))
X(p1Up2) 在下一状态,p1Up1 = true?和p1Up2的区别是起始位置不同
X(X(p1UX(p2)))

p1 until p2 ,找到p2为true的第一个地方,在那个地方前p1 is true
在这里插入图片描述
1

true每个点都满足意味着没约束,true U p1 在某个p1为true的地方
true U ¬p1 在某个p1为flase的地方
¬(true U ¬p1)意味着无法找到某个p1为flase的地方,everywhere p1 is true

∅1→∅2 如果∅1,那么∅2
在这里插入图片描述
i can’t(¬) reach F(¬∅) sometime
G§:p is True in every state

在这里插入图片描述

每处F(∅)为true
在这里插入图片描述

在这里插入图片描述

LTL本身的定义和在状态机中的体现

在这里插入图片描述
AP-INF是所有可能,property ∅是AP-INF的一个子集,Words(∅):AP-INF中满足∅的words

在这里插入图片描述
一个是对符号的拆分一个是satisfy ∅,对复杂的直接把∅替换为一坨
在这里插入图片描述
words(∅) = σ

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

狼羊过河问题

planning problem:find a path to the goal state
在这里插入图片描述
在这里插入图片描述
check !∅,如果有反例是满足∅的

MODULE main
VAR
	man:boolean;
	goat:boolean;
	wolf:boolean;
	cabbage:boolean;
	carry:{g,w,c,0};
ASSIGN
	init(man) := FALSE;
	init(goat) := FALSE;
	init(wolf) := FALSE;
	init(cabbage) := FALSE;
	init(carry) := 0;

	--man要么在左边要么在右边
	next(man) := {TRUE,FALSE};
	--man和其它同值则可以搬运,且一次可以搬运的选项是非确定性(non-deterministic),esac union 提供了next value的non-deterministic choice
	-- carry并不是实际的,只是提供了一种选项(choose to do),因为可以呆在原地不变
	next(carry) :=  case
						man = goat:g;
						-- 确保condition exhausted
						TRUE:carry;
					esac union
					case
						man = wolf:w;
						TRUE:carry;
					esac union
					case
						man = cabbage:c;
						TRUE:carry;
					esac union 0;
	next(goat):= 	case
						-- 如果goat被carry,那么反置值表示达到另一岸
						--next(carry) = g:!goat;
						-- carry = goat但man可能呆在同一岸,随着人的位置而变化
						next(carry) = g:next(man);
						TRUE:goat;
					esac
	next(wolf):=
	next(cabbage):=
	next

LTLSPEC
!( ((goat = cabbage | goat = wolf)->man = goat) U (man & cabbage & goat & wolf) )

nusmv test.smv

trace相关的p94 - 100

4个变量和转化为可达性问题(全0到全1)

在这里插入图片描述

二、分支时序逻辑(CTL)

每个node可以是{p1}{p2}{p1,p2},如switch=ff & present = off

LTL讨论path的property
CTL讨论tree的property,一个状态机可以表示为一颗树,初始状态是根节点

E

红点并不是node,而是该node有对应的ap
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

A

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
两个符号E代表Exist,Exist a path 满足∅,A代表all path满足∅,E(F(A(G(∅)))),某个子树满足A(∅)

E mix with A

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

CTL*

state formulae
path formulae
在这里插入图片描述

LTL CTL* CTL的关系

如果系统满足LTL,则对应的树满足A(∅),LTL属于CTL的一部分
CTL property不能用LTL替换,比如某些情况是子树,包含多个路径
LTL不能用CTL实现,CTL也不能用LTL实现
在这里插入图片描述
如果最简单的ltl逻辑enough for our purpose,只用ltl就行了

CTL是CTL*限制后的

LTL CTL*的转换

如果G (runinfan61.timer=2 & fan.switchCap.switch = off),如果等于初始0,找到反例并不能说明冲突存在
–LTLSPEC G! (runinfan61.timer=2 & fan.switchCap.switch = off)
如果找到反例则说明这种情况存在

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

q1uTruth

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值