Komorebi Space · Lean source

ProtectedLinearCertificates.lean

Declared contract recorded Coverage and evidence

The cited release explicitly reports completion of its registered formal contract, under its exact hypotheses.

This viewer reads the retained source; it does not run Lean or assign new claim mappings.

KomorebiSpace/ProtectedLinearCertificates.lean214 lines

Original source pathlean/KomorebiSpace/ProtectedLinearCertificates.lean
Skip declarations and read code

Skip source text

1 import Mathlib.LinearAlgebra.Dual.Lemmas
2 import Mathlib.LinearAlgebra.FiniteDimensional.Lemmas
3 import Mathlib.LinearAlgebra.Matrix.ToLin
4 import Mathlib.LinearAlgebra.Matrix.Rank
5 import Mathlib.Tactic.LinearCombination
6 import Mathlib.Tactic.Abel
7 
8 set_option autoImplicit false
9 
10 /-!
11 # KS57: exact protected answers or normalized algebraic obstruction certificates
12 
13 The alternative is proved for linear maps over an arbitrary field. A finite
14 matrix specialization retains actual row-vector equations. The proof does
15 not assume an elimination algorithm is correct, and does not certify the
16 separate Python implementation for arbitrary inputs.
17 -/
18 universe u v w z
19 noncomputable section
20 namespace KomorebiSpace.ProtectedLinearCertificates
21 open Module
22 variable {K : Type u} [Field K]
23 variable {E : Type v} {R : Type w} {S : Type z}
24 variable [AddCommGroup E] [Module K E]
25 variable [AddCommGroup R] [Module K R]
26 variable [AddCommGroup S] [Module K S]
27 variable (D : E →ₗ[K] R) (p : E →ₗ[K] S)
28 
29 def Answer (x y : E) : Prop := D y = 0 ∧ p y = p x
30 
31 def Certificate (x : E) : Prop :=
32   ∃ (lam : R →ₗ[K] K) (mu : S →ₗ[K] K),
33     lam.comp D = mu.comp p ∧ lam (D x) = 1
34 
35 /-- A certificate directly contradicts the equations of a protected answer. -/
36 theorem certificate_excludes_answer (x : E) (hc : Certificate D p x) :
37     ¬ ∃ y, Answer D p x y := by
38   rintro ⟨y, hy⟩
39   obtain ⟨lam, mu, hrel, hn⟩ := hc
40   have hzero : (1 : K) = 0 := calc
41     1 = lam (D x) := hn.symm
42     _ = mu (p x) := LinearMap.congr_fun hrel x
43     _ = mu (p y) := congrArg mu hy.2.symm
44     _ = lam (D y) := (LinearMap.congr_fun hrel y).symm
45     _ = 0 := by rw [hy.1, map_zero]
46   exact one_ne_zero hzero
47 
48 /-- Feasibility is membership in the range of the actual stacked operator. -/
49 theorem answer_iff_stacked_range (x : E) :
50     (∃ y, Answer D p x y) ↔ (0, p x) ∈ LinearMap.range (D.prod p) := by
51   constructor
52   · rintro ⟨y, hd, hp⟩
53     exact ⟨y, Prod.ext hd hp⟩
54   · rintro ⟨y, hy⟩
55     exact ⟨y, congrArg Prod.fst hy, congrArg Prod.snd hy⟩
56 
57 /-- Algebraic dual separation supplies a normalized witness when the stacked system fails. -/
58 theorem certificate_of_no_answer (x : E) (hn : ¬ ∃ y, Answer D p x y) :
59     Certificate D p x := by
60   have hb : (0, p x) ∉ LinearMap.range (D.prod p) := by
61     intro h
62     exact hn ((answer_iff_stacked_range D p x).mpr h)
63   obtain ⟨f, hf, hmap⟩ := Submodule.exists_dual_map_eq_bot_of_notMem hb inferInstance
64   let w : (R × S) →ₗ[K] K := (f (0, p x))⁻¹ • f
65   have hw (y : E) : w (D y, p y) = 0 := by
66     have hz : f (D y, p y) ∈ (LinearMap.range (D.prod p)).map f :=
67       ⟨(D y, p y), ⟨y, rfl⟩, rfl⟩
68     rw [hmap] at hz
69     change f (D y, p y) = 0 at hz
70     change (f (0, p x))⁻¹ * f (D y, p y) = 0
71     rw [hz, mul_zero]
72   have hwb : w (0, p x) = 1 := inv_mul_cancel₀ hf
73   let lam : R →ₗ[K] K := -(w.comp (LinearMap.inl K R S))
74   let mu : S →ₗ[K] K := w.comp (LinearMap.inr K R S)
75   have hsum (y : E) : w (D y, 0) + w (0, p y) = 0 := by
76     rw [← map_add]
77     simpa only [Prod.mk_add_mk, add_zero, zero_add] using hw y
78   refine ⟨lam, mu, ?_, ?_⟩
79   · ext y
80     change -w (D y, 0) = w (0, p y)
81     linear_combination -hsum y
82   · change -w (D x, 0) = 1
83     have hs := hsum x
84     rw [hwb] at hs
85     linear_combination -hs
86 
87 theorem certificate_iff_no_answer (x : E) :
88     Certificate D p x ↔ ¬ ∃ y, Answer D p x y :=
89   ⟨certificate_excludes_answer D p x, certificate_of_no_answer D p x⟩
90 
91 theorem answer_or_certificate (x : E) :
92     (∃ y, Answer D p x y) ∨ Certificate D p x := by
93   classical
94   by_cases h : ∃ y, Answer D p x y
95   · exact Or.inl h
96   · exact Or.inr (certificate_of_no_answer D p x h)
97 
98 /-- Exactly one alternative holds. -/
99 theorem exclusive_alternative (x : E) :
100     ((∃ y, Answer D p x y) ∨ Certificate D p x) ∧
101     ¬ ((∃ y, Answer D p x y) ∧ Certificate D p x) :=
102   ⟨answer_or_certificate D p x, fun h => certificate_excludes_answer D p x h.2 h.1⟩
103 
104 def ambiguity : Submodule K E := D.ker ⊓ p.ker
105 
106 theorem answer_iff_difference (x y₀ y : E) (hy₀ : Answer D p x y₀) :
107     Answer D p x y ↔ y-y₀ ∈ ambiguity D p := by
108   change (D y = 0 ∧ p y = p x) ↔ (D (y-y₀)=0 ∧ p (y-y₀)=0)
109   rw [map_sub, map_sub, hy₀.1, hy₀.2, sub_zero, sub_eq_zero]
110 
111 /-- Once an answer is chosen, the whole fiber is its affine translate by the ambiguity space. -/
112 def answerEquivAmbiguity (x y₀ : E) (hy₀ : Answer D p x y₀) :
113     {y : E // Answer D p x y} ≃ ambiguity D p where
114   toFun y := ⟨y.val-y₀, (answer_iff_difference D p x y₀ y.val hy₀).mp y.property⟩
115   invFun h := ⟨y₀+h.val, (answer_iff_difference D p x y₀ _ hy₀).mpr (by
116     simpa only [add_sub_cancel_left] using h.property)⟩
117   left_inv y := by apply Subtype.ext; change y₀+(y.val-y₀)=y.val; abel
118   right_inv h := by apply Subtype.ext; change (y₀+h.val)-y₀=h.val; abel
119 
120 theorem stacked_kernel : (D.prod p).ker = ambiguity D p := by
121   ext y
122   change ((D y, p y) = (0,0)) ↔ (D y=0 ∧ p y=0)
123   simp only [Prod.mk.injEq]
124 
125 /-- Rank-nullity includes zero-dimensional sources and targets. -/
126 theorem ambiguity_finrank [FiniteDimensional K E] :
127     Module.finrank K (ambiguity D p) =
128       Module.finrank K E - Module.finrank K (LinearMap.range (D.prod p)) := by
129   have h := LinearMap.finrank_range_add_finrank_ker (D.prod p)
130   rw [stacked_kernel] at h
131   omega
132 
133 end KomorebiSpace.ProtectedLinearCertificates
134 
135 namespace KomorebiSpace.ProtectedLinearCertificates
136 open Matrix Module
137 variable {K : Type u} [Field K]
138 variable {m n s : Type*} [Fintype m] [Fintype n] [Fintype s]
139 
140 /-- Coordinate row of an algebraic functional in the standard finite basis. -/
141 def rowCoefficients {ι : Type*} [Fintype ι] (f : (ι → K) →ₗ[K] K) : ι → K := by
142   classical
143   exact fun i => f (fun j => if i=j then 1 else 0)
144 
145 theorem linear_form_apply {ι : Type*} [Fintype ι]
146     (f : (ι → K) →ₗ[K] K) (x : ι → K) :
147     f x = rowCoefficients f ⬝ᵥ x := by
148   classical
149   rw [LinearMap.pi_apply_eq_sum_univ]
150   apply Finset.sum_congr rfl
151   intro i hi
152   exact mul_comm _ _
153 
154 /-- Literal matrix row certificates, rather than an unspecified dual obstruction. -/
155 theorem matrix_certificate_iff (A : Matrix m n K) (P : Matrix s n K) (x : n → K) :
156     (¬ ∃ y : n → K, A *ᵥ y = 0 ∧ P *ᵥ y = P *ᵥ x) ↔
157       ∃ (lam : m → K) (mu : s → K), lam ᵥ* A = mu ᵥ* P ∧ lam ⬝ᵥ (A *ᵥ x) = 1 := by
158   constructor
159   · intro h
160     obtain ⟨lam, mu, hrel, hn⟩ := certificate_of_no_answer A.mulVecLin P.mulVecLin x h
161     refine ⟨rowCoefficients lam, rowCoefficients mu, ?_, ?_⟩
162     · classical
163       funext j
164       have he := LinearMap.congr_fun hrel (Pi.single j 1)
165       change lam (A *ᵥ Pi.single j 1) = mu (P *ᵥ Pi.single j 1) at he
166       rw [linear_form_apply, linear_form_apply] at he
167       simpa only [Matrix.mulVec_single_one, Matrix.vecMul, dotProduct, Matrix.col_apply] using he
168     · rw [← linear_form_apply]
169       exact hn
170   · rintro ⟨lam, mu, hrel, hn⟩
171     apply certificate_excludes_answer A.mulVecLin P.mulVecLin x
172     refine ⟨dotProductBilin K K lam, dotProductBilin K K mu, ?_, hn⟩
173     ext y
174     change lam ⬝ᵥ (A *ᵥ y) = mu ⬝ᵥ (P *ᵥ y)
175     rw [Matrix.dotProduct_mulVec, Matrix.dotProduct_mulVec, hrel]
176 
177 theorem matrix_exclusive_alternative (A : Matrix m n K) (P : Matrix s n K) (x : n → K) :
178     ((∃ y : n → K, A *ᵥ y = 0 ∧ P *ᵥ y = P *ᵥ x) ∨
179       ∃ (lam : m → K) (mu : s → K), lam ᵥ* A = mu ᵥ* P ∧ lam ⬝ᵥ (A *ᵥ x) = 1) ∧
180     ¬ ((∃ y : n → K, A *ᵥ y = 0 ∧ P *ᵥ y = P *ᵥ x) ∧
181       ∃ (lam : m → K) (mu : s → K), lam ᵥ* A = mu ᵥ* P ∧ lam ⬝ᵥ (A *ᵥ x) = 1) := by
182   rw [← matrix_certificate_iff]
183   exact ⟨Classical.em _, fun h => h.2 h.1⟩
184 
185 /-- The literal vertical block matrix, with rows indexed by the disjoint union. -/
186 def stackedMatrix (A : Matrix m n K) (P : Matrix s n K) : Matrix (Sum m s) n K :=
187   fun i => Sum.elim (fun j => A j) (fun j => P j) i
188 
189 omit [Fintype m] [Fintype s] in
190 theorem stacked_matrix_kernel (A : Matrix m n K) (P : Matrix s n K) :
191     (stackedMatrix A P).mulVecLin.ker = ambiguity A.mulVecLin P.mulVecLin := by
192   ext y
193   change ((stackedMatrix A P) *ᵥ y = 0) ↔ (A *ᵥ y = 0 ∧ P *ᵥ y = 0)
194   constructor
195   · intro h
196     exact ⟨funext (fun i => congrFun h (Sum.inl i)), funext (fun i => congrFun h (Sum.inr i))⟩
197   · rintro ⟨hA, hP⟩
198     funext i
199     cases i with
200     | inl j => exact congrFun hA j
201     | inr j => exact congrFun hP j
202 
203 omit [Fintype m] [Fintype s] in
204 theorem matrix_ambiguity_dimension (A : Matrix m n K) (P : Matrix s n K) :
205     Module.finrank K (ambiguity A.mulVecLin P.mulVecLin) =
206       Fintype.card n - (stackedMatrix A P).rank := by
207   have h := LinearMap.finrank_range_add_finrank_ker (stackedMatrix A P).mulVecLin
208   rw [stacked_matrix_kernel, Module.finrank_fintype_fun_eq_card] at h
209   change (stackedMatrix A P).rank +
210     Module.finrank K (ambiguity A.mulVecLin P.mulVecLin) = Fintype.card n at h
211   omega
212 
213 end KomorebiSpace.ProtectedLinearCertificates
214 end

Back to source controls

Original file and source record

This copy matches the recorded source file. Its publication here does not change the work’s review status.

SHA-256: dca61c5b0e63b51e1f7f79c6aedfb3c505c865e4ff893c14f8093dd0f35c186c

Original source on GitHub

Back to Komorebi Space