Zulip Chat Archive
Stream: Program verification
Topic: Transition Systems
Logan Murphy (Sep 04 2020 at 16:05):
I've been using the following definitions to represent Labelled Transition Systems and their executions. It's been fine for my needs so far, but it's cumbersome having the valid
predicate separate from the inductive definition of execution (no one would never want an invalid execution anyway). I'm hoping to find some way to incorporate the checking that a triple (s, a, s') is in the System's transition relation into the definition of execution, if that makes sense. I'm wondering if anyone here has any idea if this is possible.
import data.set
open set
structure LTS:=
(S : Type)
(A : Type)
(Rel : set (S × A × S))
inductive execution (M : LTS)
| init : M.S → execution
| cons : M.A × M.S → execution → execution
open execution
def head {M : LTS} (x : execution M) : M.S :=
execution.cases_on x (λ s,s) (λ p x', p.2)
def valid {M : LTS} : execution M → Prop
| (init s) := true
| (cons p x) := ((head x, p.fst, p.snd) ∈ M.Rel) ∧ (valid x)
notation e ∘ p := cons p e
/-
example LTS:
(s₁) --l₁--> (s₂) --l₂--> (s₃) --l₃--> (s₄)
-/
inductive states
| s₁
| s₂
| s₃
| s₄
open states
inductive labels
| l₁
| l₂
| l₃
| l₄
open labels
@[reducible]
def M1 : LTS :=
LTS.mk states labels {(s₁, l₁, s₂), (s₂, l₂, s₃), (s₃, l₃, s₄)}
notation e ∘ p := execution.cons p e
@[reducible]
def ex₀ : execution M1 := init s₁
@[reducible]
def ex₁: execution M1 := ex₀ ∘ (l₁, s₂)
@[reducible]
def ex₂: execution M1 := ex₁ ∘ (l₂, s₃)
@[reducible]
def ex₃: execution M1 := ex₂ ∘ (l₃, s₄)
#reduce ex₃
example : valid ex₃ :=
by {repeat {rw valid},repeat {rw head}, simp}
Simon Hudon (Sep 04 2020 at 16:18):
The simplest would be to define a subtype of valid executions. I think I would go for that one because internally, it allows you to separate definitions from their proofs of validity while exposing an API that bundles the two.
You may prefer to go the route of more dependent definitions. It can be worth exploring especially to understand what a pain an overly dependent definition can be. I would define it as:
inductive execution (M : LTS) : M.S -> Type
| init (head : M.S) : execution head
| cons (action : M.A) (s s' : M.S) : execution s' -> (s, action, s') \in M.Rel → execution s
def valid_execution (M : LTS) := \Sigma s, execution s
Logan Murphy (Sep 04 2020 at 16:20):
Somehow making a subtype never even occured to me. Thanks Simon
Last updated: Dec 20 2023 at 11:08 UTC