Module K <: KNOT__HERED_PROP_OTH_REL := Knot_HeredPropOthRel(KnotInput).Definition prog := K.knot.Definition world := (prog * (store * terminationMeasure))%type.Definition instruction := instr assert.Definition stack := list instruction.Infix ";;" := instr_seq (at level 60, right associativity).Definition prog_lookup (p:prog) (l:label) : option instruction :=
  get _ (snd (unsquash p)) l.(* Safety property *)

Inductive stepstar (t:terminationMeasure) : prog -> prog -> store -> stack -> store -> stack ->  Prop :=
 | stepstar_O: forall s i p, stepstar t p p s i s i
 | stepstar_S: forall p p' p'' s i s' i' s'' i'',
              step t p p' s i s' i' -> stepstar t p' p'' s' i' s'' i'' -> stepstar t p p'' s i s'' i''.(* Safety property *)

Inductive stepstar (t:terminationMeasure) : prog -> prog -> store -> stack -> store -> stack ->  Prop :=
 | stepstar_O: forall s i p, stepstar t p p s i s i
 | stepstar_S: forall p p' p'' s i s' i' s'' i'',
              step t p p' s i s' i' -> stepstar t p' p'' s' i' s'' i'' -> stepstar t p p'' s i s'' i''.(* Safety property *)

Inductive stepstar (t:terminationMeasure) : prog -> prog -> store -> stack -> store -> stack ->  Prop :=
 | stepstar_O: forall s i p, stepstar t p p s i s i
 | stepstar_S: forall p p' p'' s i s' i' s'' i'',
              step t p p' s i s' i' -> stepstar t p' p'' s' i' s'' i'' -> stepstar t p p'' s i s'' i''.Inductive step_or_halt (t:terminationMeasure) : prog -> store -> stack -> Prop :=
  | step_or_halt_step: forall p p' r i r' i',
      step t p p' r i r' i' -> step_or_halt t p r i
  | step_or_halt_halt: forall p r,
      step_or_halt t p r nil.Inductive step_or_halt (t:terminationMeasure) : prog -> store -> stack -> Prop :=
  | step_or_halt_step: forall p p' r i r' i',
      step t p p' r i r' i' -> step_or_halt t p r i
  | step_or_halt_halt: forall p r,
      step_or_halt t p r nil.Inductive step_or_halt (t:terminationMeasure) : prog -> store -> stack -> Prop :=
  | step_or_halt_step: forall p p' r i r' i',
      step t p p' r i r' i' -> step_or_halt t p r i
  | step_or_halt_halt: forall p r,
      step_or_halt t p r nil.Definition safe (t:terminationMeasure) (p: prog) (s: store) (k: stack) :=
   forall p' s' k', stepstar t p p' s k s' k' -> step_or_halt t p' s' k'.Definition eventually_halts (t:terminationMeasure) (p:prog) (r:store) (s:stack) : Prop :=
  exists p', exists r', stepstar t p p' r s r' nil.(*****)
(* Other Stuff *)


Inductive stepN : nat -> terminationMeasure -> prog -> prog -> store -> stack -> store -> stack ->  Prop :=
 | stepN_O: forall t p s i, stepN O t p p s i s i
 | stepN_S: forall n t s i p p' p'' s' i' s'' i'',
              step t p p' s i s' i' -> stepN n t p' p'' s' i' s'' i'' -> stepN (S n) t p p'' s i s'' i''.(*****)
(* Other Stuff *)


Inductive stepN : nat -> terminationMeasure -> prog -> prog -> store -> stack -> store -> stack ->  Prop :=
 | stepN_O: forall t p s i, stepN O t p p s i s i
 | stepN_S: forall n t s i p p' p'' s' i' s'' i'',
              step t p p' s i s' i' -> stepN n t p' p'' s' i' s'' i'' -> stepN (S n) t p p'' s i s'' i''.(*****)
(* Other Stuff *)


Inductive stepN : nat -> terminationMeasure -> prog -> prog -> store -> stack -> store -> stack ->  Prop :=
 | stepN_O: forall t p s i, stepN O t p p s i s i
 | stepN_S: forall n t s i p p' p'' s' i' s'' i'',
              step t p p' s i s' i' -> stepN n t p' p'' s' i' s'' i'' -> stepN (S n) t p p'' s i s'' i''.

(* Specifications: *)
Lemma stepstar_stepN : forall t p p' s i s' i', stepstar t p p' s i s' i' -> exists n, stepN n t p p' s i s' i'.
Lemma stepN_stepstar : forall t p p' n s i s' i', stepN n t p p' s i s' i' -> stepstar t p p' s i s' i'.
Lemma step_deterministic : forall t p p1 p2 s i s1 s2 i1 i2, step t p p1 s i s1 i1 -> step t p p2 s i s2 i2 -> s1 = s2 /\ i1 = i2 /\ p1 = p2.
Lemma step_confluent : forall t p p1 p2 p' n s s1 s2 s' i i1 i2 i', step t p p1 s i s1 i1 -> step t p p2 s i s2 i2 -> stepN n t p1 p' s1 i1 s' i' -> stepN n t p2 p' s2 i2 s' i'.
Lemma step_triangle : forall n1 n2 t p p1 p2 s s1 s2 i i1 i2, n1 <= n2 -> stepN n1 t p p1 s i s1 i1 -> stepN n2 t p p2 s i s2 i2 -> stepN (n2 - n1) t p1 p2 s1 i1 s2 i2.