(* The following predicate makes it easier for us to do induction on the number of loop iterations. *)
Inductive evalDet_repeat_steps (A : Set)(P : A -> bool) : comp_state A -> comp_state A -> Prop :=
| evalDet_repeat_steps_done : 
  forall c s a s',
    evalDet_steps (cs_more c s) (cs_done a s') ->
    P a = true ->
    evalDet_repeat_steps P (cs_more c s) (cs_done a s')
| evalDet_repeat_steps_eof :
  forall c s,
    evalDet_steps (cs_more c s) (@cs_eof A) ->
    evalDet_repeat_steps P (cs_more c s) (@cs_eof A)
| evalDet_repeat_steps_step :
  forall c s a s' y,
    evalDet_steps (cs_more c s) (cs_done a s') ->
    P a = false ->
    evalDet_repeat_steps P (cs_more c s') y ->
    evalDet_repeat_steps P (cs_more c s) y.(* The following predicate makes it easier for us to do induction on the number of loop iterations. *)
Inductive evalDet_repeat_steps (A : Set)(P : A -> bool) : comp_state A -> comp_state A -> Prop :=
| evalDet_repeat_steps_done : 
  forall c s a s',
    evalDet_steps (cs_more c s) (cs_done a s') ->
    P a = true ->
    evalDet_repeat_steps P (cs_more c s) (cs_done a s')
| evalDet_repeat_steps_eof :
  forall c s,
    evalDet_steps (cs_more c s) (@cs_eof A) ->
    evalDet_repeat_steps P (cs_more c s) (@cs_eof A)
| evalDet_repeat_steps_step :
  forall c s a s' y,
    evalDet_steps (cs_more c s) (cs_done a s') ->
    P a = false ->
    evalDet_repeat_steps P (cs_more c s') y ->
    evalDet_repeat_steps P (cs_more c s) y.(* The following predicate makes it easier for us to do induction on the number of loop iterations. *)
Inductive evalDet_repeat_steps (A : Set)(P : A -> bool) : comp_state A -> comp_state A -> Prop :=
| evalDet_repeat_steps_done : 
  forall c s a s',
    evalDet_steps (cs_more c s) (cs_done a s') ->
    P a = true ->
    evalDet_repeat_steps P (cs_more c s) (cs_done a s')
| evalDet_repeat_steps_eof :
  forall c s,
    evalDet_steps (cs_more c s) (@cs_eof A) ->
    evalDet_repeat_steps P (cs_more c s) (@cs_eof A)
| evalDet_repeat_steps_step :
  forall c s a s' y,
    evalDet_steps (cs_more c s) (cs_done a s') ->
    P a = false ->
    evalDet_repeat_steps P (cs_more c s') y ->
    evalDet_repeat_steps P (cs_more c s) y.(* The following predicate makes it easier for us to do induction on the number of loop iterations. *)
Inductive evalDet_repeat_steps (A : Set)(P : A -> bool) : comp_state A -> comp_state A -> Prop :=
| evalDet_repeat_steps_done : 
  forall c s a s',
    evalDet_steps (cs_more c s) (cs_done a s') ->
    P a = true ->
    evalDet_repeat_steps P (cs_more c s) (cs_done a s')
| evalDet_repeat_steps_eof :
  forall c s,
    evalDet_steps (cs_more c s) (@cs_eof A) ->
    evalDet_repeat_steps P (cs_more c s) (@cs_eof A)
| evalDet_repeat_steps_step :
  forall c s a s' y,
    evalDet_steps (cs_more c s) (cs_done a s') ->
    P a = false ->
    evalDet_repeat_steps P (cs_more c s') y ->
    evalDet_repeat_steps P (cs_more c s) y.Inductive evalDet_repeat(A : Set)(P : A -> bool)(c : Comp A)(s : Blist) : comp_answer A -> Prop :=
  | evalDet_repeat_done : forall a s',
    evalDet_repeat_steps P (cs_more c s) (cs_done a s') ->
    evalDet_repeat P c s (ca_done a)
  | evalDet_repeat_eof :
    evalDet_repeat_steps P (cs_more c s) (@cs_eof A) ->
    evalDet_repeat P c s (@ca_eof A).Inductive evalDet_repeat(A : Set)(P : A -> bool)(c : Comp A)(s : Blist) : comp_answer A -> Prop :=
  | evalDet_repeat_done : forall a s',
    evalDet_repeat_steps P (cs_more c s) (cs_done a s') ->
    evalDet_repeat P c s (ca_done a)
  | evalDet_repeat_eof :
    evalDet_repeat_steps P (cs_more c s) (@cs_eof A) ->
    evalDet_repeat P c s (@ca_eof A).Inductive evalDet_repeat(A : Set)(P : A -> bool)(c : Comp A)(s : Blist) : comp_answer A -> Prop :=
  | evalDet_repeat_done : forall a s',
    evalDet_repeat_steps P (cs_more c s) (cs_done a s') ->
    evalDet_repeat P c s (ca_done a)
  | evalDet_repeat_eof :
    evalDet_repeat_steps P (cs_more c s) (@cs_eof A) ->
    evalDet_repeat P c s (@ca_eof A).

Lemma evalDet_step_done_inv : forall (A : Set)(c : Comp A) a ls ls', evalDet_step c ls = cs_done a ls' -> exists eqd, c = Ret eqd a.