arithmetic

Arithmetic capability traits and checked analytic operations for LunaFlow numeric types, with default real-valued instances.

math
arithmetic
elementary-functions
moon add Luna-Flow/arithmetic@0.5.0
Download zip
Author
Version
0.5.0
License
Apache-2.0
Last updated
25 days ago
Downloads
490
README

#Arithmetic

Arithmetic capability traits and checked or contextual numeric boundaries for Luna Flow projects.

#v0.4.0 - Certified Evaluation Failures

This README matches the v0.4.0 repository state. The release adds a structured failure boundary for proof-backed numerical evaluation while retaining the contextual outcomes, diagnostics, and checked capability surface introduced in 0.3.0.

For earlier release notes and repository history, see CHANGELOG.md.

#Release Notes

  • CertificationStage records the proof step that could not establish a result: range reduction, series evaluation, enclosure propagation, or target rounding.
  • CertificationFailureReason distinguishes an uncertified range, missing convergence, invalid enclosure, resource limit, and exhausted refinement budget.
  • CertificationFailureDetail retains the operation, requested and working precision, and the number of refinement attempts.
  • ArithmeticErrorKind::CertificationFailure and ArithmeticError::certification_failure preserve that detail without flattening it into an unstructured message.

#Package Positioning

  • luna-generic expresses algebraic structure such as Ring, Field, and Num.
  • arithmetic expresses analytic functions, checked operations, contextual outcomes, and enclosure-style relations.
  • The package describes small capabilities rather than declaring a bundled “real number” abstraction.
  • Concrete numeric packages should implement only the traits whose semantics they can support faithfully.

#Capability Layers

#Unchecked Elementary Traits

  • Sqrt, Cbrt, Radical
  • Exponential, Logarithmic, Power
  • Trigonometric, InverseTrigonometric
  • Hyperbolic, InverseHyperbolic
  • Constants

These traits preserve direct backend behavior and return Self.

#Checked Traits

  • SqrtChecked, DivChecked, CompareChecked
  • PowNatChecked, PowIntChecked, ParseChecked

Checked traits return Result[..., ArithmeticError] and use ArithmeticContext where the operation needs an explicit context. ArithmeticError can also carry a CertificationFailureDetail when a proof-backed backend cannot certify a result at the requested target.

#Contextual Outcome Traits

  • AddContextual, SubContextual, MulContextual, DivContextual
  • AbsContextual, SqrtContextual, ExpContextual
  • NumericFormatContextual

Contextual operations return ArithmeticOutcome[Self] inside Result, keeping the computed value and diagnostic flags together as immutable data.

#Enclosure Relations

  • Contains, Overlaps
  • DefinitelyLt, DefinitelyLe, MaybeEq

These traits model containment and definite or possible relations without pretending enclosure values form a scalar total order.

#Context Contract

  • ArithmeticContext::new clamps precision to at least 1.
  • If both exponent limits are present, e_min must not exceed e_max.
  • The decimal presets use precisions 7, 16, and 34 with their matching exponent ranges and clamping enabled.
  • ArithmeticDiagnostics::combine merges flags with logical OR, so callers can aggregate a sequence of outcomes explicitly.

The built-in Float and Double contextual implementations do not emulate arbitrary decimal precision, directed rounding, exponent clamping, or IEEE status-flag detection. They currently return exact diagnostics for successful native operations; contextual division and square root delegate validation to their checked counterparts. The richer context and diagnostics are public capability boundaries for numeric backends that can implement those semantics.

#Installation

moon add Luna-Flow/arithmetic@0.4.0 moon add Luna-Flow/luna-generic@0.3.1

Use explicit Luna Flow aliases in moon.pkg:

import {
"Luna-Flow/luna-generic" @lf_alg,
"Luna-Flow/arithmetic" @lf_arith,
}

#Quick Start

using @lf_alg { trait Add, trait Mul }
using @lf_arith { trait Sqrt }

