oxilean_std/constructive_mathematics/
types.rs1use super::functions::*;
6use oxilean_kernel::{BinderInfo, Declaration, Environment, Expr, Level, Name};
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
12pub struct GrzegorczykLevel(pub usize);
13impl GrzegorczykLevel {
14 pub const E0: GrzegorczykLevel = GrzegorczykLevel(0);
16 pub const E1: GrzegorczykLevel = GrzegorczykLevel(1);
18 pub const E2: GrzegorczykLevel = GrzegorczykLevel(2);
20 pub const E3: GrzegorczykLevel = GrzegorczykLevel(3);
22 pub fn bound(&self, x: u64) -> u64 {
24 match self.0 {
25 0 => x + 1,
26 1 => x.saturating_add(x),
27 2 => x.saturating_mul(x).saturating_add(2),
28 n => {
29 let mut v = x;
30 for _ in 0..(n - 2) {
31 v = 2u64.saturating_pow(v.min(62) as u32);
32 }
33 v
34 }
35 }
36 }
37 pub fn check_bounded(&self, f: impl Fn(u64) -> u64, k: u64) -> bool {
39 (0..=k).all(|x| f(x) <= self.bound(x))
40 }
41 pub fn is_primitive_recursive_approx(&self, f: impl Fn(u64) -> u64, k: u64) -> bool {
43 (0..=10usize).any(|n| GrzegorczykLevel(n).check_bounded(&f, k))
44 }
45}
46pub struct EfficientAlgorithm {
48 pub complexity: String,
50}
51impl EfficientAlgorithm {
52 pub fn new(complexity: impl Into<String>) -> Self {
54 Self {
55 complexity: complexity.into(),
56 }
57 }
58 pub fn correct_and_efficient(&self) -> bool {
61 !self.complexity.is_empty()
62 }
63 pub fn extracted_from_proof(&self) -> bool {
65 true
66 }
67}
68#[derive(Debug, Clone)]
71pub struct ConstructiveReal {
72 pub approx: Vec<i64>,
74 pub max_prec: usize,
75}
76impl ConstructiveReal {
77 pub fn from_rational(p: i64, q: i64, max_prec: usize) -> Self {
79 let approx = (0..=max_prec)
80 .map(|k| {
81 let num = p * (1i64 << k);
82 num / q
83 })
84 .collect();
85 ConstructiveReal { approx, max_prec }
86 }
87 pub fn add(&self, other: &ConstructiveReal) -> ConstructiveReal {
89 let max_prec = self.max_prec.min(other.max_prec);
90 let approx = (0..=max_prec)
91 .map(|k| self.approx[k] + other.approx[k])
92 .collect();
93 ConstructiveReal { approx, max_prec }
94 }
95 pub fn get_approx(&self, k: usize) -> (i64, usize) {
97 (self.approx[k.min(self.max_prec)], k)
98 }
99 pub fn approx_eq(&self, other: &ConstructiveReal, k: usize) -> bool {
101 let k = k.min(self.max_prec).min(other.max_prec);
102 (self.approx[k] - other.approx[k]).abs() <= 1
103 }
104}
105pub struct BrouwerIntuitionism {
107 _version: &'static str,
109}
110impl BrouwerIntuitionism {
111 pub fn new() -> Self {
113 Self { _version: "1907" }
114 }
115 pub fn law_of_excluded_middle_fails(&self) -> bool {
117 true
118 }
119 pub fn creating_subject(&self) -> &'static str {
122 "The creating subject creates mathematical objects freely over time; \
123 the truth of a proposition is settled only when the subject has \
124 experienced a construction."
125 }
126 pub fn choice_sequences(&self) -> &'static str {
129 "A choice sequence α is a potentially infinite sequence α(0), α(1), … \
130 whose values may be chosen freely at each step, subject only to a spread."
131 }
132}
133#[derive(Debug, Clone, Copy, PartialEq, Eq)]
136pub struct PowerSetHeyting {
137 pub universe: u64,
138}
139impl PowerSetHeyting {
140 pub fn new(n: u32) -> Self {
141 PowerSetHeyting {
142 universe: (1u64 << n) - 1,
143 }
144 }
145 pub fn meet(&self, a: u64, b: u64) -> u64 {
146 a & b
147 }
148 pub fn join(&self, a: u64, b: u64) -> u64 {
149 a | b
150 }
151 pub fn top(&self) -> u64 {
152 self.universe
153 }
154 pub fn bot(&self) -> u64 {
155 0
156 }
157 pub fn neg(&self, a: u64) -> u64 {
158 self.implication(a, self.bot())
159 }
160 pub fn implication(&self, a: u64, b: u64) -> u64 {
162 (!a & self.universe) | b
163 }
164 pub fn le(&self, a: u64, b: u64) -> bool {
165 a & b == a
166 }
167 pub fn double_neg(&self, a: u64) -> u64 {
169 self.neg(self.neg(a))
170 }
171}
172pub struct HeylandAlgebra {
174 pub carrier: Vec<String>,
176}
177impl HeylandAlgebra {
178 pub fn new(carrier: Vec<String>) -> Self {
180 Self { carrier }
181 }
182 pub fn is_heyting_algebra(&self) -> bool {
184 !self.carrier.is_empty()
185 }
186 pub fn intuitionistic_propositional_logic(&self) -> &'static str {
189 "A Heyting algebra H models IPC: ⊤ = 1, ⊥ = 0, \
190 a ∧ b = meet, a ∨ b = join, a → b = largest c with c ∧ a ≤ b."
191 }
192}
193#[derive(Debug, Clone)]
196pub struct BarRecursion {
197 pub max_depth: usize,
199 pub bar: Vec<bool>,
201}
202impl BarRecursion {
203 pub fn new(max_depth: usize) -> Self {
205 BarRecursion {
206 max_depth,
207 bar: vec![false; max_depth + 1],
208 }
209 }
210 pub fn set_bar(&mut self, n: usize) {
212 if n <= self.max_depth {
213 self.bar[n] = true;
214 }
215 }
216 pub fn in_bar(&self, n: usize) -> bool {
218 n <= self.max_depth && self.bar[n]
219 }
220 pub fn compute(
224 &self,
225 n: usize,
226 y_val: impl Fn(usize) -> i64,
227 h_step: impl Fn(usize, i64) -> i64,
228 ) -> i64 {
229 if n > self.max_depth {
230 return y_val(n);
231 }
232 if self.in_bar(n) {
233 y_val(n)
234 } else {
235 let sub = self.compute(n + 1, &y_val, &h_step);
236 h_step(n, sub)
237 }
238 }
239 pub fn bar_depth(&self) -> Option<usize> {
241 self.bar.iter().position(|&b| b)
242 }
243}
244#[derive(Debug, Clone, Copy, PartialEq, Eq)]
247pub struct ConstructiveGcd {
248 _marker: (),
249}
250impl ConstructiveGcd {
251 pub fn new() -> Self {
253 ConstructiveGcd { _marker: () }
254 }
255 pub fn gcd(&self, mut a: i64, mut b: i64) -> i64 {
257 a = a.abs();
258 b = b.abs();
259 while b != 0 {
260 let r = a % b;
261 a = b;
262 b = r;
263 }
264 a
265 }
266 pub fn extended_gcd(&self, a: i64, b: i64) -> (i64, i64, i64) {
268 if b == 0 {
269 return (a.abs(), if a >= 0 { 1 } else { -1 }, 0);
270 }
271 let (g, s1, t1) = self.extended_gcd(b, a % b);
272 (g, t1, s1 - (a / b) * t1)
273 }
274 pub fn lcm(&self, a: i64, b: i64) -> Option<i64> {
276 let g = self.gcd(a, b);
277 if g == 0 {
278 return Some(0);
279 }
280 (a / g).checked_mul(b.abs())
281 }
282 pub fn divides(&self, a: i64, b: i64) -> bool {
284 a != 0 && b % a == 0
285 }
286}
287pub struct InfiniteSequence {
289 pub choice_sequence: Vec<u8>,
291}
292impl InfiniteSequence {
293 pub fn new(choice_sequence: Vec<u8>) -> Self {
295 Self { choice_sequence }
296 }
297 pub fn spread_law(&self) -> &'static str {
299 "A spread is a decidable subtree of ω^{<ω} such that every node \
300 has an extension in the tree. Choice sequences live in spreads."
301 }
302 pub fn bar_induction(&self) -> &'static str {
305 "Bar Induction (BI_D): if B is a decidable bar on a spread and \
306 P is hereditary on B, then P holds at the empty sequence."
307 }
308}
309#[derive(Debug, Clone)]
312pub struct CountableChoiceWitness {
313 pub choices: Vec<u64>,
315}
316impl CountableChoiceWitness {
317 pub fn build(sel: impl Fn(usize) -> u64, count: usize) -> Self {
319 CountableChoiceWitness {
320 choices: (0..count).map(|n| sel(n)).collect(),
321 }
322 }
323 pub fn verify(&self, membership: impl Fn(usize, u64) -> bool) -> bool {
326 self.choices
327 .iter()
328 .enumerate()
329 .all(|(n, &x)| membership(n, x))
330 }
331 pub fn get(&self, n: usize) -> Option<u64> {
333 self.choices.get(n).copied()
334 }
335 pub fn len(&self) -> usize {
337 self.choices.len()
338 }
339 pub fn is_empty(&self) -> bool {
341 self.choices.is_empty()
342 }
343}
344pub struct ConstructiveProof {
346 pub statement: String,
348 pub algorithm: String,
350}
351impl ConstructiveProof {
352 pub fn new(statement: impl Into<String>, algorithm: impl Into<String>) -> Self {
354 Self {
355 statement: statement.into(),
356 algorithm: algorithm.into(),
357 }
358 }
359 pub fn is_effective(&self) -> bool {
361 !self.algorithm.is_empty()
362 }
363 pub fn witnesses_existential(&self) -> bool {
365 self.statement.contains('∃') || self.statement.contains("exists")
366 }
367}
368pub struct BishopMath {
370 _tag: (),
371}
372impl BishopMath {
373 pub fn new() -> Self {
375 Self { _tag: () }
376 }
377 pub fn constructive_real_analysis(&self) -> &'static str {
380 "BISH uses Cauchy sequences with an explicit modulus; every \
381 theorem has algorithmic content."
382 }
383 pub fn all_functions_continuous(&self) -> bool {
386 false
387 }
388 pub fn no_lem(&self) -> bool {
390 true
391 }
392}
393#[derive(Debug, Clone)]
396pub struct TTEOracle {
397 pub name: String,
399 pub max_precision: usize,
401 pub approx_cache: Vec<i64>,
403}
404impl TTEOracle {
405 pub fn new(name: impl Into<String>, max_precision: usize) -> Self {
407 TTEOracle {
408 name: name.into(),
409 max_precision,
410 approx_cache: Vec::new(),
411 }
412 }
413 pub fn load_cauchy(&mut self, seq: impl Fn(usize) -> i64) {
416 self.approx_cache = (0..=self.max_precision).map(|k| seq(k)).collect();
417 }
418 pub fn query(&self, k: usize) -> Option<(i64, usize)> {
420 let k = k.min(self.max_precision);
421 self.approx_cache.get(k).map(|&m| (m, k))
422 }
423 pub fn is_cauchy_consistent(&self, k: usize) -> bool {
425 if self.approx_cache.len() < 2 {
426 return true;
427 }
428 let k = k.min(self.max_precision);
429 if k == 0 {
430 return true;
431 }
432 (0..k).all(|j| {
433 let aj = self.approx_cache.get(j).copied().unwrap_or(0);
434 let aj1 = self.approx_cache.get(j + 1).copied().unwrap_or(0);
435 (aj1 - 2 * aj).abs() <= 2
436 })
437 }
438 pub fn function_name(&self) -> &str {
440 &self.name
441 }
442}
443pub struct RealNumber {
445 pub cauchy_seq: Vec<f64>,
447 pub modulus: String,
449}
450impl RealNumber {
451 pub fn new(cauchy_seq: Vec<f64>, modulus: impl Into<String>) -> Self {
453 Self {
454 cauchy_seq,
455 modulus: modulus.into(),
456 }
457 }
458 pub fn equality_is_undecidable(&self) -> bool {
460 true
461 }
462 pub fn is_apartness_relation(&self) -> bool {
465 true
466 }
467}
468pub struct ConTinuousFunction {
470 pub is_uniformly_continuous: bool,
472}
473impl ConTinuousFunction {
474 pub fn new(is_uniformly_continuous: bool) -> Self {
476 Self {
477 is_uniformly_continuous,
478 }
479 }
480 pub fn by_fan_theorem(&self) -> bool {
483 self.is_uniformly_continuous
484 }
485 pub fn kleene_brouwer(&self) -> &'static str {
488 "The Kleene–Brouwer ordering witnesses well-foundedness of the tree \
489 via an intuitionistic bar induction argument."
490 }
491}
492pub struct MarkovPrinciple {
495 _tag: (),
496}
497impl MarkovPrinciple {
498 pub fn new() -> Self {
500 Self { _tag: () }
501 }
502 pub fn statement(&self) -> &'static str {
504 "Markov's Principle (MP): for every decidable predicate P on ℕ, \
505 if ¬∀n, ¬P(n) then ∃n, P(n). Equivalently: if a Turing machine \
506 does not run forever then it halts."
507 }
508 pub fn is_accepted_in_russian_school(&self) -> bool {
510 true
511 }
512}