Realization Boundaries · Lean source

ComputableQuotientCodes.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.

Local imports (1)

RealizationBoundaries/ComputableQuotientCodes.lean282 lines

Original source pathRealizationBoundaries/ComputableQuotientCodes.lean
Skip declarations and read code

Skip source text

1 import RealizationBoundaries.ComputablePresentations
2 import Mathlib.Data.Nat.Nth
3 
4 /-! # From redundant computable codes to an actual computable copy -/
5 set_option autoImplicit false
6 set_option backward.isDefEq.respectTransparency false
7 noncomputable section
8 namespace RealizationBoundaries
9 
10 /-- Redundant natural codes are permitted, but equality of their actual meanings
11 must be oracle computable. This is stronger than a merely enumerable relator
12 presentation. -/
13 structure OracleRawGroupCodes (X : ℕ → Bool) (H : Type*) [AddGroup H] where
14   names : ℕ → H
15   names_surjective : Function.Surjective names
16   zero : ℕ
17   add : ℕ → ℕ → ℕ
18   equal : ℕ → ℕ → ℕ
19   zero_spec : names zero = 0
20   add_spec : ∀ i j, names (add i j) = names i + names j
21   equal_spec : ∀ i j, equal i j = 0 ↔ names i = names j
22   add_computable : OracleComputable X (fun k => add k.unpair.1 k.unpair.2)
23   equal_computable : OracleComputable X (fun k => equal k.unpair.1 k.unpair.2)
24 
25 namespace OracleRawGroupCodes
26 variable {X : ℕ → Bool} {H : Type*} [AddGroup H]
27 
28 /-- The least natural code of its equality class. -/
29 def Canonical (c : OracleRawGroupCodes X H) (n : ℕ) : Prop :=
30   ∀ m < n, c.names m ≠ c.names n
31 
32 instance canonical_decidable (c : OracleRawGroupCodes X H) : DecidablePred c.Canonical := by
33   intro n
34   exact Classical.propDecidable _
35 
36 theorem canonical_code_exists (c : OracleRawGroupCodes X H) (x : H) :
37     ∃ n, c.Canonical n ∧ c.names n = x := by
38   classical
39   let h := c.names_surjective x
40   refine ⟨Nat.find h, ?_, Nat.find_spec h⟩
41   intro m hm he
42   exact Nat.find_min h hm (he.trans (Nat.find_spec h))
43 
44 theorem canonical_names_injective (c : OracleRawGroupCodes X H) :
45     Function.Injective (fun n : {n // c.Canonical n} => c.names n.val) := by
46   intro n m h
47   apply Subtype.ext
48   by_contra hn
49   rcases lt_or_gt_of_ne hn with hnm | hmn
50   · exact m.property n.val hnm h
51   · exact n.property m.val hmn h.symm
52 
53 theorem canonical_infinite (c : OracleRawGroupCodes X H) [Infinite H] :
54     {n | c.Canonical n}.Infinite := by
55   intro hf
56   have hi : Set.Finite (Set.range c.names) := by
57     apply (hf.image c.names).subset
58     rintro x ⟨n, rfl⟩
59     obtain ⟨m, hm, he⟩ := c.canonical_code_exists (c.names n)
60     exact ⟨m, hm, he⟩
61   have hu : Set.range c.names = Set.univ := Set.range_eq_univ.mpr c.names_surjective
62   exact Set.infinite_univ (hu ▸ hi)
63 
64 /-- Finite equality-product: nonzero exactly when no preceding code has the
65 same meaning as the supplied code. -/
66 def previousProduct (c : OracleRawGroupCodes X H) (q n : ℕ) : ℕ :=
67   Nat.rec 1 (fun m r => r * c.equal m q) n
68 
69 theorem previousProduct_ne_zero (c : OracleRawGroupCodes X H) (q n : ℕ) :
70     c.previousProduct q n ≠ 0 ↔ ∀ m < n, c.equal m q ≠ 0 := by
71   induction n with
72   | zero => simp [previousProduct]
73   | succ n ih =>
74     change c.previousProduct q n * c.equal n q ≠ 0 ↔ _
75     rw [mul_ne_zero_iff, ih]
76     constructor
77     · rintro ⟨h, hn⟩ m hm
78       rcases Nat.lt_succ_iff_lt_or_eq.mp hm with hm | rfl
79       · exact h m hm
80       · exact hn
81     · intro h
82       exact ⟨fun m hm => h m (Nat.lt_succ_of_lt hm), h n (Nat.lt_succ_self n)⟩
83 
84 /-- Zero is the successful canonical-code test. -/
85 def canonicalTest (c : OracleRawGroupCodes X H) (n : ℕ) : ℕ :=
86   if c.previousProduct n n = 0 then 1 else 0
87 
88 theorem canonicalTest_correct (c : OracleRawGroupCodes X H) (n : ℕ) :
89     c.canonicalTest n = 0 ↔ c.Canonical n := by
90   simp only [canonicalTest, ite_eq_right_iff, one_ne_zero, imp_false]
91   change c.previousProduct n n ≠ 0 ↔ c.Canonical n
92   rw [c.previousProduct_ne_zero]
93   exact forall_congr' fun m => imp_congr_right fun _ => (c.equal_spec m n).not
94 
95 theorem previousProduct_computable (c : OracleRawGroupCodes X H) :
96     OracleComputable X (fun k => c.previousProduct k.unpair.1 k.unpair.2) := by
97   have he : OracleComputable X
98       (fun k => c.equal k.unpair.2.unpair.1 k.unpair.1) :=
99     c.equal_computable.comp ((OracleComputable.left.comp OracleComputable.right).pair
100       OracleComputable.left) |>.of_eq (fun k => by simp)
101   exact OracleComputable.prec (step := fun q m r => r * c.equal m q) (OracleComputable.const 1)
102     ((OracleComputable.right.comp OracleComputable.right).mul he)
103 
104 theorem canonicalTest_computable (c : OracleRawGroupCodes X H) :
105     OracleComputable X c.canonicalTest :=
106   (c.previousProduct_computable.comp (OracleComputable.id.pair OracleComputable.id)).isZero
107     |>.of_eq (fun n => by simp [canonicalTest])
108 
109 end OracleRawGroupCodes
110 
111 namespace OracleComputable
112 variable {X : ℕ → Bool} {f g : ℕ → ℕ}
113 
114 theorem add (hf : OracleComputable X f) (hg : OracleComputable X g) :
115     OracleComputable X (fun n => f n + g n) :=
116   (Nat.Primrec.add.recursiveIn : OracleComputable X (Nat.unpaired (· + ·))).comp
117     (hf.pair hg) |>.of_eq (fun n => by simp [Nat.unpaired])
118 
119 /-- The count of successful zero tests below a finite bound. -/
120 def zeroCount (test : ℕ → ℕ) (n : ℕ) : ℕ :=
121   Nat.rec 0 (fun m r => r + if test m = 0 then 1 else 0) n
122 
123 theorem zeroCount_computable (ht : OracleComputable X f) :
124     OracleComputable X (zeroCount f) := by
125   have hi := (ht.comp (OracleComputable.left.comp OracleComputable.right)).isZero
126   have hrec := OracleComputable.prec (step := fun _ m r => r + if f m = 0 then 1 else 0) (OracleComputable.const 0)
127     ((OracleComputable.right.comp OracleComputable.right).add hi)
128   exact (hrec.comp ((OracleComputable.const 0).pair OracleComputable.id)).of_eq
129     (fun n => by simp [zeroCount])
130 
131 theorem zeroCount_eq_count (test : ℕ → ℕ) (n : ℕ) :
132     zeroCount test n = Nat.count (fun m => test m = 0) n := by
133   induction n with
134   | zero => simp [zeroCount]
135   | succ n ih =>
136     change zeroCount test n + (if test n = 0 then 1 else 0) = _
137     rw [Nat.count_succ, ih]
138 
139 /-- A zero test for the relation: candidate `m` is successful and has exactly
140 `n` successful predecessors. -/
141 def nthTest (test : ℕ → ℕ) (k : ℕ) : ℕ :=
142   if test k.unpair.2 = 0 ∧ zeroCount test k.unpair.2 = k.unpair.1 then 0 else 1
143 
144 theorem nthTest_computable (ht : OracleComputable X f) :
145     OracleComputable X (nthTest f) := by
146   have hl : Primrec (fun k : ℕ => k.unpair.1) := Primrec.fst.comp Primrec.unpair
147   have hr : Primrec (fun k : ℕ => k.unpair.2) := Primrec.snd.comp Primrec.unpair
148   have hp : Computable (fun k : ℕ =>
149       if k.unpair.1 = 0 ∧ k.unpair.2.unpair.1 = k.unpair.2.unpair.2 then 0 else 1) :=
150     (Primrec.ite ((Primrec.eq.comp hl (Primrec.const 0)).and
151       (Primrec.eq.comp (hl.comp hr) (hr.comp hr)))
152       (Primrec.const 0) (Primrec.const 1)).to_comp
153   exact (of_computable hp).comp ((ht.comp right).pair
154     (((zeroCount_computable ht).comp right).pair left))
155       |>.of_eq (fun k => by simp [nthTest])
156 
157 theorem nthTest_correct (test : ℕ → ℕ) (n m : ℕ) :
158     nthTest test (Nat.pair n m) = 0 ↔
159       test m = 0 ∧ Nat.count (fun t => test t = 0) m = n := by
160   simp [nthTest, zeroCount_eq_count]
161 
162 /-- Increasing enumeration of an infinite oracle-decidable set is an actual
163 terminating oracle computation. -/
164 theorem nth_zero_computable (test : ℕ → ℕ) (ht : OracleComputable X test)
165     (hi : {n | test n = 0}.Infinite) :
166     OracleComputable X (Nat.nth (fun n => test n = 0)) := by
167   have total : ∀ n, ∃ m, nthTest test (Nat.pair n m) = 0 := by
168     intro n
169     refine ⟨Nat.nth (fun m => test m = 0) n, (nthTest_correct test _ _).mpr ?_⟩
170     exact ⟨Nat.nth_mem_of_infinite hi n, Nat.count_nth_of_infinite hi n⟩
171   apply (find (nthTest_computable ht) total).of_eq
172   intro n
173   have hm := (nthTest_correct test n _).mp (Nat.find_spec (total n))
174   have he := Nat.nth_count (p := fun m => test m = 0) hm.1
175   rw [hm.2] at he
176   exact he.symm
177 
178 end OracleComputable
179 
180 namespace OracleRawGroupCodes
181 variable {X : ℕ → Bool} {H : Type*} [AddGroup H] [Infinite H]
182 
183 theorem canonicalTest_infinite (c : OracleRawGroupCodes X H) :
184     {n | c.canonicalTest n = 0}.Infinite := by
185   have he : {n | c.canonicalTest n = 0} = {n | c.Canonical n} :=
186     Set.ext (c.canonicalTest_correct)
187   rw [he]
188   exact c.canonical_infinite
189 
190 /-- Increasing enumeration of the least equality-class representatives. -/
191 def enumCode (c : OracleRawGroupCodes X H) : ℕ → ℕ :=
192   Nat.nth (fun n => c.canonicalTest n = 0)
193 
194 theorem enumCode_computable (c : OracleRawGroupCodes X H) :
195     OracleComputable X c.enumCode :=
196   OracleComputable.nth_zero_computable c.canonicalTest c.canonicalTest_computable
197     c.canonicalTest_infinite
198 
199 theorem enumCode_canonical (c : OracleRawGroupCodes X H) (n : ℕ) :
200     c.Canonical (c.enumCode n) :=
201   (c.canonicalTest_correct _).mp (Nat.nth_mem_of_infinite c.canonicalTest_infinite n)
202 
203 theorem enumNames_injective (c : OracleRawGroupCodes X H) :
204     Function.Injective (fun n => c.names (c.enumCode n)) := by
205   intro n m h
206   have hc := c.canonical_names_injective
207     (show (fun k : {n // c.Canonical n} => c.names k.val)
208       ⟨c.enumCode n, c.enumCode_canonical n⟩ =
209       (fun k : {n // c.Canonical n} => c.names k.val)
210       ⟨c.enumCode m, c.enumCode_canonical m⟩ from h)
211   exact Nat.nth_injective c.canonicalTest_infinite (congrArg Subtype.val hc)
212 
213 omit [Infinite H] in
214 theorem enumNames_surjective (c : OracleRawGroupCodes X H) :
215     Function.Surjective (fun n => c.names (c.enumCode n)) := by
216   intro x
217   obtain ⟨m, hm, he⟩ := c.canonical_code_exists x
218   refine ⟨Nat.count (fun n => c.canonicalTest n = 0) m, ?_⟩
219   unfold enumCode
220   dsimp only
221   rw [Nat.nth_count (p := fun n => c.canonicalTest n = 0) ((c.canonicalTest_correct m).mpr hm)]
222   exact he
223 
224 /-- An actual bijective naming, obtained from the computed canonical enumeration. -/
225 def namesEquiv (c : OracleRawGroupCodes X H) : ℕ ≃ H :=
226   Equiv.ofBijective (fun n => c.names (c.enumCode n))
227     ⟨c.enumNames_injective, c.enumNames_surjective⟩
228 
229 /-- Search for the unique canonical name of a raw code. -/
230 def indexTest (c : OracleRawGroupCodes X H) (k : ℕ) : ℕ :=
231   c.equal (c.enumCode k.unpair.2) k.unpair.1
232 
233 theorem indexTest_computable (c : OracleRawGroupCodes X H) :
234     OracleComputable X c.indexTest :=
235   c.equal_computable.comp ((c.enumCode_computable.comp OracleComputable.right).pair
236     OracleComputable.left) |>.of_eq (fun k => by simp [indexTest])
237 
238 omit [Infinite H] in
239 theorem indexTest_total (c : OracleRawGroupCodes X H) (n : ℕ) :
240     ∃ t, c.indexTest (Nat.pair n t) = 0 := by
241   obtain ⟨t, ht⟩ := c.enumNames_surjective (c.names n)
242   refine ⟨t, ?_⟩
243   simpa only [indexTest, Nat.unpair_pair] using (c.equal_spec _ _).mpr ht
244 
245 /-- Canonical index extraction terminates by surjectivity of the enumeration. -/
246 def index (c : OracleRawGroupCodes X H) (n : ℕ) : ℕ :=
247   Nat.find (c.indexTest_total n)
248 
249 theorem index_computable (c : OracleRawGroupCodes X H) :
250     OracleComputable X c.index :=
251   OracleComputable.find c.indexTest_computable c.indexTest_total
252 
253 theorem index_spec (c : OracleRawGroupCodes X H) (n : ℕ) :
254     c.namesEquiv (c.index n) = c.names n := by
255   apply (c.equal_spec _ _).mp
256   simpa only [indexTest, index, Nat.unpair_pair] using Nat.find_spec (c.indexTest_total n)
257 
258 /-- Redundant codes with decidable oracle equality yield a genuine computable
259 Nat-domain copy of every infinite group they enumerate. No quotient equality is
260 silently treated as decidable. -/
261 def toOracleGroupCopy (c : OracleRawGroupCodes X H) : OracleGroupCopy X H where
262   names := c.namesEquiv
263   zero := c.index c.zero
264   add := fun i j => c.index (c.add (c.enumCode i) (c.enumCode j))
265   zero_spec := (c.index_spec c.zero).trans c.zero_spec
266   add_spec := by
267     intro i j
268     exact (c.index_spec _).trans (c.add_spec _ _)
269   add_computable := by
270     have ha := c.add_computable.comp
271       ((c.enumCode_computable.comp OracleComputable.left).pair
272         (c.enumCode_computable.comp OracleComputable.right))
273     exact c.index_computable.comp ha |>.of_eq (fun k => by simp)
274 
275 /-- The existence form needed by concrete raw normal-form constructions. -/
276 theorem oracleGroupCopy_of_rawCodes (c : OracleRawGroupCodes X H) :
277     Nonempty (OracleGroupCopy X H) :=
278   ⟨c.toOracleGroupCopy⟩
279 
280 end OracleRawGroupCodes
281 
282 end RealizationBoundaries

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: 1e476f875f0917cdcaf3292c399ddbb83b3dacca080c7cbd2c2faec57da32757

Original source on GitHub

Back to Realization Boundaries