Theory TangentLineLemma
section ‹ TangentLineLemma ›
text ‹This theory shows that affine approximations map tangent
lines to tangent lines. ›
theory TangentLineLemma
imports MainLemma AxDiff Cones
begin
class TangentLineLemma = MainLemma + AxDiff + Cones
begin
lemma lemWVTImpliesFunction: "isFunction (wvtFunc k h)"
proof -
{ fix x p q
assume hyp: "wvtFunc k h x p ∧ wvtFunc k h x q"
have "axDiff k h x" using AxDiff by blast
hence axdiff: "(∃ r . wvtFunc k h x r)
⟶ (∃ A . (affineApprox A (wvtFunc k h) x ))"
by auto
then obtain A where A: "affineApprox A (wvtFunc k h) x" using hyp by auto
hence "∀z. (wvtFunc k h x z) ⟷ (z = A x)"
using lemAffineEqualAtBase[of "wvtFunc k h" "A" "x"]
by auto
hence "p = A x ∧ q = A x" using hyp by blast
moreover have "affine A" using A by auto
ultimately have "p = q" by auto
}
thus ?thesis by force
qed
lemma lemWVTCts:
assumes "definedAt (wvtFunc h k) p"
shows "cts (wvtFunc h k) p"
proof -
have "axDiff h k p" using AxDiff by blast
hence axdiff: "(∃ r . wvtFunc h k p r) ⟶ (∃ A . (affineApprox A (wvtFunc h k) p ))"
by auto
then obtain A where A: "affineApprox A (wvtFunc h k) p" using assms by auto
thus ?thesis using sublemma4[of "wvtFunc h k" "A" "p"] by auto
qed
lemma lemWVTInverse: "invFunc (wvtFunc k h) = wvtFunc h k"
by force
lemma lemWVTInverseCts:
assumes "wvtFunc k h p q"
shows "cts (wvtFunc h k) q"
proof -
define whk where whk: "whk = wvtFunc h k"
have "definedAt whk q ⟶ cts whk q"
using lemWVTCts[of "h" "k" "q"] whk by fast
moreover have "definedAt whk q" using whk assms by auto
ultimately have "cts whk q" by auto
thus ?thesis using whk by auto
qed
lemma lemWVTInjective: "injective (wvtFunc k h)"
proof -
define wkh where wkh: "wkh = wvtFunc k h"
define inv where inv: "inv = invFunc wkh"
define inv2 where inv2: "inv2 = invFunc inv"
define whk where whk: "whk = wvtFunc h k"
have 1: "inv = whk" using inv whk wkh by force
have 2: "inv2 = wkh" using inv2 inv wkh by force
have"isFunction whk" using lemWVTImpliesFunction whk by auto
hence "isFunction inv" using 1 by auto
hence "injective inv2" using inv2 by auto
hence "injective wkh" using 2 by auto
thus ?thesis using wkh by auto
qed
lemma lemPresentation:
assumes "x ∈ wline m b"
and "tangentLine l (wline m b) x"
and "affineApprox A (wvtFunc m k) x"
and "wvtFunc m k x y"
and "applyAffineToLine A l l'"
shows "tangentLine l' (wline k b) y"
proof -
have main: "(tangentLine l (wline m b) x) ⟶
(injective (wvtFunc m k)) ⟶
(affineApprox A (wvtFunc m k) x) ⟶
((wvtFunc m k) x y) ⟶
(cts (invFunc (wvtFunc m k)) y) ⟶
(applyAffineToLine A l l') ⟶
(tangentLine l' (applyToSet (wvtFunc m k) (wline m b)) y)"
using lemMainLemma[of "x" "wline m b" "l" "wvtFunc m k" "A" "y" "l'"]
by blast
have 1: "(tangentLine l (wline m b) x)" using assms(2) by auto
have 2: "injective (wvtFunc m k)" using lemWVTInjective by auto
have 3: "affineApprox A (wvtFunc m k) x" using assms(3) by auto
have 4: "(wvtFunc m k) x y" using assms(4) by auto
have "invFunc (wvtFunc m k) = wvtFunc k m" using lemWVTInverse by auto
moreover have "cts (wvtFunc k m) y"
using assms(4) lemWVTInverseCts[of "y" "m" "k" "x"] by auto
ultimately have 5: "cts (invFunc (wvtFunc m k)) y" by force
have 6: "applyAffineToLine A l l'" using assms(5) by auto
hence tgt: "tangentLine l' (applyToSet (wvtFunc m k) (wline m b)) y"
using main 1 2 3 4 5 by meson
have axdiff: "axDiff k m y" using AxDiff by blast
hence "(∃ r . wvtFunc k m y r)
⟶ (∃ A' . (affineApprox A' (wvtFunc k m) y ))" by blast
then obtain A' where A': "affineApprox A' (wvtFunc k m) y" using assms(4) by auto
hence "(∃δ>0. ∀p. (p within δ of y) ⟶ (definedAt (wvtFunc k m) p))"
using sublemma4[of "wvtFunc k m" "A'" "y"] by auto
then obtain d where d: "(d > 0) ∧ (∀p.
(p within d of y) ⟶ (definedAt (wvtFunc k m) p))"
by auto
hence dpos: "d > 0" by auto
define Ball where Ball: "Ball = ball y d"
have l2r: "(applyToSet (wvtFunc m k) (wline m b)) ∩ Ball ⊆ (wline k b) ∩ Ball"
using Ball by auto
{ fix q
assume q: "q ∈ (wline k b) ∩ Ball"
hence "q within d of y" using Ball lemSep2Symmetry by auto
hence "definedAt (wvtFunc k m) q" using d by auto
hence qset: "q ∈ applyToSet (wvtFunc m k) (wvt k m q)" by auto
have "wvt k m q ⊆ applyToSet (wvtFunc k m) (wline k b)" using q by auto
hence "wvt k m q ⊆ wline m b" by auto
hence "applyToSet (wvtFunc m k) (wvt k m q)
⊆ applyToSet (wvtFunc m k) (wline m b)" by auto
hence "q ∈ applyToSet (wvtFunc m k) (wline m b)" using qset by auto
hence "q ∈ (applyToSet (wvtFunc m k) (wline m b)) ∩ Ball" using qset q by auto
}
hence r2l: "(wline k b) ∩ Ball ⊆ (applyToSet (wvtFunc m k) (wline m b)) ∩ Ball"
by auto
define lBall where lBall: "lBall = (applyToSet (wvtFunc m k) (wline m b)) ∩ Ball"
define rBall where rBall: "rBall = (wline k b) ∩ Ball"
hence equ: "lBall = rBall" using l2r r2l lBall rBall by auto
have yinBall: "y ∈ Ball" using Ball d by auto
have tgt1: "y ∈ (applyToSet (wvtFunc m k) (wline m b))" using tgt by auto
hence "y ∈ lBall" using yinBall lBall by auto
hence rtp1: "y ∈ wline k b" using equ rBall by auto
have rtp2: "onLine y l'" using tgt by auto
have tgt3: "accPoint y (applyToSet (wvtFunc m k) (wline m b))" using tgt by auto
hence tgt3': "∀ ε > 0. ∃ q ∈ (applyToSet (wvtFunc m k) (wline m b)) . (y ≠ q) ∧ (inBall q ε y)"
by auto
{ fix e
assume epos: "e > 0"
define d1 where d': "d1 = min d e"
have dd: "d1 ≤ d" using d' by auto
have de: "d1 ≤ e" using d' by auto
have d'pos: "d1 > 0" using dpos epos d' by auto
then obtain q
where q: "q ∈ (applyToSet (wvtFunc m k) (wline m b)) ∧ (y ≠ q) ∧ (inBall q d1 y)"
using tgt3' by blast
hence "q ∈ (applyToSet (wvtFunc m k) (wline m b)) ∧ (inBall q d y) ∧ (y ≠ q)"
using lemBallInBall[of "q" "y" "d1" "d"] d'pos dd by auto
hence "q ∈ lBall ∧ (y ≠ q) ∧ (inBall q d1 y)"
using q Ball lemSep2Symmetry lBall by auto
hence "q ∈ rBall ∧ (y ≠ q) ∧ (inBall q e y)"
using lemBallInBall[of "q" "y" "d1" "e"] d'pos de equ by auto
hence "∃ q ∈ rBall . (y ≠ q) ∧ (inBall q e y)" by auto
}
hence rtp3: "∀ e > 0. ∃ q ∈ wline k b . (y ≠ q) ∧ (inBall q e y)" using rBall by auto
have tgt4: "(∃ p . ( (onLine p l') ∧ (p ≠ y) ∧
(∀ ε > 0 . ∃ δ > 0 . ∀ y' ∈ (applyToSet (wvtFunc m k) (wline m b)). (
( (y' within δ of y) ∧ (y' ≠ y) )
⟶
( ∃ r . ((onLine r (lineJoining y y')) ∧ (r within ε of p))))
)
))" using tgt by auto
then obtain p where p: "( (onLine p l') ∧ (p ≠ y) ∧
(∀ ε > 0 . ∃ δ > 0 . ∀ y' ∈ (applyToSet (wvtFunc m k) (wline m b)). (
( (y' within δ of y) ∧ (y' ≠ y) )
⟶
( ∃ r . ((onLine r (lineJoining y y')) ∧ (r within ε of p))))
))" by auto
have p1: "onLine p l'" using p by auto
have p2: "p ≠ y" using p by auto
{ fix e
assume epos: "e > 0"
then obtain d2 where d2: "(d2 > 0) ∧
(∀ y' ∈ (applyToSet (wvtFunc m k) (wline m b)). (
( (y' within d2 of y) ∧ (y' ≠ y) )
⟶
( ∃ r . ((onLine r (lineJoining y y')) ∧ (r within e of p))))
)" using p by auto
hence d2pos: "d2 > 0" by auto
define dm where dm: "dm = min d2 d"
have dmd2: "dm ≤ d2" using dm by auto
have dmd: "dm ≤ d" using dm by auto
have dmpos: "dm > 0" using dpos d2pos dm by auto
{ fix y'
assume y': "(y' ∈ wline k b) ∧ (y' within dm of y) ∧ (y' ≠ y)"
hence ydm: "y' within dm of y" by auto
hence "y' within d of y" using dmpos dmd lemBallInBall[of "y'" "y" "dm" "d"] by auto
hence "y' ∈ Ball" using Ball lemSep2Symmetry by auto
hence "y' ∈ rBall" using y' rBall by auto
hence yL: "y' ∈ lBall" using equ by auto
have "y' within d2 of y"
using ydm dmpos dmd2 lemBallInBall[of "y'" "y" "dm" "d2"] by auto
hence "y' ∈ (applyToSet (wvtFunc m k) (wline m b)) ∧ (y' within d2 of y) ∧ (y' ≠ y)"
using y' yL lBall by auto
hence "∃ r . ((onLine r (lineJoining y y')) ∧ (r within e of p))"
using d2 by auto
}
hence "∃ dm > 0. ∀ y' ∈ (wline k b) .
(y' within dm of y) ∧ (y' ≠ y)
⟶ (∃ r . ((onLine r (lineJoining y y')) ∧ (r within e of p)))"
using dmpos by blast
}
hence "∀ e > 0 . ∃ dm > 0. ∀ y' ∈ (wline k b) .
(y' within dm of y) ∧ (y' ≠ y)
⟶ (∃ r . ((onLine r (lineJoining y y')) ∧ (r within e of p)))"
by auto
hence rtp4: "∃p . ( (onLine p l') ∧ (p ≠ y) ∧ (∀ e > 0 . ∃ dm > 0. ∀ y' ∈ (wline k b) .
(y' within dm of y) ∧ (y' ≠ y)
⟶ (∃ r . ((onLine r (lineJoining y y')) ∧ (r within e of p)))))"
using p1 p2 by auto
hence "tangentLine l' (wline k b) y" using rtp1 rtp2 rtp3 rtp4 by blast
thus ?thesis by auto
qed
lemma lemTangentLines:
assumes "affineApprox A (wvtFunc m k) x"
and "tl l m b x"
and "applyAffineToLine A l l'"
and "wvtFunc m k x y"
shows "tl l' k b y"
proof -
have pres: "x ∈ wline m b
⟶ tangentLine l (wline m b) x
⟶ affineApprox A (wvtFunc m k) x
⟶ wvtFunc m k x y
⟶ applyAffineToLine A l l'
⟶ tangentLine l' (wline k b) y"
using lemPresentation[of "x" "m" "b" "l" "k" "A" "y" "l'"]
by blast
have 1: "x ∈ wline m b" using assms(2) by auto
have 2: "tangentLine l (wline m b) x" using assms(2) by auto
have 3: "affineApprox A (wvtFunc m k) x" using assms(1) by simp
have 4: "wvtFunc m k x y" using assms(4) by simp
have 5: "applyAffineToLine A l l'" using assms(3) by simp
have "tangentLine l' (wline k b) y" using pres 1 2 3 4 5 by meson
thus ?thesis by auto
qed
lemma lemSelfTangentIsTimeAxis:
assumes "tangentLine l (wline k k) x"
shows "l = timeAxis"
proof -
define s where s: "s = wline k k"
hence "s ⊆ timeAxis" using s AxSelfMinus by blast
hence xOnAxis: "onTimeAxis x" using assms(1) s by auto
have x: "(x ∈ s) ∧ (onLine x l) ∧ (accPoint x s)
∧ (∃ p . ( (onLine p l) ∧ (p ≠ x) ∧
(∀ ε > 0 . ∃ δ > 0 . ∀ z ∈ s. (
( (z within δ of x) ∧ (z ≠ x) )
⟶
( ∃ r . ((onLine r (lineJoining x z)) ∧ (r within ε of p))))
)))" using s assms(1) by auto
then obtain p where
p: "( (onLine p l) ∧ (p ≠ x) ∧
(∀ ε > 0 . ∃ δ > 0 . ∀ z ∈ s. (
( (z within δ of x) ∧ (z ≠ x) )
⟶
( ∃ r . ((onLine r (lineJoining x z)) ∧ (r within ε of p))))
))" by auto
have accxs: "accPoint x s" using x by auto
define p0 where
p0: "p0 = ⦇ tval = tval p, xval = 0, yval = 0, zval = 0 ⦈"
hence p0OnAxis: "onTimeAxis p0" by auto
define dp where dp: "dp = sep2 p p0"
have pp0: "dp = sqr (tval p0 - tval p) + sqr (xval p0 - xval p) +
sqr (yval p0 - yval p) + sqr (zval p0 - zval p)"
using dp p0 by simp
moreover have "… = sqr (xval p) + sqr (yval p) + sqr (zval p)"
using p0 by auto
ultimately have dpval: "dp = sqr (xval p) + sqr (yval p) + sqr (zval p)"
using dp by simp
define e where e: "e = (min dp 1) / 2"
define e2 where e2: "e2 = sqr e"
have e2ledp: "e2 ≤ dp"
proof -
have msmall: "0 ≤ (min dp 1) ≤ 1" using lemNorm2NonNeg dp by auto
hence esmall: "0 ≤ e < 1" using e leI by force
hence e2lte: "e2 ≤ e" using e2 mult_left_le by force
have mrange: "0 ≤ (min dp 1) ≤ dp" using lemNorm2NonNeg dp by auto
hence "e ≤ dp/2" using e divide_right_mono zero_le_numeral by blast
hence "e ≤ dp" using msmall e add_increasing2 divide_nonneg_nonneg
le_cases lemSumOfTwoHalves min_def zero_le_numeral
by metis
thus ?thesis using e2lte by auto
qed
have offaxis: "∀ z . (dp > 0) ∧ onTimeAxis z ⟶ ¬ (z within e of p)"
proof -
{ fix z
{ assume z: "(dp > 0) ∧ onTimeAxis z"
have "sep2 z p = sqr (tval z - tval p)
+ sqr (xval z - xval p)
+ sqr (yval z - yval p)
+ sqr (zval z - zval p)" using p0 by simp
moreover have "… = sep2 z p0
+ sqr (xval p) + sqr (yval p) + sqr (zval p)"
using p0 z by auto
moreover have "… = sep2 z p0 + dp"
using dpval add_assoc
by presburger
moreover have "… ≥ dp" using lemNorm2NonNeg by simp
ultimately have "sep2 z p ≥ e2"
using e2ledp dual_order.trans by presburger
}
hence "(0 < dp) ∧ onTimeAxis z ⟶ ¬ (z within e of p)"
using e2 by auto
}
thus ?thesis by auto
qed
{ assume dpnz: "dp > 0"
hence enz: "e > 0" using e by auto
then obtain d where d: "(d > 0) ∧ (∀ z ∈ s. (
( (z within d of x) ∧ (z ≠ x) )
⟶
( ∃ r . ((onLine r (lineJoining x z)) ∧ (r within e of p)))))"
using p by blast
obtain q where q: "(q ∈ s) ∧ (x ≠ q) ∧ (inBall q d x)"
using accxs dpnz enz d by blast
hence qOnAxis: "q ∈ timeAxis" using s AxSelfMinus by blast
have qprops: "(q within d of x) ∧ (q ≠ x)" using q by auto
then obtain r where r: "(onLine r (lineJoining x q)) ∧ (r within e of p)"
using d q by blast
have "x ≠ q" using q by auto
moreover have "onLine x timeAxis" using xOnAxis lemTimeAxisIsLine by auto
moreover have "onLine q timeAxis" using qOnAxis lemTimeAxisIsLine by auto
ultimately have "timeAxis = lineJoining x q"
using lemLineAndPoints[of "x" "q" "timeAxis"]
by auto
hence rOnAxis: "(onTimeAxis r)" using r by auto
hence "¬ (r within e of p)" using offaxis dpnz by blast
hence "False" using r by blast
}
hence "¬ (dp > 0) ∧ (dp ≥ 0)" using lemNorm2NonNeg dp by auto
hence "dp = 0" by auto
hence "p = p0" using dp lemNullImpliesOrigin[of "p ⊖ p0"] by auto
hence "onLine p timeAxis" using p0OnAxis lemTimeAxisIsLine by auto
moreover have "onLine x timeAxis" using xOnAxis lemTimeAxisIsLine by auto
moreover have pnotx: "p ≠ x" using p by blast
ultimately have xp: "timeAxis = lineJoining x p"
using lemLineAndPoints[of "x" "p" "timeAxis"]
by auto
have "onLine p l" using p by auto
moreover have "onLine x l" using x by auto
ultimately have "l = lineJoining x p"
using lemLineAndPoints[of "x" "p" "l"] pnotx
by auto
hence "timeAxis = l" using xp by auto
thus ?thesis using s by blast
qed
lemma lemTangentLineUnique:
assumes "tl l1 m k x"
and "tl l2 m k x"
and "affineApprox A (wvtFunc m k) x"
and "wvtFunc m k x y"
and "x ∈ wline m k"
shows "l1 = l2"
proof -
define L1 where L1: "L1 = applyToSet (asFunc A) l1"
define L2 where L2: "L2 = applyToSet (asFunc A) l2"
define p1 where p1: "p1 = (x ∈ wline m k)"
define p2a where p2a: "p2a = tangentLine l1 (wline m k) x"
define p2b where p2b: "p2b = tangentLine l2 (wline m k) x"
define p3 where p3: "p3 = affineApprox A (wvtFunc m k) x"
define p4 where p4: "p4 = wvtFunc m k x y"
define p5a where p5a: "p5a = applyAffineToLine A l1 L1"
define p5b where p5b: "p5b = applyAffineToLine A l2 L2"
define tgt1 where tgt1: "tgt1 = tangentLine L1 (wline k k) y"
define tgt2 where tgt2: "tgt2 = tangentLine L2 (wline k k) y"
have pre1: "p1" using p1 assms(5) by auto
have pre2a: "p2a" using p2a assms(1) by auto
have pre2b: "p2b" using p2b assms(2) by auto
have pre3: "p3" using p3 assms(4) using assms(3) by auto
have pre4: "p4" using p4 assms(4) by auto
have "isLine l1" using assms(1) by auto
hence pre5a: "p5a" using p5a L1 assms(3) lemAffineOfLineIsLine[of "l1" "A" "L1"] by auto
have "isLine l2" using assms(2) by auto
hence pre5b: "p5b" using p5b L2 assms(3) lemAffineOfLineIsLine[of "l2" "A" "L2"] by auto
have "⟦ p1; p2a; p3; p4; p5a ⟧ ⟹ tgt1"
using p1 p2a p3 p4 p5a tgt1 lemPresentation[of "x" "m" "k" "l1" "k" "A" "y" "L1"]
by fast
hence "tgt1" using pre1 pre2a pre3 pre4 pre5a by auto
hence L1axis: "L1 = timeAxis" using tgt1 lemSelfTangentIsTimeAxis by auto
have "⟦ p1; p2b; p3; p4; p5b ⟧ ⟹ tgt2"
using p1 p2b p3 p4 p5b tgt2 lemPresentation[of "x" "m" "k" "l2" "k" "A" "y" "L2"]
by fast
hence "tgt2" using pre1 pre2b pre3 pre4 pre5b by auto
hence "L2 = timeAxis" using tgt2 lemSelfTangentIsTimeAxis by auto
hence L1L2: "L1 = L2" using L1axis by auto
obtain A' where A': "(affine A') ∧ (∀ p q . A p = q ⟷ A' q = p)"
using assms(3) lemInverseAffine[of "A"] by auto
{ fix p
define q where q: "q = A p"
hence A'q: "A' q = p" using A' by auto
{ assume "p ∈ l1"
hence "q ∈ L2" using q L1 L1L2 by auto
then obtain p2 where p2: "q = A p2 ∧ p2 ∈ l2" using L2 by auto
hence "A' q = p2" using A' by auto
hence "p = p2" using A'q by auto
hence "p ∈ l2" using p2 by auto
}
hence l2r: "p ∈ l1 ⟶ p ∈ l2" by blast
{ assume "p ∈ l2"
hence "q ∈ L1" using q L2 L1L2 by auto
then obtain p1 where p1: "q = A p1 ∧ p1 ∈ l1" using L1 by auto
hence "A' q = p1" using A' by auto
hence "p = p1" using A'q by auto
hence "p ∈ l1" using p1 by auto
}
hence "p ∈ l2 ⟶ p ∈ l1" by blast
hence "p ∈ l1 ⟷ p ∈ l2" using l2r by auto
}
thus ?thesis by blast
qed
end
end