|
| 1 | + |
| 2 | +Require Export Arith. |
| 3 | +Require Export Peano_dec. |
| 4 | +Require Export Wf_nat. |
| 5 | +Require Export Omega. |
| 6 | + |
| 7 | +(** Trees and forests. *) |
| 8 | + |
| 9 | +Inductive tree : Set := |
| 10 | + | Node : nat -> forest -> tree |
| 11 | + |
| 12 | +with forest : Set := |
| 13 | + | Fnil : forest |
| 14 | + | Fcons : tree -> forest -> forest. |
| 15 | + |
| 16 | +Scheme tree_forest_ind := Induction for tree Sort Prop |
| 17 | +with forest_tree_ind := Induction for forest Sort Prop. |
| 18 | + |
| 19 | +Definition is_nil (f:forest) : bool := match f with |
| 20 | + | Fnil => true |
| 21 | + | Fcons _ _ => false end. |
| 22 | + |
| 23 | +Hint Unfold is_nil. |
| 24 | + |
| 25 | +Definition nodi (t:tree) : nat := match t with |
| 26 | + | Node i _ => i end. |
| 27 | + |
| 28 | +Definition nodf (t:tree) : forest := match t with |
| 29 | + | Node _ f => f end. |
| 30 | + |
| 31 | +Definition head (f:forest) : tree := match f with |
| 32 | + | Fnil => Node 0 Fnil (* absurd *) |
| 33 | + | Fcons t _ => t end. |
| 34 | + |
| 35 | +Definition tail (f:forest) : forest := match f with |
| 36 | + | Fnil => Fnil |
| 37 | + | Fcons _ f => f end. |
| 38 | + |
| 39 | +(** Concatenation of two forests. *) |
| 40 | + |
| 41 | +Fixpoint append (f:forest) : forest -> forest := |
| 42 | + fun f0:forest => match f with |
| 43 | + Fnil => f0 |
| 44 | + | (Fcons t f') => (Fcons t (append f' f0)) end. |
| 45 | + |
| 46 | +(** Size of trees and forests. *) |
| 47 | + |
| 48 | +Fixpoint sizef (f:forest) : nat := |
| 49 | + match f with Fnil => O |
| 50 | + | (Fcons t f') => (plus (sizet t) (sizef f')) end |
| 51 | + |
| 52 | +with sizet (t:tree) : nat := |
| 53 | + match t with (Node _ f) => (S (sizef f)) end. |
| 54 | + |
| 55 | +(*i Concatenation of a tree at the end of a forest. |
| 56 | +
|
| 57 | +Fixpoint appendt [f:forest] : tree -> forest := |
| 58 | + [t:tree]Cases f of |
| 59 | + Fnil => (Fcons t Fnil) |
| 60 | + | (Fcons t' f') => (Fcons t' (appendt f' t)) end. |
| 61 | +i*) |
| 62 | + |
| 63 | +(** Occurrence of an index [i] in a tree ([int]) and in a forest ([inf]). *) |
| 64 | + |
| 65 | +Inductive int (i:nat) : tree -> Prop := |
| 66 | + | int_root : forall (f:forest), (int i (Node i f)) |
| 67 | + | int_sons : forall (j:nat)(f:forest), (inf i f) -> (int i (Node j f)) |
| 68 | + |
| 69 | +with inf (i:nat) : forest -> Prop := |
| 70 | + | inf_hd : forall (t:tree)(f:forest), (int i t) -> (inf i (Fcons t f)) |
| 71 | + | inf_tl : forall (t:tree)(f:forest), (inf i f) -> (inf i (Fcons t f)). |
| 72 | + |
| 73 | +Hint Resolve int_root int_sons inf_hd inf_tl. |
| 74 | + |
| 75 | +(** Lemmas on [inf]. *) |
| 76 | + |
| 77 | +Lemma inf_in_append_1 : forall (f f0:forest)(i:nat), |
| 78 | + (inf i f) -> (inf i (append f f0)). |
| 79 | +Proof. |
| 80 | +induction f; simpl. |
| 81 | +intros; inversion H; auto. |
| 82 | +intros; inversion H; auto. |
| 83 | +Save. |
| 84 | + |
| 85 | +Lemma inf_in_append_2 : forall (f f0:forest)(i:nat), |
| 86 | + (inf i f0) -> (inf i (append f f0)). |
| 87 | +Proof. |
| 88 | +induction f; simpl; auto. |
| 89 | +Save. |
| 90 | + |
| 91 | +Lemma inf_append : forall (f f0:forest)(i:nat), |
| 92 | + (inf i (append f f0)) -> (inf i f) \/ (inf i f0). |
| 93 | +Proof. |
| 94 | +induction f; simpl; intros; auto. |
| 95 | +inversion H; intuition. |
| 96 | +elim (IHf f0 i H1); auto. |
| 97 | +Save. |
| 98 | + |
| 99 | +Lemma inf_append_inv : forall f f0 i, |
| 100 | + inf i (append f f0) -> inf i f \/ inf i f0. |
| 101 | +Admitted. |
| 102 | + |
| 103 | +Hint Resolve inf_in_append_1 inf_in_append_2 inf_append. |
| 104 | + |
| 105 | +(** The property for two forests not to have indexes in common. *) |
| 106 | + |
| 107 | +Definition disjoint (f f':forest) : Prop := |
| 108 | + forall i, inf i f -> inf i f' -> False. |
| 109 | + |
| 110 | +Lemma disjoint_sym : forall f1 f2, disjoint f1 f2 -> disjoint f2 f1. |
| 111 | +Admitted. |
| 112 | + |
| 113 | +Hint Resolve disjoint_sym. |
| 114 | + |
| 115 | +(*i A technical lemma about [appendt]: |
| 116 | + if [t::f = appendt f' t'] with [~f'=Fnil] then |
| 117 | + there exists a forest [f''] such that [f'=t::f''] and [f=appendt f'' t']. |
| 118 | +
|
| 119 | +Lemma cons_eq_appendt : |
| 120 | + (t,t':tree)(f':forest) ~f'=Fnil -> (f:forest) (Fcons t f)=(appendt f' t') -> |
| 121 | + (EX f'':forest | f'=(Fcons t f'') & f=(appendt f'' t')). |
| 122 | +Proof. |
| 123 | +induction f'. |
| 124 | +Intro H; elim H; Reflexivity. |
| 125 | +intros. |
| 126 | +Exists f. |
| 127 | +simpl in H1. Injection H1. |
| 128 | +intros eqf eqt; rewrite eqt; Reflexivity. |
| 129 | +simpl in H1. Injection H1. |
| 130 | +Trivial. |
| 131 | +Save. |
| 132 | +i*) |
| 133 | + |
| 134 | +(*s If index [i] occurs in [t] or [f], it occurs in [f@t]. *) |
| 135 | + |
| 136 | +(*i |
| 137 | +Lemma inf_in_appendt : (t:tree)(f:forest)(i:nat) |
| 138 | + (inf i f) -> (inf i (appendt f t)). |
| 139 | +Proof. |
| 140 | +induction f; simpl; auto. |
| 141 | +intros; inversion H0; auto. |
| 142 | +Save. |
| 143 | +
|
| 144 | +Lemma int_in_appendt : (t:tree)(f:forest)(i:nat) |
| 145 | + (int i t) -> (inf i (appendt f t)). |
| 146 | +Proof. |
| 147 | +induction f; simpl; auto. |
| 148 | +Save. |
| 149 | +
|
| 150 | +Hints Resolve inf_in_appendt int_in_appendt. |
| 151 | +i*) |
| 152 | + |
| 153 | +(*i |
| 154 | +Proof. |
| 155 | +intros until f; pattern f; apply forest_tree_ind with |
| 156 | + P := [t:tree]Cases t of (Node i f') => |
| 157 | + ((i:nat)(inf i f') -> (s' i)=(s i)) -> (F s f') -> (F s' f') end. |
| 158 | +auto. |
| 159 | +auto. |
| 160 | +intros. |
| 161 | +inversion H2; intros; auto. |
| 162 | +apply f_odd; auto. |
| 163 | +unfold Z; unfold Z in H4; intros. |
| 164 | +rewrite H1; auto. |
| 165 | +rewrite <- H3; auto. |
| 166 | +rewrite H1; auto. |
| 167 | +rewrite <- H3; auto. |
| 168 | +i*) |
| 169 | + |
| 170 | +(** The nullity of a forest is decidable. *) |
| 171 | + |
| 172 | +Lemma dec_is_Fnil : forall (f:forest), f=Fnil \/ ~f=Fnil. |
| 173 | +Proof. |
| 174 | +intro f; case f; [ auto | right; discriminate ]. |
| 175 | +Save. |
| 176 | + |
| 177 | +Lemma append_nil : forall (f f0:forest), |
| 178 | + (append f f0)=Fnil -> f=Fnil /\ f0=Fnil. |
| 179 | +Proof. |
| 180 | +induction f; simpl; intuition. |
| 181 | +intros; discriminate H. |
| 182 | +discriminate H. |
| 183 | +Save. |
| 184 | + |
| 185 | +(*i [appendt f t] is not [Fnil]. |
| 186 | + |
| 187 | +Lemma appendt_is_not_nil : (f:forest)(t:tree)~(appendt f t)=Fnil. |
| 188 | +Proof. |
| 189 | +induction f; simpl; intros; Discriminate. |
| 190 | +Save. |
| 191 | + |
| 192 | +Hints Resolve appendt_is_not_nil. |
| 193 | +i*) |
| 194 | + |
| 195 | +(*i [appendt] is injective. |
| 196 | + |
| 197 | +Lemma appendt_eq_appendt : (f,f':forest)(t,t':tree) |
| 198 | + (appendt f t)=(appendt f' t') -> f=f' /\ t=t'. |
| 199 | +Proof. |
| 200 | +induction f; simpl; intros. |
| 201 | +induction f'; simpl; intros. |
| 202 | +simpl in H. Injection H. auto. |
| 203 | +simpl in H. Injection H. |
| 204 | +intros; elim (appendt_is_not_nil f' t' (sym_eq ? ? ? H0)). |
| 205 | +induction f'; simpl; intros; simpl in H0; Injection H0; intros. |
| 206 | +elim (appendt_is_not_nil f0 t0 H1). |
| 207 | +rewrite H2. |
| 208 | +elim (H f' t0 t' H1); intros. |
| 209 | +split; Try assumption. apply (f_equal ? ? (Fcons t1)). Eauto. |
| 210 | +Save. |
| 211 | + |
| 212 | +Hints Resolve appendt_eq_appendt. |
| 213 | +i*) |
| 214 | + |
| 215 | +(** Length of a forest (i.e. number of trees). *) |
| 216 | + |
| 217 | +Fixpoint lengthf (f:forest) : nat := |
| 218 | + match f with Fnil => O | (Fcons _ f') => (S (lengthf f')) end. |
| 219 | + |
| 220 | +(*i The length of of [f] is less than the length of [appendt f t]. |
| 221 | + |
| 222 | +Lemma lt_length_appendt : (f:forest)(t:tree)(lt (lengthf f) (lengthf (appendt f t))). |
| 223 | +Proof. |
| 224 | +induction f; simpl; auto. |
| 225 | +intros. apply lt_n_S. apply H. |
| 226 | +Save. |
| 227 | +i*) |
| 228 | + |
| 229 | +(** Validity. A tree/forest is valid if all its nodes are different. *) |
| 230 | + |
| 231 | +Inductive validt : tree -> Prop := |
| 232 | +| validt_node : forall i f, ~(inf i f) -> validf f -> validt (Node i f) |
| 233 | + |
| 234 | +with validf : forest -> Prop := |
| 235 | +| validf_nil : validf Fnil |
| 236 | +| validf_cons : forall t f, validt t -> validf f -> |
| 237 | + (forall i, int i t -> inf i f -> False) -> validf (Fcons t f). |
| 238 | + |
| 239 | +Hint Resolve validt_node validf_nil validf_cons. |
| 240 | + |
| 241 | +Lemma valid_cons : forall t f, validf (Fcons t f) -> validf f. |
| 242 | +Proof. |
| 243 | + inversion 1; intuition. |
| 244 | +Qed. |
| 245 | + |
| 246 | +Lemma valid_cons_node : |
| 247 | + forall i f1 f2, validf (Fcons (Node i f1) f2) -> validf (append f1 f2). |
| 248 | +Proof. |
| 249 | + induction f1; simpl. |
| 250 | + inversion 1; auto. |
| 251 | + intros; apply validf_cons. |
| 252 | + inversion H; intuition. |
| 253 | + inversion H2; intuition. |
| 254 | + inversion H8; intuition. |
| 255 | + apply IHf1; clear IHf1. |
| 256 | + (*TODO*) |
| 257 | +Admitted. |
| 258 | + |
| 259 | +Hint Resolve valid_cons valid_cons_node. |
| 260 | + |
| 261 | +Lemma validf_not_inf : forall n f1 f2, |
| 262 | + validf (Fcons (Node n f1) f2) -> ~(inf n (append f1 f2)). |
| 263 | +Admitted. |
| 264 | + |
| 265 | +Hint Resolve validf_not_inf. |
| 266 | + |
| 267 | +Lemma validf_disjoint: forall n f1 f2, |
| 268 | + validf (Fcons (Node n f1) f2) -> disjoint f1 f2. |
| 269 | +Admitted. |
| 270 | + |
| 271 | +Hint Resolve validf_disjoint. |
| 272 | + |
0 commit comments