README

#symcore

CAIMEOX/symbit/symcore is the public import path for this package.

The foundational expression package for Symbit. It defines the symbolic expression tree, exact numeric leaves, callable heads, and structural traversal primitives used everywhere else in the module.

#When To Use This Package

  • Import CAIMEOX/symbit/symcore directly when your code depends on this package's subsystem-specific types or algorithms.
  • Prefer this package over the root facade when you want the focused API surface listed below rather than a convenience wrapper.

#Key Public Entry Points

  • add
  • application_args
  • application_has_name
  • application_name
  • application_parts
  • applied_parts
  • applied_undefined_function
  • apply

#Example

///|
test "symcore builds structured expressions" {
let x = Expr::Symbol("x")
let expr = add([x, int(1)])
inspect(@symprint.pretty_string(expr), content="x + 1")
}

  • CAIMEOX/symbit
  • CAIMEOX/symbit/symsimplify

#Further Reading

#
FuzzyBool

type FuzzyBool = Bool?

#
MatchEnv

type MatchEnv = Map[Expr, Expr]

Mutable linked hash map that maintains the order of insertion, not thread safe.

Example

test {
let map = { 3: "three", 8: "eight", 1: "one" }
assert_eq(map.get(2), None)
assert_eq(map.get(3), Some("three"))
map.set(3, "updated")
assert_eq(map.get(3), Some("updated"))
}

#
WildPropertyResolver

type WildPropertyResolver = (WildProperty, Expr) -> Bool?

#
ComplexFloat

pub struct ComplexFloat {
value :
RawMpc

prec : Int
} derive(Eq)

Minimal arbitrary-precision complex floating literal backed by symnum's mpmath-compatible Mpc.
impl Add for ComplexFloat
impl Mul for ComplexFloat

#
ComplexFloat::format

fn ComplexFloat::format(self : ComplexFloat, dps? : Int) -> String

#
ComplexFloat::from_exact_parts

#
ComplexFloat::from_mpc

#
ComplexFloat::from_real

fn ComplexFloat::from_real(real : Float, imag? : Float) -> ComplexFloat

#
ComplexFloat::imag_part

fn ComplexFloat::imag_part(self : ComplexFloat) -> Float

#
ComplexFloat::is_finite

fn ComplexFloat::is_finite(self : ComplexFloat) -> Bool

#
ComplexFloat::precision

fn ComplexFloat::precision(self : ComplexFloat) -> Int

#
ComplexFloat::real_part

fn ComplexFloat::real_part(self : ComplexFloat) -> Float

#
ComplexFloat::reciprocal

fn ComplexFloat::reciprocal(self : ComplexFloat) -> ComplexFloat

#
ExactNumberKind

pub(all) enum ExactNumberKind {
Zero
One
NegativeOne
Half
Integer
Rational
}

#
Expr

pub(all) enum Expr {
Number(
BigRational
)
Float(Float)
ComplexFloat(ComplexFloat)
NumberSymbol(NumberSymbolKind)
Boolean(Bool)
IdentityFunction
Symbol(String)
Dummy(String, Int)
Wild(String, Array[Expr], Array[WildProperty])
WildFunction(String, Array[Int])
FunctionHead(String)
UndefinedFunction(String)
Apply(Expr, Array[Expr])
Add(Array[Expr])
Mul(Array[Expr])
Pow(Expr, Expr)
Mod(Expr, Expr)
Tuple(Array[Expr])
Dict(Array[(Expr, Expr)])
Relational(RelOp, Expr, Expr)
Derivative(Expr, Array[Expr])
Subs(Expr, Expr, Expr)
Lambda(Expr, Expr)
Function(String, Array[Expr])
}

Core symbolic expression tree used across Symbit.

Current Limits:
  • symcore defines structure and canonical construction, not the full mathematical behavior of every subsystem.
  • textual mathematics should go through symparse rather than raw head construction.
  • several higher-level object families are easier to use through their own package front doors.
impl Add for Expr
impl BitXOr for Expr
impl Compare for Expr
impl Eq for Expr
impl Hash for Expr
impl Mul for Expr
impl Sub for Expr

