SCM Foundations¶
Signed Common Meadows (SCM) provide a totalised arithmetic with a single absorptive bottom value (⊥). This library implements SCM semantics for machine learning workflows.
Algebraic Rules¶
- Total inverse: every element has an inverse;
0^{-1} = ⊥. - Absorption:
x + ⊥ = ⊥andx · ⊥ = ⊥for allx. - Weak sign:
s(x) = x/|x|for finite nonzero inputs,0at the origin,⊥when the argument is ⊥. For complex values, weak sign projects finite nonzero payloads to the unit circle and returns bottom unchanged; it is not a contract that IEEE+inf/-infdecoded payloads are valid orientation carriers. - History-aware sign:
HystereticOrientationTrackeris an engineering state machine, not an algebraic sign operation. It validates finite, non-negativeepsilonandhysteresis, plus a finite unit-magnitude prior orientation.weak_sign(value)remains the pure projection;weak_sign(value, state)is a deprecated compatibility adapter.
Practical Implications¶
- Scalar SCM ops (
zeroproofml.scm.value,zeroproofml.scm.ops) returnSCMValue(⊥)on division-by-zero / domain errors instead of IEEENaN/Inf. Since v0.6.1,SCMValue.__post_init__also refuses non-finite payloads at construction (raisesValueError), and finite-op-finite arithmetic that produces a non-finite result raisesOverflowError— numerical faults are not silently reclassified as algebraic bottom. Route non-finite IEEE inputs through the named boundaryzeroproofml.utils.ieee_bridge.from_ieee(...), which mapsNaN/±Infto⊥explicitly. - For arrays/tensors, SCM values are represented as a numeric payload + bottom mask. The mask is authoritative; payload values on masked entries are undefined and must be ignored (use strict decoding to map them to
NaNif you need an IEEE sentinel). - No layer-by-layer “guard mode” is required: singularity handling is pushed to explicit masks and a single decode at the output boundary.
- Numerical stability is handled by gradient policies and (optionally) projective tuples, rather than ad-hoc forward clamps.
Exact assertions versus machine observations¶
SCMValue, scm_real, and scm_complex are retained legacy exact-assertion
carriers. Prefer the explicit spellings scm_assert_exact_real and
scm_assert_exact_complex when that contract matters. A zero asserted there
is exact and division produces algebraic bottom.
SemanticResult and ResultTensor are the evidence-bearing typed APIs. The
Python type or spelling of 0 never proves exactness there. An uncertified
integer or floating zero is a machine-zero observation and division yields
ambiguous rejected NO_CORE; semantic bottom requires
ExactZeroEvidence.PROVEN_ZERO plus a certificate. SCMValue.value stores
None for bottom, not a numeric sentinel.
Exact SCM vs Finite IEEE Execution¶
The ideal SCM algebra is total: algebraic bottom is the single result for exact singularities and bottom absorbs every later SCM operation. v0.6.1 keeps that semantic model, but it does not pretend that every finite-machine event is the same mathematical event. The public runtime contracts are:
| Surface | Becomes ⊥ / mask |
Refused | v0.6.1 scope limits |
|---|---|---|---|
Scalar SCMValue and scalar ops |
Existing bottom, division by zero, inverse of zero, real log(x <= 0), real sqrt(x < 0), zero to negative power, complex log(0), and explicit from_ieee(NaN/±Inf) boundary imports |
Direct non-finite SCMValue(...) construction raises ValueError; finite scalar arithmetic that overflows or otherwise produces non-finite payload raises OverflowError |
Complex scalar payloads are supported when both real and imaginary components are finite; scalar scm_pow accepts a real exponent |
| Vectorized NumPy / Torch / JAX ops | Incoming masks, non-finite inputs, zero/inverse-zero division, unsupported real pow / log / sqrt domains, and backend NaN / ±Inf results from finite IEEE execution are folded into the returned mask; masked payload entries are finite zero placeholders |
Passing masks both positionally and by keyword raises TypeError; complex vector pow exponents raise TypeError |
Complex vector log / sqrt / pow are supported where tested only with real exponents; NumPy integer reciprocal promotes to floating output |
SCMRationalLayer training/autograd |
Non-finite inputs, overflowed basis features, non-finite numerator/denominator values, denominator singularities, and finite-over-finite quotient overflow are folded into bottom_mask; bottom payload entries are 0.0 placeholders |
Complex inputs or complex parameters raise TypeError; singular_epsilon must be finite and non-negative |
Training/autograd is real-valued only in v0.6.1; projective typed decoding is also real-only, while complex unit phase is a separate API |
| Strict inference decoders | Exact-zero or below-threshold finite denominators route to semantic_bottom_mask; non-finite operands or decoded quotients route to fault_mask; bottom_mask is their union |
Invalid tau_infer / tau_train values and positive thresholds that narrow to zero in the backend dtype are refused before prediction |
Eager Torch / NumPy / JAX decoders cover float and complex denominator dtypes through the configured real component dtype; richer typed-fault taxonomies are deferred beyond v0.6.1 |
No stable vector API has been demoted for v0.6.1: the stable helper names
remain supported with the limits above. The deliberately unsupported path is
complex vector pow with complex exponents, which is refused instead of being
published as fail-closed.
Fracterm Flattening¶
For rational heads we exploit fracterm flattening: small rational subgraphs are rewritten as P(x) / Q(x) to reduce singularity checks to the final denominator. Depth is capped (L ≤ 5) to avoid polynomial blow-up; with the current FRU bound table that already permits at most a 16 * d degree multiplier on the seed head, where d = max(d_p, d_q). The current implementation supports constants, variables, sparse polynomial numerators/denominators, and shallow expressions composed with +, *, and /; larger or unsupported graphs should be left on the projective path instead of being flattened. The detailed inventory and refusal criteria live in theory/01_fracterm_flattening.md. In practice, training stays on the projective/tuple path and flattening is run after training for audit/export validation rather than inside the per-step optimization loop.
Common-meadow identities such as x/x = 1 + 0/x and 1/(1/x) = x + 0/x explain why naive cancellation fails in strict SCM: canceling them to bare 1 or x erases the bottom at x = 0. Treat those identities as semantic test anchors, not necessarily as the canonical strict normal forms emitted by the simplifier; strict flattening may use any representation that keeps the singular assignment bottom under the required nonzero contract.
Explicit field_rational flattening keeps the ordinary field quotient rule (a/b)/(u/v) = av/(bu). Strict SCM flattening instead keeps the divisor denominator as a bottom-producing factor, so callers must opt in to field_rational only when ordinary field algebra is the intended contract.
Terminology¶
- Bottom (⊥): absorptive error element; any operation involving ⊥ yields ⊥.
- Projective tuple: pair
(N, D)representing the same value asN/Dwith(1, 0)denoting ⊥. - Coverage: fraction of predictions that remain finite (non-⊥) under SCM semantics.