Skip to main content

oxilean_std/reverse_mathematics/
types.rs

1//! Auto-generated module
2//!
3//! 🤖 Generated with [SplitRS](https://github.com/cool-japan/splitrs)
4
5use super::functions::*;
6use oxilean_kernel::{BinderInfo, Declaration, Environment, Expr, Level, Name};
7
8/// A coloring of pairs from {0..n} with k colors, used for Ramsey experiments.
9#[derive(Debug, Clone)]
10pub struct RamseyColoringFinder {
11    /// Number of vertices.
12    pub n: usize,
13    /// Number of colors.
14    pub k: u32,
15    /// coloring[i][j] = color of the pair {i, j}, for i < j.
16    pub coloring: Vec<Vec<u32>>,
17}
18impl RamseyColoringFinder {
19    /// Create a new all-zero coloring on n vertices.
20    pub fn new_uniform(n: usize, k: u32) -> Self {
21        let coloring = vec![vec![0u32; n]; n];
22        Self { n, k, coloring }
23    }
24    /// Set the color of pair {i, j} (i < j enforced by sorting).
25    pub fn set_color(&mut self, i: usize, j: usize, color: u32) {
26        let (lo, hi) = if i < j { (i, j) } else { (j, i) };
27        if hi < self.n && color < self.k {
28            self.coloring[lo][hi] = color;
29        }
30    }
31    /// Get the color of pair {i, j}.
32    pub fn get_color(&self, i: usize, j: usize) -> u32 {
33        let (lo, hi) = if i < j { (i, j) } else { (j, i) };
34        self.coloring
35            .get(lo)
36            .and_then(|r| r.get(hi))
37            .copied()
38            .unwrap_or(0)
39    }
40    /// Find the largest monochromatic clique for a specific color.
41    pub fn monochromatic_clique(&self, color: u32) -> Vec<usize> {
42        let mut best: Vec<usize> = vec![];
43        for start in 0..self.n {
44            let mut clique = vec![start];
45            for v in (start + 1)..self.n {
46                if clique.iter().all(|&u| self.get_color(u, v) == color) {
47                    clique.push(v);
48                }
49            }
50            if clique.len() > best.len() {
51                best = clique;
52            }
53        }
54        best
55    }
56    /// Return the largest monochromatic clique across all colors.
57    pub fn best_monochromatic_clique(&self) -> (u32, Vec<usize>) {
58        let mut best_color = 0u32;
59        let mut best_clique: Vec<usize> = vec![];
60        for c in 0..self.k {
61            let clique = self.monochromatic_clique(c);
62            if clique.len() > best_clique.len() {
63                best_color = c;
64                best_clique = clique;
65            }
66        }
67        (best_color, best_clique)
68    }
69}
70/// Omega-models and their properties.
71#[allow(dead_code)]
72#[derive(Debug, Clone)]
73pub struct OmegaModel {
74    /// Name of the model (e.g., "ω-model of ACA₀").
75    pub name: String,
76    /// Which subsystem this is a model of.
77    pub satisfies: String,
78    /// Whether this is a minimal omega-model.
79    pub is_minimal: bool,
80    /// Description.
81    pub description: String,
82}
83impl OmegaModel {
84    #[allow(dead_code)]
85    pub fn new(
86        name: impl Into<String>,
87        satisfies: impl Into<String>,
88        is_minimal: bool,
89        description: impl Into<String>,
90    ) -> Self {
91        Self {
92            name: name.into(),
93            satisfies: satisfies.into(),
94            is_minimal,
95            description: description.into(),
96        }
97    }
98    #[allow(dead_code)]
99    pub fn standard_aca0() -> Self {
100        Self::new(
101            "M_0",
102            "ACA₀",
103            true,
104            "The minimal ω-model of ACA₀: all sets arithmetically definable in N",
105        )
106    }
107    #[allow(dead_code)]
108    pub fn rec_sets() -> Self {
109        Self::new(
110            "REC",
111            "RCA₀",
112            true,
113            "The minimal ω-model of RCA₀: all recursive (computable) sets",
114        )
115    }
116    #[allow(dead_code)]
117    pub fn description_str(&self) -> String {
118        format!(
119            "OmegaModel {{ name: {}, satisfies: {}, minimal: {}, desc: {} }}",
120            self.name, self.satisfies, self.is_minimal, self.description
121        )
122    }
123}
124/// Summary statistics about the Big Five systems.
125#[allow(dead_code)]
126#[derive(Debug, Clone)]
127pub struct BigFiveStats {
128    /// Number of "classical" theorems provable in each system.
129    pub rca0_count: usize,
130    pub wkl0_count: usize,
131    pub aca0_count: usize,
132    pub atr0_count: usize,
133    pub pi11ca0_count: usize,
134}
135impl BigFiveStats {
136    #[allow(dead_code)]
137    pub fn from_scoreboard(sb: &RMScoreboard) -> Self {
138        Self {
139            rca0_count: sb.count_in("RCA₀"),
140            wkl0_count: sb.count_in("WKL₀"),
141            aca0_count: sb.count_in("ACA₀"),
142            atr0_count: sb.count_in("ATR₀"),
143            pi11ca0_count: sb.count_in("Π¹₁-CA₀"),
144        }
145    }
146    #[allow(dead_code)]
147    pub fn total(&self) -> usize {
148        self.rca0_count + self.wkl0_count + self.aca0_count + self.atr0_count + self.pi11ca0_count
149    }
150    #[allow(dead_code)]
151    pub fn display(&self) -> String {
152        format!(
153            "RCA₀:{} WKL₀:{} ACA₀:{} ATR₀:{} Π¹₁-CA₀:{} total:{}",
154            self.rca0_count,
155            self.wkl0_count,
156            self.aca0_count,
157            self.atr0_count,
158            self.pi11ca0_count,
159            self.total()
160        )
161    }
162}
163/// The Big Five subsystems of second-order arithmetic, ordered by strength.
164#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
165pub enum BigFiveSystem {
166    /// Recursive Comprehension Axiom (weakest).
167    RCA0,
168    /// Weak König's Lemma.
169    WKL0,
170    /// Arithmetical Comprehension Axiom.
171    ACA0,
172    /// Arithmetical Transfinite Recursion.
173    ATR0,
174    /// Π¹_1 Comprehension Axiom (strongest).
175    Pi11CA0,
176}
177impl BigFiveSystem {
178    /// Human-readable name of the system.
179    pub fn name(&self) -> &'static str {
180        match self {
181            BigFiveSystem::RCA0 => "RCA₀",
182            BigFiveSystem::WKL0 => "WKL₀",
183            BigFiveSystem::ACA0 => "ACA₀",
184            BigFiveSystem::ATR0 => "ATR₀",
185            BigFiveSystem::Pi11CA0 => "Π¹₁-CA₀",
186        }
187    }
188    /// Is this system stronger than or equal to the other?
189    pub fn at_least_as_strong_as(&self, other: &BigFiveSystem) -> bool {
190        self >= other
191    }
192    /// The corresponding proof-theoretic ordinal (Bachmann–Howard notation as string).
193    pub fn proof_theoretic_ordinal(&self) -> &'static str {
194        match self {
195            BigFiveSystem::RCA0 => "ω^ω",
196            BigFiveSystem::WKL0 => "ω^ω",
197            BigFiveSystem::ACA0 => "ε₀",
198            BigFiveSystem::ATR0 => "Γ₀",
199            BigFiveSystem::Pi11CA0 => "ψ(Ω_ω)",
200        }
201    }
202    /// Returns `true` if WKL₀ is Π¹_1-conservative over this system.
203    /// This holds precisely for RCA₀.
204    pub fn wkl0_is_conservative_over(&self) -> bool {
205        matches!(self, BigFiveSystem::RCA0)
206    }
207}
208/// A conservation result: `stronger` is `formula_class`-conservative over `weaker`.
209#[derive(Debug, Clone)]
210pub struct ConservationResult {
211    /// The stronger system (e.g. WKL₀).
212    pub stronger: BigFiveSystem,
213    /// The weaker system (e.g. RCA₀).
214    pub weaker: BigFiveSystem,
215    /// The class of formulas for which conservation holds.
216    pub formula_class: &'static str,
217    /// Authors and year of result.
218    pub reference: &'static str,
219}
220impl ConservationResult {
221    /// WKL₀ is Π¹_1-conservative over RCA₀ (Friedman 1976, Simpson).
222    pub fn wkl0_over_rca0() -> Self {
223        Self {
224            stronger: BigFiveSystem::WKL0,
225            weaker: BigFiveSystem::RCA0,
226            formula_class: "Π¹_1",
227            reference: "Friedman 1976; Simpson 1999",
228        }
229    }
230    /// ACA₀ is conservative over PA for first-order sentences (well-known).
231    pub fn aca0_over_pa() -> Self {
232        Self {
233            stronger: BigFiveSystem::ACA0,
234            weaker: BigFiveSystem::RCA0,
235            formula_class: "First-order arithmetic",
236            reference: "Friedman 1976; Simpson Ch. III",
237        }
238    }
239    /// ATR₀ is Π¹_2-conservative over ACA₀.
240    pub fn atr0_over_aca0() -> Self {
241        Self {
242            stronger: BigFiveSystem::ATR0,
243            weaker: BigFiveSystem::ACA0,
244            formula_class: "Π¹_2",
245            reference: "Friedman 1976",
246        }
247    }
248    /// Verify the direction: stronger ≥ weaker in the Big Five ordering.
249    pub fn is_valid_direction(&self) -> bool {
250        self.stronger >= self.weaker
251    }
252}
253/// Represents a Π¹₁ sentence and its known proof-theoretic strength.
254#[allow(dead_code)]
255#[derive(Debug, Clone)]
256pub struct Pi11Sentence {
257    /// Name of the statement.
258    pub name: String,
259    /// The statement in informal mathematics.
260    pub statement: String,
261    /// Known ordinal proof-theoretic strength.
262    pub ordinal_strength: Option<String>,
263}
264impl Pi11Sentence {
265    #[allow(dead_code)]
266    pub fn new(
267        name: impl Into<String>,
268        statement: impl Into<String>,
269        ordinal_strength: Option<impl Into<String>>,
270    ) -> Self {
271        Self {
272            name: name.into(),
273            statement: statement.into(),
274            ordinal_strength: ordinal_strength.map(Into::into),
275        }
276    }
277    #[allow(dead_code)]
278    pub fn display(&self) -> String {
279        let ord = self.ordinal_strength.as_deref().unwrap_or("unknown");
280        format!("{}: {} [strength: {}]", self.name, self.statement, ord)
281    }
282}
283/// A combinatorial principle in the RM zoo.
284#[derive(Debug, Clone)]
285pub struct RMPrinciple {
286    /// Short name (e.g. "RT²_2").
287    pub name: &'static str,
288    /// Long description.
289    pub description: &'static str,
290    /// Known RM strength.
291    pub strength: RMStrength,
292    /// Year first studied.
293    pub year: u32,
294}
295impl RMPrinciple {
296    /// Return true if this principle is equivalent (over RCA₀) to the given system.
297    pub fn equivalent_to(&self, system: &BigFiveSystem) -> bool {
298        match (&self.strength, system) {
299            (RMStrength::WKL0, BigFiveSystem::WKL0) => true,
300            (RMStrength::ACA0, BigFiveSystem::ACA0) => true,
301            (RMStrength::ATR0, BigFiveSystem::ATR0) => true,
302            (RMStrength::Pi11CA0, BigFiveSystem::Pi11CA0) => true,
303            (RMStrength::RCA0, BigFiveSystem::RCA0) => true,
304            _ => false,
305        }
306    }
307    /// Ramsey's theorem RT²_2: pairs, 2 colors.
308    pub fn rt22() -> Self {
309        Self {
310            name: "RT²_2",
311            description: "Ramsey's theorem for pairs and 2 colors",
312            strength: RMStrength::BetweenWKL0AndACA0,
313            year: 1995,
314        }
315    }
316    /// Stable Ramsey's theorem SRT²_2.
317    pub fn srt22() -> Self {
318        Self {
319            name: "SRT²_2",
320            description: "Stable Ramsey's theorem for pairs and 2 colors",
321            strength: RMStrength::BetweenRCA0AndWKL0,
322            year: 2001,
323        }
324    }
325    /// Chain-Antichain principle CAC (Dilworth).
326    pub fn cac() -> Self {
327        Self {
328            name: "CAC",
329            description: "Every infinite partial order has an infinite chain or antichain",
330            strength: RMStrength::BetweenWKL0AndACA0,
331            year: 2007,
332        }
333    }
334    /// Ascending/Descending Sequence ADS.
335    pub fn ads() -> Self {
336        Self {
337            name: "ADS",
338            description: "Every infinite linear order has an infinite ascending or descending seq",
339            strength: RMStrength::BetweenRCA0AndWKL0,
340            year: 2007,
341        }
342    }
343    /// Hindman's theorem.
344    pub fn hindman() -> Self {
345        Self {
346            name: "HT",
347            description: "Hindman's finite sums theorem",
348            strength: RMStrength::BetweenACA0AndATR0,
349            year: 1974,
350        }
351    }
352    /// Bolzano–Weierstrass theorem.
353    pub fn bolzano_weierstrass() -> Self {
354        Self {
355            name: "BW",
356            description: "Every bounded sequence of reals has a convergent subsequence",
357            strength: RMStrength::ACA0,
358            year: 1985,
359        }
360    }
361    /// Brouwer's fixed-point theorem.
362    pub fn brouwer() -> Self {
363        Self {
364            name: "BFP",
365            description: "Brouwer's fixed-point theorem for the closed disk",
366            strength: RMStrength::WKL0,
367            year: 1998,
368        }
369    }
370}
371/// Bishop-style constructive principles and their RM strengths.
372#[allow(dead_code)]
373#[derive(Debug, Clone)]
374pub struct ConstructivePrinciple {
375    /// Name of the principle.
376    pub name: String,
377    /// The classical theorem it corresponds to.
378    pub classical_counterpart: String,
379    /// Whether this is constructively provable (Bishop-style).
380    pub constructively_provable: bool,
381    /// Required axiom for constructive proof (if any).
382    pub required_axiom: Option<String>,
383}
384impl ConstructivePrinciple {
385    #[allow(dead_code)]
386    pub fn new(
387        name: impl Into<String>,
388        classical: impl Into<String>,
389        constructive: bool,
390        axiom: Option<impl Into<String>>,
391    ) -> Self {
392        Self {
393            name: name.into(),
394            classical_counterpart: classical.into(),
395            constructively_provable: constructive,
396            required_axiom: axiom.map(Into::into),
397        }
398    }
399    #[allow(dead_code)]
400    pub fn display(&self) -> String {
401        let ax = self.required_axiom.as_deref().unwrap_or("none");
402        format!(
403            "Principle '{}' (classical: '{}') constructive={}, axiom={}",
404            self.name, self.classical_counterpart, self.constructively_provable, ax
405        )
406    }
407}
408/// Represents a formal proof system in reverse mathematics.
409#[allow(dead_code)]
410#[derive(Debug, Clone, PartialEq, Eq)]
411pub enum ProofSystem {
412    /// Primitive Recursive Arithmetic (PRA).
413    PRA,
414    /// Elementary Recursive Arithmetic (ECA).
415    ECA,
416    /// Robinson Arithmetic (Q).
417    RobinsonQ,
418    /// Peano Arithmetic (PA).
419    PeanoPA,
420    /// Second-Order Arithmetic (Z₂).
421    Z2,
422    /// A custom-named system.
423    Custom(String),
424}
425impl ProofSystem {
426    #[allow(dead_code)]
427    pub fn name(&self) -> String {
428        match self {
429            Self::PRA => "PRA".to_owned(),
430            Self::ECA => "ECA".to_owned(),
431            Self::RobinsonQ => "Q".to_owned(),
432            Self::PeanoPA => "PA".to_owned(),
433            Self::Z2 => "Z₂".to_owned(),
434            Self::Custom(s) => s.clone(),
435        }
436    }
437    /// Returns `true` if `other` is provably a conservative extension of `self`.
438    #[allow(dead_code)]
439    pub fn is_conservative_over(&self, other: &ProofSystem) -> bool {
440        use ProofSystem::*;
441        matches!(
442            (self, other),
443            (Z2, PeanoPA)
444                | (PeanoPA, RobinsonQ)
445                | (Z2, RobinsonQ)
446                | (PeanoPA, ECA)
447                | (Z2, ECA)
448                | (PeanoPA, PRA)
449                | (Z2, PRA)
450        )
451    }
452    /// Returns the set of systems stronger than (or equal to) `self`.
453    #[allow(dead_code)]
454    pub fn stronger_systems(&self) -> Vec<ProofSystem> {
455        use ProofSystem::*;
456        match self {
457            PRA => vec![PRA, ECA, RobinsonQ, PeanoPA, Z2],
458            ECA => vec![ECA, RobinsonQ, PeanoPA, Z2],
459            RobinsonQ => vec![RobinsonQ, PeanoPA, Z2],
460            PeanoPA => vec![PeanoPA, Z2],
461            Z2 => vec![Z2],
462            Custom(_) => vec![self.clone()],
463        }
464    }
465}
466/// A finite approximation to an infinite binary tree (König / WKL₀).
467/// Nodes are stored as bit-strings of bounded length.
468#[derive(Debug, Clone)]
469pub struct WeakKonigTree {
470    /// Maximum depth of stored nodes.
471    pub max_depth: u32,
472    /// The set of nodes (as `u64` bit-strings of length ≤ max_depth).
473    pub nodes: Vec<u64>,
474    /// The length of each node bit-string (parallel to `nodes`).
475    pub depths: Vec<u32>,
476}
477impl WeakKonigTree {
478    /// Create a complete binary tree of depth `d`.
479    pub fn complete(d: u32) -> Self {
480        let mut nodes = Vec::new();
481        let mut depths = Vec::new();
482        for depth in 0..=d {
483            for bits in 0u64..(1u64 << depth) {
484                nodes.push(bits);
485                depths.push(depth);
486            }
487        }
488        Self {
489            max_depth: d,
490            nodes,
491            depths,
492        }
493    }
494    /// Return the number of nodes at depth `d`.
495    pub fn count_at_depth(&self, d: u32) -> usize {
496        self.depths.iter().filter(|&&depth| depth == d).count()
497    }
498    /// Return true if the tree is infinite (has nodes at every depth 0..=max_depth).
499    pub fn is_infinite(&self) -> bool {
500        (0..=self.max_depth).all(|d| self.count_at_depth(d) > 0)
501    }
502    /// Greedily extract an infinite path (always extend with bit 0 if possible, else 1).
503    /// Returns the sequence of bits representing the path.
504    pub fn greedy_path(&self) -> Vec<u8> {
505        let mut path = Vec::new();
506        let mut prefix: u64 = 0;
507        for depth in 1..=self.max_depth {
508            let zero_child = prefix;
509            let one_child = prefix | (1u64 << (depth - 1));
510            let has_zero = self
511                .nodes
512                .iter()
513                .zip(self.depths.iter())
514                .any(|(&n, &d)| d == depth && n == zero_child);
515            let has_one = self
516                .nodes
517                .iter()
518                .zip(self.depths.iter())
519                .any(|(&n, &d)| d == depth && n == one_child);
520            if has_zero {
521                prefix = zero_child;
522                path.push(0u8);
523            } else if has_one {
524                prefix = one_child;
525                path.push(1u8);
526            } else {
527                break;
528            }
529        }
530        path
531    }
532}
533/// A tagged statement together with the RCA₀ axiom kind it falls under.
534#[derive(Debug, Clone)]
535pub struct RMA0System {
536    /// Human-readable description of the statement.
537    pub statement: &'static str,
538    /// The axiom kind.
539    pub kind: RCA0AxiomKind,
540    /// Whether this instance is valid (for illustrative purposes).
541    pub is_valid: bool,
542}
543impl RMA0System {
544    /// Verify that this is a valid RCA₀ axiom instance.
545    pub fn verify(&self) -> bool {
546        self.is_valid
547    }
548    /// Return a human-readable summary.
549    pub fn summary(&self) -> String {
550        format!(
551            "[{:?}] {} — {}",
552            self.kind,
553            self.statement,
554            if self.is_valid { "VALID" } else { "INVALID" }
555        )
556    }
557    /// Produce the standard Σ⁰_1-comprehension instance for a given predicate name.
558    pub fn sigma01_comprehension_for(predicate: &'static str) -> Self {
559        Self {
560            statement: predicate,
561            kind: RCA0AxiomKind::Sigma01Comprehension,
562            is_valid: true,
563        }
564    }
565}
566/// One level in the RM hierarchy.
567#[derive(Debug, Clone)]
568pub struct RMHierarchyEntry {
569    /// The Big Five system.
570    pub system: BigFiveSystem,
571    /// Representative equivalent principles (names only).
572    pub equivalents: Vec<&'static str>,
573    /// Key conservation result for this level.
574    pub conservation_note: &'static str,
575}
576/// A theorem statement together with the minimal subsystem that proves it.
577#[allow(dead_code)]
578#[derive(Debug, Clone)]
579pub struct RMTheorem {
580    /// Name of the theorem.
581    pub name: String,
582    /// Informal statement.
583    pub statement: String,
584    /// The minimal Big-Five system that proves the theorem.
585    pub minimal_system: String,
586    /// Known equivalences with other theorems over RCA₀.
587    pub equivalences: Vec<String>,
588    /// Is the theorem provable in RCA₀ itself (not just equivalent over it)?
589    pub provable_in_rca0: bool,
590}
591impl RMTheorem {
592    /// Construct a new RM theorem record.
593    #[allow(dead_code)]
594    pub fn new(
595        name: impl Into<String>,
596        statement: impl Into<String>,
597        minimal_system: impl Into<String>,
598        equivalences: Vec<impl Into<String>>,
599        provable_in_rca0: bool,
600    ) -> Self {
601        Self {
602            name: name.into(),
603            statement: statement.into(),
604            minimal_system: minimal_system.into(),
605            equivalences: equivalences.into_iter().map(Into::into).collect(),
606            provable_in_rca0,
607        }
608    }
609    /// Returns a formatted summary.
610    #[allow(dead_code)]
611    pub fn summary(&self) -> String {
612        let equiv_str = if self.equivalences.is_empty() {
613            "none known".to_owned()
614        } else {
615            self.equivalences.join(", ")
616        };
617        format!(
618            "[{}] Minimal system: {}. Equivalences: {}. Provable in RCA₀: {}.",
619            self.name, self.minimal_system, equiv_str, self.provable_in_rca0
620        )
621    }
622}
623/// Enumeration of formal independence results in set theory.
624#[allow(dead_code)]
625#[derive(Debug, Clone)]
626pub struct IndependenceResult {
627    /// Name of the statement.
628    pub statement: String,
629    /// Base theory (e.g., "ZFC").
630    pub base_theory: String,
631    /// True = independent; False = provable or disprovable.
632    pub is_independent: bool,
633    /// Notes on the independence result.
634    pub notes: String,
635}
636impl IndependenceResult {
637    #[allow(dead_code)]
638    pub fn new(
639        statement: impl Into<String>,
640        base: impl Into<String>,
641        ind: bool,
642        notes: impl Into<String>,
643    ) -> Self {
644        Self {
645            statement: statement.into(),
646            base_theory: base.into(),
647            is_independent: ind,
648            notes: notes.into(),
649        }
650    }
651    #[allow(dead_code)]
652    pub fn display(&self) -> String {
653        let kind = if self.is_independent {
654            "INDEPENDENT"
655        } else {
656            "PROVABLE"
657        };
658        format!(
659            "[{}] {} over {} ({})",
660            kind, self.statement, self.base_theory, self.notes
661        )
662    }
663}
664/// A Turing machine oracle that answers membership queries for a set X ⊆ ℕ.
665/// Used to model oracle-relative computability in the RM hierarchy.
666#[derive(Debug, Clone)]
667pub struct ComputableFunction {
668    /// A description / name for this function (e.g. "Halting problem oracle").
669    pub name: &'static str,
670    /// Degree information: `Some(k)` means the function has degree 0^(k) (k-th jump).
671    pub jump_level: Option<u32>,
672    /// The function table for inputs 0..table.len() (partial; `None` = diverges).
673    pub table: Vec<Option<u64>>,
674}
675impl ComputableFunction {
676    /// Create the characteristic function of the set {n | n < bound} (computable).
677    pub fn indicator_below(bound: u64) -> Self {
678        let table = (0u64..bound + 4)
679            .map(|n| Some(if n < bound { 1 } else { 0 }))
680            .collect();
681        Self {
682            name: "indicator_below",
683            jump_level: Some(0),
684            table,
685        }
686    }
687    /// Evaluate at input n, returning `None` if the function diverges.
688    pub fn eval(&self, n: usize) -> Option<u64> {
689        self.table.get(n).copied().flatten()
690    }
691    /// Return true if this function is total on 0..n.
692    pub fn is_total_up_to(&self, n: usize) -> bool {
693        (0..n).all(|i| self.table.get(i).copied().flatten().is_some())
694    }
695    /// Simulate the n-th step of a Turing machine oracle computation (stub).
696    /// In a full implementation this would run a UTM; here we return the table value.
697    pub fn oracle_query(&self, input: usize, _steps: u32) -> Option<u64> {
698        self.eval(input)
699    }
700}
701/// The Friedman-style reverse mathematics scoreboard.
702#[allow(dead_code)]
703#[derive(Debug, Default)]
704pub struct RMScoreboard {
705    pub theorems: Vec<(String, String)>,
706}
707impl RMScoreboard {
708    #[allow(dead_code)]
709    pub fn new() -> Self {
710        Self::default()
711    }
712    #[allow(dead_code)]
713    pub fn record(&mut self, theorem: impl Into<String>, system: impl Into<String>) {
714        self.theorems.push((theorem.into(), system.into()));
715    }
716    #[allow(dead_code)]
717    pub fn theorems_in(&self, system: &str) -> Vec<&str> {
718        self.theorems
719            .iter()
720            .filter(|(_, s)| s == system)
721            .map(|(t, _)| t.as_str())
722            .collect()
723    }
724    #[allow(dead_code)]
725    pub fn count_in(&self, system: &str) -> usize {
726        self.theorems_in(system).len()
727    }
728    #[allow(dead_code)]
729    pub fn standard() -> Self {
730        let mut sb = Self::new();
731        for thm in standard_rm_theorems() {
732            sb.record(thm.name.clone(), thm.minimal_system.clone());
733        }
734        sb
735    }
736}
737/// A fragment axiom verifier for RCA₀.
738/// Checks whether a given closed formula (represented as a tag) is an instance
739/// of one of the axiom schemes of RCA₀.
740#[derive(Debug, Clone, PartialEq, Eq)]
741pub enum RCA0AxiomKind {
742    /// Σ⁰_1 comprehension: {n | φ(n)} exists for Σ⁰_1 φ.
743    Sigma01Comprehension,
744    /// Σ⁰_1 induction: φ(0) ∧ ∀n(φ(n)→φ(n+1)) → ∀n φ(n) for Σ⁰_1 φ.
745    Sigma01Induction,
746    /// Basic arithmetic axioms (successor, addition, multiplication).
747    BasicArithmetic,
748    /// Recursive definition (primitive recursion).
749    PrimitiveRecursion,
750}
751/// Display the RM hierarchy: Big Five systems with proof-theoretic ordinals
752/// and key equivalent principles.
753#[derive(Debug, Clone)]
754pub struct RMHierarchy {
755    entries: Vec<RMHierarchyEntry>,
756}
757impl RMHierarchy {
758    /// Build the standard Big Five hierarchy with known equivalents.
759    pub fn standard() -> Self {
760        Self {
761            entries: vec![
762                RMHierarchyEntry {
763                    system: BigFiveSystem::RCA0,
764                    equivalents: vec![
765                        "Σ⁰₁-comprehension",
766                        "Σ⁰₁-induction",
767                        "Primitive recursion",
768                        "Low basis theorem",
769                        "Σ⁰₁-bounding",
770                    ],
771                    conservation_note: "Base system; WKL₀ is Π¹₁-conservative over RCA₀",
772                },
773                RMHierarchyEntry {
774                    system: BigFiveSystem::WKL0,
775                    equivalents: vec![
776                        "König's lemma (binary trees)",
777                        "Brouwer's fixed-point theorem",
778                        "Hahn-Banach theorem",
779                        "Gödel completeness theorem",
780                        "Maximal ideal theorem",
781                        "Jordan curve theorem",
782                    ],
783                    conservation_note: "Π¹₁-conservative over RCA₀ (Friedman 1976)",
784                },
785                RMHierarchyEntry {
786                    system: BigFiveSystem::ACA0,
787                    equivalents: vec![
788                        "Bolzano-Weierstrass theorem",
789                        "Arithmetical comprehension",
790                        "Sequential completeness of ℝ",
791                        "Comparability of well-orderings",
792                        "König's lemma (finitely branching)",
793                        "CAC (chain-antichain)",
794                        "Omitting types theorem",
795                    ],
796                    conservation_note: "Conservative over PA for first-order sentences",
797                },
798                RMHierarchyEntry {
799                    system: BigFiveSystem::ATR0,
800                    equivalents: vec![
801                        "Open determinacy",
802                        "Bar induction",
803                        "Comparison of well-orderings",
804                        "Hausdorff scattered characterisation",
805                        "Ulm's theorem",
806                        "Perfect set theorem",
807                        "Σ¹₁ separation",
808                    ],
809                    conservation_note: "Π¹₂-conservative over ACA₀",
810                },
811                RMHierarchyEntry {
812                    system: BigFiveSystem::Pi11CA0,
813                    equivalents: vec![
814                        "Π¹₁-comprehension",
815                        "Σ¹₁-determinacy",
816                        "Hyperarithmetic theorem",
817                        "Every Π¹₁ set is a union of ω₁-many Borel sets",
818                        "Cantor-Bendixson theorem (full)",
819                    ],
820                    conservation_note: "Strongest of the Big Five",
821                },
822            ],
823        }
824    }
825    /// Print the hierarchy to a String (suitable for display/logging).
826    pub fn display(&self) -> String {
827        let mut out = String::from("=== Reverse Mathematics Hierarchy ===\n");
828        for entry in &self.entries {
829            out.push_str(&format!(
830                "\n[{}] (ordinal: {})\n",
831                entry.system.name(),
832                entry.system.proof_theoretic_ordinal()
833            ));
834            out.push_str(&format!("  Conservation: {}\n", entry.conservation_note));
835            out.push_str("  Equivalents:\n");
836            for eq in &entry.equivalents {
837                out.push_str(&format!("    - {}\n", eq));
838            }
839        }
840        out
841    }
842    /// Return the entry for the given system, if present.
843    pub fn entry_for(&self, system: &BigFiveSystem) -> Option<&RMHierarchyEntry> {
844        self.entries.iter().find(|e| &e.system == system)
845    }
846}
847/// Strength classification for a combinatorial principle in the RM zoo.
848#[derive(Debug, Clone, PartialEq, Eq)]
849pub enum RMStrength {
850    /// Provable in RCA₀.
851    RCA0,
852    /// Strictly between RCA₀ and WKL₀.
853    BetweenRCA0AndWKL0,
854    /// Equivalent to WKL₀ over RCA₀.
855    WKL0,
856    /// Strictly between WKL₀ and ACA₀.
857    BetweenWKL0AndACA0,
858    /// Equivalent to ACA₀ over RCA₀.
859    ACA0,
860    /// Strictly between ACA₀ and ATR₀.
861    BetweenACA0AndATR0,
862    /// Equivalent to ATR₀ over RCA₀.
863    ATR0,
864    /// Equivalent to Π¹_1-CA₀ over RCA₀.
865    Pi11CA0,
866    /// Strictly above all Big Five (requires additional set-existence).
867    AbovePi11CA0,
868    /// Strength not yet determined.
869    Unknown,
870}
871impl RMStrength {
872    /// Return the closest Big Five system from below (or None if below RCA₀).
873    pub fn lower_bound_system(&self) -> Option<BigFiveSystem> {
874        match self {
875            RMStrength::RCA0 => Some(BigFiveSystem::RCA0),
876            RMStrength::BetweenRCA0AndWKL0 => Some(BigFiveSystem::RCA0),
877            RMStrength::WKL0 => Some(BigFiveSystem::WKL0),
878            RMStrength::BetweenWKL0AndACA0 => Some(BigFiveSystem::WKL0),
879            RMStrength::ACA0 => Some(BigFiveSystem::ACA0),
880            RMStrength::BetweenACA0AndATR0 => Some(BigFiveSystem::ACA0),
881            RMStrength::ATR0 => Some(BigFiveSystem::ATR0),
882            RMStrength::Pi11CA0 | RMStrength::AbovePi11CA0 => Some(BigFiveSystem::Pi11CA0),
883            RMStrength::Unknown => None,
884        }
885    }
886}