(** * 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_comp :
forall n s f nel sel nl sl,
sem (comp n s f nel sel) nl sl =
sem f (map (fun ne => sem ne nl nil) nel) (map (fun se => sem se nl sl) sel).