Add LoadPath "..".
Set Implicit Arguments.
Local Open Scope logic.
(** A representation predicate.  Two things: -We assert the existence of an abstract representation [x] of the module state using [ghostp sh loc x]. -This abstract representation is related to the heap layout via the representation invariant [R]. *)
Definition rep {A: Type} (r: ident) (x: A) (R: ident -> A -> environ -> mpred) : environ -> mpred :=
fun rho => (EX sh: Share.t, EX loc: address, ghostp sh loc x) * R r x rho.
(** An abstract specification in usual Hoare style. *)
Record aspec {A: Type} := mk_aspec
{ Pspec: A -> environ -> Prop
; Qspec: A -> environ -> val -> Prop }.
(** Rspecs: lift rep-style predicates above to operate on sets of abstract states (given by some predicate P,Q,...).  In addition to (P,Q), we specify a module initialization function that establishes the representation invariant at the outset. [r] is a "root pointer" into the data structure.  E.g., in a linked list [r] is a pointer to the first cons cell. *)
Section rspec.
Context {A: Type} (argsig: list (ident*type)) (retty: type).
Context (R: ident -> A -> environ -> mpred) (p: @aspec A).
Definition rspec_init (r: ident) (init: A) : unit -> environ -> mpred :=
fun tt rho => rep r init R rho.
Definition rspec_pre (r: ident) : unit -> environ -> mpred :=
fun tt rho => EX x: A, rep r x R rho && !!p.(Pspec) x rho.
Definition rspec_post (r: ident) : unit -> environ -> mpred :=
fun tt rho => EX x: A, rep r x R rho && !!p.(Qspec) x rho (retval rho).
Definition init_rspec (r: ident) (init: A) : funspec :=
mk_funspec (argsig,Tvoid) cc_default unit TT (rspec_init r init * TT).
Definition rspec (r: ident) : funspec :=
mk_funspec (argsig,retty) cc_default unit (rspec_pre r) (rspec_post r).
End rspec.
Definition nonvoid (ty: type) := match ty with Tvoid => False | _ => True end.
Definition nonvoidty := {ty: type | nonvoid ty}.
Definition get_nonvoidty : nonvoidty -> type := @proj1_sig _ nonvoid.
Infix "$" := (fun f => [eta f]) (at level 50).

(* Specifications: *)
Lemma nonvoid_nonvoidty ty : nonvoid $ get_nonvoidty ty.
Lemma rfun_of_xident_eq {id f} : rfun_of_xident id = Some f -> f.(f_id) = id.
End module_defs.