(* BEGIN NEW MATERIAL *)
Class heightable (A : Type) : Type := Heightable {
height : A -> nat;
is_height_zero : forall a : A, {height a = 0} + {height a <> 0} (* Should run in O(1) time for trees *)
}.
Arguments Heightable [A] _ _.
Definition is_height_zero_spec {A : Type} (height : A -> nat) : Type :=
forall a : A, {height a = 0} + {height a <> 0}.
Definition list_height {A} `{heightable A} (LA : list A) : nat :=
fold_right max 0 (map height LA).
Fixpoint list_is_height_zero_bool {A} `{heightable A} (L : list A) : bool :=
match L with
| nil => true
| a :: L' =>
if is_height_zero a then list_is_height_zero_bool L' else false
end.
Instance list_heightable {A} `{heightable A} : heightable (list A).
apply Heightable with list_height.
induction a. left. trivial.
unfold list_height in *.
case (is_height_zero a). destruct IHa. left.
simpl. rewrite e, e0. trivial.
right. intro. apply n. simpl in H0. rewrite e in H0. apply H0.
right. intro. apply n. simpl in H0. icase (height a). icase (fold_right max 0 (map height a0)).
Defined.
Class decomposible (A : Type) : Type := Decomposible {
decompose : A -> (A * A)
}.
Arguments Decomposible [A] _.
Class roundableLeft (A : Type) : Type := RoundableLeft {
roundL : nat -> A -> option A
}.
Arguments RoundableLeft [A] _.
Class roundableRight (A : Type) : Type := RoundableRight {
roundR : nat -> A -> option A
}.
Arguments RoundableRight [A] _.
Class avgable (A : Type) : Type := Avgable {
avg : nat -> A -> A -> option A
}.
Arguments Avgable [A] _.
(* END NEW MATERIAL *)
Module Type SHARE_MODEL.
Include BA_FACTS.
Parameter EqDec_share: EqDec t.
Existing Instance EqDec_share.
(* Splittability *)
Parameter split : t -> t * t.

Axiom split_together : forall x1 x2 x,
split x = (x1, x2) ->
lub x1 x2 = x.