End LG.
(* The [init] function is not meant to be called from clients directly. Thus it can use an _internal_ abstraction, LG.data_ok, in its specification. *)
Definition init_spec :=
DECLARE _LG_init
WITH n: Z, gv: globals
PRE  []
PROP ()
LOCAL(gvars gv)
SEP(LG.data n gv)
POST [ tvoid ]
PROP()
LOCAL ()
SEP (LG.data_ok n gv).
(* The [bump] and [get] functions are meant to be called from client modules.  *)
Definition bump_spec :=
DECLARE _LG_bump
WITH n: Z, gv: globals
PRE  []
PROP (n < Int.max_signed)
LOCAL(gvars gv)
SEP(LG.data n gv)
POST [ tvoid ]
PROP()
LOCAL ()
SEP (LG.data (n+1) gv).
Definition get_spec :=
DECLARE _LG_get
WITH n: Z, gv: globals
PRE  []
PROP ()
LOCAL(gvars gv)
SEP(LG.data n gv)
POST [ tint ]
PROP()
LOCAL (temp ret_temp (Vint (Int.repr n)))
SEP (LG.data n gv).
Definition client_spec :=
DECLARE _client
WITH n: Z, gv: globals
PRE  []
PROP (n < 1000000000)
LOCAL(gvars gv)
SEP(LG.data n gv)
POST [ tint ]
PROP()
LOCAL (temp ret_temp (Vint (Int.repr (n+2))))
SEP (LG.data (n+2) gv).
Definition main_spec :=
DECLARE _main
WITH gv : globals
PRE  [] main_pre prog nil gv
POST [ tint ]
PROP()
LOCAL (temp ret_temp (Vint (Int.repr 5)))
SEP(TT).
Definition Gprog : funspecs :=
ltac:(with_library prog [
init_spec; bump_spec; get_spec; client_spec; main_spec]).

(* Specifications: *)
Lemma orp_if_bool:
forall {A} {NA: NatDed A} (P Q: A),
orp P Q = EX b: bool, if b then P else Q.
Lemma body_init:  semax_body Vprog Gprog f_LG_init init_spec.
Lemma body_bump:  semax_body Vprog Gprog f_LG_bump bump_spec.
Lemma body_get:  semax_body Vprog Gprog f_LG_get get_spec.
Lemma body_client: semax_body Vprog Gprog f_client client_spec.
Lemma body_main:  semax_body Vprog Gprog f_main main_spec.