Skip to content

Commit 87c249d

Browse files
thomaskwaringtwwar
andauthored
chore(LTS): add API for TraceEq and relatives (#617)
Follow-up to cslib#613 adding API & simplifying arguments related to trace equivalence. --- - [ ] depends on: cslib#613 --------- Co-authored-by: twwar <tom.waring@unimelb.edu.au>
1 parent 6311ef1 commit 87c249d

5 files changed

Lines changed: 177 additions & 115 deletions

File tree

Cslib/Foundations/Semantics/LTS/Basic.lean

Lines changed: 57 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,13 +78,22 @@ Definition of a multistep transition.
7878
rule. This makes working with lists of labels more convenient, because we follow the same
7979
construction. It is also similar to what is done in the `SimpleGraph` library in mathlib.)
8080
-/
81-
@[scoped grind]
81+
@[scoped grind, mk_iff]
8282
inductive MTr (lts : LTS State Label) : State → List Label → State → Prop where
8383
| refl {s : State} : lts.MTr s [] s
8484
| stepL {s1 : State} {μ : Label} {s2 : State} {μs : List Label} {s3 : State} :
8585
lts.Tr s1 μ s2 → lts.MTr s2 μs s3 →
8686
lts.MTr s1 (μ :: μs) s3
8787

88+
/-- In any zero-steps multistep transition, the origin and the derivative are the same. -/
89+
@[scoped grind .]
90+
theorem MTr.nil_eq (h : lts.MTr s1 [] s2) : s1 = s2 := by
91+
cases h
92+
rfl
93+
94+
@[simp] theorem MTr.nil_iff (s1 s2 : State) : lts.MTr s1 [] s2 ↔ s1 = s2 :=
95+
⟨nil_eq lts, fun h => h ▸ MTr.refl⟩
96+
8897
/-- Any transition is also a multistep transition. -/
8998
@[scoped grind →]
9099
theorem MTr.single {s1 : State} {μ : Label} {s2 : State} :
@@ -94,6 +103,16 @@ theorem MTr.single {s1 : State} {μ : Label} {s2 : State} :
94103
· exact h
95104
· apply MTr.refl
96105

106+
/-- A multistep transition along `μ :: μs` is a transition labelled by `μ` plus a multistep
107+
transition labelled by `μs`. -/
108+
theorem MTr.cons_iff {lts : LTS State Label} :
109+
lts.MTr s1 (μ :: μs) s2 ↔ ∃ s, lts.Tr s1 μ s ∧ lts.MTr s μs s2 := by
110+
constructor
111+
· rintro (_ | ⟨htr, hmtr⟩)
112+
exact ⟨_, htr, hmtr⟩
113+
· intro ⟨s, htr, hmtr⟩
114+
exact .stepL htr hmtr
115+
97116
/-- Any multistep transition can be extended by adding a transition. -/
98117
theorem MTr.stepR {s1 : State} {μs : List Label} {s2 : State} {μ : Label} {s3 : State} :
99118
lts.MTr s1 μs s2 → lts.Tr s2 μ s3 → lts.MTr s1 (μs ++ [μ]) s3 := by
@@ -128,11 +147,28 @@ theorem MTr.single_invert (s1 : State) (μ : Label) (s2 : State) :
128147
cases hmtr
129148
exact htr
130149

