#![allow(clippy::items_after_test_module)]
use oxilean_kernel::{BinderInfo, Declaration, Environment, Expr, Level, Name};
use super::types::{FinSurreal, GameValue, Sign};
pub fn app(f: Expr, a: Expr) -> Expr {
Expr::App(Box::new(f), Box::new(a))
}
pub fn app2(f: Expr, a: Expr, b: Expr) -> Expr {
app(app(f, a), b)
}
pub fn app3(f: Expr, a: Expr, b: Expr, c: Expr) -> Expr {
app(app2(f, a, b), c)
}
pub fn cst(s: &str) -> Expr {
Expr::Const(Name::str(s), vec![])
}
pub fn prop() -> Expr {
Expr::Sort(Level::zero())
}
pub fn type0() -> Expr {
Expr::Sort(Level::succ(Level::zero()))
}
pub fn pi(bi: BinderInfo, name: &str, dom: Expr, body: Expr) -> Expr {
Expr::Pi(bi, Name::str(name), Box::new(dom), Box::new(body))
}
pub fn lam(bi: BinderInfo, name: &str, dom: Expr, body: Expr) -> Expr {
Expr::Lam(bi, Name::str(name), Box::new(dom), Box::new(body))
}
pub fn arrow(a: Expr, b: Expr) -> Expr {
pi(BinderInfo::Default, "_", a, b)
}
pub fn bvar(n: u32) -> Expr {
Expr::BVar(n)
}
pub fn nat_ty() -> Expr {
cst("Nat")
}
pub fn int_ty() -> Expr {
cst("Int")
}
pub fn bool_ty() -> Expr {
cst("Bool")
}
pub fn real_ty() -> Expr {
cst("Real")
}
pub fn and(p: Expr, q: Expr) -> Expr {
app2(cst("And"), p, q)
}
pub fn or(p: Expr, q: Expr) -> Expr {
app2(cst("Or"), p, q)
}
pub fn not(p: Expr) -> Expr {
app(cst("Not"), p)
}
pub fn iff(p: Expr, q: Expr) -> Expr {
app2(cst("Iff"), p, q)
}
pub fn forall_surreal(name: &str, body: Expr) -> Expr {
pi(BinderInfo::Default, name, surreal_ty(), body)
}
pub fn exists_surreal(name: &str, body: Expr) -> Expr {
app(
cst("Exists"),
lam(BinderInfo::Default, name, surreal_ty(), body),
)
}
pub(super) fn eq_surreal(x: Expr, y: Expr) -> Expr {
app3(cst("Eq"), surreal_ty(), x, y)
}
pub fn surreal_ty() -> Expr {
type0()
}
pub fn surreal_set_ty() -> Expr {
arrow(surreal_ty(), prop())
}
pub fn game_ty() -> Expr {
type0()
}
pub fn sign_seq_ty() -> Expr {
arrow(nat_ty(), bool_ty())
}
pub fn birthday_ty() -> Expr {
arrow(surreal_ty(), nat_ty())
}
pub fn left_set_ty() -> Expr {
arrow(surreal_ty(), surreal_set_ty())
}
pub fn right_set_ty() -> Expr {
arrow(surreal_ty(), surreal_set_ty())
}
pub fn mk_surreal_ty() -> Expr {
arrow(surreal_set_ty(), arrow(surreal_set_ty(), surreal_ty()))
}
pub fn valid_cut_ty() -> Expr {
arrow(surreal_set_ty(), arrow(surreal_set_ty(), prop()))
}
pub fn birthday_zero_ty() -> Expr {
app3(
cst("Eq"),
nat_ty(),
app(cst("Birthday"), cst("SZero")),
cst("NatZero"),
)
}
pub fn birthday_one_ty() -> Expr {
app3(
cst("Eq"),
nat_ty(),
app(cst("Birthday"), cst("SOne")),
cst("NatOne"),
)
}
pub fn birthday_neg_one_ty() -> Expr {
app3(
cst("Eq"),
nat_ty(),
app(cst("Birthday"), cst("SNegOne")),
cst("NatOne"),
)
}
pub fn left_set_empty_at_zero_ty() -> Expr {
prop()
}
pub fn right_set_empty_at_zero_ty() -> Expr {
prop()
}
pub fn surreal_le_ty() -> Expr {
arrow(surreal_ty(), arrow(surreal_ty(), prop()))
}
pub fn surreal_lt_ty() -> Expr {
arrow(surreal_ty(), arrow(surreal_ty(), prop()))
}
pub fn surreal_eq_ty() -> Expr {
arrow(surreal_ty(), arrow(surreal_ty(), prop()))
}
pub fn total_order_surreal_ty() -> Expr {
forall_surreal(
"x",
forall_surreal(
"y",
or(
app2(cst("SurrealLe"), bvar(1), bvar(0)),
app2(cst("SurrealLe"), bvar(0), bvar(1)),
),
),
)
}
pub fn le_refl_surreal_ty() -> Expr {
forall_surreal("x", app2(cst("SurrealLe"), bvar(0), bvar(0)))
}
pub fn le_antisymm_surreal_ty() -> Expr {
forall_surreal(
"x",
forall_surreal(
"y",
arrow(
app2(cst("SurrealLe"), bvar(1), bvar(0)),
arrow(
app2(cst("SurrealLe"), bvar(0), bvar(2)),
eq_surreal(bvar(1), bvar(0)),
),
),
),
)
}
pub fn le_trans_surreal_ty() -> Expr {
forall_surreal(
"x",
forall_surreal(
"y",
forall_surreal(
"z",
arrow(
app2(cst("SurrealLe"), bvar(2), bvar(1)),
arrow(
app2(cst("SurrealLe"), bvar(1), bvar(0)),
app2(cst("SurrealLe"), bvar(2), bvar(0)),
),
),
),
),
)
}
pub fn surreal_add_ty() -> Expr {
arrow(surreal_ty(), arrow(surreal_ty(), surreal_ty()))
}
pub fn surreal_neg_ty() -> Expr {
arrow(surreal_ty(), surreal_ty())
}
pub fn surreal_mul_ty() -> Expr {
arrow(surreal_ty(), arrow(surreal_ty(), surreal_ty()))
}
pub fn surreal_inv_ty() -> Expr {
arrow(surreal_ty(), surreal_ty())
}
pub fn add_comm_surreal_ty() -> Expr {
forall_surreal(
"x",
forall_surreal(
"y",
eq_surreal(
app2(cst("SurrealAdd"), bvar(1), bvar(0)),
app2(cst("SurrealAdd"), bvar(0), bvar(1)),
),
),
)
}
pub fn add_assoc_surreal_ty() -> Expr {
forall_surreal(
"x",
forall_surreal(
"y",
forall_surreal(
"z",
eq_surreal(
app2(
cst("SurrealAdd"),
app2(cst("SurrealAdd"), bvar(2), bvar(1)),
bvar(0),
),
app2(
cst("SurrealAdd"),
bvar(2),
app2(cst("SurrealAdd"), bvar(1), bvar(0)),
),
),
),
),
)
}
pub fn mul_comm_surreal_ty() -> Expr {
forall_surreal(
"x",
forall_surreal(
"y",
eq_surreal(
app2(cst("SurrealMul"), bvar(1), bvar(0)),
app2(cst("SurrealMul"), bvar(0), bvar(1)),
),
),
)
}
pub fn surreal_ordered_field_ty() -> Expr {
app(cst("OrderedField"), surreal_ty())
}
pub fn add_zero_surreal_ty() -> Expr {
forall_surreal(
"x",
eq_surreal(app2(cst("SurrealAdd"), bvar(0), cst("SZero")), bvar(0)),
)
}
pub fn add_neg_surreal_ty() -> Expr {
forall_surreal(
"x",
eq_surreal(
app2(cst("SurrealAdd"), bvar(0), app(cst("SurrealNeg"), bvar(0))),
cst("SZero"),
),
)
}
pub fn simplest_in_cut_ty() -> Expr {
arrow(
surreal_set_ty(),
arrow(surreal_set_ty(), arrow(surreal_ty(), prop())),
)
}
pub fn simplicity_theorem_ty() -> Expr {
pi(
BinderInfo::Default,
"L",
surreal_set_ty(),
pi(
BinderInfo::Default,
"R",
surreal_set_ty(),
arrow(
app2(cst("ValidCut"), bvar(1), bvar(0)),
exists_surreal("x", app3(cst("SimplestInCut"), bvar(2), bvar(1), bvar(0))),
),
),
)
}
pub fn simplest_dyadic_ty() -> Expr {
arrow(int_ty(), arrow(int_ty(), arrow(surreal_ty(), prop())))
}
pub fn sign_expansion_ty() -> Expr {
arrow(surreal_ty(), sign_seq_ty())
}
pub fn from_sign_seq_ty() -> Expr {
arrow(sign_seq_ty(), arrow(nat_ty(), surreal_ty()))
}
pub fn sign_expansion_injective_ty() -> Expr {
forall_surreal(
"x",
forall_surreal(
"y",
arrow(
app3(
cst("Eq"),
sign_seq_ty(),
app(cst("SignExpansion"), bvar(1)),
app(cst("SignExpansion"), bvar(0)),
),
eq_surreal(bvar(1), bvar(0)),
),
),
)
}
pub fn sign_expansion_zero_ty() -> Expr {
prop()
}
pub fn sign_expansion_pos_int_ty() -> Expr {
arrow(nat_ty(), prop())
}
pub fn omnific_int_ty() -> Expr {
arrow(surreal_ty(), prop())
}
pub fn integer_part_ty() -> Expr {
arrow(surreal_ty(), surreal_ty())
}
pub fn fractional_part_ty() -> Expr {
arrow(surreal_ty(), surreal_ty())
}
pub fn omnific_int_closed_add_ty() -> Expr {
forall_surreal(
"x",
forall_surreal(
"y",
arrow(
app(cst("OmnificInt"), bvar(1)),
arrow(
app(cst("OmnificInt"), bvar(0)),
app(cst("OmnificInt"), app2(cst("SurrealAdd"), bvar(1), bvar(0))),
),
),
),
)
}
pub fn nat_embeds_in_omnific_ty() -> Expr {
arrow(nat_ty(), app(cst("OmnificInt"), app(cst("OfNat"), bvar(0))))
}
pub fn surreal_exp_ty() -> Expr {
arrow(surreal_ty(), surreal_ty())
}
pub fn surreal_log_ty() -> Expr {
arrow(surreal_ty(), surreal_ty())
}
pub fn surreal_pow_ty() -> Expr {
arrow(surreal_ty(), arrow(surreal_ty(), surreal_ty()))
}
pub fn exp_log_inv_ty() -> Expr {
forall_surreal(
"x",
arrow(
app2(cst("SurrealLt"), cst("SZero"), bvar(0)),
eq_surreal(
app(cst("SurrealExp"), app(cst("SurrealLog"), bvar(0))),
bvar(0),
),
),
)
}
pub fn log_exp_inv_ty() -> Expr {
forall_surreal(
"x",
eq_surreal(
app(cst("SurrealLog"), app(cst("SurrealExp"), bvar(0))),
bvar(0),
),
)
}
pub fn exp_add_ty() -> Expr {
forall_surreal(
"x",
forall_surreal(
"y",
eq_surreal(
app(cst("SurrealExp"), app2(cst("SurrealAdd"), bvar(1), bvar(0))),
app2(
cst("SurrealMul"),
app(cst("SurrealExp"), bvar(1)),
app(cst("SurrealExp"), bvar(0)),
),
),
),
)
}
pub fn surreal_exp_positive_ty() -> Expr {
forall_surreal(
"x",
app2(
cst("SurrealLt"),
cst("SZero"),
app(cst("SurrealExp"), bvar(0)),
),
)
}
pub fn surreal_fun_ty() -> Expr {
arrow(surreal_ty(), surreal_ty())
}
pub fn surreal_lim_ty() -> Expr {
arrow(arrow(nat_ty(), surreal_ty()), arrow(surreal_ty(), prop()))
}
pub fn surreal_continuous_ty() -> Expr {
arrow(surreal_fun_ty(), arrow(surreal_ty(), prop()))
}
pub fn surreal_deriv_ty() -> Expr {
arrow(surreal_fun_ty(), surreal_fun_ty())
}
pub fn surreal_ivt_ty() -> Expr {
pi(
BinderInfo::Default,
"f",
surreal_fun_ty(),
forall_surreal(
"a",
forall_surreal(
"b",
arrow(
app2(cst("SurrealLt"), bvar(1), bvar(0)),
exists_surreal("c", prop()),
),
),
),
)
}
pub fn surreal_dist_ty() -> Expr {
arrow(surreal_ty(), arrow(surreal_ty(), surreal_ty()))
}
pub fn epsilon_delta_cont_ty() -> Expr {
arrow(surreal_fun_ty(), arrow(surreal_ty(), prop()))
}
pub fn eps_delta_iff_continuous_ty() -> Expr {
pi(
BinderInfo::Default,
"f",
surreal_fun_ty(),
forall_surreal(
"a",
iff(
app2(cst("EpsilonDeltaCont"), bvar(1), bvar(0)),
app2(cst("SurrealContinuous"), bvar(1), bvar(0)),
),
),
)
}
pub fn infinitesimal_epsilon_ty() -> Expr {
exists_surreal("eps", prop())
}
pub fn game_to_surreal_ty() -> Expr {
arrow(game_ty(), surreal_ty())
}
pub fn nim_value_ty() -> Expr {
arrow(nat_ty(), surreal_ty())
}
pub fn nim_sum_ty() -> Expr {
arrow(surreal_ty(), arrow(surreal_ty(), surreal_ty()))
}
pub fn surreal_zero_p_pos_ty() -> Expr {
prop()
}
pub fn nim_value_additive_ty() -> Expr {
arrow(nat_ty(), arrow(nat_ty(), prop()))
}
pub fn surreal_game_equiv_ty() -> Expr {
arrow(game_ty(), prop())
}
pub fn positive_surreal_fp_win_ty() -> Expr {
forall_surreal(
"x",
arrow(
app2(cst("SurrealLt"), cst("SZero"), bvar(0)),
app(cst("FirstPlayerWins"), bvar(0)),
),
)
}
pub fn no_is_real_closed_ty() -> Expr {
app(cst("RealClosedField"), surreal_ty())
}
pub fn surreal_archimedean_class_ty() -> Expr {
forall_surreal(
"x",
forall_surreal(
"y",
arrow(
app2(cst("SurrealLt"), cst("SZero"), bvar(1)),
arrow(
app2(cst("SurrealLt"), cst("SZero"), bvar(0)),
app(
cst("Exists"),
lam(
BinderInfo::Default,
"n",
nat_ty(),
app2(
cst("SurrealLt"),
bvar(1),
app2(cst("SurrealMul"), app(cst("OfNat"), bvar(0)), bvar(2)),
),
),
),
),
),
),
)
}
pub fn mul_one_surreal_ty() -> Expr {
forall_surreal(
"x",
eq_surreal(app2(cst("SurrealMul"), bvar(0), cst("SOne")), bvar(0)),
)
}
pub fn mul_inv_surreal_ty() -> Expr {
forall_surreal(
"x",
arrow(
not(eq_surreal(bvar(0), cst("SZero"))),
eq_surreal(
app2(cst("SurrealMul"), bvar(0), app(cst("SurrealInv"), bvar(0))),
cst("SOne"),
),
),
)
}
pub fn distrib_surreal_ty() -> Expr {
forall_surreal(
"x",
forall_surreal(
"y",
forall_surreal(
"z",
eq_surreal(
app2(
cst("SurrealMul"),
bvar(2),
app2(cst("SurrealAdd"), bvar(1), bvar(0)),
),
app2(
cst("SurrealAdd"),
app2(cst("SurrealMul"), bvar(2), bvar(1)),
app2(cst("SurrealMul"), bvar(2), bvar(0)),
),
),
),
),
)
}
pub fn ordinal_surreal_ty() -> Expr {
arrow(cst("Ordinal"), surreal_ty())
}
pub fn surreal_omega_ty() -> Expr {
surreal_ty()
}
pub fn surreal_epsilon0_ty() -> Expr {
surreal_ty()
}
pub fn omega_gt_all_naturals_ty() -> Expr {
arrow(
nat_ty(),
app2(
cst("SurrealLt"),
app(cst("OfNat"), bvar(0)),
cst("SurrealOmega"),
),
)
}
pub fn omega_plus_one_ty() -> Expr {
app2(
cst("SurrealLt"),
cst("SurrealOmega"),
app2(cst("SurrealAdd"), cst("SurrealOmega"), cst("SOne")),
)
}
pub fn ordinal_add_embeds_ty() -> Expr {
pi(
BinderInfo::Default,
"alpha",
cst("Ordinal"),
pi(
BinderInfo::Default,
"beta",
cst("Ordinal"),
eq_surreal(
app(
cst("OrdinalSurreal"),
app2(cst("OrdinalAdd"), bvar(1), bvar(0)),
),
app2(
cst("SurrealAdd"),
app(cst("OrdinalSurreal"), bvar(1)),
app(cst("OrdinalSurreal"), bvar(0)),
),
),
),
)
}
pub fn sign_tree_ty() -> Expr {
type0()
}
pub fn tree_parent_ty() -> Expr {
arrow(surreal_ty(), arrow(surreal_ty(), prop()))
}
pub fn sign_seq_prefix_order_ty() -> Expr {
forall_surreal(
"x",
forall_surreal("y", iff(app2(cst("TreeParent"), bvar(1), bvar(0)), prop())),
)
}
pub fn surreal_lt_iff_sign_seq_lt_ty() -> Expr {
forall_surreal(
"x",
forall_surreal(
"y",
iff(
app2(cst("SurrealLt"), bvar(1), bvar(0)),
app2(
cst("LexLt"),
app(cst("SignExpansion"), bvar(1)),
app(cst("SignExpansion"), bvar(0)),
),
),
),
)
}
pub fn omnific_int_ring_ty() -> Expr {
app(cst("Ring"), cst("OmnificInts"))
}
pub fn omnific_int_closed_mul_ty() -> Expr {
forall_surreal(
"x",
forall_surreal(
"y",
arrow(
app(cst("OmnificInt"), bvar(1)),
arrow(
app(cst("OmnificInt"), bvar(0)),
app(cst("OmnificInt"), app2(cst("SurrealMul"), bvar(1), bvar(0))),
),
),
),
)
}
pub fn omnific_int_euclidean_div_ty() -> Expr {
forall_surreal(
"a",
forall_surreal(
"b",
arrow(
app(cst("OmnificInt"), bvar(1)),
arrow(
app(cst("OmnificInt"), bvar(0)),
arrow(not(eq_surreal(bvar(0), cst("SZero"))), prop()),
),
),
),
)
}
pub fn int_part_omnific_ty() -> Expr {
forall_surreal(
"x",
app(cst("OmnificInt"), app(cst("IntegerPart"), bvar(0))),
)
}
pub fn hahn_series_ty() -> Expr {
type0()
}
pub fn hahn_series_embed_ty() -> Expr {
arrow(surreal_ty(), hahn_series_ty())
}
pub fn hahn_series_add_ty() -> Expr {
arrow(hahn_series_ty(), arrow(hahn_series_ty(), hahn_series_ty()))
}
pub fn hahn_series_mul_ty() -> Expr {
arrow(hahn_series_ty(), arrow(hahn_series_ty(), hahn_series_ty()))
}
pub fn no_is_hahn_series_field_ty() -> Expr {
app(cst("IsField"), hahn_series_ty())
}
pub fn hahn_support_well_ordered_ty() -> Expr {
pi(
BinderInfo::Default,
"s",
hahn_series_ty(),
app(cst("WellOrdered"), app(cst("Support"), bvar(0))),
)
}
pub fn hyperreal_ty() -> Expr {
type0()
}
pub fn hyperreal_embed_ty() -> Expr {
arrow(hyperreal_ty(), surreal_ty())
}
pub fn hyperreal_transfer_principle_ty() -> Expr {
app2(cst("TransferPrinciple"), hyperreal_ty(), real_ty())
}
pub fn hyperreal_standard_part_ty() -> Expr {
arrow(hyperreal_ty(), real_ty())
}
pub fn hyperreal_infinitesimal_def_ty() -> Expr {
pi(
BinderInfo::Default,
"x",
hyperreal_ty(),
iff(app(cst("Infinitesimal"), bvar(0)), prop()),
)
}
pub fn surreal_seq_lim_ty() -> Expr {
arrow(arrow(nat_ty(), surreal_ty()), arrow(surreal_ty(), prop()))
}
pub fn surreal_squeeze_theorem_ty() -> Expr {
prop()
}
pub fn surreal_deriv_at_ty() -> Expr {
arrow(
surreal_fun_ty(),
arrow(surreal_ty(), arrow(surreal_ty(), prop())),
)
}
pub fn surreal_chain_rule_ty() -> Expr {
pi(
BinderInfo::Default,
"f",
surreal_fun_ty(),
pi(
BinderInfo::Default,
"g",
surreal_fun_ty(),
forall_surreal("a", prop()),
),
)
}
pub fn surreal_integral_ty() -> Expr {
arrow(
surreal_fun_ty(),
arrow(surreal_ty(), arrow(surreal_ty(), surreal_ty())),
)
}
pub fn surreal_ftc_ty() -> Expr {
pi(
BinderInfo::Default,
"f",
surreal_fun_ty(),
forall_surreal(
"a",
forall_surreal(
"b",
eq_surreal(
app3(
cst("SurrealIntegral"),
app(cst("SurrealDeriv"), bvar(2)),
bvar(1),
bvar(0),
),
app2(
cst("SurrealAdd"),
app(bvar(2), bvar(0)),
app(cst("SurrealNeg"), app(bvar(2), bvar(1))),
),
),
),
),
)
}
pub fn game_equiv_ty() -> Expr {
arrow(game_ty(), arrow(game_ty(), prop()))
}
pub fn game_add_ty() -> Expr {
arrow(game_ty(), arrow(game_ty(), game_ty()))
}
pub fn game_neg_ty() -> Expr {
arrow(game_ty(), game_ty())
}
pub fn game_equiv_is_zero_ty() -> Expr {
pi(
BinderInfo::Default,
"g",
game_ty(),
iff(
app2(cst("GameEquiv"), bvar(0), cst("ZeroGame")),
app(cst("SecondPlayerWins"), bvar(0)),
),
)
}
pub fn surreal_embed_game_hom_ty() -> Expr {
pi(
BinderInfo::Default,
"g",
game_ty(),
pi(
BinderInfo::Default,
"h",
game_ty(),
eq_surreal(
app(cst("GameToSurreal"), app2(cst("GameAdd"), bvar(1), bvar(0))),
app2(
cst("SurrealAdd"),
app(cst("GameToSurreal"), bvar(1)),
app(cst("GameToSurreal"), bvar(0)),
),
),
),
)
}
pub fn surreal_induction_ty() -> Expr {
arrow(arrow(surreal_ty(), prop()), prop())
}
pub fn birthday_induction_ty() -> Expr {
pi(
BinderInfo::Default,
"P",
arrow(surreal_ty(), prop()),
arrow(
forall_surreal(
"x",
arrow(
forall_surreal(
"y",
arrow(
app2(
cst("NatLt"),
app(cst("Birthday"), bvar(0)),
app(cst("Birthday"), bvar(1)),
),
app(bvar(3), bvar(0)),
),
),
app(bvar(1), bvar(0)),
),
),
forall_surreal("x", app(bvar(1), bvar(0))),
),
)
}
pub fn no_is_universal_ordered_field_ty() -> Expr {
pi(
BinderInfo::Default,
"F",
type0(),
arrow(
app(cst("OrderedField"), bvar(0)),
app2(cst("Embeds"), bvar(0), surreal_ty()),
),
)
}
pub fn surreal_mul_def_ty() -> Expr {
forall_surreal("x", forall_surreal("y", prop()))
}
pub fn mul_assoc_surreal_ty() -> Expr {
forall_surreal(
"x",
forall_surreal(
"y",
forall_surreal(
"z",
eq_surreal(
app2(
cst("SurrealMul"),
app2(cst("SurrealMul"), bvar(2), bvar(1)),
bvar(0),
),
app2(
cst("SurrealMul"),
bvar(2),
app2(cst("SurrealMul"), bvar(1), bvar(0)),
),
),
),
),
)
}
pub fn mul_zero_surreal_ty() -> Expr {
forall_surreal(
"x",
eq_surreal(app2(cst("SurrealMul"), bvar(0), cst("SZero")), cst("SZero")),
)
}
pub fn no_is_kappa_saturated_ty() -> Expr {
pi(
BinderInfo::Default,
"kappa",
cst("Cardinal"),
app2(cst("KappaSaturated"), surreal_ty(), bvar(0)),
)
}
pub fn no_is_homogeneous_ty() -> Expr {
app(cst("HomogeneousStructure"), surreal_ty())
}
pub fn no_is_o_minimal_ty() -> Expr {
app(cst("OMinimalStructure"), surreal_ty())
}
pub fn no_elementary_equiv_real_ty() -> Expr {
app2(cst("ElementarilyEquivalent"), surreal_ty(), real_ty())
}
pub fn no_unique_up_to_sat_ty() -> Expr {
pi(
BinderInfo::Default,
"F",
type0(),
arrow(
app(cst("RealClosedField"), bvar(0)),
arrow(
app2(cst("KappaSaturated"), bvar(0), cst("OmegaOne")),
app2(cst("Isomorphic"), bvar(0), surreal_ty()),
),
),
)
}
pub fn real_embeds_in_no_ty() -> Expr {
app2(cst("Embeds"), real_ty(), surreal_ty())
}
pub fn real_embed_preserves_order_ty() -> Expr {
pi(
BinderInfo::Default,
"x",
real_ty(),
pi(
BinderInfo::Default,
"y",
real_ty(),
iff(
app2(cst("RealLe"), bvar(1), bvar(0)),
app2(
cst("SurrealLe"),
app(cst("EmbedReal"), bvar(1)),
app(cst("EmbedReal"), bvar(0)),
),
),
),
)
}
pub fn no_decidable_rcf_ty() -> Expr {
app(cst("DecidableRCF"), surreal_ty())
}
pub fn tarski_transfers_to_no_ty() -> Expr {
pi(
BinderInfo::Default,
"phi",
cst("Formula"),
arrow(
app(cst("RealSentence"), bvar(0)),
app2(cst("HoldsIn"), surreal_ty(), bvar(0)),
),
)
}
pub fn build_surreal_env(env: &mut Environment) {
let axioms: &[(&str, Expr)] = &[
("Surreal", surreal_ty()),
("Game", game_ty()),
("SignSeq", sign_seq_ty()),
("SZero", surreal_ty()),
("SOne", surreal_ty()),
("SNegOne", surreal_ty()),
("NatZero", nat_ty()),
("NatOne", nat_ty()),
("EmptySeq", sign_seq_ty()),
("Birthday", birthday_ty()),
("LeftSet", left_set_ty()),
("RightSet", right_set_ty()),
("MkSurreal", mk_surreal_ty()),
("ValidCut", valid_cut_ty()),
("SurrealLe", surreal_le_ty()),
("SurrealLt", surreal_lt_ty()),
("SurrealEq", surreal_eq_ty()),
("total_order_surreal", total_order_surreal_ty()),
("le_refl_surreal", le_refl_surreal_ty()),
("le_antisymm_surreal", le_antisymm_surreal_ty()),
("le_trans_surreal", le_trans_surreal_ty()),
("SurrealAdd", surreal_add_ty()),
("SurrealNeg", surreal_neg_ty()),
("SurrealMul", surreal_mul_ty()),
("SurrealInv", surreal_inv_ty()),
("add_comm_surreal", add_comm_surreal_ty()),
("add_assoc_surreal", add_assoc_surreal_ty()),
("mul_comm_surreal", mul_comm_surreal_ty()),
("add_zero_surreal", add_zero_surreal_ty()),
("add_neg_surreal", add_neg_surreal_ty()),
("surreal_ordered_field", surreal_ordered_field_ty()),
("OrderedField", arrow(type0(), prop())),
("SimplestInCut", simplest_in_cut_ty()),
("simplicity_theorem", simplicity_theorem_ty()),
("simplest_dyadic", simplest_dyadic_ty()),
("SignExpansion", sign_expansion_ty()),
("FromSignSeq", from_sign_seq_ty()),
("PlusSeq", arrow(nat_ty(), sign_seq_ty())),
("OfNat", arrow(nat_ty(), surreal_ty())),
("sign_expansion_injective", sign_expansion_injective_ty()),
("OmnificInt", omnific_int_ty()),
("IntegerPart", integer_part_ty()),
("FractionalPart", fractional_part_ty()),
("omnific_int_closed_add", omnific_int_closed_add_ty()),
("nat_embeds_in_omnific", nat_embeds_in_omnific_ty()),
("SurrealExp", surreal_exp_ty()),
("SurrealLog", surreal_log_ty()),
("SurrealPow", surreal_pow_ty()),
("exp_log_inv", exp_log_inv_ty()),
("log_exp_inv", log_exp_inv_ty()),
("exp_add", exp_add_ty()),
("surreal_exp_positive", surreal_exp_positive_ty()),
("SurrealLim", surreal_lim_ty()),
("SurrealContinuous", surreal_continuous_ty()),
("SurrealDeriv", surreal_deriv_ty()),
("surreal_ivt", surreal_ivt_ty()),
("SurrealDist", surreal_dist_ty()),
("EpsilonDeltaCont", epsilon_delta_cont_ty()),
("eps_delta_iff_continuous", eps_delta_iff_continuous_ty()),
("infinitesimal_epsilon", infinitesimal_epsilon_ty()),
("GameToSurreal", game_to_surreal_ty()),
("NimValue", nim_value_ty()),
("NimSum", nim_sum_ty()),
("nim_value_additive", nim_value_additive_ty()),
("surreal_game_equiv", surreal_game_equiv_ty()),
("FirstPlayerWins", arrow(surreal_ty(), prop())),
("positive_surreal_fp_win", positive_surreal_fp_win_ty()),
("XorNat", arrow(nat_ty(), arrow(nat_ty(), nat_ty()))),
("GameValue", arrow(game_ty(), surreal_ty())),
("ZeroGame", game_ty()),
("RealClosedField", arrow(type0(), prop())),
("no_is_real_closed", no_is_real_closed_ty()),
("surreal_archimedean_class", surreal_archimedean_class_ty()),
("mul_one_surreal", mul_one_surreal_ty()),
("mul_inv_surreal", mul_inv_surreal_ty()),
("distrib_surreal", distrib_surreal_ty()),
("Ordinal", type0()),
(
"OrdinalAdd",
arrow(cst("Ordinal"), arrow(cst("Ordinal"), cst("Ordinal"))),
),
("OrdinalSurreal", ordinal_surreal_ty()),
("SurrealOmega", surreal_omega_ty()),
("SurrealEpsilon0", surreal_epsilon0_ty()),
("omega_gt_all_naturals", omega_gt_all_naturals_ty()),
("omega_plus_one", omega_plus_one_ty()),
("ordinal_add_embeds", ordinal_add_embeds_ty()),
("SignTree", sign_tree_ty()),
("TreeParent", tree_parent_ty()),
(
"AppendSign",
arrow(sign_seq_ty(), arrow(surreal_ty(), sign_seq_ty())),
),
("LexLt", arrow(sign_seq_ty(), arrow(sign_seq_ty(), prop()))),
("sign_seq_prefix_order", sign_seq_prefix_order_ty()),
(
"surreal_lt_iff_sign_seq_lt",
surreal_lt_iff_sign_seq_lt_ty(),
),
("OmnificInts", type0()),
("Ring", arrow(type0(), prop())),
("omnific_int_ring", omnific_int_ring_ty()),
("omnific_int_closed_mul", omnific_int_closed_mul_ty()),
("omnific_int_euclidean_div", omnific_int_euclidean_div_ty()),
("int_part_omnific", int_part_omnific_ty()),
("HahnSeries", hahn_series_ty()),
("HahnSeriesEmbed", hahn_series_embed_ty()),
("HahnSeriesAdd", hahn_series_add_ty()),
("HahnSeriesMul", hahn_series_mul_ty()),
("IsField", arrow(type0(), prop())),
("WellOrdered", arrow(type0(), prop())),
("Support", arrow(hahn_series_ty(), type0())),
("no_is_hahn_series_field", no_is_hahn_series_field_ty()),
("hahn_support_well_ordered", hahn_support_well_ordered_ty()),
("HyperReal", hyperreal_ty()),
("HyperRealEmbed", hyperreal_embed_ty()),
("TransferPrinciple", arrow(type0(), arrow(type0(), prop()))),
("Infinitesimal", arrow(hyperreal_ty(), prop())),
("EmbedReal", arrow(real_ty(), hyperreal_ty())),
(
"hyperreal_transfer_principle",
hyperreal_transfer_principle_ty(),
),
("hyperreal_standard_part", hyperreal_standard_part_ty()),
(
"hyperreal_infinitesimal_def",
hyperreal_infinitesimal_def_ty(),
),
("SurrealSeqLim", surreal_seq_lim_ty()),
("surreal_squeeze_theorem", surreal_squeeze_theorem_ty()),
("SurrealDerivAt", surreal_deriv_at_ty()),
("SurrealIntegral", surreal_integral_ty()),
("surreal_chain_rule", surreal_chain_rule_ty()),
("surreal_ftc", surreal_ftc_ty()),
("GameEquiv", game_equiv_ty()),
("GameAdd", game_add_ty()),
("GameNeg", game_neg_ty()),
("SecondPlayerWins", arrow(game_ty(), prop())),
("game_equiv_is_zero", game_equiv_is_zero_ty()),
("surreal_embed_game_hom", surreal_embed_game_hom_ty()),
("NatLt", arrow(nat_ty(), arrow(nat_ty(), prop()))),
("Embeds", arrow(type0(), arrow(type0(), prop()))),
("SurrealInduction", surreal_induction_ty()),
("birthday_induction", birthday_induction_ty()),
(
"no_is_universal_ordered_field",
no_is_universal_ordered_field_ty(),
),
("surreal_mul_def", surreal_mul_def_ty()),
("mul_assoc_surreal", mul_assoc_surreal_ty()),
("mul_zero_surreal", mul_zero_surreal_ty()),
("Cardinal", type0()),
("KappaSaturated", arrow(type0(), arrow(type0(), prop()))),
("HomogeneousStructure", arrow(type0(), prop())),
("OMinimalStructure", arrow(type0(), prop())),
(
"ElementarilyEquivalent",
arrow(type0(), arrow(type0(), prop())),
),
("OmegaOne", type0()),
("Isomorphic", arrow(type0(), arrow(type0(), prop()))),
("no_is_kappa_saturated", no_is_kappa_saturated_ty()),
("no_is_homogeneous", no_is_homogeneous_ty()),
("no_is_o_minimal", no_is_o_minimal_ty()),
("no_elementary_equiv_real", no_elementary_equiv_real_ty()),
("no_unique_up_to_sat", no_unique_up_to_sat_ty()),
("RealLe", arrow(real_ty(), arrow(real_ty(), prop()))),
("DecidableRCF", arrow(type0(), prop())),
("Formula", type0()),
("RealSentence", arrow(cst("Formula"), prop())),
("HoldsIn", arrow(type0(), arrow(cst("Formula"), prop()))),
("real_embeds_in_no", real_embeds_in_no_ty()),
(
"real_embed_preserves_order",
real_embed_preserves_order_ty(),
),
("no_decidable_rcf", no_decidable_rcf_ty()),
("tarski_transfers_to_no", tarski_transfers_to_no_ty()),
];
for (name, ty) in axioms {
env.add(Declaration::Axiom {
name: Name::str(*name),
univ_params: vec![],
ty: ty.clone(),
})
.ok();
}
}
pub fn nim_grundy(n: u64) -> u64 {
n
}
pub fn nim_xor(a: u64, b: u64) -> u64 {
a ^ b
}
pub fn nim_is_p_position(heaps: &[u64]) -> bool {
heaps.iter().fold(0u64, |acc, &h| acc ^ h) == 0
}
pub fn nim_to_surreal(n: u64) -> FinSurreal {
FinSurreal::new(n as i64, 0)
}
pub fn simplest_in_interval(lo: f64, hi: f64) -> Option<f64> {
if lo >= hi {
return None;
}
let ceil_lo = lo.ceil() as i64;
let floor_hi = hi.floor() as i64;
if ceil_lo <= floor_hi {
let best = if ceil_lo <= 0 && floor_hi >= 0 {
0
} else if ceil_lo > 0 {
ceil_lo
} else {
floor_hi
};
return Some(best as f64);
}
for k in 1..=53u32 {
let denom = (1u64 << k) as f64;
let lo_n = (lo * denom).floor() as i64 + 1;
let hi_n = (hi * denom).ceil() as i64 - 1;
if lo_n <= hi_n {
let n = if lo_n <= 0 && hi_n >= 0 {
0
} else if lo_n > 0 {
lo_n
} else {
hi_n
};
return Some(n as f64 / denom);
}
}
None
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_fin_surreal_zero_one() {
let zero = FinSurreal::zero();
let one = FinSurreal::one();
assert!(zero.lt(&one));
assert!(!one.lt(&zero));
assert_eq!(zero.to_f64(), 0.0);
assert_eq!(one.to_f64(), 1.0);
}
#[test]
fn test_fin_surreal_add() {
let half = FinSurreal::half();
let result = half.add(&half);
assert_eq!(result, FinSurreal::one());
let neg_one = FinSurreal::neg_one();
let sum = FinSurreal::one().add(&neg_one);
assert_eq!(sum, FinSurreal::zero());
}
#[test]
fn test_fin_surreal_mul() {
let two = FinSurreal::new(2, 0);
let three = FinSurreal::new(3, 0);
let six = two.mul(&three);
assert_eq!(six.numerator, 6);
assert_eq!(six.exp, 0);
let half = FinSurreal::half();
let result = two.mul(&half);
assert_eq!(result, FinSurreal::one());
}
#[test]
fn test_sign_expansion_zero() {
let zero = FinSurreal::zero();
let signs = zero.sign_expansion();
assert!(signs.is_empty(), "zero has empty sign expansion");
}
#[test]
fn test_sign_expansion_one() {
let one = FinSurreal::one();
let signs = one.sign_expansion();
assert!(!signs.is_empty());
assert_eq!(signs[0], Sign::Plus);
}
#[test]
fn test_nim_xor_and_p_position() {
assert_eq!(nim_xor(3, 5), 6);
assert!(nim_is_p_position(&[1, 2, 3]));
assert!(!nim_is_p_position(&[1, 2, 4]));
}
#[test]
fn test_simplest_in_interval() {
let s = simplest_in_interval(0.3, 0.7).expect("operation should succeed");
assert!((s - 0.5).abs() < 1e-10);
let s2 = simplest_in_interval(1.1, 1.9).expect("abs should succeed");
assert!((s2 - 1.5).abs() < 1e-10);
assert!(simplest_in_interval(1.0, 0.0).is_none());
}
#[test]
fn test_build_surreal_env() {
let mut env = Environment::new();
build_surreal_env(&mut env);
assert!(env.get(&Name::str("Surreal")).is_some());
assert!(env.get(&Name::str("Birthday")).is_some());
assert!(env.get(&Name::str("SurrealAdd")).is_some());
assert!(env.get(&Name::str("SignExpansion")).is_some());
assert!(env.get(&Name::str("OmnificInt")).is_some());
assert!(env.get(&Name::str("SurrealExp")).is_some());
assert!(env.get(&Name::str("NimValue")).is_some());
}
}
pub(super) fn nim_mul_internal(a: u64, b: u64) -> u64 {
if a == 0 || b == 0 {
return 0;
}
if a == 1 {
return b;
}
if b == 1 {
return a;
}
a ^ b
}