1- structure Trace where
2- n_pred: Nat
1+ structure Trace (n_pred: Nat) where
32 length: Nat
43 predicates : Vector (Vector Bool length) n_pred
54deriving Repr
65
7-
86/-- LTL Formulas in NNF -/
97inductive Formula n_pred
108 | Var : Fin n_pred -> (neg: Bool) -> Formula n_pred -- neg: Whether the variable is negated
@@ -15,30 +13,80 @@ inductive Formula n_pred
1513 | Or : Formula n_pred -> Formula n_pred -> Formula n_pred
1614 | And : Formula n_pred -> Formula n_pred -> Formula n_pred
1715 | Until : Formula n_pred -> Formula n_pred -> Formula n_pred
16+ deriving DecidableEq
1817
1918namespace Formula
2019
21- def eval_aux (t: Trace ) (phi: Formula t.n_pred ) (i: Fin t.length): Prop :=
20+ def eval_aux (phi: Formula n ) (t: Trace n ) (i: Fin t.length): Prop :=
2221 match phi with
2322 | Var v neg => xor t.predicates[v][i] neg
24- | Next psi => if h: i < t.length - 1 then
25- eval_aux t psi ⟨i.val + 1 , by omega⟩
26- else
27- False
28- | WeakNext psi => if h: i < t.length - 1 then
29- eval_aux t psi ⟨i.val + 1 , by omega⟩
30- else
31- True
32- | Globally psi => ∀ j, j ≥ i → eval_aux t psi j
33- | Finally psi => ∃ j, j ≥ i ∧ eval_aux t psi j
34- | Or psi1 psi2 => (eval_aux t psi1 i) ∨ (eval_aux t psi2 i)
35- | And psi1 psi2 => (eval_aux t psi1 i) ∧ (eval_aux t psi2 i)
23+ | Next psi => if h: i < t.length - 1 then eval_aux psi t ⟨i.val + 1 , by omega⟩ else False
24+ | WeakNext psi => (h: i < t.length - 1 ) → eval_aux psi t ⟨i.val + 1 , by omega⟩
25+ | Globally psi => ∀ j, j ≥ i → eval_aux psi t j
26+ | Finally psi => ∃ j, j ≥ i ∧ eval_aux psi t j
27+ | Or psi1 psi2 => (eval_aux psi1 t i) ∨ (eval_aux psi2 t i)
28+ | And psi1 psi2 => (eval_aux psi1 t i) ∧ (eval_aux psi2 t i)
3629 | Until psi1 psi2 => ∃ j, j ≥ i ∧
37- (eval_aux t psi2 j) ∧
38- (∀ k, i ≤ k → k < j → eval_aux t psi1 k)
30+ (eval_aux psi2 t j) ∧
31+ (∀ k, i ≤ k → k < j → eval_aux psi1 t k)
32+
33+ def eval (phi : Formula n) (t : Trace n) : Prop :=
34+ if h : t.length > 0 then
35+ eval_aux phi t ⟨0 , h⟩
36+ else
37+ match phi with
38+ -- I guess technically, WeakNext and Globally
39+ -- are both true on empty traces, and are the only ones.
40+ | WeakNext _ | Globally _ => True
41+ | Or psi1 psi2 => eval psi1 t ∨ eval psi2 t
42+ | And psi1 psi2 => eval psi1 t ∧ eval psi2 t
43+ | _ => False
44+
45+
46+ theorem or_eval (phi psi: Formula n) (t: Trace n):
47+ (phi.Or psi).eval t ↔ phi.eval t ∨ psi.eval t := by
48+ constructor
49+ . intro h
50+ simp [eval, eval_aux] at h
51+ by_cases htl: 0 < t.length
52+ . simp [htl] at h
53+ unfold eval
54+ simp [htl]
55+ exact h
56+ . simp [htl] at h
57+ assumption
58+ . intro h
59+ rw [eval]
60+ by_cases htl: 0 < t.length
61+ all_goals simp [htl]
62+ . unfold eval at h
63+ simp [htl] at h
64+ rw [eval_aux]
65+ assumption
66+ . exact h
67+
3968
40- -- def eval (t: Trace) (phi: Formula t.n_pred) (h: t.length > 0): Bool :=
41- -- eval_aux t phi ⟨0, h⟩
69+ theorem and_eval (phi psi: Formula n) (t: Trace n):
70+ (phi.And psi).eval t ↔ phi.eval t ∧ psi.eval t := by
71+ constructor
72+ . intro h
73+ simp [eval, eval_aux] at h
74+ by_cases htl: 0 < t.length
75+ . simp [htl] at h
76+ unfold eval
77+ simp [htl]
78+ exact h
79+ . simp [htl] at h
80+ assumption
81+ . intro h
82+ rw [eval]
83+ by_cases htl: 0 < t.length
84+ all_goals simp [htl]
85+ . unfold eval at h
86+ simp [htl] at h
87+ rw [eval_aux]
88+ assumption
89+ . exact h
4290
4391
4492end Formula
0 commit comments