use super::functions::*;
use oxilean_kernel::{BinderInfo, Declaration, Environment, Expr, Level, Name};
#[derive(Debug, Clone)]
pub struct RamseyColoringFinder {
pub n: usize,
pub k: u32,
pub coloring: Vec<Vec<u32>>,
}
impl RamseyColoringFinder {
pub fn new_uniform(n: usize, k: u32) -> Self {
let coloring = vec![vec![0u32; n]; n];
Self { n, k, coloring }
}
pub fn set_color(&mut self, i: usize, j: usize, color: u32) {
let (lo, hi) = if i < j { (i, j) } else { (j, i) };
if hi < self.n && color < self.k {
self.coloring[lo][hi] = color;
}
}
pub fn get_color(&self, i: usize, j: usize) -> u32 {
let (lo, hi) = if i < j { (i, j) } else { (j, i) };
self.coloring
.get(lo)
.and_then(|r| r.get(hi))
.copied()
.unwrap_or(0)
}
pub fn monochromatic_clique(&self, color: u32) -> Vec<usize> {
let mut best: Vec<usize> = vec![];
for start in 0..self.n {
let mut clique = vec![start];
for v in (start + 1)..self.n {
if clique.iter().all(|&u| self.get_color(u, v) == color) {
clique.push(v);
}
}
if clique.len() > best.len() {
best = clique;
}
}
best
}
pub fn best_monochromatic_clique(&self) -> (u32, Vec<usize>) {
let mut best_color = 0u32;
let mut best_clique: Vec<usize> = vec![];
for c in 0..self.k {
let clique = self.monochromatic_clique(c);
if clique.len() > best_clique.len() {
best_color = c;
best_clique = clique;
}
}
(best_color, best_clique)
}
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct OmegaModel {
pub name: String,
pub satisfies: String,
pub is_minimal: bool,
pub description: String,
}
impl OmegaModel {
#[allow(dead_code)]
pub fn new(
name: impl Into<String>,
satisfies: impl Into<String>,
is_minimal: bool,
description: impl Into<String>,
) -> Self {
Self {
name: name.into(),
satisfies: satisfies.into(),
is_minimal,
description: description.into(),
}
}
#[allow(dead_code)]
pub fn standard_aca0() -> Self {
Self::new(
"M_0",
"ACA₀",
true,
"The minimal ω-model of ACA₀: all sets arithmetically definable in N",
)
}
#[allow(dead_code)]
pub fn rec_sets() -> Self {
Self::new(
"REC",
"RCA₀",
true,
"The minimal ω-model of RCA₀: all recursive (computable) sets",
)
}
#[allow(dead_code)]
pub fn description_str(&self) -> String {
format!(
"OmegaModel {{ name: {}, satisfies: {}, minimal: {}, desc: {} }}",
self.name, self.satisfies, self.is_minimal, self.description
)
}
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct BigFiveStats {
pub rca0_count: usize,
pub wkl0_count: usize,
pub aca0_count: usize,
pub atr0_count: usize,
pub pi11ca0_count: usize,
}
impl BigFiveStats {
#[allow(dead_code)]
pub fn from_scoreboard(sb: &RMScoreboard) -> Self {
Self {
rca0_count: sb.count_in("RCA₀"),
wkl0_count: sb.count_in("WKL₀"),
aca0_count: sb.count_in("ACA₀"),
atr0_count: sb.count_in("ATR₀"),
pi11ca0_count: sb.count_in("Π¹₁-CA₀"),
}
}
#[allow(dead_code)]
pub fn total(&self) -> usize {
self.rca0_count + self.wkl0_count + self.aca0_count + self.atr0_count + self.pi11ca0_count
}
#[allow(dead_code)]
pub fn display(&self) -> String {
format!(
"RCA₀:{} WKL₀:{} ACA₀:{} ATR₀:{} Π¹₁-CA₀:{} total:{}",
self.rca0_count,
self.wkl0_count,
self.aca0_count,
self.atr0_count,
self.pi11ca0_count,
self.total()
)
}
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum BigFiveSystem {
RCA0,
WKL0,
ACA0,
ATR0,
Pi11CA0,
}
impl BigFiveSystem {
pub fn name(&self) -> &'static str {
match self {
BigFiveSystem::RCA0 => "RCA₀",
BigFiveSystem::WKL0 => "WKL₀",
BigFiveSystem::ACA0 => "ACA₀",
BigFiveSystem::ATR0 => "ATR₀",
BigFiveSystem::Pi11CA0 => "Π¹₁-CA₀",
}
}
pub fn at_least_as_strong_as(&self, other: &BigFiveSystem) -> bool {
self >= other
}
pub fn proof_theoretic_ordinal(&self) -> &'static str {
match self {
BigFiveSystem::RCA0 => "ω^ω",
BigFiveSystem::WKL0 => "ω^ω",
BigFiveSystem::ACA0 => "ε₀",
BigFiveSystem::ATR0 => "Γ₀",
BigFiveSystem::Pi11CA0 => "ψ(Ω_ω)",
}
}
pub fn wkl0_is_conservative_over(&self) -> bool {
matches!(self, BigFiveSystem::RCA0)
}
}
#[derive(Debug, Clone)]
pub struct ConservationResult {
pub stronger: BigFiveSystem,
pub weaker: BigFiveSystem,
pub formula_class: &'static str,
pub reference: &'static str,
}
impl ConservationResult {
pub fn wkl0_over_rca0() -> Self {
Self {
stronger: BigFiveSystem::WKL0,
weaker: BigFiveSystem::RCA0,
formula_class: "Π¹_1",
reference: "Friedman 1976; Simpson 1999",
}
}
pub fn aca0_over_pa() -> Self {
Self {
stronger: BigFiveSystem::ACA0,
weaker: BigFiveSystem::RCA0,
formula_class: "First-order arithmetic",
reference: "Friedman 1976; Simpson Ch. III",
}
}
pub fn atr0_over_aca0() -> Self {
Self {
stronger: BigFiveSystem::ATR0,
weaker: BigFiveSystem::ACA0,
formula_class: "Π¹_2",
reference: "Friedman 1976",
}
}
pub fn is_valid_direction(&self) -> bool {
self.stronger >= self.weaker
}
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct Pi11Sentence {
pub name: String,
pub statement: String,
pub ordinal_strength: Option<String>,
}
impl Pi11Sentence {
#[allow(dead_code)]
pub fn new(
name: impl Into<String>,
statement: impl Into<String>,
ordinal_strength: Option<impl Into<String>>,
) -> Self {
Self {
name: name.into(),
statement: statement.into(),
ordinal_strength: ordinal_strength.map(Into::into),
}
}
#[allow(dead_code)]
pub fn display(&self) -> String {
let ord = self.ordinal_strength.as_deref().unwrap_or("unknown");
format!("{}: {} [strength: {}]", self.name, self.statement, ord)
}
}
#[derive(Debug, Clone)]
pub struct RMPrinciple {
pub name: &'static str,
pub description: &'static str,
pub strength: RMStrength,
pub year: u32,
}
impl RMPrinciple {
pub fn equivalent_to(&self, system: &BigFiveSystem) -> bool {
match (&self.strength, system) {
(RMStrength::WKL0, BigFiveSystem::WKL0) => true,
(RMStrength::ACA0, BigFiveSystem::ACA0) => true,
(RMStrength::ATR0, BigFiveSystem::ATR0) => true,
(RMStrength::Pi11CA0, BigFiveSystem::Pi11CA0) => true,
(RMStrength::RCA0, BigFiveSystem::RCA0) => true,
_ => false,
}
}
pub fn rt22() -> Self {
Self {
name: "RT²_2",
description: "Ramsey's theorem for pairs and 2 colors",
strength: RMStrength::BetweenWKL0AndACA0,
year: 1995,
}
}
pub fn srt22() -> Self {
Self {
name: "SRT²_2",
description: "Stable Ramsey's theorem for pairs and 2 colors",
strength: RMStrength::BetweenRCA0AndWKL0,
year: 2001,
}
}
pub fn cac() -> Self {
Self {
name: "CAC",
description: "Every infinite partial order has an infinite chain or antichain",
strength: RMStrength::BetweenWKL0AndACA0,
year: 2007,
}
}
pub fn ads() -> Self {
Self {
name: "ADS",
description: "Every infinite linear order has an infinite ascending or descending seq",
strength: RMStrength::BetweenRCA0AndWKL0,
year: 2007,
}
}
pub fn hindman() -> Self {
Self {
name: "HT",
description: "Hindman's finite sums theorem",
strength: RMStrength::BetweenACA0AndATR0,
year: 1974,
}
}
pub fn bolzano_weierstrass() -> Self {
Self {
name: "BW",
description: "Every bounded sequence of reals has a convergent subsequence",
strength: RMStrength::ACA0,
year: 1985,
}
}
pub fn brouwer() -> Self {
Self {
name: "BFP",
description: "Brouwer's fixed-point theorem for the closed disk",
strength: RMStrength::WKL0,
year: 1998,
}
}
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct ConstructivePrinciple {
pub name: String,
pub classical_counterpart: String,
pub constructively_provable: bool,
pub required_axiom: Option<String>,
}
impl ConstructivePrinciple {
#[allow(dead_code)]
pub fn new(
name: impl Into<String>,
classical: impl Into<String>,
constructive: bool,
axiom: Option<impl Into<String>>,
) -> Self {
Self {
name: name.into(),
classical_counterpart: classical.into(),
constructively_provable: constructive,
required_axiom: axiom.map(Into::into),
}
}
#[allow(dead_code)]
pub fn display(&self) -> String {
let ax = self.required_axiom.as_deref().unwrap_or("none");
format!(
"Principle '{}' (classical: '{}') constructive={}, axiom={}",
self.name, self.classical_counterpart, self.constructively_provable, ax
)
}
}
#[allow(dead_code)]
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ProofSystem {
PRA,
ECA,
RobinsonQ,
PeanoPA,
Z2,
Custom(String),
}
impl ProofSystem {
#[allow(dead_code)]
pub fn name(&self) -> String {
match self {
Self::PRA => "PRA".to_owned(),
Self::ECA => "ECA".to_owned(),
Self::RobinsonQ => "Q".to_owned(),
Self::PeanoPA => "PA".to_owned(),
Self::Z2 => "Z₂".to_owned(),
Self::Custom(s) => s.clone(),
}
}
#[allow(dead_code)]
pub fn is_conservative_over(&self, other: &ProofSystem) -> bool {
use ProofSystem::*;
matches!(
(self, other),
(Z2, PeanoPA)
| (PeanoPA, RobinsonQ)
| (Z2, RobinsonQ)
| (PeanoPA, ECA)
| (Z2, ECA)
| (PeanoPA, PRA)
| (Z2, PRA)
)
}
#[allow(dead_code)]
pub fn stronger_systems(&self) -> Vec<ProofSystem> {
use ProofSystem::*;
match self {
PRA => vec![PRA, ECA, RobinsonQ, PeanoPA, Z2],
ECA => vec![ECA, RobinsonQ, PeanoPA, Z2],
RobinsonQ => vec![RobinsonQ, PeanoPA, Z2],
PeanoPA => vec![PeanoPA, Z2],
Z2 => vec![Z2],
Custom(_) => vec![self.clone()],
}
}
}
#[derive(Debug, Clone)]
pub struct WeakKonigTree {
pub max_depth: u32,
pub nodes: Vec<u64>,
pub depths: Vec<u32>,
}
impl WeakKonigTree {
pub fn complete(d: u32) -> Self {
let mut nodes = Vec::new();
let mut depths = Vec::new();
for depth in 0..=d {
for bits in 0u64..(1u64 << depth) {
nodes.push(bits);
depths.push(depth);
}
}
Self {
max_depth: d,
nodes,
depths,
}
}
pub fn count_at_depth(&self, d: u32) -> usize {
self.depths.iter().filter(|&&depth| depth == d).count()
}
pub fn is_infinite(&self) -> bool {
(0..=self.max_depth).all(|d| self.count_at_depth(d) > 0)
}
pub fn greedy_path(&self) -> Vec<u8> {
let mut path = Vec::new();
let mut prefix: u64 = 0;
for depth in 1..=self.max_depth {
let zero_child = prefix;
let one_child = prefix | (1u64 << (depth - 1));
let has_zero = self
.nodes
.iter()
.zip(self.depths.iter())
.any(|(&n, &d)| d == depth && n == zero_child);
let has_one = self
.nodes
.iter()
.zip(self.depths.iter())
.any(|(&n, &d)| d == depth && n == one_child);
if has_zero {
prefix = zero_child;
path.push(0u8);
} else if has_one {
prefix = one_child;
path.push(1u8);
} else {
break;
}
}
path
}
}
#[derive(Debug, Clone)]
pub struct RMA0System {
pub statement: &'static str,
pub kind: RCA0AxiomKind,
pub is_valid: bool,
}
impl RMA0System {
pub fn verify(&self) -> bool {
self.is_valid
}
pub fn summary(&self) -> String {
format!(
"[{:?}] {} — {}",
self.kind,
self.statement,
if self.is_valid { "VALID" } else { "INVALID" }
)
}
pub fn sigma01_comprehension_for(predicate: &'static str) -> Self {
Self {
statement: predicate,
kind: RCA0AxiomKind::Sigma01Comprehension,
is_valid: true,
}
}
}
#[derive(Debug, Clone)]
pub struct RMHierarchyEntry {
pub system: BigFiveSystem,
pub equivalents: Vec<&'static str>,
pub conservation_note: &'static str,
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct RMTheorem {
pub name: String,
pub statement: String,
pub minimal_system: String,
pub equivalences: Vec<String>,
pub provable_in_rca0: bool,
}
impl RMTheorem {
#[allow(dead_code)]
pub fn new(
name: impl Into<String>,
statement: impl Into<String>,
minimal_system: impl Into<String>,
equivalences: Vec<impl Into<String>>,
provable_in_rca0: bool,
) -> Self {
Self {
name: name.into(),
statement: statement.into(),
minimal_system: minimal_system.into(),
equivalences: equivalences.into_iter().map(Into::into).collect(),
provable_in_rca0,
}
}
#[allow(dead_code)]
pub fn summary(&self) -> String {
let equiv_str = if self.equivalences.is_empty() {
"none known".to_owned()
} else {
self.equivalences.join(", ")
};
format!(
"[{}] Minimal system: {}. Equivalences: {}. Provable in RCA₀: {}.",
self.name, self.minimal_system, equiv_str, self.provable_in_rca0
)
}
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct IndependenceResult {
pub statement: String,
pub base_theory: String,
pub is_independent: bool,
pub notes: String,
}
impl IndependenceResult {
#[allow(dead_code)]
pub fn new(
statement: impl Into<String>,
base: impl Into<String>,
ind: bool,
notes: impl Into<String>,
) -> Self {
Self {
statement: statement.into(),
base_theory: base.into(),
is_independent: ind,
notes: notes.into(),
}
}
#[allow(dead_code)]
pub fn display(&self) -> String {
let kind = if self.is_independent {
"INDEPENDENT"
} else {
"PROVABLE"
};
format!(
"[{}] {} over {} ({})",
kind, self.statement, self.base_theory, self.notes
)
}
}
#[derive(Debug, Clone)]
pub struct ComputableFunction {
pub name: &'static str,
pub jump_level: Option<u32>,
pub table: Vec<Option<u64>>,
}
impl ComputableFunction {
pub fn indicator_below(bound: u64) -> Self {
let table = (0u64..bound + 4)
.map(|n| Some(if n < bound { 1 } else { 0 }))
.collect();
Self {
name: "indicator_below",
jump_level: Some(0),
table,
}
}
pub fn eval(&self, n: usize) -> Option<u64> {
self.table.get(n).copied().flatten()
}
pub fn is_total_up_to(&self, n: usize) -> bool {
(0..n).all(|i| self.table.get(i).copied().flatten().is_some())
}
pub fn oracle_query(&self, input: usize, _steps: u32) -> Option<u64> {
self.eval(input)
}
}
#[allow(dead_code)]
#[derive(Debug, Default)]
pub struct RMScoreboard {
pub theorems: Vec<(String, String)>,
}
impl RMScoreboard {
#[allow(dead_code)]
pub fn new() -> Self {
Self::default()
}
#[allow(dead_code)]
pub fn record(&mut self, theorem: impl Into<String>, system: impl Into<String>) {
self.theorems.push((theorem.into(), system.into()));
}
#[allow(dead_code)]
pub fn theorems_in(&self, system: &str) -> Vec<&str> {
self.theorems
.iter()
.filter(|(_, s)| s == system)
.map(|(t, _)| t.as_str())
.collect()
}
#[allow(dead_code)]
pub fn count_in(&self, system: &str) -> usize {
self.theorems_in(system).len()
}
#[allow(dead_code)]
pub fn standard() -> Self {
let mut sb = Self::new();
for thm in standard_rm_theorems() {
sb.record(thm.name.clone(), thm.minimal_system.clone());
}
sb
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum RCA0AxiomKind {
Sigma01Comprehension,
Sigma01Induction,
BasicArithmetic,
PrimitiveRecursion,
}
#[derive(Debug, Clone)]
pub struct RMHierarchy {
entries: Vec<RMHierarchyEntry>,
}
impl RMHierarchy {
pub fn standard() -> Self {
Self {
entries: vec![
RMHierarchyEntry {
system: BigFiveSystem::RCA0,
equivalents: vec![
"Σ⁰₁-comprehension",
"Σ⁰₁-induction",
"Primitive recursion",
"Low basis theorem",
"Σ⁰₁-bounding",
],
conservation_note: "Base system; WKL₀ is Π¹₁-conservative over RCA₀",
},
RMHierarchyEntry {
system: BigFiveSystem::WKL0,
equivalents: vec![
"König's lemma (binary trees)",
"Brouwer's fixed-point theorem",
"Hahn-Banach theorem",
"Gödel completeness theorem",
"Maximal ideal theorem",
"Jordan curve theorem",
],
conservation_note: "Π¹₁-conservative over RCA₀ (Friedman 1976)",
},
RMHierarchyEntry {
system: BigFiveSystem::ACA0,
equivalents: vec![
"Bolzano-Weierstrass theorem",
"Arithmetical comprehension",
"Sequential completeness of ℝ",
"Comparability of well-orderings",
"König's lemma (finitely branching)",
"CAC (chain-antichain)",
"Omitting types theorem",
],
conservation_note: "Conservative over PA for first-order sentences",
},
RMHierarchyEntry {
system: BigFiveSystem::ATR0,
equivalents: vec![
"Open determinacy",
"Bar induction",
"Comparison of well-orderings",
"Hausdorff scattered characterisation",
"Ulm's theorem",
"Perfect set theorem",
"Σ¹₁ separation",
],
conservation_note: "Π¹₂-conservative over ACA₀",
},
RMHierarchyEntry {
system: BigFiveSystem::Pi11CA0,
equivalents: vec![
"Π¹₁-comprehension",
"Σ¹₁-determinacy",
"Hyperarithmetic theorem",
"Every Π¹₁ set is a union of ω₁-many Borel sets",
"Cantor-Bendixson theorem (full)",
],
conservation_note: "Strongest of the Big Five",
},
],
}
}
pub fn display(&self) -> String {
let mut out = String::from("=== Reverse Mathematics Hierarchy ===\n");
for entry in &self.entries {
out.push_str(&format!(
"\n[{}] (ordinal: {})\n",
entry.system.name(),
entry.system.proof_theoretic_ordinal()
));
out.push_str(&format!(" Conservation: {}\n", entry.conservation_note));
out.push_str(" Equivalents:\n");
for eq in &entry.equivalents {
out.push_str(&format!(" - {}\n", eq));
}
}
out
}
pub fn entry_for(&self, system: &BigFiveSystem) -> Option<&RMHierarchyEntry> {
self.entries.iter().find(|e| &e.system == system)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum RMStrength {
RCA0,
BetweenRCA0AndWKL0,
WKL0,
BetweenWKL0AndACA0,
ACA0,
BetweenACA0AndATR0,
ATR0,
Pi11CA0,
AbovePi11CA0,
Unknown,
}
impl RMStrength {
pub fn lower_bound_system(&self) -> Option<BigFiveSystem> {
match self {
RMStrength::RCA0 => Some(BigFiveSystem::RCA0),
RMStrength::BetweenRCA0AndWKL0 => Some(BigFiveSystem::RCA0),
RMStrength::WKL0 => Some(BigFiveSystem::WKL0),
RMStrength::BetweenWKL0AndACA0 => Some(BigFiveSystem::WKL0),
RMStrength::ACA0 => Some(BigFiveSystem::ACA0),
RMStrength::BetweenACA0AndATR0 => Some(BigFiveSystem::ACA0),
RMStrength::ATR0 => Some(BigFiveSystem::ATR0),
RMStrength::Pi11CA0 | RMStrength::AbovePi11CA0 => Some(BigFiveSystem::Pi11CA0),
RMStrength::Unknown => None,
}
}
}