(* *********************************************************************)
(*                                                                     *)
(*              The Compcert verified compiler                         *)
(*                                                                     *)
(*          Xavier Leroy, INRIA Paris-Rocquencourt                     *)
(*                                                                     *)
(*  Copyright Institut National de Recherche en Informatique et en     *)
(*  Automatique.  All rights reserved.  This file is distributed       *)
(*  under the terms of the INRIA Non-Commercial License Agreement.     *)
(*                                                                     *)
(* *********************************************************************)
(** Animating the CompCert C semantics *)
Require Cstrategy.
Local Open Scope string_scope.
Local Open Scope list_scope.
(** Error monad with options or lists *)
Notation "'do' X <- A ; B" := (match A with Some X => B | None => None end)
(at level 200, X ident, A at level 100, B at level 200)
: option_monad_scope.
Notation "'do' X , Y <- A ; B" := (match A with Some (X, Y) => B | None => None end)
(at level 200, X ident, Y ident, A at level 100, B at level 200)
: option_monad_scope.
Notation "'do' X , Y , Z <- A ; B" := (match A with Some (X, Y, Z) => B | None => None end)
(at level 200, X ident, Y ident, Z ident, A at level 100, B at level 200)
: option_monad_scope.
Notation " 'check' A ; B" := (if A then B else None)
(at level 200, A at level 100, B at level 200)
: option_monad_scope.
Notation "'do' X <- A ; B" := (match A with Some X => B | None => nil end)
(at level 200, X ident, A at level 100, B at level 200)
: list_monad_scope.
Notation " 'check' A ; B" := (if A then B else nil)
(at level 200, A at level 100, B at level 200)
: list_monad_scope.
Definition is_val (a: expr) : option (val * type) :=
match a with
| Eval v ty => Some(v, ty)
| _ => None
end.

(* Specifications: *)
Lemma is_val_inv:
forall a v ty, is_val a = Some(v, ty) -> a = Eval v ty.