我们的目标是写出一个函数,输入一个 CTL 模型和一个 Formula,输出模型中所有能 satisfy 这个 Formula 的状态集合。
fn satisfiable_states(self: &CTLModule, formula: CTLFormula)
根据 CTL 中连接词的定义,我们可以写出:
fn satisfiable_states(self: &CTLModule, formula: CTLFormula) {
match formula {
⊤ => self.S,
⊥ => ∅,
Atomic(atomic) => {s ∈ self.S | atomic is true in state s},
Not(inner_formula) => self.S - model.sat(inner_formula),
inner_formula1 ∧ inner_formula2 => model.sat(inner_formula1) ∩ model.sat(inner_formula2),
inner_formula1 ∨ inner_formula2 => model.sat(inner_formula1) ∪ model.sat(inner_formula2),
inner_formula1 → inner_formula2 => model.sat(Not(inner_formula1) ∨ inner_formula2),
// suppose we want to solve EX instead of AX, following ones are similar
AX(inner_formula) => model.sat(Not(EX(Not(inner_formula)))),
A[inner_formula1 U inner_formula2] => sat(Not(E[Not(inner_formula2) U (Not(inner_formula1) ∧ Not(inner_formula2))] ∨ EG Not(inner_formula2)))
EF(inner_formula1) => sat(E[⊤ U inner_formula1])
EG(inner_formula1) => sat(Not(AF(Not(inner_formula1))))
AG(inner_formula1) => sat(Not(EF(Not(inner_formula1))))
EX(inner_formula) => todo!(),
AF(inner_formula) => todo!(),
E[inner_formula1 U inner_formula2] => todo!(),
}
}
Now we've done the trivial cases and "merged" the other cases into three.
然后我们一个个解这三个 case。
EX
能满足 EX(inner_formula)
的状态,也就是“存在一个后继状态满足 inner_formula
” 的状态。
只需要先找出所有能满足 inner_formula
的状态,再找出他们所有的前驱状态即可。
EX(inner_formula) => {
let direct_satisfy = model.sat(inner_formula);
direct_satisfy
.map(|satisfying_state| model.predecessors(satisfying_state))
.union_all()
},
AF
能满足 AF(inner_formula)
的状态,也就是“对于所有从这个点分散出去的 branch,inner_formula 都会在某状态下成立”的状态。
首先能满足 inner_formula 的所有 state 肯定满足上述条件,然后如果某个 state 的前驱的所有后继也都满足条件,那“这个 state 的前驱”也满足条件。
AF(inner_formula) => {
let direct_satisfy = model.sat(inner_formula);
let mut current_satisfied = direct_satisfy;
let mut last_iteration_satisfied = None;
while last_iteration_satisfied != current_satisfied {
last_iteration_satisfied = Some(current_satisfied);
current_satisfied = current_satisfied.union({s ∈ self.S | forall model.successor(s), s is in current_satisfied});
}
current_satisfied
}
EU
这个 case 稍微复杂些,E[inner_formula1 U inner_formula2]
的语意是存在某个 path,使得 inner_formula1
至少成立到 inner_formula2
成立为止。
首先由于 U 对 inner_formula2
成立后 inner_formula1
是否继续成立不做要求,所以所有 inner_formula2
成立的 state 都满足条件。
接着,对于所有已知满足条件的状态,如果他的前驱能满足 inner_formula1
,那么这个状态也满足条件。
E[inner_formula1 U inner_formula2] => {
let satisfy_formula1 = model.sat(inner_formula1);
let satisfy_formula2 = model.sat(inner_formula2);
let mut current_satisfied = satisfy_formula2;
let mut last_iteration_satisfied = None;
while last_iteration_satisfied != current_satisfied {
last_iteration_satisfied = Some(current_satisfied);
current_satisfied = current_satisfied.union(model.successor(s).intersect(satisfy_formula1));
}
}
如此一来我们就完成了这整个算法。