1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268
| Require Import Arith.
Inductive tree : Set :=
| Leaf: tree
| Node: tree -> nat -> tree -> tree.
Fixpoint find (t:tree) (n:nat) {struct t} :=
match t with
| Leaf => false
| Node l m r =>
match nat_compare n m with
| Lt => find l n
| Gt => find r n
| Eq => true
end
end.
Fixpoint insert (t:tree) (n:nat) {struct t} :=
match t with
| Leaf => Node Leaf n Leaf
| Node l m r =>
match nat_compare n m with
| Lt => Node (insert l n) m r
| Gt => Node l m (insert r n)
| Eq => t
end
end.
Inductive tree_between : tree -> nat -> nat -> Prop :=
| leaf_tree_between :
forall a b,
tree_between Leaf a b
| node_tree_between :
forall l m r, forall a b,
tree_between l a m -> a < m < b -> tree_between r m b ->
tree_between (Node l m r) a b
with tree_less : tree -> nat -> Prop :=
| leaf_tree_less :
forall b,
tree_less Leaf b
| node_tree_less :
forall l m r, forall b,
tree_less l m -> m < b -> tree_between r m b ->
tree_less (Node l m r) b
with tree_more : tree -> nat -> Prop :=
| leaf_tree_more :
forall a,
tree_more Leaf a
| node_tree_more :
forall l m r, forall a,
tree_between l a m -> a < m -> tree_more r m ->
tree_more (Node l m r) a.
Inductive tree_ordered : tree -> Prop :=
| leaf_tree_ordered :
tree_ordered Leaf
| node_tree_ordered :
forall l m r,
tree_less l m -> tree_more r m ->
tree_ordered (Node l m r).
Inductive member : tree -> nat -> Prop :=
| left_member :
forall m n l r,
member l n ->
member (Node l m r) n
| right_member :
forall m n l r,
member r n ->
member (Node l m r) n
| root_member :
forall l n r,
member (Node l n r) n.
Lemma tree_between_more:
forall t a b,
tree_between t a b -> tree_more t a.
Proof.
induction t; intros a b tb.
apply leaf_tree_more.
inversion tb; subst; clear tb. apply node_tree_more.
exact H2.
destruct H5. exact H.
exact (IHt2 n b H6).
Qed.
Lemma tree_between_less:
forall t a b,
tree_between t a b -> tree_less t b.
Proof.
induction t; intros a b tb.
apply leaf_tree_less.
inversion tb; subst; clear tb. apply node_tree_less.
exact (IHt1 a n H2).
destruct H5. exact H0.
exact H6.
Qed.
Lemma tree_less_ordered:
forall t n,
tree_less t n -> tree_ordered t.
Proof.
intros. induction H.
exact leaf_tree_ordered.
apply node_tree_ordered.
exact H.
exact (tree_between_more r m b H1).
Qed.
Lemma tree_more_ordered:
forall t n,
tree_more t n -> tree_ordered t.
Proof.
intros. induction H.
exact leaf_tree_ordered.
apply node_tree_ordered.
exact (tree_between_less l a m H).
exact H1.
Qed.
Lemma member_more:
forall t n a,
member t n -> tree_more t a -> a < n.
Proof.
induction t; intros m a mem more.
(* Leaf *)
inversion mem.
(* Node *)
inversion more; subst; clear more.
inversion mem; subst; clear mem.
(* left_member *)
apply tree_between_more in H2.
exact (IHt1 m a H6 H2).
(* right member *)
apply gt_trans with (m := n).
exact (IHt2 m n H6 H5).
red. exact H4.
(* root member *)
exact H4.
Qed.
Lemma member_less:
forall t n a,
member t n -> tree_less t a -> a > n.
Proof.
induction t; intros m a mem less.
(* Leaf *)
inversion mem.
(* Node *)
inversion less; subst; clear less.
inversion mem; subst; clear mem.
(* left_member *)
apply gt_trans with (m := n).
red. assumption.
exact (IHt1 m n H6 H2).
(* right_member *)
apply tree_between_less in H5.
exact (IHt2 m a H6 H5).
(* root_member *)
red. assumption.
Qed.
Theorem find_iff_member :
forall t, tree_ordered t ->
forall n, find t n = true <-> member t n.
Proof.
intros t ord n.
split; intro H.
(* -> *)
induction t.
(* Leaf *)
inversion H.
(* Node *)
inversion ord; subst; clear ord.
simpl in H. remember (nat_compare n n0) as n_n0.
symmetry in Heqn_n0. destruct n_n0.
(* n = n0 *)
apply nat_compare_eq in Heqn_n0. subst.
apply root_member.
(* n < n0 *)
apply left_member. apply tree_less_ordered in H2.
exact (IHt1 H2 H).
(* n > n0 *)
apply right_member. apply tree_more_ordered in H4.
exact (IHt2 H4 H).
(* <- *)
induction t.
(* Leaf *)
inversion H.
(* Node *)
inversion ord; subst; clear ord.
simpl. remember (nat_compare n n0) as n_n0.
symmetry in Heqn_n0. destruct n_n0.
(* n=m *)
reflexivity.
(* n<m *)
apply tree_less_ordered in H2.
inversion H; subst; clear H.
(* left_member *)
exact (IHt1 H2 H6).
(* right_member *)
apply nat_compare_lt in Heqn_n0.
apply (member_more t2 n n0 H6) in H4.
apply lt_asym in H4. contradiction.
(* root_member *)
apply nat_compare_lt in Heqn_n0.
contradict Heqn_n0. apply lt_irrefl.
(* n>m *)
apply tree_more_ordered in H4.
inversion H; subst; clear H.
(* left_member *)
apply nat_compare_gt in Heqn_n0.
apply (member_less t1 n n0 H6) in H2.
apply gt_asym in H2. contradiction.
(* right_member *)
exact (IHt2 H4 H6).
(* root_member *)
apply nat_compare_gt in Heqn_n0.
contradict Heqn_n0. apply lt_irrefl.
Qed.
Theorem insert_conservative :
forall t m n, member t m -> member (insert t n) m.
Proof.
intros t m n mem.
induction t.
(* Leaf *)
inversion mem.
(* Node *)
simpl. destruct (nat_compare n n0).
(* n = n0 *)
assumption.
(* n < n0 *)
inversion mem; subst; clear mem.
(* left_member *)
apply left_member. apply IHt1. assumption.
(* right_member *)
apply right_member. assumption.
(* root_member *)
apply root_member.
(* n > n0 *)
inversion mem; subst; clear mem.
(* left_member *)
apply left_member. assumption.
(* right_member *)
apply right_member. apply IHt2. assumption.
(* root_member *)
apply root_member.
Qed.
Theorem insert_inclusive :
forall t n, member (insert t n) n.
Proof.
intros t n. induction t.
(* Leaf *)
simpl. apply root_member.
(* Node *)
simpl. remember (nat_compare n n0) as n_n0. destruct n_n0.
(* n = n0 *)
symmetry in Heqn_n0.
apply nat_compare_eq in Heqn_n0. subst.
apply root_member.
(* n < n0 *)
apply left_member. assumption.
(* n > n0 *)
apply right_member. assumption.
Qed. |
Partager