#
ExprForm

pub enum ExprForm {
Number(
BigRational
)
Float(Float)
ComplexFloat(ComplexFloat)
NumberSymbol(NumberSymbolKind)
Symbol(String)
Dummy(String, Int)
Wild(String, Array[Expr], Array[WildProperty])
WildFunction(String, Array[Int])
IdentityFunction
FunctionHead(String)
UndefinedFunction(String)
Apply(Expr, Array[Expr])
Boolean(Bool)
Add(Array[Expr])
Mul(Array[Expr])
Pow(Expr, Expr)
Mod(Expr, Expr)
Tuple(Array[Expr])
Dict(Array[(Expr, Expr)])
Relational(RelOp, Expr, Expr)
Derivative(Expr, Array[Expr])
Subs(Expr, Expr, Expr)
Lambda(Expr, Expr)
}

#
Float

pub struct Float {
value :
RawMpf

prec : Int
} derive(Eq)

Minimal arbitrary-precision floating literal backed by symnum's mpmath-compatible Mpf.
impl Add for Float
impl Mul for Float
impl Neg for Float
impl Show for Float

#
Float::format

fn Float::format(self : Float, dps? : Int) -> String

Render the floating literal with a stable decimal representation.

#
Float::from_double

fn Float::from_double(value : Double, prec? : Int, rnd? :
RoundMode
) -> Float

Convert a machine Double into a core Float.

#
Float::from_exact

Convert a BigRational into a floating literal.

#
Float::from_int

fn Float::from_int(value : Int, prec? : Int) -> Float

Construct a floating literal from an integer.

#
Float::from_mpf

fn Float::from_mpf(value :
RawMpf
, prec? : Int) -> Float

Wrap an existing raw Mpf together with the precision it should carry in Symbit's core object layer.

#
Float::from_rational

Convert an exact rational into a core Float at the requested precision.

#
Float::from_str

Parse a decimal string into a core Float.

#
Float::is_finite

fn Float::is_finite(self : Float) -> Bool

True when the underlying payload is finite.

#
Float::precision

fn Float::precision(self : Float) -> Int

Return the tracked binary precision.

#
Float::reciprocal

#
Float::to_double

Convert the floating literal to a machine Double.

#
Float::to_mpf

Return the underlying raw Mpf payload.

#
Float::to_rational

Convert the floating literal back into an exact rational pair when finite.

#
Kind

pub(all) enum Kind {
NumberKind
BooleanKind
TupleKind(Array[Kind])
UndefinedKind
}

#
NumberSymbolKind

pub(all) enum NumberSymbolKind {
ImaginaryUnit
Pi
Exp1
EulerGamma
GoldenRatio
Catalan
Infinity
NegativeInfinity
ComplexInfinity
NaN
}

#
RelOp

pub(all) enum RelOp {
Eq
Ne
Lt
Le
Gt
Ge
}

#
SympifyInput

pub(all) enum SympifyInput {
FromExpr(Expr)
FromBool(Bool)
FromInt(Int)
FromRational(
BigRational
)
FromFloat(Float)
FromComplexFloat(ComplexFloat)
NumberSymbol(NumberSymbolKind)
SymbolName(String)
DummyName(String)
WildName(String)
WildSpec(String, Array[SympifyInput], Array[WildProperty])
FunctionHeadName(String)
UndefinedFunctionName(String)
Application(SympifyInput, Array[SympifyInput])
Tuple(Array[SympifyInput])
Dict(Array[(SympifyInput, SympifyInput)])
}

Typed inputs accepted by the sympify coercion entrypoint.

#
WildProperty

pub(all) enum WildProperty {
Symbol
Integer
Rational
Real
Positive
Negative
Finite
Nonzero
}

#
add

fn add(args : Array[Expr]) -> Expr

Build a symbolic sum and apply standard constructor canonicalization.

  • Does: Constructs an additive expression from child expressions.
  • Input: Array[Expr].
  • Returns: A single canonicalized Expr.
  • Limits: This is expression construction, not a full simplification pass.