fn hypot2[T : Add + Mul + Sqrt](x : T, y : T) -> T {
Sqrt::sqrt(x * x + y * y)
}

let context = @lf_arith.ArithmeticContext::decimal64()
let outcome = @lf_arith.DivContextual::div_contextual(10.0, 4.0, context).unwrap()
inspect(outcome.value, content="2.5")
inspect(outcome.diagnostics.inexact, content="false")

#Documentation

#Changelog

Historical release notes live in CHANGELOG.md. This README stays focused on the current package baseline and entry points.

#Development

Useful local commands:

moon fmt moon info moon check --target all moon test

#Release Checklist

  1. Bump moon.mod to the intended release version.
  2. Update README.md, all three localized documentation trees, and CHANGELOG.md.
  3. Run moon fmt --check, moon info, moon build --target all, moon check --target all --frozen, and the default, JavaScript, and native test suites.
  4. Trigger publish-package with the exact moon.mod version. The workflow repeats the checks, publishes to mooncakes, and creates the matching GitHub release.

The workflow publishes the version declared in moon.mod to mooncakes; it does not accept a mismatched release version.

#
AbsContextual

pub(open) trait AbsContextual {
fn abs_contextual(Self, ArithmeticContext) -> Result[ArithmeticOutcome[Self], ArithmeticError]
}

#
AddContextual

pub(open) trait AddContextual {
fn add_contextual(Self, Self, ArithmeticContext) -> Result[ArithmeticOutcome[Self], ArithmeticError]
}

#
Cbrt

pub(open) trait Cbrt {
fn cbrt(Self) -> Self
}

impl Cbrt for Float
impl Cbrt for Double

#
CompareChecked

pub(open) trait CompareChecked {
fn compare_checked(Self, Self) -> Result[Int, ArithmeticError]
}

#
Constants

pub(open) trait Constants {
fn pi() -> Self
fn tau() -> Self
fn e() -> Self
}

impl Constants for Float
impl Constants for Double

#
Contains

pub(open) trait Contains {
fn contains(Self, Self) -> Bool
}

#
DefinitelyLe

pub(open) trait DefinitelyLe {
fn definitely_le(Self, Self) -> Bool
}

#
DefinitelyLt

pub(open) trait DefinitelyLt {
fn definitely_lt(Self, Self) -> Bool
}

#
DivChecked

pub(open) trait DivChecked {
fn div_checked(Self, Self, ArithmeticContext) -> Result[Self, ArithmeticError]
}

impl DivChecked for Float

#
DivContextual

pub(open) trait DivContextual {
fn div_contextual(Self, Self, ArithmeticContext) -> Result[ArithmeticOutcome[Self], ArithmeticError]
}

#
ExpContextual

pub(open) trait ExpContextual {
fn exp_contextual(Self, ArithmeticContext) -> Result[ArithmeticOutcome[Self], ArithmeticError]
}

#
Exponential

pub(open) trait Exponential {
fn exp(Self) -> Self
fn exp2(Self) -> Self
}

#
Hyperbolic

pub(open) trait Hyperbolic {
fn sinh(Self) -> Self
fn cosh(Self) -> Self
fn tanh(Self) -> Self
}

impl Hyperbolic for Float

#
InverseHyperbolic

pub(open) trait InverseHyperbolic {
fn asinh(Self) -> Self
fn acosh(Self) -> Self
fn atanh(Self) -> Self
}

#
InverseTrigonometric

pub(open) trait InverseTrigonometric {
fn asin(Self) -> Self
fn acos(Self) -> Self
fn atan(Self) -> Self
fn atan2(Self, Self) -> Self
}

#
Logarithmic

pub(open) trait Logarithmic {
fn ln(Self) -> Self
fn log2(Self) -> Self
fn log10(Self) -> Self
}

#
MaybeEq

pub(open) trait MaybeEq {
fn maybe_eq(Self, Self) -> Bool
}

#
MulContextual

