#![allow(dead_code)]
use hfs::prelude::*;
fn int(n: isize) -> Set {
unsafe {
match n {
0 => Set::nat(0).id_kpair(),
-1 => Set::nat(1).id_kpair(),
1.. => Set::nat(0).kpair_unchecked(Set::nat(n as usize)),
..=-2 => Set::nat(1).kpair_unchecked(Set::nat((-n) as usize)),
}
}
}
fn nat_to_int(n: usize) -> isize {
let x = ((n + 1) / 2) as isize;
if n % 2 == 0 {
x
} else {
-x
}
}
fn class_int() -> Class {
unsafe { Class::new_unchecked((0..).map(|n| int(nat_to_int(n)))) }
}
fn rat_unchecked(m: isize, n: usize) -> Set {
unsafe { int(m).kpair_unchecked(Set::nat(n)) }
}
fn rat(m: isize, n: usize) -> Option<Set> {
fn reduce(m: usize, n: usize) -> (usize, usize) {
let g = gcd::binary_usize(m, n);
(m / g, n / g)
}
if n == 0 {
return None;
}
let (m, n) = if m >= 0 {
let (x, y) = reduce(m as usize, n);
(x as isize, y)
} else {
let (x, y) = reduce((-m) as usize, n);
(-(x as isize), y)
};
Some(rat_unchecked(m, n))
}
fn class_rat() -> Class {
unsafe {
Class::new_unchecked(class::Product::new(0.., 1..).filter_map(|(m, n)| {
let m = nat_to_int(m);
if gcd::binary_usize(m.unsigned_abs(), n) == 1 {
Some(rat_unchecked(m, n))
} else {
None
}
}))
}
}
fn real(x: f64) -> Class {
class_rat().select(move |r| {
let r = unsafe {
let (k, n) = r.ksplit().unwrap_unchecked().pair();
let (s, m) = k.ksplit().unwrap_unchecked().pair();
let f = m.card() as f64 / n.card() as f64;
if s.is_empty() {
f
} else {
-f
}
};
r < x
})
}
fn main() {
println!("Square root of 2:\n{{");
for set in real(f64::sqrt(2.0)).into_iter().take(10) {
println!(" {set},");
}
println!(" ...\n}}");
}