Library cmd2
Require Import List.
Require Import ZArith.
Require Import List.
Require Import EqNat.
Require Import Classical.
Require Import util.
Require Import heap.
Require Import heap_tactic.
Require Import bipl.
Require Import axiomatic.
Import valandloc.
Inductive cmd2 : Set :=
skip2 : cmd2
| assign2 : var.v -> expr -> cmd2
| lookup2 : var.v -> expr -> cmd2
| mutation2 : expr -> expr -> cmd2
| test_equal2 : var.v -> expr -> expr -> cmd2
| test_lt2: var.v -> expr -> expr -> cmd2
| test_not2: var.v -> var.v -> cmd2
| test_and2: var.v -> var.v -> var.v -> cmd2
| test_or2: var.v -> var.v -> var.v -> cmd2
| while2 : expr -> cmd2 -> cmd2
| seq2 : cmd2 -> cmd2 -> cmd2
| ifte2 : expr -> cmd2 -> cmd2 -> cmd2.
Open Local Scope sep_scope.
Open Local Scope heap_scope.
Close Local Scope nat_scope.
Definition state := prod store.s heap.h.
Open Local Scope nat_scope.
operational semantics
Inductive exec2 : option state -> cmd2 -> option state -> Prop :=
exec_none2 : forall c, exec2 None c None
| exec_skip2: forall s h, exec2 (Some (s, h)) skip2 (Some (s, h))
| exec_assign2 : forall s h x e,
exec2 (Some (s, h)) (assign2 x e) (Some (store.update x (eval e s) s, h))
| exec_lookup2 : forall s h x e p v,
val2loc (eval e s) = p -> heap.lookup p h = Some v -> exec2 (Some (s, h)) (lookup2 x e) (Some (store.update x v s, h))
| exec_lookup_err2 : forall s h x e p,
val2loc (eval e s) = p ->
heap.lookup p h = None -> exec2 (Some (s, h)) (lookup2 x e) None
| exec_mutation2 : forall s h e e' p v,
val2loc (eval e s) = p -> heap.lookup p h = Some v -> exec2 (Some (s, h)) (mutation2 e e') (Some (s, heap.update p (eval e' s) h))
| exec_mutation_err2 : forall s h e e' p,
val2loc (eval e s) = p -> heap.lookup p h = None -> exec2 (Some (s, h)) (mutation2 e e') None
| exec_test2_ok: forall s h v e1 e2,
(eval e1 s = eval e2 s)%Z ->
exec2 (Some (s, h)) (test_equal2 v e1 e2) (Some (store.update v 1%Z s, h))
| exec_test2_nok: forall s h v e1 e2,
(eval e1 s <> eval e2 s)%Z ->
exec2 (Some (s, h)) (test_equal2 v e1 e2) (Some (store.update v 0%Z s, h))
| exec_lt2_ok: forall s h v e1 e2,
(eval e1 s < eval e2 s)%Z ->
exec2 (Some (s, h)) (test_lt2 v e1 e2) (Some (store.update v 1%Z s, h))
| exec_lt2_nok: forall s h v e1 e2,
(eval e1 s >= eval e2 s)%Z ->
exec2 (Some (s, h)) (test_lt2 v e1 e2) (Some (store.update v 0%Z s, h))
| exec_not2_ok: forall s h v e,
(eval (var_e e) s = 0)%Z ->
exec2 (Some (s, h)) (test_not2 v e) (Some (store.update v 1%Z s, h))
| exec_not2_nok: forall s h v e,
(eval (var_e e) s <> 0)%Z ->
exec2 (Some (s, h)) (test_not2 v e) (Some (store.update v 0%Z s, h))
| exec_and2_ok: forall s h v e1 e2,
(eval (var_e e1) s <> 0 /\ eval (var_e e2) s <> 0)%Z ->
exec2 (Some (s, h)) (test_and2 v e1 e2) (Some (store.update v 1%Z s, h))
| exec_and2_nok: forall s h v e1 e2,
(eval (var_e e1) s = 0 \/ eval (var_e e2) s = 0)%Z ->
exec2 (Some (s, h)) (test_and2 v e1 e2) (Some (store.update v 0%Z s, h))
| exec_or2_ok: forall s h v e1 e2,
(eval (var_e e1) s <> 0 \/ eval (var_e e2) s <> 0)%Z ->
exec2 (Some (s, h)) (test_or2 v e1 e2) (Some (store.update v 1%Z s, h))
| exec_or2_nok: forall s h v e1 e2,
(eval (var_e e1) s = 0 /\ eval (var_e e2) s = 0)%Z ->
exec2 (Some (s, h)) (test_and2 v e1 e2) (Some (store.update v 0%Z s, h))
| exec_seq2 : forall s s' s'' c d,
exec2 s c s' -> exec2 s' d s'' -> exec2 s (seq2 c d) s''
| exec_while_true2 : forall s h s' s'' b c,
(eval b s <> 0)%Z ->
exec2 (Some (s, h)) c s' ->
exec2 s' (while2 b c) s'' ->
exec2 (Some (s, h)) (while2 b c) s''
| exec_while_false2 : forall s h b c,
(eval b s = 0)%Z ->
exec2 (Some (s, h)) (while2 b c) (Some (s, h))
| exec_ifte_true2 : forall b c d s h s',
(eval b s <> 0)%Z ->
exec2 (Some (s, h)) c s' ->
exec2 (Some (s, h)) (ifte2 b c d) s'
| exec_ifte_false2 : forall b c d s h s',
(eval b s = 0)%Z ->
exec2 (Some (s, h)) d s' ->
exec2 (Some (s, h)) (ifte2 b c d) s'.
Axiom trad12_fp: cmd -> var.v -> cmd2.
Definition trad12 (c: cmd) : cmd2 :=
let x := (modified_cmd_var c) in
(trad12_fp c 0 ).