pub(open) trait MulContextual {
fn mul_contextual(Self, Self, ArithmeticContext) -> Result[ArithmeticOutcome[Self], ArithmeticError]
}

#
NumericFormatContextual

pub(open) trait NumericFormatContextual {
fn zero_contextual(ArithmeticContext) -> Self
fn one_contextual(ArithmeticContext) -> Self
fn epsilon_contextual(ArithmeticContext) -> Self
fn min_normal_contextual(ArithmeticContext) -> Self
fn max_finite_contextual(ArithmeticContext) -> Self
fn classify_contextual(Self) -> FpClass
}

#
Overlaps

pub(open) trait Overlaps {
fn overlaps(Self, Self) -> Bool
}

#
ParseChecked

pub(open) trait ParseChecked {
fn parse_checked(String, ArithmeticContext) -> Result[Self, ArithmeticError]
}

#
PowIntChecked

pub(open) trait PowIntChecked {
fn pow_int_checked(Self, Int, ArithmeticContext) -> Result[Self, ArithmeticError]
}

#
PowNatChecked

pub(open) trait PowNatChecked {
fn pow_nat_checked(Self, UInt, ArithmeticContext) -> Result[Self, ArithmeticError]
}

#
Power

pub(open) trait Power {
fn pow(Self, Self) -> Self
}

impl Power for Int
impl Power for Int16
impl Power for Int64
impl Power for UInt
impl Power for UInt16
impl Power for UInt64
impl Power for Float
impl Power for Double

#
Radical

pub(open) trait Radical : Sqrt + Cbrt {
}

impl Radical for Float
impl Radical for Double

#
Sqrt

pub(open) trait Sqrt {
fn sqrt(Self) -> Self
}

impl Sqrt for Float
impl Sqrt for Double

#
SqrtChecked

pub(open) trait SqrtChecked {
fn sqrt_checked(Self, ArithmeticContext) -> Result[Self, ArithmeticError]
}

#
SqrtContextual

pub(open) trait SqrtContextual {
fn sqrt_contextual(Self, ArithmeticContext) -> Result[ArithmeticOutcome[Self], ArithmeticError]
}

#
SubContextual

pub(open) trait SubContextual {
fn sub_contextual(Self, Self, ArithmeticContext) -> Result[ArithmeticOutcome[Self], ArithmeticError]
}

#
Trigonometric

pub(open) trait Trigonometric {
fn sin(Self) -> Self
fn cos(Self) -> Self
fn tan(Self) -> Self
}

#
ArithmeticContext

pub struct ArithmeticContext {
precision : Int
rounding : RoundingMode
e_min : Int?
e_max : Int?
clamp : Bool
} derive(Eq)

#
ArithmeticContext::decimal128

#
ArithmeticContext::decimal32

#
ArithmeticContext::decimal64

#
ArithmeticContext::new

fn ArithmeticContext::new(precision : Int, rounding? : RoundingMode, e_min? : Int, e_max? : Int, clamp? : Bool) -> ArithmeticContext

#
ArithmeticDiagnostics

pub struct ArithmeticDiagnostics {
inexact : Bool
rounded : Bool
overflow : Bool
underflow : Bool
subnormal : Bool
clamped : Bool
} derive(Eq,
Debug
)

#
ArithmeticDiagnostics::combine

#
ArithmeticDiagnostics::empty

#
ArithmeticDiagnostics::new

fn ArithmeticDiagnostics::new(inexact? : Bool, rounded? : Bool, overflow? : Bool, underflow? : Bool, subnormal? : Bool, clamped? : Bool) -> ArithmeticDiagnostics

#
ArithmeticError

pub struct ArithmeticError {
kind : ArithmeticErrorKind
message : String
} derive(Eq)

#
ArithmeticError::certification_failure

fn ArithmeticError::certification_failure(detail : CertificationFailureDetail) -> ArithmeticError

#
ArithmeticError::certification_failure_detail

fn ArithmeticError::certification_failure_detail(self : ArithmeticError) -> CertificationFailureDetail?