test "symcore add constructs readable sums" {
let x = Expr::Symbol("x")
inspect(@symprint.pretty_string(add([x, int(1)])), content="x + 1")
}

#
application_args

fn application_args(expr : Expr) -> Array[Expr]?

#
application_has_name

fn application_has_name(expr : Expr, name : String, arity? : Int) -> Bool

#
application_name

fn application_name(expr : Expr) -> String?

#
application_parts

fn application_parts(expr : Expr) -> (Expr, Array[Expr])?

#
applied_parts

fn applied_parts(expr : Expr) -> (String, Array[Expr])?

#
applied_undefined_function

fn applied_undefined_function(name : String, args : Array[Expr]) -> Expr

#
apply

fn apply(head : Expr, args : Array[Expr]) -> Expr?

#
apply_lambda_expr

fn apply_lambda_expr(vars : Expr, body : Expr, args : Array[Expr]) -> Expr?

#
arbitrary_array_use_gen

fn[T] arbitrary_array_use_gen(bound : Int, elem_gen :
Gen
[T]) ->
Gen
[Array[T]]

#
arbitrary_polys

fn arbitrary_polys() ->
Gen
[Expr]

#
args

fn args(expr : Expr) -> Array[Expr]

#
atoms

fn atoms(expr : Expr) -> Array[Expr]

#
bool_value

fn bool_value(expr : Expr) -> Bool?

#
canonical_derivative_args

fn canonical_derivative_args(deriv_args : ArrayView[Expr]) -> Array[Expr]

#
children

fn children(expr : Expr) -> ArrayView[Expr]

#
clear_wild_property_resolver

fn clear_wild_property_resolver() -> Unit

#
common_kind

fn common_kind(kinds : Array[Kind]) -> Kind

#
compare_expr

fn compare_expr(a : Expr, b : Expr) -> Int

#
compare_expr_normalized

fn compare_expr_normalized(a : Expr, b : Expr) -> Int

#
complex_float_from_exact_parts

fn complex_float_from_exact_parts(real :
BigRational
, imag :
BigRational
, prec? : Int) -> ComplexFloat

#
current_distribute

fn current_distribute() -> Bool

#
current_evaluate

fn current_evaluate() -> Bool

#
current_exp_is_pow

fn current_exp_is_pow() -> Bool

#
derivative

fn derivative(expr : Expr, wrt : Expr, order? : Expr) -> Expr

Build a derivative expression over a variable and optional order.

  • Does: Constructs a core derivative node.
  • Input: An expression, a differentiation variable, and an optional order.
  • Returns: Expr::Derivative.
  • Limits: This front door builds the expression object only; analytical calculus routines live in higher-level packages.

#
derivative_constructor_expr

fn derivative_constructor_expr(expr : Expr, deriv_args : ArrayView[Expr]) -> Expr

#
derivative_parts

fn derivative_parts(expr : Expr) -> (Expr, Array[Expr])?

#
derivative_signature_error

fn derivative_signature_error(deriv_args : ArrayView[Expr]) -> String?

#
dict_items

fn dict_items(expr : Expr) -> Array[(Expr, Expr)]?

#
dummy

fn dummy(name? : String) -> Expr

#
dummy_display_name

fn dummy_display_name(name : String) -> String

#
dummy_parts

fn dummy_parts(expr : Expr) -> (String, Int)?

#
evalf

fn evalf(expr : Expr, prec? : Int) -> Expr

Evaluate exact numeric leaves and common transcendental constants/functions into Expr::Float or Expr::ComplexFloat at the requested precision.

#
exact_number_head_name

fn exact_number_head_name(kind : ExactNumberKind) -> String

#
exact_number_kind

fn exact_number_kind(expr : Expr) -> ExactNumberKind?

#
exact_number_num_den

#
exact_numeric_expr_num_den

#
expr_display

fn expr_display(expr : Expr) -> String

#
expr_form

fn expr_form(expr : Expr) -> ExprForm

