From a264ffa5a06f689e68dacc99cf18af817557c2a2 Mon Sep 17 00:00:00 2001 From: Pierre Courtieu <Pierre.Courtieu@cnam.fr> Date: Thu, 7 Nov 2024 17:06:23 +0100 Subject: [PATCH] WIP. --- .../Gathering/InR2/Weber/Weber_point.v | 597 +++++------------- Util/ListComplements.v | 3 +- Util/NumberComplements.v | 61 ++ Util/Preliminary.v | 83 +++ 4 files changed, 311 insertions(+), 433 deletions(-) diff --git a/CaseStudies/Gathering/InR2/Weber/Weber_point.v b/CaseStudies/Gathering/InR2/Weber/Weber_point.v index f3e9f05f..683e2137 100644 --- a/CaseStudies/Gathering/InR2/Weber/Weber_point.v +++ b/CaseStudies/Gathering/InR2/Weber/Weber_point.v @@ -1740,7 +1740,7 @@ assert (Hineq : (norm (list_sumVS (map (u w) ps)) + INR (countA_occ equiv R2_EqD * rewrite S_INR. lra. } transitivity (INR (Nat.div2 (length ps + 1))) ; [| now apply le_INR]. -eapply Rplus_le_reg_r ; rewrite Hineq. Search INR Rle le. +eapply Rplus_le_reg_r ; rewrite Hineq. rewrite <-(Rplus_le_compat_l (INR (Nat.div2 (length ps + 1))) _ _ (le_INR _ _ Hcount)). rewrite <-plus_INR. apply le_INR. apply div2_sum_p1_ge. Qed. @@ -1799,358 +1799,7 @@ Qed. (* Notation "L '^lftof' x '^in' ps" := (INR (Rlength (line_left L x ps))) (at level 100, no associativity). *) -Notation "'^R' x" := (INR (Rlength x)) (at level 180, no associativity). - -(* Definition lefts L x (ps:list R2) := (INR (Rlength (line_left L x ps))). *) -Definition rights L x (ps:list R2) := (INR (Rlength (line_right L x ps))). -(* Definition ons L x (ps:list R2) := (INR (Rlength (line_on L x ps))). *) -(* -(* We can always find a point w' strictly on the right of w but close - enough so that there is not point of ps between w and w', including - w' itself. Thus the left of w' is exactly left w + on w and right w - = right w'. - -------------------p1---p2-----------w----w'---p3----p4----------- - p5 - p6 - -In this case: take e.g. w' = the middle of [w;p3] *) -Lemma shift_right: forall L w (ps: list R2), - ps <> nil -> (* Seems necessary *) - line_dir L =/= 0%VS -> - aligned_on L (w :: ps) -> - { w' | aligned_on L (w' :: w :: ps) /\ - L^on w' ps = nil - /\ PermutationA equiv (L^left w' ps) (L^left w ps ++ L^on w ps) - /\ L^right w' ps= L^right w ps - /\ w =/=w' }. -Proof. - intros L w ps h_ps_nonil h_lineOK h_align. - assert (line_contains L w) as h_line_w. - { apply aligned_on_cons_iff in h_align. - now destruct h_align. } - assert (forall w' : R2, ((L ^P) w <= (L^P) w')%R -> - inclA equiv ((L ^right) w' ps) ((L ^right) w ps)) - as h_right_incl. - { now apply line_right_inclA_3. } - assert (forall w' : R2, ((L ^P) w' <= (L^P) w)%R -> - inclA equiv ((L ^left) w' ps) ((L ^left) w ps)) - as h_left_incl. - { now apply line_left_inclA_3. } - specialize (@line_left_on_right_partition _ _ _ _ _ L w ps) as h_split. - specialize (@line_right_inclA_4 _ _ _ _ _ L w ps) as h_right. - - (* TODO: first see if there is something in ps on the right of w. *) - destruct ((L ^right) w ps) eqn:heq_lright. - - exists ((L^-P)((L^P) w + 1))%R. - remember ((L^-P)((L^P) w + 1))%R as w'. - specialize (@line_left_on_right_partition _ _ _ _ _ L w' ps) as h_split'. - assert ((L ^P) w < (L ^P) w')%R as h_lt_w_w'. - { subst w'. - rewrite line_P_iP;try auto. - lra. } - assert ((L ^P) w <= (L ^P) w')%R as h_le_w_w' by lra. - specialize h_right_incl with (1:=h_le_w_w'). - specialize h_right with (1:=h_lt_w_w'). - assert (line_contains L w'). - { subst. - lazy beta delta [line_contains]. - rewrite line_P_iP;auto. } - assert ((L ^on) w' ps = nil) as h_lon_w'_nil. - { specialize inclA_nil with (2:=h_right). - intros H0. - apply H0. - typeclasses eauto. } - assert (h_right_w'_nil : (L ^right) w' ps = nil). - { apply inclA_nil with (2:=h_right_incl). - typeclasses eauto. } - assert (PermutationA equiv ((L ^right) w ps) ((L ^right) w' ps)) as h_right_w_w'. - { rewrite heq_lright. - apply inclA_nil in h_right_incl. - rewrite h_right_incl. - - constructor. - - typeclasses eauto. } - repeat split. - + rewrite -> aligned_on_cons_iff. - split;auto. - + assumption. - + (* rewrite <- heq_lright in h_split. *) - (* rewrite H0 in h_split. *) - setoid_rewrite app_nil_end. - rewrite app_nil_end at 1. - - setoid_rewrite <- h_lon_w'_nil at 1. - setoid_rewrite <- heq_lright at 1 2. - rewrite h_right_w_w' at 1. - setoid_rewrite app_assoc_reverse. - transitivity ps. - * now symmetry. - * now rewrite heq_lright. - + rewrite heq_lright in h_right_w_w'. - apply PermutationA_nil with (2:=h_right_w_w'). - typeclasses eauto. - + rewrite Heqw'. - intro abs. - assert ((L ^P) w == (L ^P) ((L ^-P) ((L ^P) w + 1))) as h_abs. - { now rewrite <- abs. } - setoid_rewrite line_P_iP in h_abs. - cbn -[line_proj] in h_abs. - * lra. - * assumption. - - rewrite <- heq_lright in *. - assert ((L ^right) w ps <> nil). - { symmetry. - rewrite heq_lright. - apply nil_cons. } - remember (L^-P (((line_min L ((L ^right) w ps)) - (L^P w)) / 2)) as w'. - exists w'. - - repeat split. - + rewrite -> aligned_on_cons_iff. - split. - * subst w'. - now apply line_contains_proj_inv. - * assumption. - + eapply (Preliminary.PermutationA_nil setoid_equiv). - Print Instances Proper. - rewrite h_split. - rewrite 2 line_on_app. - assert ((L ^on) w' ((L ^left) w ps) = nil). - { } - assert ((L ^on) w' ((L ^on) w ps) = nil). - { admit. } - assert ((L ^on) w' ((L ^right) w ps) = nil). - { admit. } - app_eq_nil - subst w'. - red. - rewrite line_P_iP. - reflexivity. - * - remember (middle w (L^-P (line_min L ((L ^right) w ps))%VS)) as w'. - exists w'. - specialize (@line_left_on_right_partition _ _ _ _ _ L w' ps) as h_split'. - assert (line_contains L w'). - { subst. - apply line_contains_middle;auto. - lazy beta delta [line_contains]. - rewrite line_P_iP;auto. } - - repeat split. - + rewrite -> aligned_on_cons_iff. - split;auto. - + - - destruct ((L ^on) w' ps) eqn:heq_lonw' ;auto. - assert ((L ^P) w < (L ^P) r0)%R. - { admit. } - assert ((L ^P) r0 < ((L ^min) ((L ^right) w ps)))%R. - { admit. } - - - - - assert ((L ^P) w < (L ^P)((L ^-P) ((L ^min) ((L ^right) w ps))))%R as h_lt_w_w'. - { rewrite line_P_iP;auto. - specialize (@line_min_spec_nonnil _ _ _ _ _ L ps) with (1:=h_ps_nonil) as h_lmin_ps. - specialize (@line_min_spec_nonnil _ _ _ _ _ L) with (1:=H) as h_lmin_ps2. - apply Rgt_lt. - specialize (@line_right_spec _ _ _ _ _ L w ((L ^-P) ((L ^min) ((L ^right) w ps))) ps) as h. - destruct h as [h1 h2]. - - rewrite h_lmin_ps2. - - } - assert ((L ^P) w < (L ^P) w')%R as h_lt_w_w'. - { subst w'. - specialize (line_bounds L ps) as h_line_bounds. - - rewrite line_P_iP;try auto. - lra. } - assert ((L ^P) w <= (L ^P) w')%R as h_le_w_w' by lra. - specialize h_right_incl with (1:=h_le_w_w'). - specialize h_right with (1:=h_lt_w_w'). - assert (line_contains L w'). - { subst. - lazy beta delta [line_contains]. - rewrite line_P_iP;auto. } - assert ((L ^on) w' ps = nil) as h_lon_w'_nil. - { specialize inclA_nil with (2:=h_right). - intros H0. - apply H0. - typeclasses eauto. } - assert (h_right_w'_nil : (L ^right) w' ps = nil). - { apply inclA_nil with (2:=h_right_incl). - typeclasses eauto. } - assert (PermutationA equiv ((L ^right) w ps) ((L ^right) w' ps)) as h_right_w_w'. - { rewrite heq_lright. - apply inclA_nil in h_right_incl. - rewrite h_right_incl. - - constructor. - - typeclasses eauto. } - repeat split. - + rewrite -> aligned_on_cons_iff. - split;auto. - + assumption. - + (* rewrite <- heq_lright in h_split. *) - (* rewrite H0 in h_split. *) - setoid_rewrite app_nil_end. - rewrite app_nil_end at 1. - - setoid_rewrite <- h_lon_w'_nil at 1. - setoid_rewrite <- heq_lright at 1 2. - rewrite h_right_w_w' at 1. - setoid_rewrite app_assoc_reverse. - transitivity ps. - * now symmetry. - * now rewrite heq_lright. - + rewrite heq_lright in h_right_w_w'. - apply PermutationA_nil with (2:=h_right_w_w'). - typeclasses eauto. - + rewrite Heqw'. - intro abs. - assert ((L ^P) w == (L ^P) ((L ^-P) ((L ^P) w + 1))) as h_abs. - { now rewrite <- abs. } - setoid_rewrite line_P_iP in h_abs. - cbn -[line_proj] in h_abs. - * lra. - * assumption. - - - assert (line_contains L w'). - { subst. - apply line_contains_middle. - - apply aligned_on_cons_iff in h_align. - destruct h_align. - assumption. - - unfold line_contains. - rewrite line_P_iP_min. - reflexivity. } - - specialize (@line_left_on_right_partition _ _ _ _ _ L w' ps) as h_split'. - (* Only if there is something in ps on the left of w. *) - exists w'. - repeat split. - + rewrite -> aligned_on_cons_iff. - split;auto. - + - enough (not (exists x, InA equiv x ps /\ (L ^P) x = (L ^P) w')). - { destruct ((L ^on) w' ps) eqn:heq_lon ; try auto. - exfalso. - assert (InA equiv r0 ((L ^on) w' ps)). - { rewrite heq_lon. - constructor 1;auto. } - apply H1. - exists r0. - split. - - apply line_on_spec in H2. - destruct H2;auto. - - apply line_on_spec in H2. - destruct H2;auto. } - - intro abs. - destruct abs. - rewrite <- (line_on_spec L) in H1. - destruct abs as [w'' [h_InA_w'' h_eq_w'']]. - - - (* Only if there is something in ps on the left of w. *) - exists (middle w (L^-P (line_min L ((L ^right) w ps))%VS)). - remember (middle w (L^-P (line_min L ((L ^right) w ps))%VS)) as w'. - unfold middle in Heqw'. - - assert ((L ^P) w < (L ^P) w')%R as h_left_nil. - { admit. } - assert (line_contains L w'). - { subst. - apply line_contains_middle. - - apply aligned_on_cons_iff in h_align. - destruct h_align. - assumption. - - unfold line_contains. - rewrite line_P_iP_min. - reflexivity. } - assert (line_contains L w). - { apply aligned_on_cons_iff in h_align. - destruct h_align. - assumption. } - specialize (@line_left_on_right_partition _ _ _ _ _ L w' ps) as h_split'. - - - repeat split. - - rewrite -> aligned_on_cons_iff. - split;auto. - - - Set Nested Proofs Allowed. - enough (PermutationA equiv ((L ^on) w' ps) (nil:list R2)). - { apply Preliminary.PermutationA_nil with (2:= H1);auto. } - rewrite line_on_perm_compat. - 4: apply h_split. - 2: reflexivity. - 2:reflexivity. - rewrite line_on_app. - rewrite line_on_app. - assert ((L ^on) w' ((L ^left) w ps) = nil). - { unfold line_on. - rewrite -> (@filter_nilA _ equiv);try typeclasses eauto. - intros x H1. - apply eqb_false_iff. - intros abs. - apply line_left_spec in H1. - destruct H1. - unfold equiv, R_Setoid, eq_setoid in abs. - change ((L ^P) w' = (L ^P) x)%R in abs. - lra. } - - line_left_spec. - - - apply eqlistA_PermutationA. - rewrite eqlistA_app. - 4:assumption. - rewrite eqlistA_app. - - apply app_eq_nil. - - rewrite h_split'. - rewrite line_on_app. - - - - - -apply aligned_on_cons_iff in h_align as h_align2. - destruct h_align2 as [h1 h2]. - apply aligned_on_cons_iff ; split. - + rewrite Heqw'. - apply line_contains_middle. - * assumption. - * admit. (* shoudl be trivial, unless L^min is by default *) - + assumption. - - - - admit. - -Admitted. - - -(* Symmetrical for going on the left of w. *) -Lemma shift_left: forall L w (ps: list R2), - ps <> nil -> (* Seems necessary *) - line_dir L =/= 0%VS -> - aligned_on L (w :: ps) -> - { w' | aligned_on L (w' :: w :: ps) /\ - L^on w' ps = nil - /\ PermutationA equiv (L^right w' ps) (L^right w ps ++ L^on w ps) - /\ L^left w' ps= L^left w ps - /\ w =/=w' }. -Proof. - intros L w ps h_ps_nonil h_lineOK h_align. - admit. - -Admitted. - -*) +Notation "'^R' x" := (INR (length x)) (at level 180, no associativity). Lemma weber_aligned_sufficient L ps w : ps <> nil -> (* Seems necessary *) @@ -2337,7 +1986,7 @@ Proof. intros A l H. destruct (Nat.eq_decidable (length l) 0). - now apply length_0. - - assert (0 < Rlength l). + - assert (0 < length l). { lia. } apply (lt_0_INR (length l)) in H1. exfalso. @@ -2432,7 +2081,7 @@ Proof. now apply h_incl. } apply (@InA_nth _ equiv 0%VS w' ((L ^on) w' ps)) in H0. destruct H0 as [n [y [h1 h2]]]. - assert (0 < Rlength ((L ^on) w' ps)) by lia. + assert (0 < length ((L ^on) w' ps)) by lia. apply lt_INR in H0. cbn in H0. lra. } @@ -2604,11 +2253,7 @@ Lemma INR_add_le: forall x y r: nat, Proof. intros x y r h_Rlt. rewrite <- plus_INR. - (* 1%R is actually a notation for (IZR 1%Z). *) - change (IZR (Zpos xH)) with (INR 1). - rewrite <- plus_INR. - apply le_INR. - lia. + now apply NumberComplements.INR_add_le. Qed. Lemma INR_add_le': forall x y r: nat, @@ -2627,14 +2272,8 @@ Lemma INR_minus_le: forall x y r: nat, (((INR x) - (INR y) + 1 <= INR r)%R) . Proof. intros x y r h_le h_Rlt. - (* hideously going back and forth from R to nat. *) - rewrite <- minus_INR;[|apply INR_le]. - 2:{ now apply le_INR. } - (* 1%R is actually a notation for (IZR 1%Z). *) - change (IZR (Zpos xH)) with (INR 1). - rewrite <- plus_INR. - apply le_INR. - lia. + rewrite <- minus_INR;auto. + now apply NumberComplements.INR_add_le. Qed. Lemma INR_minus_le': forall x y r: nat, @@ -2648,62 +2287,6 @@ Proof. now apply INR_lt. Qed. -(* Dealing with hyps generated by "remember" *) -Ltac reremember_in h := - repeat match goal with - H: ?X = _ |- _ => (* (INR (length _)) *) - is_var X; - rewrite <- H in h - end. - -Ltac reremember_ := - repeat match goal with - H: ?X = _ |- _ => - is_var X; - rewrite <- H - end. - -Ltac unremember_in h := - repeat match goal with - H: ?X = _ |- _ => - is_var X; - rewrite H in h - end. - -Ltac unremember_ := - repeat match goal with - H: ?X = _ |- _ => - is_var X; - rewrite H - end. - -Ltac remember_move_all t name ath := - remember t as name in *; - match goal with - H: name = t |- _ => - move H after ath; - move name at top - end. - -Ltac remember_move_in t name inlh ath := - remember t as name in inlh ; - match goal with - H: name = t |- _ => - move H after ath; - move name at top - end. - -Tactic Notation "alias" constr(t) "as" ident(name) "after" hyp(h) := - remember_move_all t name h. - -Tactic Notation "alias" constr(t) "as" ident(name) "in" hyp_list(lh) "after" hyp(h) := - remember_move_in t name lh h. - -Tactic Notation "unremember" := unremember_. -Tactic Notation "unremember" "in" hyp(h) := unremember_in h. -Tactic Notation "reremember" := reremember_. -Tactic Notation "reremember" "in" hyp(h) := reremember_in h. - Lemma weber_aligned_spec_right_bigger_2 L ps w : ps <> nil -> (* Seems necessary *) line_dir L =/= 0%VS -> @@ -2740,8 +2323,14 @@ Proof. rewrite Ropp_minus_distr' in h_Rlt_Rabs. assert (((^R (L ^right) w ps) - (^R (L ^left) w ps) + 1 <= (^R (L ^on) w ps))%R) as h_weber_strong. - { apply INR_minus_le';try lra. - apply INR_le;lra. } + { rewrite <- minus_INR. + - apply INR_add_le_INR. + rewrite minus_INR. + + reremember. + assumption. + + reremember. + apply INR_le;lra. + - apply INR_le;lra. } clear h_Rlt_Rabs. move x before w. alias (^R (L ^left) x ps) as leftx after h_neq_ps_nil. @@ -2792,8 +2381,6 @@ Proof. lra. Qed. -(* Require Import LibHyps.LibHyps. *) - Lemma weber_aligned_spec_left_bigger_2 L ps w : ps <> nil -> (* Seems necessary *) line_dir L =/= 0%VS -> @@ -2989,8 +2576,8 @@ Proof. split;auto. apply weber_aligned with ps;auto. } specialize (line_on_length_aligned L w ps h_alignwps) as h_on_countA. - assert (Rlength ((L ^left) w ps) + Rlength ((L ^right) w ps) < Nat.div2 (Rlength ps + 1)). - { specialize (div2_sum_p1_ge (Rlength ps)) as h_le. + assert (length ((L ^left) w ps) + length ((L ^right) w ps) < Nat.div2 (length ps + 1)). + { specialize (div2_sum_p1_ge (length ps)) as h_le. lia. } apply weber_aligned_spec with (L:=L);auto. - assert (0 <= (^R (L ^left) w ps) < (^R (L ^on) w ps))%R. @@ -3006,6 +2593,65 @@ Proof. apply Rabs_def1;lra. Qed. +Ltac duplic h name := + set (name := h); + clearbody name; + move name before h. + +Ltac duplic_autoname h := + let name := fresh h "'" in + duplic h name. + +Tactic Notation "dup" hyp(h) := duplic_autoname h. +Tactic Notation "dup" hyp(h) "as" ident(name) := duplic h name. + + +Lemma left_right_balanced_even ps (w:R2) L: + (Rabs ((^R (L ^left) w ps) - (^R (L ^right) w ps)) = 0)%R -> + (^R (L ^on) w ps) = 0%R -> + Nat.Even (length ps). +Proof. + intros h_eq0 h_on_0. + assert (((^R (L ^left) w ps) = (^R (L ^right) w ps))) as h_left_right. + { destruct (Rle_lt_dec (^R (L ^left) w ps) (^R (L ^right) w ps))%R as [h | h]. + - rewrite Rabs_left1 in h_eq0;try lra. + - rewrite Rabs_pos_eq in h_eq0;try lra. } + specialize (line_left_on_right_partition L w ps) as h_partition. + + apply PermutationA_length in h_partition. + repeat rewrite app_length in h_partition. + apply (f_equal INR) in h_partition. + repeat rewrite plus_INR in h_partition. + rewrite h_on_0, h_left_right in h_partition. + assert ((^R ps) = (2 * (^R (L ^right) w ps))%R) by lra. + change 2%R with (INR 2%nat) in H. + rewrite <- mult_INR in H. + apply INR_injection in H. + rewrite H. + eexists ;eauto. +Qed. + +Lemma middle_diff_l: forall x y:R2, x<>y -> middle x y <> x. +Proof. + intros x y H. + specialize (middle_diff H) as h. + intro abs. + rewrite abs in h. + apply h. + constructor;auto. +Qed. + +Lemma middle_diff_r: forall x y:R2, x<>y -> middle x y <> y. +Proof. + intros x y H. + specialize (middle_diff H) as h. + intro abs. + rewrite abs in h. + apply h. + constructor 2. + constructor;auto. +Qed. + (* When there are an odd number of points, the weber point is always unique. *) Lemma weber_odd_unique ps w : Nat.Odd (length ps) -> Weber ps w -> OnlyWeber ps w. @@ -3016,12 +2662,101 @@ Proof. * 2. Show that there is a weber point on the segment [w1, w2] * that is not in ps (i.e. with multiplicity 0). * 3. Using weber_aligned_spec show that n is even. *) + intros h_Odd_ps h_weber_w. + assert (ps<>nil) as h_nonnil. + { intro abs. + rewrite abs in h_Odd_ps. + cbn in h_Odd_ps. + inversion h_Odd_ps. + lia. } + destruct (aligned_dec ps) as [h_align | h_nalign]. + 2:{ apply weber_Naligned_unique;auto. } + split;auto. + intros x h_weber_x. + destruct (equiv_dec x w);auto. + exfalso. + alias (line_calc ps) as L after h_weber_w. + assert (aligned_on L ps) as h_aligned_on. + { unremember. + now apply line_calc_spec. } + specialize (weber_aligned h_nonnil h_aligned_on h_weber_w) as ha_align_w. + specialize (weber_aligned h_nonnil h_aligned_on h_weber_x) as ha_align_x. + assert ((aligned_on L (w::ps))). + { apply aligned_on_cons_iff;split;auto. } + assert ((aligned_on L (x::ps))). + { apply aligned_on_cons_iff;split;auto. } + assert (line_dir L =/= 0%VS) as h_dir_nonnull. + { apply line_dir_nonnul with x w;auto. } + dup h_weber_w. + rewrite -> (@weber_aligned_spec_weak L) in h_weber_w';auto. + assert (exists pt, Weber ps pt /\ ((^R (L ^on) pt ps) = 0)%R). + { destruct (equiv_dec (^R (L ^on) w ps) 0)%R. + - exists w;auto. + - destruct (equiv_dec (^R (L ^on) x ps) 0)%R. + + exists x;auto. + + assert (forall m, + (L ^P x < L ^P m)%R + -> (L ^P m < L ^P w)%R + -> Weber ps m /\ ((^R (L ^on) m ps) = 0)%R). + { intros m H1 H2. + alias (^R (L ^left) w ps) as leftw after h_Odd_ps. + alias (^R (L ^right) w ps) as rightw after h_Odd_ps. + alias (^R (L ^on) w ps) as onw after h_Odd_ps. + alias (^R (L ^left) x ps) as leftx after h_Odd_ps. + alias (^R (L ^right) x ps) as rightx after h_Odd_ps. + alias (^R (L ^on) x ps) as onx after h_Odd_ps. + alias (^R (L ^left) m ps) as leftm after h_Odd_ps. + alias (^R (L ^right) m ps) as rightm after h_Odd_ps. + alias (^R (L ^on) m ps) as onm after h_Odd_ps. + assert(leftx - rightx = onx)%R by admit. + assert (rightw - leftw = onw)%R by admit. + assert (leftx + onx + rightx = leftw + onw + rightw)%R by admit. + assert (leftw + onw + rightw = leftm + onm + rightm)%R by admit. + assert (rightm >= rightx + onx)%R by admit. + assert (leftm >= onw + leftw)%R by admit. + assert(0 <= onm)%R by admit. + assert (leftm - rightm <= onm)%R. + { lra. } + assert (onm = 0)%R. + lra. + split; try lra. + apply (@weber_aligned_spec_weak L);auto; try lra. + - admit. + - reremember. + admit. } + exists (middle w x). + destruct (H1 (middle w x));auto. + { admit. } + { admit. } + } + destruct H1 as [pt [hpt1 hpt2]]. + rewrite -> (@weber_aligned_spec_weak L) in hpt1;auto. + 2:{ specialize (weber_aligned h_nonnil h_aligned_on hpt1) as ha_align_pt. + apply aligned_on_cons_iff;split;auto. } + assert (Rabs ((^R (L ^left) pt ps) - (^R (L ^right) pt ps)) >= 0)%R. + { apply Rle_ge. + apply Rabs_pos. } + + assert (Nat.Even (length ps)). + { eapply left_right_balanced_even with (w := pt) (L:=L);try lra. } + Admitted. Lemma weber_segment_InA ps w1 w2 : (forall w, Weber ps w <-> segment w1 w2 w) -> InA equiv w1 ps /\ InA equiv w2 ps. -Proof. Admitted. +Proof. + (* Proof sketch: suppose w1 is not occupied, then there is a point + close to w1 but outside the segment that is also a weber point + (since left, right and on would be the same). This would be a + contradiction. *) +Admitted. +(* +Lemma weber_segment_InA' ps w1 w2 : + (forall w, Weber ps w <-> segment w1 w2 w) + <-> InA equiv w1 ps /\ InA equiv w2 ps /\ Weber ps w1 /\ Weber ps w2. +Proof. Admitted. +*) End WeberPoint. diff --git a/Util/ListComplements.v b/Util/ListComplements.v index 0f0ef68a..98ed93b3 100644 --- a/Util/ListComplements.v +++ b/Util/ListComplements.v @@ -30,6 +30,7 @@ Require Import Psatz. Require Import SetoidDec. Require Import Pactole.Util.Preliminary. Require Import Pactole.Util.NumberComplements. +Require Import Arith. Set Implicit Arguments. @@ -939,8 +940,6 @@ intro l1. induction l1 as [| e l1]; intro l2. Defined. -Require Import Arith. - Lemma nth_firstn2: forall (l : list A) k n df, k < n -> nth k l df = List.nth k (firstn n l) df. Proof. intros l k n df H. diff --git a/Util/NumberComplements.v b/Util/NumberComplements.v index 76d8f79d..a453654d 100644 --- a/Util/NumberComplements.v +++ b/Util/NumberComplements.v @@ -612,3 +612,64 @@ Proof using ltc_ll_ul ltc_lr_ur. Qed. End lt_pred_mul_ul_ur. + + +Lemma INR_injection: forall n1 n2, + INR n1 = INR n2 -> + n1 = n2. +Proof. + induction n1 using nat_ind2;intros. + - destruct n2;auto. + destruct n2. + + exfalso. + cbn in H. + lra. + + exfalso. + repeat rewrite S_INR in H. + assert (INR n2 >= 0)%R. + { apply Rle_ge, pos_INR. } + cbn in H. + lra. + - destruct n2. + + exfalso. + cbn in H. + lra. + + destruct n2;auto. + repeat rewrite S_INR in H. + assert (INR n2 >= 0)%R. + { apply Rle_ge, pos_INR. } + cbn in H. + lra. + - assert (INR n1 >= 0)%R. + { apply Rle_ge, pos_INR. } + repeat rewrite S_INR in H. + destruct n2. + { exfalso. + cbn in H. + lra. } + destruct n2. + + exfalso. + cbn in H. + lra. + + rewrite (IHn1 n2);auto. + repeat rewrite S_INR in H. + lra. +Qed. + +Lemma INR_add_le: forall x y: nat, x < y -> (((INR x) + 1 <= (INR y))%R). +Proof. + intros x y h_Rlt. + change (IZR (Zpos xH)) with (INR 1). + rewrite <- plus_INR. + apply le_INR. + lia. +Qed. + +Lemma INR_add_le_INR: forall x y : nat, + ((INR x) < (INR y))%R -> + (((INR x) + 1 <= (INR y))%R) . +Proof. + intros x y h_Rlt. + apply INR_add_le. + now apply INR_lt. +Qed. diff --git a/Util/Preliminary.v b/Util/Preliminary.v index 58551d1e..4182c099 100644 --- a/Util/Preliminary.v +++ b/Util/Preliminary.v @@ -72,6 +72,89 @@ Ltac revert_all := | |- ?B => repeat revert_one B end. + +(* Dealing with hyps generated by "remember" *) +Ltac reremember_in h := + repeat match goal with + H: ?X = _ |- _ => + is_var X; + rewrite <- H in h + end. + +Ltac reremember_ := + repeat match goal with + H: ?X = _ |- _ => + is_var X; + rewrite <- H + end. + +Ltac unremember_in h := + repeat match goal with + H: ?X = _ |- _ => + is_var X; + rewrite H in h + end. + +Ltac unremember_ := + repeat match goal with + H: ?X = _ |- _ => + is_var X; + rewrite H + end. + +Ltac remember_all_move_after t name ath := + remember t as name in *; + match goal with + H: name = t |- _ => + move H after ath; + move name at top + end. + +Ltac remember_all_move_before t name ath := + remember t as name in *; + match goal with + H: name = t |- _ => + move H before ath; + move name at top + end. + +Ltac remember_in_move_after t name inlh ath := + remember t as name in inlh ; + match goal with + H: name = t |- _ => + move H after ath; + move name at top + end. + +Ltac remember_in_move_before t name inlh ath := + remember t as name in inlh ; + match goal with + H: name = t |- _ => + move H before ath; + move name at top + end. + +(* alias is like remember but allows to move around the var and hyp + created . *) +Tactic Notation "alias" constr(t) "as" ident(name) "after" hyp(h) := + remember_all_move_after t name h. +Tactic Notation "alias" constr(t) "as" ident(name) "before" hyp(h) := + remember_all_move_before t name h. + +Tactic Notation "alias" constr(t) "as" ident(name) "in" hyp_list(lh) "after" hyp(h) := + remember_in_move_after t name lh h. +Tactic Notation "alias" constr(t) "as" ident(name) "in" hyp_list(lh) "before" hyp(h) := + remember_in_move_before t name lh h. + +(* unremember is equivalent to applying subst to all hyps of the form +id = term (not the symmetric though, as would subst so). *) +Tactic Notation "unremember" := unremember_. +Tactic Notation "unremember" "in" hyp(h) := unremember_in h. +(* reremember tries to identify new occurrences of remembered + expressions and replace them by the name. *) +Tactic Notation "reremember" := reremember_. +Tactic Notation "reremember" "in" hyp(h) := reremember_in h. + Definition injective {A B : Type} (eqA : relation A) (eqB : relation B) (f : A -> B) : Prop := forall x y, eqB (f x) (f y) -> eqA x y. -- GitLab