Set Implicit Arguments. Unset Strict Implicit. Import Prenex Implicits.
Ltac invs h := inversion h; subst => {h}. Section sec_traces. Context {A B : Type}.
This definition is similar to that for lazy lists from Chapter 13
of the Coq'Art book.
However, to support traces following labeled transition relations, constructors
have additional elements.
CoInductive trace : Type := | Tnil : A -> trace | Tcons : A -> B -> trace -> trace. Definition hd tr := match tr with | Tnil a => a | Tcons a b tr0 => a end. Definition trace_decompose (tr : trace) : trace := match tr with | Tnil a => Tnil a | Tcons a b tr' => Tcons a b tr' end.A, B: Typeforall tr : trace, tr = trace_decompose trby case. Qed.A, B: Typeforall tr : trace, tr = trace_decompose tr
CoInductive bisim : trace -> trace -> Prop := | bisim_nil : forall a, bisim (Tnil a) (Tnil a) | bisim_cons : forall a b tr tr', bisim tr tr' -> bisim (Tcons a b tr) (Tcons a b tr').A, B: Typeforall tr : trace, bisim tr trA, B: Typeforall tr : trace, bisim tr trA, B: Type
CIH: forall tr : trace, bisim tr trforall tr : trace, bisim tr trexact/bisim_cons/CIH. Qed.A, B: Type
CIH: forall tr : trace, bisim tr tr
a: A
b: B
tr: tracebisim (Tcons a b tr) (Tcons a b tr)A, B: Typeforall tr1 tr2 : trace, bisim tr1 tr2 -> bisim tr2 tr1A, B: Typeforall tr1 tr2 : trace, bisim tr1 tr2 -> bisim tr2 tr1A, B: Type
CIH: forall tr1 tr2 : trace, bisim tr1 tr2 -> bisim tr2 tr1forall tr1 tr2 : trace, bisim tr1 tr2 -> bisim tr2 tr1exact/bisim_cons/CIH. Qed.A, B: Type
CIH: forall tr1 tr2 : trace, bisim tr1 tr2 -> bisim tr2 tr1
a: A
b: B
tr1, tr': trace
H3: bisim tr1 tr'bisim (Tcons a b tr') (Tcons a b tr1)A, B: Typeforall tr1 tr2 tr3 : trace, bisim tr1 tr2 -> bisim tr2 tr3 -> bisim tr1 tr3A, B: Typeforall tr1 tr2 tr3 : trace, bisim tr1 tr2 -> bisim tr2 tr3 -> bisim tr1 tr3A, B: Type
CIH: forall tr1 tr2 tr3 : trace, bisim tr1 tr2 -> bisim tr2 tr3 -> bisim tr1 tr3forall tr1 tr2 tr3 : trace, bisim tr1 tr2 -> bisim tr2 tr3 -> bisim tr1 tr3exact: (bisim_cons _ _ (CIH _ _ _ H3 H4)). Qed.A, B: Type
CIH: forall tr1 tr2 tr3 : trace, bisim tr1 tr2 -> bisim tr2 tr3 -> bisim tr1 tr3
a: A
b: B
tr1, tr', tr'0: trace
H3: bisim tr1 tr'
H4: bisim tr' tr'0bisim (Tcons a b tr1) (Tcons a b tr'0)A, B: Typeforall tr0 tr1 : trace, bisim tr0 tr1 -> hd tr0 = hd tr1by move => tr0 tr1 []. Qed.A, B: Typeforall tr0 tr1 : trace, bisim tr0 tr1 -> hd tr0 = hd tr1
CoFixpoint trace_append (tr tr' : trace) : trace := match tr with | Tnil a => tr' | Tcons a b tr0 => Tcons a b (trace_append tr0 tr') end. #[local] Infix "+++" := trace_append (at level 60, right associativity).A, B: Typeforall (a : A) (tr : trace), Tnil a +++ tr = trA, B: Typeforall (a : A) (tr : trace), Tnil a +++ tr = trA, B: Type
a: A
tr: traceTnil a +++ tr = trby case tr. Qed.A, B: Type
a: A
tr: tracetrace_decompose (Tnil a +++ tr) = trA, B: Typeforall (a : A) (b : B) (tr tr' : trace), Tcons a b tr +++ tr' = Tcons a b (tr +++ tr')A, B: Typeforall (a : A) (b : B) (tr tr' : trace), Tcons a b tr +++ tr' = Tcons a b (tr +++ tr')A, B: Type
a: A
b: B
tr, tr': traceTcons a b tr +++ tr' = Tcons a b (tr +++ tr')by case tr. Qed.A, B: Type
a: A
b: B
tr, tr': tracetrace_decompose (Tcons a b tr +++ tr') = Tcons a b (tr +++ tr')A, B: Typeforall tr1 tr2 tr3 tr4 : trace, bisim tr1 tr2 -> bisim tr3 tr4 -> bisim (tr1 +++ tr3) (tr2 +++ tr4)A, B: Typeforall tr1 tr2 tr3 tr4 : trace, bisim tr1 tr2 -> bisim tr3 tr4 -> bisim (tr1 +++ tr3) (tr2 +++ tr4)A, B: Type
CIH: forall tr1 tr2 tr3 tr4 : trace, bisim tr1 tr2 -> bisim tr3 tr4 -> bisim (tr1 +++ tr3) (tr2 +++ tr4)forall tr1 tr2 tr3 tr4 : trace, bisim tr1 tr2 -> bisim tr3 tr4 -> bisim (tr1 +++ tr3) (tr2 +++ tr4)A, B: Type
CIH: forall tr1 tr2 tr3 tr4 : trace, bisim tr1 tr2 -> bisim tr3 tr4 -> bisim (tr1 +++ tr3) (tr2 +++ tr4)
tr1, tr2, tr3, tr4: trace
a1: A
Hbs2: bisim tr3 tr4bisim (Tnil a1 +++ tr3) (Tnil a1 +++ tr4)A, B: Type
CIH: forall tr1 tr2 tr3 tr4 : trace, bisim tr1 tr2 -> bisim tr3 tr4 -> bisim (tr1 +++ tr3) (tr2 +++ tr4)
tr1, tr2, tr3, tr4: trace
a1: A
b1: B
tr1', tr2': trace
Hbs1': bisim tr1' tr2'
Hbs2: bisim tr3 tr4bisim (Tcons a1 b1 tr1' +++ tr3) (Tcons a1 b1 tr2' +++ tr4)A, B: Type
CIH: forall tr1 tr2 tr3 tr4 : trace, bisim tr1 tr2 -> bisim tr3 tr4 -> bisim (tr1 +++ tr3) (tr2 +++ tr4)
tr1, tr2, tr3, tr4: trace
a1: A
Hbs2: bisim tr3 tr4bisim (Tnil a1 +++ tr3) (Tnil a1 +++ tr4)A, B: Type
CIH: forall tr1 tr2 tr3 tr4 : trace, bisim tr1 tr2 -> bisim tr3 tr4 -> bisim (tr1 +++ tr3) (tr2 +++ tr4)
tr1, tr2, tr3, tr4: trace
a1: A
b1: B
tr1', tr2': trace
Hbs1': bisim tr1' tr2'
Hbs2: bisim tr3 tr4bisim (Tcons a1 b1 tr1' +++ tr3) (Tcons a1 b1 tr2' +++ tr4)A, B: Type
CIH: forall tr1 tr2 tr3 tr4 : trace, bisim tr1 tr2 -> bisim tr3 tr4 -> bisim (tr1 +++ tr3) (tr2 +++ tr4)
tr1, tr2, tr3, tr4: trace
a1: A
Hbs2: bisim tr3 tr4bisim tr3 tr4A, B: Type
CIH: forall tr1 tr2 tr3 tr4 : trace, bisim tr1 tr2 -> bisim tr3 tr4 -> bisim (tr1 +++ tr3) (tr2 +++ tr4)
tr1, tr2, tr3, tr4: trace
a1: A
b1: B
tr1', tr2': trace
Hbs1': bisim tr1' tr2'
Hbs2: bisim tr3 tr4bisim (Tcons a1 b1 tr1' +++ tr3) (Tcons a1 b1 tr2' +++ tr4)A, B: Type
CIH: forall tr1 tr2 tr3 tr4 : trace, bisim tr1 tr2 -> bisim tr3 tr4 -> bisim (tr1 +++ tr3) (tr2 +++ tr4)
tr1, tr2, tr3, tr4: trace
a1: A
b1: B
tr1', tr2': trace
Hbs1': bisim tr1' tr2'
Hbs2: bisim tr3 tr4bisim (Tcons a1 b1 tr1' +++ tr3) (Tcons a1 b1 tr2' +++ tr4)A, B: Type
CIH: forall tr1 tr2 tr3 tr4 : trace, bisim tr1 tr2 -> bisim tr3 tr4 -> bisim (tr1 +++ tr3) (tr2 +++ tr4)
tr1, tr2, tr3, tr4: trace
a1: A
b1: B
tr1', tr2': trace
Hbs1': bisim tr1' tr2'
Hbs2: bisim tr3 tr4bisim (Tcons a1 b1 tr1' +++ tr3) (Tcons a1 b1 tr2' +++ tr4)exact/bisim_cons/CIH. Qed. End sec_traces. Infix "+++" := trace_append (at level 60, right associativity).A, B: Type
CIH: forall tr1 tr2 tr3 tr4 : trace, bisim tr1 tr2 -> bisim tr3 tr4 -> bisim (tr1 +++ tr3) (tr2 +++ tr4)
tr1, tr2, tr3, tr4: trace
a1: A
b1: B
tr1', tr2': trace
Hbs1': bisim tr1' tr2'
Hbs2: bisim tr3 tr4bisim (Tcons a1 b1 (tr1' +++ tr3)) (Tcons a1 b1 (tr2' +++ tr4))