Expose the structural view of an expression.

  • Does: Converts Expr into its public structural discriminator.
  • Input: Any Expr.
  • Returns: An ExprForm.
  • Limits: This is for branching and inspection, not a stable serialization format.

#
expr_kind

fn expr_kind(expr : Expr) -> Kind

#
expr_match

fn expr_match(pattern : Expr, expr : Expr, repl_dict? : Map[Expr, Expr]) -> Map[Expr, Expr]?

#
float_from_double

fn float_from_double(value : Double, prec? : Int, rnd? :
RoundMode
) -> Float

Top-level convenience wrapper from Double.

#
float_from_exact

Top-level convenience wrapper from an exact rational.

#
float_from_str

Top-level convenience wrapper matching the rest of symcore.

#
free_symbols

fn free_symbols(expr : Expr) -> Array[Expr]

Collect the free symbolic variables occurring in an expression.

  • Does: Walks an expression and extracts its free symbols.
  • Input: Any Expr.
  • Returns: Array[Expr], typically containing Expr::Symbol items.
  • Limits: The order is canonicalized rather than source-order oriented.

#
func

fn func(expr : Expr) -> Expr?

#
function

fn function(name : String, args : Array[Expr]) -> Expr

Build a named symbolic function application.

  • Does: Constructs expressions such as sin(x), log(x), or f(x).
  • Input: A function name String and Array[Expr] arguments.
  • Returns: A single application Expr.
  • Limits: The head name is taken literally; this front door does not parse textual mathematics.

test "symcore function builds named applications" {
let x = Expr::Symbol("x")
inspect(@symprint.pretty_string(function("sin", [x])), content="sin(x)")
}

#
function_head_name

fn function_head_name(expr : Expr) -> String?

#
fuzzy_and

fn fuzzy_and(args : Array[Bool?]) -> Bool?

#
fuzzy_bool

fn fuzzy_bool(value : Bool?) -> Bool?

#
fuzzy_group

fn fuzzy_group(args : Array[Bool?], quick_exit? : Bool) -> Bool?

#
fuzzy_nand

fn fuzzy_nand(args : Array[Bool?]) -> Bool?

#
fuzzy_not

fn fuzzy_not(value : Bool?) -> Bool?

#
fuzzy_or

fn fuzzy_or(args : Array[Bool?]) -> Bool?

#
fuzzy_xor

fn fuzzy_xor(args : Array[Bool?]) -> Bool?

#
has

fn has(expr : Expr, needle : Expr) -> Bool

#
hash_expr_normalized

fn hash_expr_normalized(expr : Expr) -> Int

#
head_name

fn head_name(expr : Expr) -> String

#
int

fn int(value : Int) -> Expr

Build an exact integer atom.

  • Does: Creates a number expression representing an exact integer.
  • Input: A MoonBit Int.
  • Returns: Expr::Number.
  • Limits: This front door accepts machine-sized Int input only.

test "symcore int builds an exact integer expression" {
inspect(@symprint.pretty_string(int(3)), content="3")
}

#
is_application

fn is_application(expr : Expr) -> Bool

#
is_atomic

fn is_atomic(expr : Expr) -> Bool

#
is_complex_number_atom

fn is_complex_number_atom(expr : Expr) -> Bool

#
is_false

fn is_false(expr : Expr) -> Bool

#
is_finite_number_atom

fn is_finite_number_atom(expr : Expr) -> Bool

#
is_function_head

fn is_function_head(expr : Expr) -> Bool

#
is_infinite

fn is_infinite(expr : Expr) -> Bool

#
is_nan

fn is_nan(expr : Expr) -> Bool

#
is_number_atom

fn is_number_atom(expr : Expr) -> Bool

#
is_number_symbol

fn is_number_symbol(expr : Expr) -> Bool

#
is_one

fn is_one(expr : Expr) -> Bool

#
is_real_number_atom

fn is_real_number_atom(expr : Expr) -> Bool

#
is_singleton_expr

fn is_singleton_expr(expr : Expr) -> Bool

#
is_true

