Lvc.IL.Events

Require Import List.
Require Export Util Relations Relations2 Val Exp AutoIndTac.

Set Implicit Arguments.

Definition external := nat.

Inductive extern :=
  ExternI {
      extern_fnc : external;
      extern_args : list val;
      extern_res : val
    }.

Inductive event :=
  | EvtExtern (call:extern)

  | EvtTau.

Definition internally_deterministic {X : Type} (R : XeventXProp)
:= x y x1 x2, R x EvtTau x1R x y x2x1 = x2 y = EvtTau.

Definition externally_determined {X : Type} (R : XeventXProp)
:= x e x1 x2, R x e x1R x e x2x1 = x2.

Definition filter_tau (o:event) (L:list event) : list event :=
  match o with
      | EvtTauL
      | ee :: L
  end.

Lemma filter_tau_nil evt B
 : (filter_tau evt nil ++ B)%list = filter_tau evt B.

Lemma filter_tau_app evt A B
 : (filter_tau evt A ++ B)%list = filter_tau evt (A ++ B).

Inductive plus2 (X : Type) (R : XeventXProp)
: Xlist eventXProp :=
  plus2O x y el
  : R x y
    → el = (filter_tau y nil)
    → plus2 R x el
| plus2S x y yl z el
  : R x y
    → el = (filter_tau y yl)
    → plus2 R yl z
    → plus2 R x el z.

Inductive star2 (X : Type) (R : XeventXProp) : Xlist eventXProp :=
    star2_refl : x : X, star2 R x nil x
  | S_star2 : y x yl z, R x y star2 R yl zstar2 R x (filter_tau y yl) z.

Lemma star2_plus2_plus2
     : (X : Type) R (x y z : X) A B,
       star2 R x A yplus2 R y B zplus2 R x (A++B) z.

Lemma star2_trans
 : (X : Type) R (x y z : X) A B,
       star2 R x A ystar2 R y B zstar2 R x (A++B) z.

Lemma plus2_destr_nil
: (X : Type) R (x z : X),
    plus2 R x nil z y : X, R x EvtTau y star2 R y nil z.

Lemma star2_plus2
: (X : Type) (R: XeventXProp) (x y z : X),
    R x EvtTau ystar2 R y nil zplus2 R x nil z.

Lemma star2_reach X (R:XeventXProp) σ1 σ2a σ2b
: star2 R σ1 nil σ2a
  → star2 R σ1 nil σ2b
  → internally_deterministic R
  → (star2 R σ2a nil σ2b star2 R σ2b nil σ2a).

Lemma star2_reach_normal X (R:XeventXProp) σ1 σ2a σ2b
: star2 R σ1 nil σ2a
  → star2 R σ1 nil σ2b
  → internally_deterministic R
  → normal2 R σ2a
  → star2 R σ2b nil σ2a.

Lemma star2_reach_normal2 X (R:XeventXProp) σ1 σ2a σ2b
: star2 R σ1 nil σ2a
  → star2 R σ1 nil σ2b
  → internally_deterministic R
  → normal2 R σ2a
  → normal2 R σ2b
  → σ2a = σ2b.

Lemma plus2_reach X (R:XeventXProp) σ1 σ2a σ2b
: plus2 R σ1 nil σ2a
  → plus2 R σ1 nil σ2b
  → internally_deterministic R
  → (star2 R σ2a nil σ2b star2 R σ2b nil σ2a).

Inductive star2n (X : Type) (R : XeventXProp) : natXlist eventXProp :=
    star2n_refl : x : X, star2n R 0 x nil x
  | S_star2n n : y x yl z,
                   R x y
                   → star2n R n yl z
                   → star2n R (S n) x (filter_tau y yl) z.

Inductive plus2n (X : Type) (R : XeventXProp)
: natXlist eventXProp :=
  plus2nO x y el
  : R x y
    → el = (filter_tau y nil)
    → plus2n R 0 x el
| plus2nS n x y yl z el
  : R x y
    → el = (filter_tau y yl)
    → plus2n R n yl z
    → plus2n R (S n) x el z.

Lemma plus2_plus2n X (R: XeventXProp) x A y
: plus2 R x A y
  → n, plus2n R n x A y.

Lemma star2n_star2 X (R: XeventXProp) x A y n
: star2n R n x A y
  → star2 R x A y.

Lemma plus2n_star2n X (R: XeventXProp) x A y n
: plus2n R n x A y
  → star2n R (S n) x A y.

Lemma star2_star2n X (R: XeventXProp) x A y
: star2 R x A y
  → n, star2n R n x A y.

Lemma star2n_reach X (R:XeventXProp) σ1 σ2a σ2b n
: star2n R n σ1 nil σ2a
  → star2n R σ1 nil σ2b
  → internally_deterministic R
  → (star2n R (-n) σ2a nil σ2b star2n R (n-) σ2b nil σ2a).

Lemma plus2_star2 X R (x y:X) A
: plus2 R x A y
  → star2 R x A y.

Lemma star2_normal X R (x y:X)
  : star2 R x nil y
    → normal2 R x
    → x = y.

Lemma star2_reach_silent_step (X : Type) (R:XeventXProp) (x y z : X)
: R x EvtTau y
  → star2 R x nil z
  → internally_deterministic R
  → x = z star2 R y nil z.