Skip to content

Commit fc6e300

Browse files
committed
Ceva's theorem
1 parent fcb078e commit fc6e300

File tree

3 files changed

+231
-0
lines changed

3 files changed

+231
-0
lines changed

LeanCamCombi/Ceva.lean

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import Mathlib
2+
import LeanCamCombi.Mathlib.Analysis.Convex.Combination
3+
import LeanCamCombi.Mathlib.LinearAlgebra.AffineSpace.Combination
4+
5+
open AffineMap Finset
6+
7+
variable {ι 𝕜 V : Type*} [DecidableEq ι] [LinearOrderedField 𝕜] [AddCommGroup V] [Module 𝕜 V]
8+
{s t : Finset ι} {w : ι → 𝕜} {x y : ι → V} {i : ι}
9+
10+
-- /-- **Ceva's theorem** for affine combinations. -/
11+
-- theorem ceva_affineComb [Nontrivial 𝕜] (hy : ∀ i ∈ s, y i ∈ affineSpan 𝕜 (x '' (s \ {i})))
12+
-- (hs : s.Nonempty) :
13+
-- (∃ z, ∃ c : ι → 𝕜, ∀ i ∈ s, lineMap (y i) (x i) (c i) = z) ↔
14+
-- ∃ w : ι → 𝕜, ∑ i ∈ s, w i = 1 ∧ ∀ i ∈ s, w i ≠ 1 → (s \ {i}).centerMass w x = y i where
15+
-- mp := by
16+
-- rintro ⟨z, c, hz⟩
17+
-- obtain ⟨i, hi⟩ := hs
18+
-- norm_cast at hy
19+
-- obtain ⟨w, hw₁, hyi⟩ := mem_affineSpan_image.1 <| hy i hi
20+
-- refine ⟨Pi.single i (c i) + (1 - c i) • Function.update w i 0, fun j hj ↦ ?_, ?_, ?_⟩
21+
-- · sorry
22+
23+
-- -- choose hc₀ hc₁ hz using hz
24+
-- sorry
25+
-- mpr := by
26+
-- rintro ⟨w, hw₁, hwxy⟩
27+
-- refine ⟨s.centerMass w x, w, fun i hi ↦ ?_⟩
28+
-- rw [← hwxy, lineMap_centerMass_sdiff_singleton_of_ne_one hi (hw₀ _ hi) hw₁]
29+
30+
/-- **Ceva's theorem** for convex combinations. -/
31+
theorem ceva_convexComb (hy : ∀ i ∈ s, y i ∈ convexHull 𝕜 (x '' (s \ {i})))
32+
(hs : s.Nontrivial) :
33+
(∃ z, ∃ c : ι → 𝕜, ∀ i ∈ s, 0 ≤ c i ∧ c i ≤ 1 ∧ lineMap (y i) (x i) (c i) = z) ↔
34+
∃ w : ι → 𝕜,
35+
(∀ i ∈ s, 0 ≤ w i) ∧ ∑ i ∈ s, w i = 1 ∧ ∀ i ∈ s, (s \ {i}).centerMass w x = y i where
36+
mp := by
37+
rintro ⟨z, c, hz⟩
38+
choose hc₀ hc₁ hz using hz
39+
by_cases hc : ∀ i ∈ s, c i = 1
40+
· refine ⟨fun _ ↦ (#s)⁻¹, by simp, by simp [hs.nonempty.card_ne_zero], fun i hi ↦ ?_⟩
41+
simp only [centerMass, sum_const, nsmul_eq_mul, mul_inv_rev, inv_inv, ← smul_sum, ← mul_smul,
42+
mul_right_comm, ne_eq, Nat.cast_eq_zero, hs.nonempty.card_ne_zero, not_false_eq_true,
43+
mul_inv_cancel₀, one_mul]
44+
sorry
45+
-- obtain ⟨j, hj, hji⟩ := hs.exists_ne i
46+
push_neg at hc
47+
obtain ⟨i, hi, hci⟩ := hc
48+
norm_cast at hy
49+
obtain ⟨w, hw₀, hw₁, hyi⟩ := mem_convexHull_image.1 <| hy i hi
50+
refine ⟨Pi.single i (c i) + (1 - c i) • Function.update w i 0, fun j hj ↦
51+
add_nonneg (Pi.single_nonneg (α := fun _ ↦ 𝕜).2 (hc₀ _ hi) _) <|
52+
mul_nonneg (sub_nonneg.2 <| hc₁ _ hi) ?_, ?_, fun j hj ↦ ?_⟩
53+
· obtain rfl | hji := eq_or_ne j i
54+
· simp
55+
· simpa [hji] using hw₀ _ (by simp [*])
56+
· simp [sum_add_distrib, hi, ← mul_sum, sum_update_of_mem, ← sum_erase_eq_sub, hw₁]
57+
obtain rfl | hij := eq_or_ne i j
58+
· rwa [centerMass_congr (w := (1 - c i) • w) (sdiff_singleton_eq_erase ..) _ fun _ _ ↦ rfl,
59+
centerMass_smul_left]
60+
exact sub_ne_zero.2 hci.symm
61+
aesop
62+
have := (hz i hi).trans (hz j hj).symm
63+
simp [centerMass, sum_add_distrib]
64+
sorry
65+
mpr := by
66+
rintro ⟨w, hw₀, hw₁, hwxy⟩
67+
refine ⟨s.centerMass w x, w, fun i hi ↦ ⟨hw₀ _ hi, hw₁ ▸ single_le_sum hw₀ hi, ?_⟩⟩
68+
rw [← hwxy _ hi, lineMap_centerMass_sdiff_singleton_of_nonneg hi _ hw₁]
69+
exact fun j hj ↦ hw₀ _ <| sdiff_subset hj
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
import Mathlib.Analysis.Convex.Combination
2+
3+
open AffineMap Finset
4+
5+
section oldVars
6+
variable {ι R E : Type*} [LinearOrderedField R] [AddCommGroup E] [Module R E] {s : Finset ι}
7+
{f : ι → E} {x : E}
8+
9+
lemma mem_convexHull_image :
10+
x ∈ convexHull R (f '' s) ↔
11+
∃ w : ι → R, (∀ i ∈ s, 0 ≤ w i) ∧ ∑ i ∈ s, w i = 1 ∧ s.centerMass w f = x where
12+
mp hp := by
13+
classical
14+
rw [← Subtype.range_val (s := s.toSet), ← Set.range_comp,
15+
convexHull_range_eq_exists_affineCombination] at hp
16+
obtain ⟨t, w, hw₀, hw₁, rfl⟩ := hp
17+
refine ⟨fun i ↦ if hi : i ∈ Subtype.val '' (t : Set s.toSet) then w ⟨i, by aesop⟩ else 0,
18+
by aesop, ?_⟩
19+
· simp [Finset.sum_dite]
20+
sorry
21+
mpr := by
22+
rintro ⟨w, hw₀, hw₁, rfl⟩; exact s.centerMass_mem_convexHull hw₀ (by simp [hw₁]) (by aesop)
23+
24+
end oldVars
25+
26+
variable {ι 𝕜 V : Type*} [LinearOrderedField 𝕜] [AddCommGroup V] [Module 𝕜 V]
27+
{s t : Finset ι} {v w : ι → 𝕜} {x y : ι → V} {i : ι}
28+
29+
lemma centerMass_congr (hst : s = t) (hvw : ∀ i ∈ t, v i = w i) (hxy : ∀ i ∈ t, x i = y i) :
30+
s.centerMass v x = t.centerMass w y := by
31+
unfold centerMass; rw [sum_congr hst hvw, sum_congr hst fun i hi ↦ by rw [hvw i hi, hxy i hi]]
32+
33+
variable [DecidableEq ι]
34+
35+
lemma centerMass_union (hst : Disjoint s t) (hs : (∀ i ∈ s, w i = 0) ∨ ∑ i ∈ s, w i ≠ 0)
36+
(ht : (∀ i ∈ t, w i = 0) ∨ ∑ i ∈ t, w i ≠ 0) (hw₁ : ∑ i ∈ s ∪ t, w i = 1) :
37+
(s ∪ t).centerMass w x =
38+
(∑ i ∈ s, w i) • s.centerMass w x + (∑ i ∈ t, w i) • t.centerMass w x := by
39+
obtain hs | hs := hs
40+
· simp only [sum_union hst, sum_eq_zero hs, zero_add] at hw₁
41+
simp only [centerMass, sum_union hst, sum_eq_zero hs, hw₁, zero_add, inv_one, smul_add,
42+
one_smul, inv_zero, zero_smul, smul_zero, add_left_eq_self]
43+
exact sum_eq_zero fun i hi ↦ by simp [hs _ hi]
44+
obtain ht | ht := ht
45+
· simp only [sum_union hst, sum_eq_zero ht, add_zero] at hw₁
46+
simp only [centerMass, sum_union hst, hw₁, sum_eq_zero ht, add_zero, inv_one, smul_add,
47+
one_smul, inv_zero, zero_smul, smul_zero, add_right_eq_self]
48+
exact sum_eq_zero fun i hi ↦ by simp [ht _ hi]
49+
· simp [centerMass, hs, ht, hst, sum_union, hw₁]
50+
51+
lemma centerMass_union_of_ne_zero (hst : Disjoint s t) (hs : ∑ i ∈ s, w i ≠ 0)
52+
(ht : ∑ i ∈ t, w i ≠ 0) (hw₁ : ∑ i ∈ s ∪ t, w i = 1) :
53+
(s ∪ t).centerMass w x =
54+
(∑ i ∈ s, w i) • s.centerMass w x + (∑ i ∈ t, w i) • t.centerMass w x :=
55+
centerMass_union hst (.inr hs) (.inr ht) hw₁
56+
57+
lemma centerMass_union_of_nonneg (hst : Disjoint s t) (hw₀ : ∀ i ∈ s ∪ t, 0 ≤ w i)
58+
(hw₁ : ∑ i ∈ s ∪ t, w i = 1) :
59+
(s ∪ t).centerMass w x =
60+
(∑ i ∈ s, w i) • s.centerMass w x + (∑ i ∈ t, w i) • t.centerMass w x := by
61+
refine centerMass_union hst ?_ ?_ hw₁
62+
· rw [← sum_eq_zero_iff_of_nonneg fun j hj ↦ hw₀ _ <| subset_union_left hj]
63+
exact em _
64+
· rw [← sum_eq_zero_iff_of_nonneg fun j hj ↦ hw₀ _ <| subset_union_right hj]
65+
exact em _
66+
67+
lemma lineMap_centerMass_centerMass (hst : Disjoint s t)
68+
(hs : (∀ i ∈ s, w i = 0) ∨ ∑ i ∈ s, w i ≠ 0) (ht : (∀ i ∈ t, w i = 0) ∨ ∑ i ∈ t, w i ≠ 0)
69+
(hw₁ : ∑ i ∈ s ∪ t, w i = 1) :
70+
lineMap (s.centerMass w x) (t.centerMass w x) (∑ i ∈ t, w i) = (s ∪ t).centerMass w x := by
71+
rw [lineMap_apply_module, ← hw₁, sum_union hst, add_sub_cancel_right,
72+
centerMass_union hst hs ht hw₁]
73+
74+
lemma lineMap_centerMass_centerMass_of_ne_zero (hst : Disjoint s t) (hs : ∑ i ∈ s, w i ≠ 0)
75+
(ht : ∑ i ∈ t, w i ≠ 0) (hw₁ : ∑ i ∈ s ∪ t, w i = 1) :
76+
lineMap (s.centerMass w x) (t.centerMass w x) (∑ i ∈ t, w i) = (s ∪ t).centerMass w x :=
77+
lineMap_centerMass_centerMass hst (.inr hs) (.inr ht) hw₁
78+
79+
lemma lineMap_centerMass_centerMass_of_nonneg (hst : Disjoint s t) (hw₀ : ∀ i ∈ s ∪ t, 0 ≤ w i)
80+
(hw₁ : ∑ i ∈ s ∪ t, w i = 1) :
81+
lineMap (s.centerMass w x) (t.centerMass w x) (∑ i ∈ t, w i) = (s ∪ t).centerMass w x := by
82+
rw [lineMap_apply_module, ← hw₁, sum_union hst, add_sub_cancel_right,
83+
centerMass_union_of_nonneg hst hw₀ hw₁]
84+
85+
lemma lineMap_centerMass_sdiff (hi : i ∈ s) (hi₀ : w i ≠ 0) (hi₁ : w i ≠ 1)
86+
(hw₁ : ∑ i ∈ s, w i = 1) :
87+
lineMap ((s \ {i}).centerMass w x) (x i) (w i) = s.centerMass w x := by
88+
rw [← centerMass_singleton i x hi₀, ← sum_singleton w i,
89+
lineMap_centerMass_centerMass] <;>
90+
simp [*, union_eq_left.2, sub_eq_zero, eq_comm (b := w _)]
91+
92+
lemma centerMass_sdiff_of_weight_eq_zero (hi : i ∈ s) (hi₀ : w i = 0) :
93+
(s \ {i}).centerMass w x = s.centerMass w x := by
94+
simp [hi₀, sum_sdiff_eq_sub (singleton_subset_iff.2 hi), centerMass]
95+
96+
lemma lineMap_centerMass_sdiff_singleton_of_ne_one (hi : i ∈ s) (hi₁ : w i ≠ 1)
97+
(hw₁ : ∑ j ∈ s, w j = 1) :
98+
lineMap ((s \ {i}).centerMass w x) (x i) (w i) = s.centerMass w x := by
99+
obtain hi₀ | hi₀ := eq_or_ne (w i) 0
100+
· simp [centerMass_sdiff_of_weight_eq_zero hi, hi₀]
101+
· rw [← centerMass_singleton i x hi₀, ← sum_singleton w i, lineMap_centerMass_centerMass] <;>
102+
simp [*, union_eq_left.2, sub_eq_zero, eq_comm (b := w _)]
103+
104+
lemma lineMap_centerMass_sdiff_singleton_of_nonneg (hi : i ∈ s) (hw₀ : ∀ j ∈ s \ {i}, 0 ≤ w j)
105+
(hw₁ : ∑ j ∈ s, w j = 1) :
106+
lineMap ((s \ {i}).centerMass w x) (x i) (w i) = s.centerMass w x := by
107+
obtain hi₁ | hi₁ := eq_or_ne (w i) 1
108+
· rw [← centerMass_singleton i x (w := w) (by simp [hi₁]), ← sum_singleton w i,
109+
lineMap_centerMass_centerMass]
110+
rotate_left 2
111+
· rw [← sum_eq_zero_iff_of_nonneg hw₀]
112+
exact em _
113+
all_goals simp [*, union_eq_left.2, sub_eq_zero, eq_comm (b := w _)]
114+
· exact lineMap_centerMass_sdiff_singleton_of_ne_one hi hi₁ hw₁
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import Mathlib.LinearAlgebra.AffineSpace.Combination
2+
3+
variable {ι k V P : Type*} [Ring k] [AddCommGroup V] [Module k V] [AddTorsor V P]
4+
{p₀ : P} {p : ι → P} {w : ι → k} {s : Finset ι} {t : Set P}
5+
6+
-- TODO: Replace
7+
lemma weightedVSub_mem_vectorSpan' (h : ∑ i ∈ s, w i = 0) (hp : ∀ i ∈ s, p i ∈ t) :
8+
s.weightedVSub p w ∈ vectorSpan k t := by
9+
obtain rfl | ⟨i, hi⟩ := s.eq_empty_or_nonempty
10+
· simp
11+
rw [Finset.weightedVSub_eq_weightedVSubOfPoint_of_sum_eq_zero s w p h (p i)]
12+
simp
13+
exact sum_mem fun j hj ↦ Submodule.smul_mem _ _ <| vsub_mem_vectorSpan _ (hp _ hj) (hp _ hi)
14+
15+
-- TODO: Replace
16+
lemma affineCombination_mem_affineSpan' [Nontrivial k] (h : ∑ i ∈ s, w i = 1)
17+
(hp : ∀ i ∈ s, p i ∈ t) : s.affineCombination k p w ∈ affineSpan k t := by
18+
classical
19+
have hnz : ∑ i ∈ s, w i ≠ 0 := h.symm ▸ one_ne_zero
20+
have hn : s.Nonempty := Finset.nonempty_of_sum_ne_zero hnz
21+
cases' hn with i1 hi1
22+
let w1 : ι → k := Function.update (Function.const ι 0) i1 1
23+
have hw1 : ∑ i ∈ s, w1 i = 1 := by
24+
simp only [w1, Function.const_zero, Finset.sum_update_of_mem hi1, Pi.zero_apply,
25+
Finset.sum_const_zero, add_zero]
26+
have hw1s : s.affineCombination k p w1 = p i1 :=
27+
s.affineCombination_of_eq_one_of_eq_zero w1 p hi1 (Function.update_self ..) fun _ _ hne =>
28+
Function.update_of_ne hne ..
29+
have hv : s.affineCombination k p w -ᵥ p i1 ∈ (affineSpan k t).direction := by
30+
rw [direction_affineSpan, ← hw1s, Finset.affineCombination_vsub]
31+
apply weightedVSub_mem_vectorSpan' _ hp
32+
simp [Pi.sub_apply, h, hw1]
33+
rw [← vsub_vadd (s.affineCombination k p w) (p i1)]
34+
exact AffineSubspace.vadd_mem_of_mem_direction hv (mem_affineSpan k <| hp _ hi1)
35+
36+
lemma mem_affineSpan_image [Nontrivial k] :
37+
p₀ ∈ affineSpan k (p '' s) ↔
38+
∃ w : ι → k, ∑ i ∈ s, w i = 1 ∧ p₀ = s.affineCombination k p w where
39+
mp hp := by
40+
classical
41+
rw [← Subtype.range_val (s := s.toSet), ← Set.range_comp] at hp
42+
obtain ⟨w, hw, rfl⟩ := eq_affineCombination_of_mem_affineSpan_of_fintype hp
43+
refine ⟨fun i ↦ if hi : i ∈ s then w ⟨i, hi⟩ else 0, ?_, ?_⟩
44+
simp [Finset.sum_dite]
45+
convert hw using 1
46+
sorry
47+
sorry
48+
mpr := by rintro ⟨w, hw₁, rfl⟩; exact affineCombination_mem_affineSpan' hw₁ (by aesop)

0 commit comments

Comments
 (0)