Local Open Scope logic.
Section PROG.
Let a : var := 0.
Let s : var := 1.
Let p : var := 2.
Let r : var := 3.
Let START : adr := 0.
Let LOOP : adr := 1.
Let DONE : adr := 2.
Definition STARTbody := (a::nil,
Do Mem a := a .+ 1; Do Mem (a .+ 1) := a .+ 2; Do Mem (a .+ 2) := Const 0;
Go LOOP ((a.+3)::(Var a)::(Var a)::(Const DONE)::nil)).
Definition LOOPbody := (a::s::p::r::nil,
If p Then (Do p := Mem p; Go LOOP (Var a::Var s::Var p::Var r::nil))
Else Go r (Var a::Var s::nil)).
Definition DONEbody := (a::s::nil,  Go DONE (Var a::Var s::nil)).
Definition myprog : program :=
(START, STARTbody):: (LOOP,  LOOPbody) :: (DONE,   DONEbody) :: nil.
Definition STARTspec : funspec := (a::nil,
fun s => allocpool (eval (Var a) s)).
Definition DONEspec: funspec := (a::s::nil,
fun s' => lseg (eval (Var s) s') (eval (Const 0) s') * allocpool (eval (Var a) s')).
Definition LOOPspec: funspec :=  (a::s::p::r::nil,
fun s' => lseg (eval (Var s) s') (eval (Var p) s')
* lseg (eval (Var p) s') (eval (Const 0) s')
* allocpool (eval (Var a) s')
&& cont DONEspec (eval (Var r) s')).
Definition myspec := (START, STARTspec):: ((LOOP, LOOPspec) :: (DONE, DONEspec) :: nil).

(* Specifications: *)
Lemma prove_START: semax_body myspec STARTspec STARTbody.
eapply semax_pre; [intro ; call_tac; apply derives_refl |  simpl ].