Definition other := store.Module K <: KNOT__HERED_PROP_OTH := Knot_HeredPropOth(KnotInput).Definition prog := K.knot.Definition world := (prog * store)%type.Definition assert := pred world.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 : prog -> prog -> store -> stack -> store -> stack ->  Prop :=
 | stepstar_O: forall s i p, stepstar p p s i s i
 | stepstar_S: forall p p' p'' s i s' i' s'' i'',
              step p p' s i s' i' -> stepstar p' p'' s' i' s'' i'' -> stepstar p p'' s i s'' i''.(* Safety property *)

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

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

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

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

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

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