Section Cover.
Variable A : Type.
Variable eqA_dec : forall a b : A, {a = b} + {a <> b}.
Variable empty : A.
(* A list of trees is a cover of a tree if all the trees in the list delimit a frontier in the tree *)
Inductive cover : list (btree A) -> btree A -> Prop :=
| cover_one : forall t, cover (t :: nil) t
| cover_node :
forall l1 l2 t1 t2 t3,
permutation l1 (t1 :: t2 :: l2) ->
cover (node t1 t2 :: l2) t3 -> cover l1 t3.
Hint Constructors cover : core.
Proof using.
intros t l1 l2 H; generalize l2; elim H; clear H t l1 l2; auto.
intros t l2 H; rewrite (permutation_one_inv _ _ _ H); auto.
intros l1 l2 t1 t2 t3 H H0 H1 l0 H2.
apply cover_node with (2 := H0).
apply permutation_trans with (2 := H).
apply permutation_sym; auto.
Qed.
intros t1 t2 l1 H; elim H; clear t1 l1 H; simpl in |- *; auto.
intros t; apply cover_node with (l2 := nil (A:=btree A)) (t1 := t2) (t2 := t);
auto.
intros l1 l2 t1 t0 t3 H H0 H1.
apply cover_node with (l2 := t2 :: l2) (t1 := t1) (t2 := t0); auto.
apply permutation_trans with (t2 :: t1 :: t0 :: l2); auto.
apply permutation_trans with (t1 :: t2 :: t0 :: l2); auto.
apply cover_permutation with (1 := H1); auto.
Qed.
Proof using.
intros l t H; case H; simpl in |- *; auto.
intros t0; discriminate.
intros l1 l2 t1 t2 t3 H0 H1; red in |- *; intros H2;
absurd (length l1 = length (t1 :: t2 :: l2)); auto.
rewrite H2; simpl in |- *; intros; discriminate.
apply permutation_length with (1 := H0); auto.
Qed.
Proof using.
intros l; elim l; simpl in |- *; auto.
intros H; case H; auto.
intros a l0; case l0; auto.
intros H H0; exists a; auto.
intros b l1 H H0; case H.
red in |- *; intros; discriminate.
intros x H1; exists (node a x).
apply cover_cons_l; auto.
Qed.
Proof using.
intros l t1 t2 t3 H; generalize t2 t3; elim H; clear H l t1 t2 t3;
auto with datatypes.
simpl in |- *; intros t t2 t3 [H1| H1]; auto.
rewrite H1; auto.
case H1.
intros l1 l2 t1 t2 t3 H H0 H1 t0 t4 H2 H3.
cut (In t0 (t1 :: t2 :: l2)); auto.
simpl in |- *; intros [H4| [H4| H4]]; auto with datatypes.
apply (H1 (node t1 t2)); simpl in |- *; auto.
rewrite H4; auto.
apply (H1 (node t1 t2)); simpl in |- *; auto.
rewrite H4; auto.
apply (H1 t0); simpl in |- *; auto.
apply permutation_in with (1 := H); simpl in |- *; auto.
Qed.
Proof using.
intros l t1 t2 H H0; apply cover_in_inb_inb with (1 := H) (2 := H0); auto.
Qed.
Let cover_inv_leaf_aux :
forall t l, cover l t -> forall a : A, t = leaf a -> l = leaf a :: nil.
Proof using.
intros t l H; elim H; simpl in |- *; auto.
intros t0 a H0; apply f_equal2 with (f := cons (A:=btree A)); auto.
intros.
generalize (H2 a H3); intros; discriminate.
Qed.
Proof using.
intros a l H; (apply cover_inv_leaf_aux with (t := leaf a); auto).
Qed.
Proof using.
intros t1 t2 H; inversion H; auto.
absurd (length (t1 :: nil) = length (t0 :: t3 :: l2)).
simpl in |- *; intros; discriminate.
apply permutation_length with (1 := H0); auto.
Qed.

Lemma cover_inv_app_aux :
forall t t1 t2 l,
cover l t ->
t = node t1 t2 ->
l = node t1 t2 :: nil \/
(exists l1 : _,
(exists l2 : _, (cover l1 t1 /\ cover l2 t2) /\ permutation l (l1 ++ l2))).