Section establishing_decidability.
Reserved Notation "x ≺ y" (at level 70, no associativity).
Inductive bt_lt : bt -> bt -> Prop :=
| in_btlt_0 : forall s t,                   ∅ ≺ s⪧t
| in_btlt_1 : forall s s' t t', s ≺ s' -> s⪧t ≺ s'⪧t'
| in_btlt_2 : forall s t t',    t ≺ t' -> s⪧t ≺ s⪧t'
where "s ≺ t" := (bt_lt s t).
Hint Constructors bt_lt : core.
Fact bt_lt_irrefl s : ~ s ≺ s.
Fact bt_lt_trans r s t : r ≺ s -> s ≺ t -> r ≺ t.
Fact bt_lt_eq_lt_dec s t : { s ≺ t } + { s = t } + { t ≺ s }.
Fixpoint bt_insert s t : bt :=
match t with
| ∅   => s⪧∅
| t⪧u => match bt_lt_eq_lt_dec s t with
| inleft (left _)  => s⪧t⪧u
| inleft (right _) => t⪧u
| inright _        => t⪧(s→u)
end
end
where "s → t" := (bt_insert s t).
Fact bt_lt_eq_lt_dec_refl s : exists H, bt_lt_eq_lt_dec s s = inleft (right H).
Ltac bt_lt_eq H :=
match goal with
|- context [bt_lt_eq_lt_dec ?x ?x]
=> destruct (bt_lt_eq_lt_dec_refl x) as (H & ->)
end.
Fact bt_insert_leaf s : s→∅ = s⪧∅.
Fact bt_insert_gt s t u : t ≺ s -> s→t⪧u = t⪧(s→u).
Fact bt_insert_equiv s t : s→t ≈ s⪧t.
Fixpoint bt_norm t :=
match t with
| ∅   => ∅
| s⪧t => s† → t†
end
where "t †" := (bt_norm t).
Hint Resolve bt_insert_equiv : core.
Fact bt_norm_eq t : t† ≈ t.
Opaque bt_insert.
Tactic Notation "rew" "bt" "insert" :=
repeat match goal with
|             |- context[_→∅]     => rewrite bt_insert_leaf
|             |- context[?x→?x⪧_] => rewrite bt_insert_eq
| H : ?x ≺ ?y |- context[?x→?y⪧_] => rewrite bt_insert_lt with (1 := H)
| H : ?x ≺ ?y |- context[?y→?x⪧_] => rewrite bt_insert_gt with (1 := H)
end.
Tactic Notation "bt" "insert" "case" hyp(x) hyp(y) :=
destruct (bt_lt_eq_lt_dec x y) as [ [|] | ]; subst; rew bt insert; auto.
Tactic Notation "bt" "lt" "trans" constr(t) := apply bt_lt_trans with t; auto.
Tactic Notation "bt" "lt" "cycle" :=
match goal with
| H1 : ?x ≺ ?x |- _  => destruct (@bt_lt_irrefl x); auto
| H1 : ?x ≺ ?y,
H2 : ?y ≺ ?x |- _  => destruct (@bt_lt_irrefl x); bt lt trans y
| H1 : ?x ≺ ?y,
H2 : ?y ≺ ?z,
H3 : ?z ≺ ?x |- _  => destruct (@bt_lt_irrefl x); bt lt trans y; bt lt trans z
end.
Fact bt_insert_cntr s t : s→s→t = s→t.
Fact bt_insert_comm s t u : s→t→u = t→s→u.
Hint Resolve bt_insert_cntr bt_insert_comm bt_norm_eq : core.

Theorem bt_norm_idem s : s†† = s†.