131-
/-- In any zero-steps multistep transition, the origin and the derivative are the same. -/
132-
@[scoped grind .]
133-
theorem MTr.nil_eq (h : lts.MTr s1 [] s2) : s1 = s2 := by
134-
cases h
135-
rfl
150+
/-- A 1-sized multistep transition is exactly a single transision with the given label. -/
151+
@[simp] theorem MTr.singleton_iff (s1 : State) (μ : Label) (s2 : State) :
152+
lts.MTr s1 [μ] s2 ↔ lts.Tr s1 μ s2 := ⟨MTr.single_invert lts s1 μ s2, MTr.single lts⟩
153+
154+
/-- A multistep transition over a concatenation can be split into two multistep transitions. -/
155+
theorem MTr.split {lts : LTS State Label} (h : lts.MTr s1 (μs ++ μs') s2) :
156+
∃ s, lts.MTr s1 μs s ∧ lts.MTr s μs' s2 := by
157+
induction μs generalizing s1 s2 with
158+
| nil => use s1, .refl, h
159+
| cons μ μs ih =>
160+
rw [List.cons_append] at h
161+
cases h
162+
case stepL s htr hmtr =>
163+
obtain ⟨s', hmtr', hmtr''⟩ := ih hmtr
164+
use s', .stepL htr hmtr', hmtr''
165+
166+
/-- Multistep-transitions over `μs ++ μs'` are exactly multistep transitions over `μs` and `μs'`
167+
with a common end & start state (respectively). -/
168+
theorem MTr.append_iff : lts.MTr s1 (μs ++ μs') s2 ↔ ∃ s, lts.MTr s1 μs s ∧ lts.MTr s μs' s2 := by
169+
refine ⟨MTr.split, ?_⟩
170+
intro ⟨_, h, h'⟩
171+
exact h.comp lts h'
136172

137173
/-- A state `s1` can reach a state `s2` if there exists a multistep transition from
138174
`s1` to `s2`. -/
@@ -167,6 +203,21 @@ class Deterministic (lts : LTS State Label) where
167203
deterministic (s1 : State) (μ : Label) (s2 s3 : State) :
168204
lts.Tr s1 μ s2 → lts.Tr s1 μ s3 → s2 = s3
169205

206+
theorem Deterministic.eq_of_tr {lts : LTS State Label} [lts.Deterministic]
207+
(htr : lts.Tr s1 μ s2) (htr' : lts.Tr s1 μ s2') : s2 = s2' :=
208+
Deterministic.deterministic s1 μ s2 s2' htr htr'
209+
210+
/-- In a deterministic lts, multistep transitions with a given start state and trace reach a unique
211+
end state. -/
212+
theorem Deterministic.eq_of_mTr {lts : LTS State Label} [lts.Deterministic]
213+
(hmtr : lts.MTr s1 μs s2) (hmtr' : lts.MTr s1 μs s2') : s2 = s2' := by
214+
induction μs generalizing s1 s2 s2' with
215+
| nil => grind
216+
| cons μ μs ih =>
217+
rcases hmtr with (_ | ⟨htr, hmtr⟩); rcases hmtr' with (_ | ⟨htr', hmtr'⟩)
218+
rw [eq_of_tr htr htr'] at hmtr
219+
exact ih hmtr hmtr'
220+
170221
/-- The `μ`-image of a state `s` is the set of all `μ`-derivatives of `s`. -/
171222
@[scoped grind =]
172223
def image (s : State) (μ : Label) : Set State := { s' : State | lts.Tr s μ s' }

Cslib/Foundations/Semantics/LTS/Bisimulation.lean

Lines changed: 22 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ module
99
public import Cslib.Foundations.Relation.Domain
1010
public import Cslib.Foundations.Semantics.LTS.Simulation
1111
public import Cslib.Foundations.Semantics.LTS.TraceEq
12+
public import Mathlib.Tactic.TFAE
1213

1314
/-! # Bisimulation and Bisimilarity
1415
@@ -183,6 +184,10 @@ instance : IsEquiv State (HomBisimilarity lts) where
183184
symm _ _ := Bisimilarity.symm
184185
trans _ _ _ := Bisimilarity.trans
185186

187+
/-- Bisimulation implies simulation equivalence. -/
188+
theorem IsBisimulation.simulationEquiv (h : IsBisimulation lts₁ lts₂ r) (hrel : r s₁ s₂) :
189+
s₁ ≤≥[lts₁,lts₂] s₂ := ⟨⟨r, hrel, h.isSimulation⟩, flip r, hrel, h.inv.isSimulation⟩
190+
186191
/-- The union of two bisimulations is a bisimulation. -/
187192
@[scoped grind .]
188193
theorem IsBisimulation.sup (hrb : IsBisimulation lts₁ lts₂ r) (hsb : IsBisimulation lts₁ lts₂ s) :
@@ -302,30 +307,16 @@ theorem IsBisimulationUpTo.isBisimulation (h : IsBisimulationUpTo lts₁ lts₂
302307

303308
/-- If two states are related by a bisimulation, they can mimic each other's multi-step
304309
transitions. -/
305-
theorem IsBisimulation.bisim_trace
306-
(hb : IsBisimulation lts₁ lts₂ r) (hr : r s₁ s₂) :
310+
theorem IsBisimulation.bisim_trace (hb : IsBisimulation lts₁ lts₂ r) (hr : r s₁ s₂) :
307311
∀ μs s₁', lts₁.MTr s₁ μs s₁' → ∃ s₂', lts₂.MTr s₂ μs s₂' ∧ r s₁' s₂' :=
308312
hb.isSimulation.sim_trace hr
309313

310314
/-! ## Relation to trace equivalence -/
311315

312316
/-- Any bisimulation implies trace equivalence. -/
313317
@[scoped grind =>]
314-
theorem IsBisimulation.traceEq
315-
(hb : IsBisimulation lts₁ lts₂ r) (hr : r s₁ s₂) :
316-
s₁ ~tr[lts₁,lts₂] s₂ := by
317-
ext μs
318-
constructor
319-
case mp =>
320-
intro h
321-
obtain ⟨s₁', h⟩ := h
322-
obtain ⟨s₂', hmtr⟩ := IsBisimulation.bisim_trace hb hr μs s₁' h
323-
use s₂', hmtr.1
324-
case mpr =>
325-
intro h
326-
obtain ⟨s₂', h⟩ := h
327-
obtain ⟨s₁', hmtr⟩ := IsBisimulation.bisim_trace hb.inv hr μs s₂' h
328-
use s₁', hmtr.1
318+
theorem IsBisimulation.traceEq (hb : IsBisimulation lts₁ lts₂ r) (hr : r s₁ s₂) :
319+
s₁ ~tr[lts₁,lts₂] s₂ := (hb.simulationEquiv hr).traceEq
329320

330321
/-- Bisimilarity is included in trace equivalence. -/
331322
@[scoped grind .]
@@ -412,30 +403,30 @@ theorem IsBisimulation.deterministic_traceEq_isBisimulation
412403
[lts₁.Deterministic] [lts₂.Deterministic] :
413404
(IsBisimulation lts₁ lts₂ (TraceEq lts₁ lts₂)) := by
414405
rw [IsBisimulation.isSimulation_iff, TraceEq.flip_eq]
415-
exact ⟨TraceEq.deterministic_isSimulation, TraceEq.deterministic_isSimulation
406+
exact ⟨Deterministic.isSimulation_traceEq, Deterministic.isSimulation_traceEq
416407

417408
/-- In deterministic LTSs, trace equivalence implies bisimilarity. -/
418409
theorem Bisimilarity.deterministic_traceEq_bisim {lts₁ : LTS State₁ Label} {lts₂ : LTS State₂ Label}
419410
[lts₁.Deterministic] [lts₂.Deterministic] (h : s₁ ~tr[lts₁,lts₂] s₂) :
420411
(s₁ ~[lts₁,lts₂] s₂) := by
421-
exists TraceEq lts₁ lts₂
422-
constructor
423-
case left =>
424-
exact h
425-
case right =>
426-
apply IsBisimulation.deterministic_traceEq_isBisimulation
412+
use TraceEq lts₁ lts₂, h, IsBisimulation.deterministic_traceEq_isBisimulation
413+
414+
/-- In a deterministic lts, bisimilarity, trace equivalence, and simulation equivalence are
415+
equivalent to one-another. -/
416+
theorem Deterministic.bisim_tfae {lts₁ : LTS State₁ Label} {lts₂ : LTS State₂ Label}
417+
[lts₁.Deterministic] [lts₂.Deterministic] (s₁ : State₁) (s₂ : State₂) :
418+
[s₁ ~[lts₁,lts₂] s₂, s₁ ~tr[lts₁,lts₂] s₂, s₁ ≤≥[lts₁,lts₂] s₂].TFAE := by
419+
tfae_have 23 := Deterministic.traceEq_iff_simulationEquiv s₁ s₂
420+
tfae_have 12 := Bisimilarity.le_traceEq s₁ s₂
421+
tfae_have 21 := Bisimilarity.deterministic_traceEq_bisim
422+
tfae_finish
427423

428424
/-- In deterministic LTSs, bisimilarity and trace equivalence coincide. -/
429425
theorem Bisimilarity.deterministic_bisim_eq_traceEq
430426
{lts₁ : LTS State₁ Label} {lts₂ : LTS State₂ Label}
431427
[lts₁.Deterministic] [lts₂.Deterministic] : Bisimilarity lts₁ lts₂ = TraceEq lts₁ lts₂ := by
432-
funext s₁ s₂
433-
simp only [eq_iff_iff]
434-
constructor
435-
case mp =>
436-
apply Bisimilarity.le_traceEq
437-
case mpr =>
438-
apply Bisimilarity.deterministic_traceEq_bisim
428+
ext s₁ s₂
429+
exact (Deterministic.bisim_tfae s₁ s₂).out 0 1
439430

440431
/-- Homogeneous bisimilarity can also be characterized through symmetric simulations. -/
441432
theorem HomBisimilarity.symm_simulation :

Cslib/Foundations/Semantics/LTS/Execution.lean

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -131,11 +131,4 @@ theorem Execution.split
131131
simp [Execution]
132132
grind
133133

134-
/-- A multistep transition over a concatenation can be split into two multistep transitions. -/
135-
theorem MTr.split {lts : LTS State Label} {s0 : State} {μs1 μs2 : List Label} {s2 : State}
136-
(h : lts.MTr s0 (μs1 ++ μs2) s2) : ∃ s1, lts.MTr s0 μs1 s1 ∧ lts.MTr s1 μs2 s2 := by
137-
obtain ⟨ss, h_ss⟩ := Execution.of_mTr h
138-
have := Execution.split h_ss μs1.length
139-
grind
140-
141134
end Cslib.LTS

Cslib/Foundations/Semantics/LTS/Simulation.lean

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -89,31 +89,18 @@ theorem IsSimulation.comp
8989
(r2 : State₂ → State₃ → Prop)
9090
(h1 : IsSimulation lts₁ lts₂ r1) (h2 : IsSimulation lts₂ lts₃ r2) :
9191
IsSimulation lts₁ lts₃ (Relation.Comp r1 r2) := by
92-
simp_all only [IsSimulation]
9392
intro s₁ s2 hrc μ s₁' htr
9493
rcases hrc with ⟨sb, hr1, hr2⟩
95-
specialize h1 s₁ sb hr1 μ
96-
specialize h2 sb s2 hr2 μ
97-
have h1' := h1 s₁' htr
98-
obtain ⟨s₁'', h1'tr, h1'⟩ := h1'
99-
have h2' := h2 s₁'' h1'tr
100-
obtain ⟨s2'', h2'tr, h2'⟩ := h2'
101-
exists s2''
102-
constructor
103-
· exact h2'tr
104-
· exists s₁''
94+
obtain ⟨s₁'', h1'tr, h1'⟩ := h1 s₁ sb hr1 μ s₁' htr
95+
obtain ⟨s2'', h2'tr, h2'⟩ := h2 sb s2 hr2 μ s₁'' h1'tr
96+
use s2'', h2'tr, s₁'', h1', h2'
10597

10698
/-- Similarity is transitive. -/
10799
theorem Similarity.trans (h1 : s₁ ≤[lts₁,lts₂] s2) (h2 : s2 ≤[lts₂,lts₃] s₃) :
108100
s₁ ≤[lts₁,lts₃] s₃ := by
109101
obtain ⟨r1, hr1, hr1s⟩ := h1
110102
obtain ⟨r2, hr2, hr2s⟩ := h2
111-
exists Relation.Comp r1 r2
112-
constructor
113-
case left =>
114-
exists s2
115-
case right =>
116-
apply IsSimulation.comp r1 r2 hr1s hr2s
103+
use! Relation.Comp r1 r2, s2, hr1, hr2, IsSimulation.comp r1 r2 hr1s hr2s
117104

118105
theorem IsSimulation.sup (hr : IsSimulation lts₁ lts₂ r)
119106
(hs : IsSimulation lts₁ lts₂ s) : IsSimulation lts₁ lts₂ (r ⊔ s) := by

0 commit comments

Comments
 (0)