theory Imp use state.State use bool.Bool use int.Int (* ************************ SYNTAX ************************ *) type aexpr = | Anum int | Avar id | Aadd aexpr aexpr | Asub aexpr aexpr | Amul aexpr aexpr type bexpr = | Btrue | Bfalse | Band bexpr bexpr | Bnot bexpr | Beq aexpr aexpr | Ble aexpr aexpr type com = | Cskip | Cassign id aexpr | Cseq com com | Cif bexpr com com | Cwhile bexpr com (* ************************ SEMANTICS ************************ *) function aeval (st:state) (e:aexpr) : int = match e with | Anum n -> n | Avar x -> st[x] | Aadd e1 e2 -> aeval st e1 + aeval st e2 | Asub e1 e2 -> aeval st e1 - aeval st e2 | Amul e1 e2 -> aeval st e1 * aeval st e2 end function beval (st:state) (b:bexpr) : bool = match b with | Btrue -> true | Bfalse -> false | Bnot b' -> notb (beval st b') | Band b1 b2 -> andb (beval st b1) (beval st b2) | Beq a1 a2 -> aeval st a1 = aeval st a2 | Ble a1 a2 -> aeval st a1 <= aeval st a2 end inductive ceval state com state = (* skip *) | E_Skip : forall m. ceval m Cskip m (* assignement *) | E_Ass : forall m a x. ceval m (Cassign x a) m[x <- aeval m a] (* sequence *) | E_Seq : forall cmd1 cmd2 m0 m1 m2. ceval m0 cmd1 m1 -> ceval m1 cmd2 m2 -> ceval m0 (Cseq cmd1 cmd2) m2 (* if then else *) | E_IfTrue : forall m0 m1 cond cmd1 cmd2. beval m0 cond -> ceval m0 cmd1 m1 -> ceval m0 (Cif cond cmd1 cmd2) m1 | E_IfFalse : forall m0 m1 cond cmd1 cmd2. not beval m0 cond -> ceval m0 cmd2 m1 -> ceval m0 (Cif cond cmd1 cmd2) m1 (* while *) | E_WhileEnd : forall cond m body. not beval m cond -> ceval m (Cwhile cond body) m | E_WhileLoop : forall mi mj mf cond body. beval mi cond -> ceval mi body mj -> ceval mj (Cwhile cond body) mf -> ceval mi (Cwhile cond body) mf (* Determinstic semantics *) lemma ceval_deterministic_aux : forall c mi mf1. ceval mi c mf1 -> forall mf2. ([@inversion] ceval mi c mf2) -> mf1 = mf2 lemma ceval_deterministic : forall c mi mf1 mf2. ceval mi c mf1 -> ceval mi c mf2 -> mf1 = mf2 end