Fixpoint is_val_list (al: exprlist) : option (list (val * type)) :=
  match al with
  | Enil => Some nil
  | Econs a1 al => do vt1 <- is_val a1; do vtl <- is_val_list al; Some(vt1::vtl)
  end.Definition is_skip (s: statement) : {s = Sskip} + {s <> Sskip}.Definition eventval_of_val (v: val) (t: typ) : option eventval :=
  match v with
  | Vint i => check (typ_eq t AST.Tint); Some (EVint i)
  | Vfloat f => check (typ_eq t AST.Tfloat); Some (EVfloat f)
  | Vsingle f => check (typ_eq t AST.Tsingle); Some (EVsingle f)
  | Vlong n => check (typ_eq t AST.Tlong); Some (EVlong n)
  | Vptr b ofs =>
      do id <- Genv.invert_symbol ge b;
      check (Genv.public_symbol ge id);
      check (typ_eq t AST.Tptr);
      Some (EVptr_global id ofs)
  | _ => None
  end.Fixpoint list_eventval_of_val (vl: list val) (tl: list typ) : option (list eventval) :=
  match vl, tl with
  | nil, nil => Some nil
  | v1::vl, t1::tl =>
      do ev1 <- eventval_of_val v1 t1;
      do evl <- list_eventval_of_val vl tl;
      Some (ev1 :: evl)
  | _, _ => None
  end.Definition val_of_eventval (ev: eventval) (t: typ) : option val :=
  match ev with
  | EVint i => check (typ_eq t AST.Tint); Some (Vint i)
  | EVfloat f => check (typ_eq t AST.Tfloat); Some (Vfloat f)
  | EVsingle f => check (typ_eq t AST.Tsingle); Some (Vsingle f)
  | EVlong n => check (typ_eq t AST.Tlong); Some (Vlong n)
  | EVptr_global id ofs =>
      check (Genv.public_symbol ge id);
      check (typ_eq t AST.Tptr);
      do b <- Genv.find_symbol ge id;
      Some (Vptr b ofs)
  end.Ltac mydestr :=
  match goal with
  | [ |- None = Some _ -> _ ] => let X := fresh "X" in intro X; discriminate
  | [ |- Some _ = Some _ -> _ ] => let X := fresh "X" in intro X; inv X
  | [ |- match ?x with Some _ => _ | None => _ end = Some _ -> _ ] => destruct x eqn:?; mydestr
  | [ |- match ?x with true => _ | false => _ end = Some _ -> _ ] => destruct x eqn:?; mydestr
  | [ |- match ?x with left _ => _ | right _ => _ end = Some _ -> _ ] => destruct x; mydestr
  | _ => idtac
  end.

(* Specifications: *)
Lemma eventval_of_val_sound: forall v t ev, eventval_of_val v t = Some ev -> eventval_match ge ev t v.
Lemma eventval_of_val_complete: forall ev t v, eventval_match ge ev t v -> eventval_of_val v t = Some ev.
Lemma list_eventval_of_val_sound: forall vl tl evl, list_eventval_of_val vl tl = Some evl -> eventval_list_match ge evl tl vl.
Lemma list_eventval_of_val_complete: forall evl tl vl, eventval_list_match ge evl tl vl -> list_eventval_of_val vl tl = Some evl.
Lemma val_of_eventval_sound: forall ev t v, val_of_eventval ev t = Some v -> eventval_match ge ev t v.
Lemma val_of_eventval_complete: forall ev t v, eventval_match ge ev t v -> val_of_eventval ev t = Some v.