fn is_true(expr : Expr) -> Bool

#
is_zero

fn is_zero(expr : Expr) -> Bool

#
kind_name

fn kind_name(kind : Kind) -> String

#
lambda_arity

fn lambda_arity(vars : Expr) -> Int?

#
lambda_expr

fn lambda_expr(vars : Expr, body : Expr) -> Expr

#
lambda_parts

fn lambda_parts(expr : Expr) -> (Expr, Expr)?

#
lambda_signature_error

fn lambda_signature_error(vars : Expr) -> String?

#
map_children

fn map_children(expr : Expr, f : (Expr) -> Expr) -> Expr

#
mod_expr

fn mod_expr(lhs : Expr, rhs : Expr) -> Expr

#
mul

fn mul(args : Array[Expr]) -> Expr

Build a symbolic product and apply standard constructor canonicalization.

  • Does: Constructs a multiplicative expression from child expressions.
  • Input: Array[Expr].
  • Returns: A single canonicalized Expr.
  • Limits: It does not replace targeted simplifiers such as rational or trigonometric normalization.

#
normalize_legacy_expr

fn normalize_legacy_expr(expr : Expr) -> Expr

#
number_symbol_kind

fn number_symbol_kind(expr : Expr) -> NumberSymbolKind?

#
number_symbol_kind_from_name

fn number_symbol_kind_from_name(name : String) -> NumberSymbolKind?

#
number_symbol_name

fn number_symbol_name(kind : NumberSymbolKind) -> String

#
postorder

fn postorder(expr : Expr) -> Array[Expr]

#
pow

fn pow(base : Expr, exp : Expr) -> Expr

Build a symbolic power expression.

  • Does: Constructs base**exp using the core power front door.
  • Input: A base Expr and an exponent Expr.
  • Returns: A single Expr.
  • Limits: Advanced algebraic normalization lives in higher-level packages.

#
preorder

fn preorder(expr : Expr) -> Array[Expr]

#
rational_from_ints

fn rational_from_ints(num : Int, den : Int) -> Expr raise
RationalError

Build an exact rational atom from a numerator and denominator.

  • Does: Creates a rational expression with exact arithmetic.
  • Input: Two MoonBit Int values.
  • Returns: Expr::Number.
  • Limits: Raises @symnum.RationalError when the denominator is zero.

#
raw_add

fn raw_add(args : Array[Expr]) -> Expr

Build Add directly without flattening, sorting, or constant folding.

#
raw_apply

fn raw_apply(head : Expr, args : Array[Expr]) -> Expr?

#
raw_derivative

fn raw_derivative(expr : Expr, deriv_args : ArrayView[Expr]) -> Expr

#
raw_dict_expr

fn raw_dict_expr(items : Array[(Expr, Expr)]) -> Expr

#
raw_function

fn raw_function(name : String, args : Array[Expr]) -> Expr

#
raw_mod_expr

fn raw_mod_expr(lhs : Expr, rhs : Expr) -> Expr

#
raw_mul

fn raw_mul(args : Array[Expr]) -> Expr

#
raw_pow

fn raw_pow(base : Expr, exp : Expr) -> Expr

#
rebuild_application

fn rebuild_application(expr : Expr, args : Array[Expr]) -> Expr?

#
relational_parts

fn relational_parts(expr : Expr) -> (RelOp, Expr, Expr)?

#
replace

fn replace(expr : Expr, query : (Expr) -> Bool, value : (Expr) -> Expr) -> Expr

fn s(input : SympifyInput) -> Expr

#
set_wild_property_resolver

fn set_wild_property_resolver(resolver : (WildProperty, Expr) -> Bool?) -> Unit

#
singleton_expr_by_name

fn singleton_expr_by_name(name : String) -> Expr?

#
singleton_head

fn singleton_head(expr : Expr) -> Expr?

#
singleton_instance_name

fn singleton_instance_name(expr : Expr) -> String?

#
sort_exprs_in_place

fn sort_exprs_in_place(args : Array[Expr]) -> Unit

#
sorted_dict_entries

