From e29b0c71f446ea6267711c7cc19294fd93fb81ad Mon Sep 17 00:00:00 2001 From: xleroy Date: Sat, 9 Mar 2013 17:28:10 +0000 Subject: Assorted cleanups, esp. to avoid generating _rec and _rect recursors in submodules. (Extraction does not remove them, then.) common/Switch: replaced use of FMaps by our own Maps. git-svn-id: https://yquem.inria.fr/compcert/svn/compcert/trunk@2139 fca1b0fc-160b-0410-b1d3-a4f43f01ea2e --- lib/UnionFind.v | 144 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 80 insertions(+), 64 deletions(-) (limited to 'lib/UnionFind.v') diff --git a/lib/UnionFind.v b/lib/UnionFind.v index 84d0348e..46a886ea 100644 --- a/lib/UnionFind.v +++ b/lib/UnionFind.v @@ -15,14 +15,16 @@ (** A persistent union-find data structure. *) -Require Recdef. -Require Setoid. Require Coq.Program.Wf. Require Import Coqlib. Open Scope nat_scope. Set Implicit Arguments. +(* To avoid useless definitions of inductors in extracted code. *) +Local Unset Elimination Schemes. +Local Unset Case Analysis Schemes. + Module Type MAP. Variable elt: Type. Variable elt_eq: forall (x y: elt), {x=y} + {x<>y}. @@ -151,20 +153,33 @@ Record unionfind : Type := mk { m: M.t elt; mwf: well_founded (order m) }. Definition t := unionfind. +Definition getlink (m: M.t elt) (a: elt) : {a' | M.get a m = Some a'} + {M.get a m = None}. +Proof. + destruct (M.get a m). left. exists e; auto. right; auto. +Defined. + (* The canonical representative of an element *) Section REPR. Variable uf: t. -Function repr (a: elt) {wf (order uf.(m)) a} : elt := - match M.get a uf.(m) with - | Some a' => repr a' - | None => a +Definition F_repr (a: elt) (rec: forall b, order uf.(m) b a -> elt) : elt := + match getlink uf.(m) a with + | inleft (exist a' P) => rec a' P + | inright _ => a end. + +Definition repr (a: elt) : elt := Fix uf.(mwf) (fun _ => elt) F_repr a. + +Lemma repr_unroll: + forall a, repr a = match M.get a uf.(m) with Some a' => repr a' | None => a end. Proof. - intros. auto. - apply mwf. + intros. unfold repr at 1. rewrite Fix_eq. + unfold F_repr. destruct (getlink uf.(m) a) as [[a' P] | Q]. + rewrite P; auto. + rewrite Q; auto. + intros. unfold F_repr. destruct (getlink (m uf) x) as [[a' P] | Q]; auto. Qed. Lemma repr_none: @@ -172,8 +187,7 @@ Lemma repr_none: M.get a uf.(m) = None -> repr a = a. Proof. - intros. - functional induction (repr a). congruence. auto. + intros. rewrite repr_unroll. rewrite H; auto. Qed. Lemma repr_some: @@ -181,14 +195,14 @@ Lemma repr_some: M.get a uf.(m) = Some a' -> repr a = repr a'. Proof. - intros. - functional induction (repr a). congruence. congruence. + intros. rewrite repr_unroll. rewrite H; auto. Qed. Lemma repr_res_none: forall (a: elt), M.get (repr a) uf.(m) = None. Proof. - intros. functional induction (repr a). auto. auto. + apply (well_founded_ind (mwf uf)). intros. + rewrite repr_unroll. destruct (M.get x (m uf)) as [y|] eqn:X; auto. Qed. Lemma repr_canonical: @@ -308,25 +322,23 @@ Definition identify := mk (M.set a b uf.(m)) identify_wf. Lemma repr_identify_1: forall x, repr uf x <> a -> repr identify x = repr uf x. Proof. - intros. functional induction (repr uf x). - - rewrite <- IHe; auto. apply repr_some. simpl. rewrite M.gsspec. - destruct (M.elt_eq a0 a). congruence. auto. - - apply repr_none. simpl. rewrite M.gsspec. rewrite dec_eq_false; auto. + intros x0; pattern x0. apply (well_founded_ind (mwf uf)); intros. + rewrite (repr_unroll uf) in *. + destruct (M.get x (m uf)) as [a'|] eqn:X. + rewrite <- H; auto. + apply repr_some. simpl. rewrite M.gsspec. rewrite dec_eq_false; auto. congruence. + apply repr_none. simpl. rewrite M.gsspec. rewrite dec_eq_false; auto. Qed. Lemma repr_identify_2: forall x, repr uf x = a -> repr identify x = repr uf b. Proof. - intros. functional induction (repr uf x). - - rewrite <- IHe; auto. apply repr_some. simpl. rewrite M.gsspec. - rewrite dec_eq_false; auto. congruence. - - transitivity (repr identify b). apply repr_some. simpl. - rewrite M.gsspec. apply dec_eq_true. - apply repr_identify_1. auto. + intros x0; pattern x0. apply (well_founded_ind (mwf uf)); intros. + rewrite (repr_unroll uf) in H0. destruct (M.get x (m uf)) as [a'|] eqn:X. + rewrite <- (H a'); auto. + apply repr_some. simpl. rewrite M.gsspec. rewrite dec_eq_false; auto. congruence. + subst x. rewrite (repr_unroll identify). simpl. rewrite M.gsspec. + rewrite dec_eq_true. apply repr_identify_1. auto. Qed. End IDENTIFY. @@ -474,14 +486,22 @@ Section PATHLEN. Variable uf: t. -Function pathlen (a: elt) {wf (order uf.(m)) a} : nat := - match M.get a uf.(m) with - | Some a' => S (pathlen a') - | None => O +Definition F_pathlen (a: elt) (rec: forall b, order uf.(m) b a -> nat) : nat := + match getlink uf.(m) a with + | inleft (exist a' P) => S (rec a' P) + | inright _ => O end. + +Definition pathlen (a: elt) : nat := Fix uf.(mwf) (fun _ => nat) F_pathlen a. + +Lemma pathlen_unroll: + forall a, pathlen a = match M.get a uf.(m) with Some a' => S(pathlen a') | None => O end. Proof. - intros. auto. - apply mwf. + intros. unfold pathlen at 1. rewrite Fix_eq. + unfold F_pathlen. destruct (getlink uf.(m) a) as [[a' P] | Q]. + rewrite P; auto. + rewrite Q; auto. + intros. unfold F_pathlen. destruct (getlink (m uf) x) as [[a' P] | Q]; auto. Qed. Lemma pathlen_none: @@ -489,8 +509,7 @@ Lemma pathlen_none: M.get a uf.(m) = None -> pathlen a = 0. Proof. - intros. - functional induction (pathlen a). congruence. auto. + intros. rewrite pathlen_unroll. rewrite H; auto. Qed. Lemma pathlen_some: @@ -498,8 +517,7 @@ Lemma pathlen_some: M.get a uf.(m) = Some a' -> pathlen a = S (pathlen a'). Proof. - intros. - functional induction (pathlen a). congruence. congruence. + intros. rewrite pathlen_unroll. rewrite H; auto. Qed. Lemma pathlen_zero: @@ -507,9 +525,8 @@ Lemma pathlen_zero: Proof. intros; split; intros. apply pathlen_none. rewrite <- H. apply repr_res_none. - functional induction (pathlen a). - congruence. - apply repr_none. auto. + apply repr_none. rewrite pathlen_unroll in H. + destruct (M.get a (m uf)); congruence. Qed. End PATHLEN. @@ -529,23 +546,19 @@ Proof. intros. unfold merge. destruct (M.elt_eq (repr uf a) (repr uf b)). auto. - functional induction (pathlen (identify uf (repr uf a) b (repr_res_none uf a) (sym_not_equal n)) x). - simpl in e. rewrite M.gsspec in e. - destruct (M.elt_eq a0 (repr uf a)). - inversion e; subst a'; clear e. - replace (repr uf a0) with (repr uf a). rewrite dec_eq_true. - rewrite IHn0. rewrite dec_eq_false; auto. - rewrite (pathlen_none uf a0). omega. subst a0. apply repr_res_none. - subst a0. rewrite repr_canonical; auto. - rewrite (pathlen_some uf a0 a'); auto. - rewrite IHn0. - replace (repr uf a0) with (repr uf a'). - destruct (M.elt_eq (repr uf a') (repr uf a)); omega. - symmetry. apply repr_some; auto. - - simpl in e. rewrite M.gsspec in e. destruct (M.elt_eq a0 (repr uf a)). - congruence. rewrite (repr_none uf a0); auto. - rewrite dec_eq_false; auto. symmetry. apply pathlen_none; auto. + set (uf' := identify uf (repr uf a) b (repr_res_none uf a) (not_eq_sym n)). + pattern x. apply (well_founded_ind (mwf uf')); intros. + rewrite (pathlen_unroll uf'). destruct (M.get x0 (m uf')) as [x'|] eqn:G. + rewrite H; auto. simpl in G. rewrite M.gsspec in G. + destruct (M.elt_eq x0 (repr uf a)). rewrite e. rewrite repr_canonical. rewrite dec_eq_true. + inversion G. subst x'. rewrite dec_eq_false; auto. + replace (pathlen uf (repr uf a)) with 0. omega. + symmetry. apply pathlen_none. apply repr_res_none. + rewrite (repr_unroll uf x0), (pathlen_unroll uf x0); rewrite G. + destruct (M.elt_eq (repr uf x') (repr uf a)); omega. + simpl in G. rewrite M.gsspec in G. destruct (M.elt_eq x0 (repr uf a)); try discriminate. + rewrite (repr_none uf x0) by auto. rewrite dec_eq_false; auto. + symmetry. apply pathlen_zero; auto. apply repr_none; auto. Qed. Lemma pathlen_gt_merge: @@ -604,13 +617,16 @@ Definition compress := mk (M.set a b uf.(m)) compress_wf. Lemma repr_compress: forall x, repr compress x = repr uf x. Proof. - intros. functional induction (repr compress x). - simpl in e. rewrite M.gsspec in e. destruct (M.elt_eq a0 a). - subst a0. injection e; intros. subst a'. rewrite IHe. rewrite <- a_repr_b. - apply repr_canonical. - rewrite IHe. symmetry. apply repr_some; auto. - simpl in e. rewrite M.gsspec in e. destruct (M.elt_eq a0 a). - congruence. symmetry. apply repr_none. auto. + apply (well_founded_ind (mwf compress)); intros. + rewrite (repr_unroll compress). + destruct (M.get x (m compress)) as [y|] eqn:G. + rewrite H; auto. + simpl in G. rewrite M.gsspec in G. destruct (M.elt_eq x a). + inversion G. subst x y. rewrite <- a_repr_b. apply repr_canonical. + symmetry; apply repr_some; auto. + simpl in G. rewrite M.gsspec in G. destruct (M.elt_eq x a). + congruence. + symmetry; apply repr_none; auto. Qed. End COMPRESS. -- cgit