(* a functional form of the small-step semantics*)
Fixpoint evalDet_step(A : Set)(c : Comp A)(s : Blist) : comp_state A :=
  match c in Comp A return comp_state A with
    | Ret pf a => cs_done a s
    | Rnd n  => 
      match (shiftOut s n) with
        | Some (v, s') => cs_more (Ret (@Bvector_eq_dec n) v) s'
        | None => (@cs_eof (Bvector n))
      end
    | Bind c1 c2 =>     
      match (evalDet_step c1 s) with
        | cs_eof _ => (@cs_eof _)
        | cs_done b s' => cs_more (c2 b) s'
        | cs_more c1' s' => cs_more (Bind c1' c2) s'
      end
    | Repeat c P =>
      cs_more (Bind c (fun a => if (P a) then (Ret (comp_eq_dec c) a) else (Repeat c P))) s
   end.Inductive evalDet_steps(A : Set) : comp_state A -> comp_state A -> Prop :=
  | evalDet_steps_refl : forall ans,
    evalDet_steps ans ans
  | evalDet_steps_step : 
    forall c s ans ans',
      (evalDet_step c s) = ans ->
      evalDet_steps ans ans' ->
      evalDet_steps (cs_more c s) ans'.Inductive evalDet_steps(A : Set) : comp_state A -> comp_state A -> Prop :=
  | evalDet_steps_refl : forall ans,
    evalDet_steps ans ans
  | evalDet_steps_step : 
    forall c s ans ans',
      (evalDet_step c s) = ans ->
      evalDet_steps ans ans' ->
      evalDet_steps (cs_more c s) ans'.Inductive evalDet_steps(A : Set) : comp_state A -> comp_state A -> Prop :=
  | evalDet_steps_refl : forall ans,
    evalDet_steps ans ans
  | evalDet_steps_step : 
    forall c s ans ans',
      (evalDet_step c s) = ans ->
      evalDet_steps ans ans' ->
      evalDet_steps (cs_more c s) ans'.Inductive evalDet(A : Set)(c : Comp A)(s : Blist) : comp_answer A -> Prop :=
  | evalDet_done : forall a s',
    evalDet_steps (cs_more c s) (cs_done a s') ->
    evalDet c s (ca_done a)
  | evalDet_eof :
    evalDet_steps (cs_more c s) (@cs_eof A) ->
    evalDet c s (@ca_eof A).Inductive evalDet(A : Set)(c : Comp A)(s : Blist) : comp_answer A -> Prop :=
  | evalDet_done : forall a s',
    evalDet_steps (cs_more c s) (cs_done a s') ->
    evalDet c s (ca_done a)
  | evalDet_eof :
    evalDet_steps (cs_more c s) (@cs_eof A) ->
    evalDet c s (@ca_eof A).Inductive evalDet(A : Set)(c : Comp A)(s : Blist) : comp_answer A -> Prop :=
  | evalDet_done : forall a s',
    evalDet_steps (cs_more c s) (cs_done a s') ->
    evalDet c s (ca_done a)
  | evalDet_eof :
    evalDet_steps (cs_more c s) (@cs_eof A) ->
    evalDet c s (@ca_eof A).

Theorem evalDet_steps_bind_more_h : forall(A B : Set) x y, evalDet_steps x y -> forall (c1 : Comp B)(c2 : B -> Comp A) s c1' s', x = (cs_more c1 s) -> y = (cs_more c1' s') -> evalDet_steps (cs_more (Bind c1 c2) s) (cs_more (Bind c1' c2) s').