(** * Semantics

  - [sem e vnl vsl] is the evaluation of the expression [e] where the [i]th normal variable is
    instantiated with the [i]th value of [vnl], and the [i]th safe variable is
    instantiated with the [i]th value of [vsl].
    If a variable is not assigned a value, then it is assumed to be the empty bitstring [nil].
    Values in [vnl] and [vsl] that do not correspond to a variable are ignored.

  - [BC_ind_inf] is an induction principle that makes easier dealing with arities in inductive proofs.
*)

Fixpoint sem_rec (sem_g sem_h0 sem_h1:list bs->list bs->bs)(v:bs)(vnl vsl:list bs) :=
  match v with
    | nil => sem_g vnl vsl
    | b::v' =>
      if b then sem_h1 (v'::vnl) (sem_rec sem_g sem_h0 sem_h1 v' vnl vsl :: vsl)
      else sem_h0 (v'::vnl) (sem_rec sem_g sem_h0 sem_h1 v' vnl vsl :: vsl)
  end.Fixpoint sem (e:BC)(vnl vsl:list bs) : bs :=
  match e with
  | zero => nil
  | proj n s j => 
    if leb (S j) n then
      nth j vnl nil
      else nth (j-n) vsl nil
  | succ b => b :: hd nil vsl
  | pred => tail (hd nil vsl)
  | cond =>
      match vsl with
      | a :: b :: c :: d :: _ => 
        match a with 
          | nil => b
          | true :: _ => c
          | false :: _ => d
        end
      | a :: b :: c :: _ => 
        match a with 
          | nil => b
          | true :: _ => c
          | false :: _ => nil
        end
      | a :: b :: _ => 
        match a with 
          | nil => b
          | _ => nil
        end
      | _ => nil
      end
  | rec g h0 h1 => sem_rec (sem g) (sem h0) (sem h1) (hd nil vnl) (tail vnl) vsl
  | comp _ _ h nl sl => 
    sem h (List.map (fun ne => sem ne vnl nil) nl) 
          (List.map (fun se => sem se vnl vsl) sl)
  end.

Lemma sem_firstn_safe : forall f n s vnl vsl, arities f = ok_arities n s -> sem f vnl vsl = sem f vnl (firstn s vsl).