#
ArithmeticError::division_by_zero

fn ArithmeticError::division_by_zero(message : String) -> ArithmeticError

#
ArithmeticError::domain_error

fn ArithmeticError::domain_error(message : String) -> ArithmeticError

#
ArithmeticError::format_error

fn ArithmeticError::format_error(message : String) -> ArithmeticError

#
ArithmeticError::is_certification_failure

fn ArithmeticError::is_certification_failure(self : ArithmeticError) -> Bool

#
ArithmeticError::is_division_by_zero

fn ArithmeticError::is_division_by_zero(self : ArithmeticError) -> Bool

#
ArithmeticError::is_domain_error

fn ArithmeticError::is_domain_error(self : ArithmeticError) -> Bool

#
ArithmeticError::is_format_error

fn ArithmeticError::is_format_error(self : ArithmeticError) -> Bool

#
ArithmeticError::is_parse_error

fn ArithmeticError::is_parse_error(self : ArithmeticError) -> Bool

#
ArithmeticError::is_unordered_comparison

fn ArithmeticError::is_unordered_comparison(self : ArithmeticError) -> Bool

#
ArithmeticError::is_unsupported

fn ArithmeticError::is_unsupported(self : ArithmeticError) -> Bool

#
ArithmeticError::parse_error

fn ArithmeticError::parse_error(message : String) -> ArithmeticError

#
ArithmeticError::unordered_comparison

fn ArithmeticError::unordered_comparison(message : String) -> ArithmeticError

#
ArithmeticError::unsupported

fn ArithmeticError::unsupported(message : String) -> ArithmeticError

#
ArithmeticErrorKind

pub enum ArithmeticErrorKind {
DivisionByZero
ParseError
DomainError
FormatError
UnsupportedOperation
UnorderedComparison
CertificationFailure(CertificationFailureDetail)
} derive(Eq)

#
ArithmeticOutcome

pub struct ArithmeticOutcome[T] {
value : T
diagnostics : ArithmeticDiagnostics
} derive(Eq,
Debug
)

#
ArithmeticOutcome::exact

fn[T] ArithmeticOutcome::exact(value : T) -> ArithmeticOutcome[T]

#
ArithmeticOutcome::with_diagnostics

fn[T] ArithmeticOutcome::with_diagnostics(value : T, diagnostics : ArithmeticDiagnostics) -> ArithmeticOutcome[T]

#
CertificationFailureDetail

pub struct CertificationFailureDetail {
operation : String
stage : CertificationStage
reason : CertificationFailureReason
target_precision : Int
work_precision : Int
refinements : Int
} derive(Eq)

#
CertificationFailureDetail::new

fn CertificationFailureDetail::new(operation : String, stage : CertificationStage, reason : CertificationFailureReason, target_precision : Int, work_precision : Int, refinements : Int) -> CertificationFailureDetail

#
CertificationFailureDetail::operation

#
CertificationFailureDetail::reason

#
CertificationFailureDetail::refinements

#
CertificationFailureDetail::stage

#
CertificationFailureDetail::target_precision

fn CertificationFailureDetail::target_precision(self : CertificationFailureDetail) -> Int

#
CertificationFailureDetail::work_precision

fn CertificationFailureDetail::work_precision(self : CertificationFailureDetail) -> Int

#
CertificationFailureReason

pub(all) enum CertificationFailureReason {
RangeNotCertified
SeriesDidNotConverge
InvalidEnclosure
ResourceLimit
RefinementBudgetExhausted
} derive(Eq)

#
CertificationStage

pub(all) enum CertificationStage {
RangeReduction
SeriesEvaluation
EnclosurePropagation
TargetRounding
} derive(Eq)

#
FpClass

pub(all) enum FpClass {
Finite
Infinity
NaN
} derive(Eq,
Debug
)

#
RoundingMode

pub(all) enum RoundingMode {
ToNearestEven
TowardZero
TowardPositive
TowardNegative
AwayFromZero
} derive(Eq)