Require Import ZArith. Require Import Program.Equality. Require Import Structures.Equalities. Require Import String. Axiom vareq: string -> string -> bool. Open Scope Z_scope. Open Scope string_scope. Definition varname := string. Definition store := varname -> Z. Inductive aexp: Type := | Var (v:varname) | Eval (v:varname) (a:aexp). Definition update (s:store) (x:varname) (y:Z) := fun z => if vareq x z then y else s z. Inductive eval_aexp: aexp -> store -> Z -> Prop := | Rule1 (v:varname) (s:store): (eval_aexp (Var v) s (s v)) | Rule2 (v:varname) (a1:aexp) (s:store) (H: s v = 0): (eval_aexp (Eval v a1) s 0) | Rule3 (v:varname) (a1:aexp) (n1 n2:Z) (s:store) (H1: s v <> 0) (H2: eval_aexp a1 s n1) (H2: eval_aexp (Eval v a1) (update s v n1) n2): (eval_aexp (Eval v a1) s (n1+n2)). Theorem quiz2: forall a s n, (eval_aexp a s n) -> (forall v, Zeven (s v)) -> Zeven n. Proof. intros a s n. intro H. induction H; intros. (* Case 1: Var *) apply H. (* Case 2: Eval0 *) simpl. apply I. (* Case 3: EvalN *) apply Zeven_plus_Zeven. apply IHeval_aexp1. assumption. apply IHeval_aexp2. unfold update. intro v0. case (vareq v v0). apply IHeval_aexp1. assumption. apply H2. Qed.