import .imp_syntax import .imp_common namespace imp inductive eval_unop : unary_op → val → val → Prop | neg : ∀ i, eval_unop unary_op.neg (val.int i) (val.int (- i)) | not : ∀ b, eval_unop unary_op.not (val.bool b) (val.bool (bnot b)). open binary_op inductive eval_binop : binary_op → val → val → val → Prop | add_i : forall i1 i2, eval_binop add (val.int i1) (val.int i2) (val.int (i1 + i2)) | add_s : forall s1 s2, eval_binop add (val.str s1) (val.str s2) (val.str $ s1 ++ s2) | sub : forall i1 i2, eval_binop sub (val.int i1) (val.int i2) (val.int $ i1 - i2) | mul : forall i1 i2, eval_binop mul (val.int i1) (val.int i2) (val.int $ i1 * i2) | div : forall i1 i2, ¬ (i2 = 0) -> eval_binop div (val.int i1) (val.int i2) (val.int $ i1 / i2) | eval_mod : forall i1 i2, ¬ (i2 = 0) -> eval_binop mod (val.int i1) (val.int i2) (val.int $ i1 % i2) | eval_eq : forall v1 v2, eval_binop eq v1 v2 (val.bool (decidable.to_bool $ v1 = v2)) | eval_lt : forall i1 i2, eval_binop lt (val.int i1) (val.int i2) (val.bool (decidable.to_bool $ i1 < i2)) | eval_le : forall i1 i2, eval_binop le (val.int i1) (val.int i2) (val.bool (decidable.to_bool $ i1 <= i2)) | eval_conj : forall b1 b2, eval_binop conj (val.bool b1) (val.bool b2) (val.bool (b1 && b2)) | eval_disj : forall b1 b2, eval_binop disj (val.bool b1) (val.bool b2) (val.bool (b1 || b2)) inductive eval_e (s : store) : expr -> val -> Prop | val : forall v, eval_e (expr.val v) v | var : forall x v, s.lookup x = some v -> eval_e (expr.var x) v | unary_op : forall op e v v', eval_e e v -> eval_unop op v v' -> eval_e (expr.unary_op op e) v' | binary_op : forall op e1 e2 v1 v2 v', eval_e e1 v1 -> eval_e e2 v2 -> eval_binop op v1 v2 v' -> eval_e (expr.binary_op op e1 e2) v' open stmt inductive eval_s : store -> stmt -> store -> Prop | nop : forall s, eval_s s nop s | set : forall s x e v, eval_e s e v -> eval_s s (stmt.set x e) (update x v s) | ifelse_t : forall s e p1 p2 s', eval_e s e (val.bool tt) -> eval_s s p1 s' -> eval_s s (ifelse e p1 p2) s' | ifelse_f : forall s e p1 p2 s', eval_e s e (val.bool ff) -> eval_s s p2 s' -> eval_s s (ifelse e p1 p2) s' | while_t : forall s1 e p s2 s3, eval_e s1 e (val.bool tt) -> eval_s s1 p s2 -> eval_s s2 (while e p) s3 -> eval_s s1 (while e p) s3 | while_f : forall s e p, eval_e s e (val.bool ff) -> eval_s s (while e p) s | seq : forall s1 p1 s2 p2 s3, eval_s s1 p1 s2 -> eval_s s2 p2 s3 -> eval_s s1 (seq p1 p2) s3 end imp