(*D11*)
 Definition sub (x y : canonTree) : option canonTree :=
  match eq_dec (glb x y) y with
  | left _ => Some (glb x (comp y))
  | right _ => None
  end.

(* Specifications: *)
Lemma sub_join : forall t1 t2 t3, sub t1 t2 = Some t3 <-> join t2 t3 t1.
Lemma decompose_share_height_no_increase: forall sh sh' sh'' , decompose sh = (sh',sh'')-> height sh' <= height sh /\ height sh'' <= height sh.
Lemma tree_top_rewrite : forall c, exist _ (Leaf true) c = top.
Lemma tree_bot_rewrite : forall c, exist _ (Leaf false) c = bot.
Lemma tree_basic_rewrite : forall b c, exist _ (Leaf b) c = top \/ exist _ (Leaf b) c = bot.
Lemma tree_case_rewrite : forall t, (t = top \/ t = bot) \/ exists t1 t2 c, t = exist _ (Node t1 t2) c.
Lemma decompose_basic: forall b c c1 c2, decompose (exist _ (Leaf b) c) = (exist _ (Leaf b) c1,exist _ (Leaf b) c2).
Lemma decompose_top: decompose top = (top,top).
Lemma decompose_bot: decompose bot = (bot,bot).
Lemma decompose_Node: forall t1 t2 c c1 c2, decompose (exist _ (Node t1 t2) c) = (exist _ t1 c1, exist _ t2 c2).
Lemma identity_bot: forall s, identity s <-> s = bot.
Lemma tree_proof_replace: forall (t : ShareTree) c1 c2, exist (fun t => canonicalTree t) t c1 = exist _ t c2.
Lemma top_unrel: forall a, unrel top a = a.
Lemma bot_unrel: forall a, unrel bot a = a.
Lemma mkCanon_lub : forall t11 t12 t21 t22 t31 t32, lub (exist _ (mkCanon (Node t11 t12)) (mkCanon_correct _)) (exist _ (mkCanon (Node t21 t22)) (mkCanon_correct _)) = (exist _ (mkCanon (Node t31 t32)) (mkCanon_correct _))<-> lub (exist _ (mkCanon t11) (mkCanon_correct _)) (exist _ (mkCanon t21) (mkCanon_correct _)) = (exist _ (mkCanon t31) (mkCanon_correct _))/\ lub (exist _ (mkCanon t12) (mkCanon_correct _)) (exist _ (mkCanon t22) (mkCanon_correct _)) = (exist _ (mkCanon t32) (mkCanon_correct _)).
Lemma mkCanon_glb : forall t11 t12 t21 t22 t31 t32, glb (exist _ (mkCanon (Node t11 t12)) (mkCanon_correct _)) (exist _ (mkCanon (Node t21 t22)) (mkCanon_correct _)) = (exist _ (mkCanon (Node t31 t32)) (mkCanon_correct _))<-> glb (exist _ (mkCanon t11) (mkCanon_correct _)) (exist _ (mkCanon t21) (mkCanon_correct _)) = (exist _ (mkCanon t31) (mkCanon_correct _))/\ glb (exist _ (mkCanon t12) (mkCanon_correct _)) (exist _ (mkCanon t22) (mkCanon_correct _)) = (exist _ (mkCanon t32) (mkCanon_correct _)).
Lemma decompose_lub: forall t1 t11 t12 t2 t21 t22 t3 t31 t32, decompose t1 = (t11,t12) -> decompose t2 = (t21,t22) -> decompose t3 = (t31,t32) -> (lub t1 t2 = t3 <-> (lub t11 t21 = t31 /\ lub t12 t22 = t32)).
Lemma decompose_glb: forall t1 t11 t12 t2 t21 t22 t3 t31 t32, decompose t1 = (t11,t12) -> decompose t2 = (t21,t22) -> decompose t3 = (t31,t32) -> (glb t1 t2 = t3 <-> (glb t11 t21 = t31 /\ glb t12 t22 = t32)).
Lemma unrel_right_obmit: forall a a1 a2 t1 t2 c c1, t1 <> Leaf false -> decompose a = (a1,a2) -> unrel (exist _ (Node t1 t2) c) a = unrel (exist _ t1 c1) a1.
Lemma unrel_left_obmit: forall a a1 a2 t c c', decompose a = (a1,a2) -> unrel (exist _ (Node (Leaf false) t) c) a = unrel (exist _ t c') a2.
Lemma unrel_lub: forall a b1 b2, unrel a (lub b1 b2) = lub (unrel a b1) (unrel a b2).
Lemma unrel_glb: forall a b1 b2, unrel a (glb b1 b2) = glb (unrel a b1) (unrel a b2).
Lemma unrel_bot: forall a, unrel a bot = bot.
Lemma unrel_top: forall a, unrel a top = top.
Lemma unrel_join: forall x a b c, join a b c -> join (unrel x a) (unrel x b) (unrel x c).
Lemma unrel_disjoint: forall a a', a <> bot -> glb a a' = bot -> unrel a a' = bot.
Lemma decompose_height_zero: forall s sL sR, decompose s = (sL,sR) -> height s = 0 -> sL = s /\ sR = s.
Lemma decompose_equal: forall a b aL aR bL bR, decompose a = (aL,aR) -> decompose b = (bL,bR) -> (a = b <-> aL = bL /\ aR = bR).
Lemma decompose_nonzero: forall sL sR s, decompose s = (sL,sR) -> (s <> bot <-> sL <> bot \/ sR <> bot).
Lemma tree_avg_equal: forall sL sR sL' sR' s n, avg n sL sR = Some s -> avg n sL' sR' = Some s -> sL = sL' /\ sR = sR'.
Lemma tree_avg_bot: forall n, avg (S n) bot bot = Some bot.
Lemma tree_avg_zero: forall sL sR s n, avg n sL sR = Some s -> (s = bot <-> sL = bot /\ sR = bot).
Lemma tree_avg_nonzero: forall sL sR s n, avg n sL sR = Some s -> (s <> bot <-> sL <> bot \/ sR <> bot).
Lemma tree_avg_bound: forall sL sR s n, avg n sL sR = Some s -> (height s <= n)%nat.
Lemma Lsh_recompose: Lsh = recompose (top, bot).
Lemma Rsh_recompose: Rsh = recompose (bot,top).
Lemma decompose_Rsh: forall sh, unrel Rsh sh = snd (decompose sh).
Lemma decompose_Lsh: forall sh, unrel Lsh sh = fst (decompose sh).
Lemma rel_Lsh: forall sh, rel Lsh sh = recompose (sh,bot).
Lemma rel_Rsh: forall sh, rel Rsh sh = recompose (bot,sh).
Lemma lub_rel_recompose: forall sh1 sh2, lub (rel Lsh sh1) (rel Rsh sh2) = recompose (sh1,sh2).