Definition var := nat.Instance EqDec_var: EqDec var := _.Definition adr := nat.Instance EqDec_adr : EqDec adr := _.Definition locals := table var adr.Definition heap := adr -> option adr.Inductive expr :=
 | Const: adr -> expr
 | Var: var -> expr
 | Offset: expr -> nat -> expr
 | Mem: expr -> expr.Inductive expr :=
 | Const: adr -> expr
 | Var: var -> expr
 | Offset: expr -> nat -> expr
 | Mem: expr -> expr.Inductive expr :=
 | Const: adr -> expr
 | Var: var -> expr
 | Offset: expr -> nat -> expr
 | Mem: expr -> expr.Inductive expr :=
 | Const: adr -> expr
 | Var: var -> expr
 | Offset: expr -> nat -> expr
 | Mem: expr -> expr.Inductive expr :=
 | Const: adr -> expr
 | Var: var -> expr
 | Offset: expr -> nat -> expr
 | Mem: expr -> expr.Notation "'If' x 'Then' c1 'Else' c2" := (IfThenElse x c1 c2)  (at level 200, x at level 90, c1 at level 200, c2 at level 200).Inductive control :=
| Assign: expr -> expr -> control -> control
| IfThenElse: expr -> control -> control -> control
| Go: expr -> list expr -> control.Inductive control :=
| Assign: expr -> expr -> control -> control
| IfThenElse: expr -> control -> control -> control
| Go: expr -> list expr -> control.Inductive control :=
| Assign: expr -> expr -> control -> control
| IfThenElse: expr -> control -> control -> control
| Go: expr -> list expr -> control.Inductive control :=
| Assign: expr -> expr -> control -> control
| IfThenElse: expr -> control -> control -> control
| Go: expr -> list expr -> control.Definition program := table adr (list var * control).Definition bind_option (A B: Type) (f: option A) (g: A -> option B) : option B :=
  match f with None => None | Some x => g x end.Definition emptyheap : heap := fun _ => None.Definition heap_get (h: heap) (a: adr) : option adr := h a.Definition heap_set (a v: adr) (h: heap) :=
   fun i => if eq_dec i a then Some v else h i.

Lemma heap_gso: forall h x y v, x<>y -> heap_get (heap_set x v h) y = heap_get h y.