fn sorted_dict_entries(items : Array[(Expr, Expr)]) -> Array[(Expr, Expr)]

#
standalone_function_head_display_name

fn standalone_function_head_display_name(name : String) -> String

#
subs_expr

fn subs_expr(expr : Expr, variable : Expr, value : Expr) -> Expr

Build or extend a structural substitution expression.

  • Does: Replaces one exact subexpression with another exact subexpression.
  • Input: The target expression, the variable expression, and the replacement expression.
  • Returns: A rewritten Expr, often a Subs node.
  • Limits: Matching is structural; it does not perform algebraic equivalence matching.

test "symcore subs_expr performs structural replacement" {
let x = Expr::Symbol("x")
let expr = add([x, int(1)])
inspect(
@symprint.pretty_string(subs_expr(expr, x, int(3))),
content="Subs(x + 1, x, 3)",
)
}

#
subs_parts

fn subs_parts(expr : Expr) -> (Expr, Expr, Expr)?

#
subs_signature_error

fn subs_signature_error(variable : Expr, value : Expr) -> String?

#
subst

fn subst(expr : Expr, env : Map[String, Expr]) -> Expr

#
sympify

fn sympify(input : SympifyInput) -> Expr

Convert a typed value into a core symbolic expression.

  • Does: Lifts a supported host-side input into Expr.
  • Input: A SympifyInput.
  • Returns: A single Expr.
  • Limits: This is typed lifting, not full textual parsing; text parsing belongs in symparse.

test "symcore sympify lifts typed inputs into expr" {
let expr = sympify(
SympifyInput::Tuple([
SympifyInput::FromInt(1),
SympifyInput::SymbolName("x"),
]),
)
inspect(@symprint.pretty_string(expr), content="(1, x)")
}

#
sympify_dict

fn sympify_dict(items : Array[(SympifyInput, SympifyInput)]) -> Expr

Lift dictionary-like key/value pairs into a first-class core dict node.

#
sympify_name

fn sympify_name(name : String) -> Expr

Treat a string as a symbolic name and lift it into Expr.

#
sympify_tuple

fn sympify_tuple(items : Array[SympifyInput]) -> Expr

Lift a tuple payload into a first-class core tuple node.

#
torf

fn torf(args : Array[Bool?]) -> Bool?

#
tuple_items

fn tuple_items(expr : Expr) -> Array[Expr]?

#
undefined_application_parts

fn undefined_application_parts(expr : Expr) -> (String, Array[Expr])?

#
wild_display_name

fn wild_display_name(name : String) -> String

#
wild_function_matches

fn wild_function_matches(pattern : Expr, expr : Expr, repl_dict? : Map[Expr, Expr]) -> Map[Expr, Expr]?

#
wild_function_parts

fn wild_function_parts(expr : Expr) -> (String, Array[Int])?

#
wild_matches

fn wild_matches(pattern : Expr, expr : Expr, repl_dict? : Map[Expr, Expr]) -> Map[Expr, Expr]?

#
wild_name

fn wild_name(expr : Expr) -> String?

#
wild_parts

fn wild_parts(expr : Expr) -> (String, Array[Expr], Array[WildProperty])?

#
wild_property_name

fn wild_property_name(property : WildProperty) -> String

#
with_distribute

fn[T] with_distribute(value : Bool, thunk : () -> T) -> T

#
with_distribute_raise

fn[T] with_distribute_raise(value : Bool, thunk : () -> T raise) -> T raise

#
with_evaluate

fn[T] with_evaluate(value : Bool, thunk : () -> T) -> T

#
with_evaluate_raise

fn[T] with_evaluate_raise(value : Bool, thunk : () -> T raise) -> T raise

#
with_exp_is_pow

fn[T] with_exp_is_pow(value : Bool, thunk : () -> T) -> T

#
with_exp_is_pow_raise

fn[T] with_exp_is_pow_raise(value : Bool, thunk : () -> T raise) -> T raise

#
xreplace

fn xreplace(expr : Expr, rules : Array[(Expr, Expr)]) -> Expr