(*Unital*)
Instance discHeap_unital':
@UnitalSeparationAlgebra Heap' discHeap_R' Heap_Join'.
(*Residual*)
Instance discHeap_residual':
@ResidualSeparationAlgebra Heap' discHeap_R' Heap_Join'.
(*Downwards-closed*)
Definition monHeap_dSA':
@DownwardsClosedSeparationAlgebra Heap' monHeap_R' Heap_Join'.
(* Increasing *)
Instance monHeap_increasing':
@IncreasingSeparationAlgebra Heap' monHeap_R' Heap_Join'.
(* Residual *)
Instance monHeap_residual':
@ResidualSeparationAlgebra Heap' monHeap_R' Heap_Join'.
(* Unital *)
Instance monHeap_unital':
@UnitalSeparationAlgebra Heap' monHeap_R' Heap_Join'.
End heaps'.
(***********************************)
(* TYPED HEAPS                     *)
(***********************************)
Section typed_heaps.
Inductive htype:=
|char
|short1
|short2.
Inductive ht_ord: htype -> htype -> Prop :=
|htype_refl x: ht_ord x x
|htype_sht1 : ht_ord char short1
|htype_sht2 : ht_ord char short2.
Instance ht_preorder: PreOrder ht_ord.
Notation THeap':= (nat -> option htype).
Definition THvalid (TH:THeap'):=
forall n, TH n = Some short1 <->
TH (S n) = Some short2.
Record THeap: Type :=
{ theap:> nat -> option htype;
th_wf1: THvalid theap}.
Instance THeap_Join': Join THeap' :=
@fun_Join _ _ (@option_Join _ (trivial_Join)).
Inductive THeap_Join: Join THeap :=
| th_join (h1 h2 h3: THeap): THeap_Join' h1 h2 h3 ->
THeap_Join h1 h2 h3.
Instance THeap_SA': @SeparationAlgebra _ THeap_Join':=
@fun_SA _ _ _ (@option_SA _ _ (trivial_SA)).

(* Specifications: *)
Lemma THeap_Join_valid:
forall {h1 h2 h3}, THeap_Join' h1 h2 h3 ->
THvalid h1 ->
THvalid h2 ->
THvalid h3.