CTL模型检测的问题表示为,给定一个TS模型和一个CTL公式 ϕ \phi ϕ,如何判断 T S ⊨ ϕ TS\vDash \phi TS⊨ϕ是否成立?
CTL模型检测的方法就和前面不太一样了,我们需要从新的角度进行思考
我们的方法是:
- 递归地计算 S a t ( ϕ ) = { s ∈ S ∣ s ⊨ ϕ } Sat(\phi)=\{s\in S|s\vDash\phi\} Sat(ϕ)={s∈S∣s⊨ϕ}
- 检查是不是所有的初始状态都属于 S a t ( ϕ ) Sat(\phi) Sat(ϕ),即 S 0 ⊆ S a t ( ϕ ) S_{0}\subseteq Sat(\phi) S0⊆Sat(ϕ)
首先我们先来介绍一个需要用到的概念
存在范式(Existential normal form)
CTL公式
ϕ
\phi
ϕ的存在范式定义为
ϕ
:
:
=
true | a |
ϕ
1
∧
ϕ
2
|
¬
ϕ
|
∃
◯
ϕ
|
∃
(
ϕ
1
U
ϕ
2
)
|
∃
□
ϕ
\phi::=\text{true | a | }\phi_{1}\wedge\phi_{2}\text{ | }\lnot\phi\text{ | }\exist\bigcirc\phi\text{ | }\exist(\phi_{1}U\phi_{2})\text{ | }\exist\Box\phi
ϕ::=true | a | ϕ1∧ϕ2 | ¬ϕ | ∃◯ϕ | ∃(ϕ1Uϕ2) | ∃□ϕ
就是说,如果一个CTL公式是一个存在范式,那么它由命题公式以及这几个符号所组成: ¬ , ∧ , ∃ ◯ , ∃ U , ∃ □ \lnot,\wedge,\exist\bigcirc,\exist\ U,\exist\Box ¬,∧,∃◯,∃ U,∃□
我们有如下结论
对于任意一个CTL公式,都存在一个存在范式与之等价
CTL模型检测
算法流程
对于一个CTL公式 ϕ \phi ϕ,我们先将其转化为一个存在范式
接下来,我们采用的方式递归地自底向上的计算方式:
1、建立一棵CTL公式
ϕ
\phi
ϕ的语法分析树
2、从这棵树的叶子节点,分别计算每个叶子节点的可满足集,即计算Sat(a)
3、然后向上走到上一层的节点中,对这些个节点进行可满足集的计算
4、重复上面的步骤,直到走到根节点,并最终计算根节点的可满足集(其实这么一层层走上去,到了根节点计算的就是
S
a
t
(
ϕ
)
Sat(\phi)
Sat(ϕ))
下面我们来看看应该如何着手进行模型检测
现在有一个CTL公式 ϕ = ∃ ◯ a ∨ ( b U ¬ c ) \phi=\exist\bigcirc a\vee(bU\lnot c) ϕ=∃◯a∨(bU¬c)
首先将这个公式解析成一棵语法树
我们先从叶子节点出发,自底向上开始递归,这颗语法树的叶子节点是a,b和c,所以我们就先计算Sat(a),Sat(b),Sat(c)
计算完叶子节点之后,我们就开始叶子节点的上一层,我们看到a的上一层是
∃
◯
\exist\bigcirc
∃◯,所以我们将这个公式和a结合记为
ϕ
1
\phi_{1}
ϕ1,然后开始计算
S
a
t
(
ϕ
1
)
Sat(\phi_{1})
Sat(ϕ1)
叶子节点的上一层计算还没有结束,c的上一层是
¬
\lnot
¬,将其与c结合,我们第二步就开始计算
S
a
t
(
¬
c
)
Sat(\lnot c)
Sat(¬c)
看到b的上一层是 ∃ U \exist U ∃U,不过它是基于b和 ¬ c \lnot c ¬c这两个公式,所以将其记为 ϕ 2 \phi_{2} ϕ2,第三步就开始计算 S a t ( ϕ 2 ) Sat(\phi_{2}) Sat(ϕ2)
计算完叶子节点的上一层了,那么接下来就是接着往上计算,这个例子中再上一层就是根节点了,我们将 ϕ 1 \phi_{1} ϕ1和 ϕ 2 \phi_{2} ϕ2用命题公式符号 a 1 a_{1} a1和 a 2 a_{2} a2进行替换,最终整个公式转换成 a 1 ∨ a 2 a_{1}\vee a_{2} a1∨a2,那么 S a t ( ϕ ) = S a t ( a 1 ) ∪ S a t ( a 2 ) Sat(\phi)=Sat(a_{1})\cup Sat(a_{2}) Sat(ϕ)=Sat(a1)∪Sat(a2),到此就完成了 S a t ( ϕ ) Sat(\phi) Sat(ϕ)的计算,有了 S a t ( ϕ ) Sat(\phi) Sat(ϕ),就可以看看是否所有的初始状态都在 S a t ( ϕ ) Sat(\phi) Sat(ϕ)里面,到此CTL模型检测的流程结束。
可满足集的计算
在上面我们只是走完了整个CTL模型检测的流程,并没有讲述特别多的细节,特别是这个可满足集的计算,Sat(a)这玩意儿究竟是怎么计算的呢?下面给出它的计算方法:
- S a t ( t r u e ) = S Sat(true)=S Sat(true)=S
- S a t ( a ) = { s ∈ S ∣ a ∈ L ( s ) } Sat(a)=\{s\in S|a\in L(s)\} Sat(a)={s∈S∣a∈L(s)},对于任意a∈AP(还记得么L是标签函数)
- S a t ( ϕ ∧ ψ ) = S a t ( ϕ ) ∩ S a t ( ψ ) Sat(\phi\wedge\psi)=Sat(\phi)\cap Sat(\psi) Sat(ϕ∧ψ)=Sat(ϕ)∩Sat(ψ)
- S a t ( ¬ ϕ ) = S ∖ S a t ( ϕ ) Sat(\lnot\phi)=S\setminus Sat(\phi) Sat(¬ϕ)=S∖Sat(ϕ)
- S a t ( ∃ ◯ ϕ ) = { s ∈ S ∣ P o s t ( s ) ∩ S a t ( ϕ ) ≠ ∅ } Sat(\exist\bigcirc\phi)=\{s\in S|Post(s)\cap Sat(\phi)\neq\varnothing\} Sat(∃◯ϕ)={s∈S∣Post(s)∩Sat(ϕ)=∅}
这几个还算比较直观,我们知道存在范式还有几个符号 ∃ U , ∃ □ \exist U,\exist\Box ∃U,∃□,这俩就比较麻烦了,让我们慢慢来
首先是计算这个
S
a
t
(
∃
a
U
b
)
Sat(\exist aUb)
Sat(∃aUb),假设它返回的状态集合为T
,它的元素为:
(1)
S
a
t
(
b
)
⊆
T
Sat(b)\subseteq T
Sat(b)⊆T(就是说Sat(b)代表的状态在T里面)
(2)
s
∈
S
a
t
(
a
)
and
P
o
s
t
(
s
)
∩
T
≠
∅
implise
s
∈
T
s\in Sat(a)\text{ and } Post(s)\cap T\neq\varnothing\text{ implise }s\in T
s∈Sat(a) and Post(s)∩T=∅ implise s∈T(就是说如果s是Sat(a)中的状态,并且s能够经过有限次的转化能够转变为Sat(b)中的状态,那么s就在T里面)
来看一下它的算法流程
假设这个大圈表示一个TS系统,我们这个算法先要从Sat(b)所代表的集合开始,Sat(b)就是所有满足b的状态的集合,现在先令T=Sat(b),看看这边的示例图,Sat(b)有俩状态,现在我们把它们称为T
然后,我们去寻找那些属于Sat(a)的状态,并且如果有状态s∈Sat(a),并且s经过一步的转换可以达到Sat(b)的状态,那么就把这些个状态加入到T,T=TU{s},图中看到第一个红色的状态∈Sat(a),又可以经过一步到达T,所以把它加入。
注意,现在的T已经扩大了,因为刚刚加入了一个元素,接下来继续找找,有没有状态属于Sat(a),并且能够一步转换为T中的状态,如有过就加入,就这样递归下去,直到找到所有属于Sat(a)并且经过有限次转化,能够成为Sat(b)中状态的状态。
用伪码来描述这个过程:
然后是这个 ∃ □ \exist\Box ∃□,这个感觉和上面那个有点相反的感觉,上面的是一个个添加,这里是一个个删除
S
a
t
(
∃
□
ψ
)
Sat(\exist\Box\psi)
Sat(∃□ψ),它返回的状态集合为T:
(1)
T
⊆
S
a
t
(
ψ
)
T\subseteq Sat(\psi)
T⊆Sat(ψ)(就是说T里面的状态都属于
S
a
t
(
ψ
)
Sat(\psi)
Sat(ψ))
(2)
s
∈
T
implies
P
o
s
t
(
s
)
∩
T
≠
∅
s\in T\text{ implies } Post(s)\cap T\neq\varnothing
s∈T implies Post(s)∩T=∅(如果s在T里面,那么s的后继中没有状态在T里面)
算法流程:
先让
T
=
S
a
t
(
ψ
)
T=Sat(\psi)
T=Sat(ψ)
我们看到现在有这么三个状态属于
S
a
t
(
ψ
)
Sat(\psi)
Sat(ψ),最下面的那个状态有后继还是属于T,所以我们就把这个后继从T中删除就可以了
用伪码来描述这个过程就是这样子的:
至此Sat的计算也讲解完毕。
CTL模型检测的复杂度
CTL模型检测的时间复杂度为
O
(
s
i
z
e
(
T
S
)
⋅
∣
ϕ
∣
)
O(size(TS)·|\phi|)
O(size(TS)⋅∣ϕ∣)