eml-complex-smuggle-audit.md
EML complex-smuggle audit — VA00/SymbolicRegressionPackage
Auditor: Craig (archivist / Dr CSW polymath seat)
Date: 2026-04-20
Requested by: Jonny (eml programme — Gate α pre-work)
Target: github.com/VA00/SymbolicRegressionPackage @ master (cloned 2026-04-20T17:35Z)
Paper under audit: arXiv:2603.21852, Odrzywolek, Jagiellonian — "eml(x,y) = exp(x) − ln(y) as a universal generator for elementary functions" (PNAS submission)
Question asked: Do the reference implementation's "exact sin/cos/Pi/I" recoveries rely on intermediate eml(x, y≤0) evaluations that silently yield complex values via ln(negative)? If so, which claims collapse?
Verdict
SMUGGLE FOUND. Pervasive. Every claimed recovery of a non-Liouvillian target (sin, cos, tan, arc-trig, π, i) runs on complex principal-log arithmetic. No real-valued path in the repository generates any of these functions exactly or approximately. The real (f32/f64) paths explicitly filter ln(negative) → NaN and discard those candidates.
The paper's "every elementary function" claim, if advertised as reachable by finite real-valued eml trees, is false-by-construction in its own reference code. What the code does demonstrate is a modest, honest result: eml + {1} generates the Liouvillian closure exactly, via real arithmetic.
This is consistent with Euler's Wilkie o-minimal proof (debate entry 7, ratified entry 24) — the empirical behaviour of the reference implementation matches the theoretical impossibility.
Evidence — five independent paths, all complex
1. Compiler (EML_toolkit/EmL_compiler/eml_compiler_v4.py)
The compiler emits closed-form eml trees for symbolic targets. Its definitions of i and π are hardcoded and both require ln(−1):
def eml_const_I():
minus_one = eml_neg("1")
two = eml_int(2)
return eml_neg(eml_exp(eml_div(eml_log(minus_one), two))) # i = −exp(ln(−1)/2)
def eml_const_Pi():
i_eml = eml_const_I()
log_minus1 = eml_log(eml_neg("1"))
return eml_mul(i_eml, log_minus1) # π = i · ln(−1)
— eml_compiler_v4.py:50–62.
Inverse trig is routed through complex logarithmic identities:
def ASIN_LOG(z): return I*log(-I*z + sqrt(1 - z**2))
def ACOS_LOG(z): return I*log(z + sqrt(z - 1)*sqrt(z + 1))
def ATAN_LOG(z): return (-I/2)*log((-I + z)/(-I - z))
— eml_compiler_v4.py:80–82.
Any sin/cos target that enters normalize_to_exp_log() gets sympy.rewrite(exp)-ed to −I·(exp(Ix) − exp(−Ix))/2, which pulls in I, which pulls in ln(−1). There is no alternative branch.
2. PyTorch trainer (EML_toolkit/EmL_training/PyTorch_v16_final/tree_prototype_torch_v16_final.py)
Line 34, module scope:
DTYPE = torch.complex128
REAL_DTYPE = torch.float64
The entire forward pass runs in torch.complex128. "Real-valued eml tree" is not a thing in this trainer; every intermediate is complex. The depth-5/6 failure statistics in the README (30/64 and 56/64 "NaN restarts") are consistent with branch-cut / dynamic-range blowup under complex arithmetic, not with real-domain unreachability.
Scope note: the PyTorch sweep targets are _target_eml_depth2 ... _target_eml_depth6, which are self-generated synthetic eml expressions (from EML_expression_generation.nb) — not sin/cos/erf. Wolfram's "75% blind-failure at depth 3-4" figure is about re-discovering a known eml tree from its own samples, not about generating elementary functions. This is a search-efficiency result, not a universality result.
3. CUDA recognizer — two builds, asymmetric behaviour
EML_toolkit/EmL_recognizer/eml_gpu_fp32_hybrid_unary.cu (real path):
float out = expf(left_value) - logf(right_value); // line 361
// ... logf(negative) returns NaN; candidate filtered by finite-check
EML_toolkit/EmL_recognizer/eml_gpu_complex32_hybrid_unary.cu (complex path):
typedef thrust::complex<float> complex32; // line 34
complex32 out = thrust::exp(left_value) - thrust::log(right_value); // line 359
printf("Branch: principal complex log\n"); // line 584
The existence of a separate complex build is a tell: the authors know the real path cannot recover targets requiring ln(negative), so they maintain a parallel complex path for those. Any search hit for I, π, sin(k), cos(k), etc. comes from the complex path.
4. Rust search/verify (three binaries)
rust_verify/src/main.rs, rust_autogen_search/src/main.rs, rust_autogen_parallel_search/src/main.rs — all three define:
fn ln(self) -> Option<C> {
let r = self.abs();
if r == 0.0 { return None; }
Some(C::new(r.ln(), self.arg())) // principal complex branch
}
Default mode: DomainMode::Complex. Scan constants include -1, 0, 1, 2, E, Pi, I. No real-only mode is exercised in the committed verification logs. The logged π recovery reads:
Pi ≡ Sqrt[Minus[Sqr[Log[-1]]]] # rust_verify.log
— literally the square root of the negation of the square of ln(−1). This is only well-defined under complex principal log.
5. Wolfram symbolic verifier (verify_eml_symbolic_chain.wl)
Top-level branch-correction definition (both copies, lines 10–18):
LogLower[z_] := Piecewise[
{ {Log[-z] - I Pi, Element[z, Reals] && z < 0} },
Log[z]
];
EML[x_, y_] := Exp[x] - LogLower[y];
The verifier explicitly installs the lower-edge of the complex principal log, ln(−|z|) = ln|z| − iπ, as the meaning of ln inside eml. Every claimed identity (iConst, piConst, cosEML, sinEML) is checked under this semantics. In pure-real arithmetic these identities are ill-defined.
6. eml_compiler_clean_math_v0.py (the "clean math" variant)
Advertised as a real-safer variant. Reality: it wraps eml_compiler_v4 via import eml_compiler_v4 as base and only patches eml_neg to avoid Log[0]. It does not override eml_const_I or eml_const_Pi. Any trig target still compiles through the complex branch.
Claims that collapse
Classifying against the Jonny programme's ENDORSE/REJECT list (eml-programme-gates.md):
| Claim | Code evidence | Status |
|---|---|---|
| "eml + {1} generates the Liouvillian closure exactly via finite real trees" | fp32 CUDA, Test_C_math_h, f64 Rust paths all support this | STANDS |
| "eml + {1} generates sin, cos, tan on ℝ exactly via finite real trees" | No real path supports this; all three complex paths required | COLLAPSES (already rejected by Wilkie; now also by reference-code behaviour) |
| "eml generates the constants i and π via finite real trees" | eml_const_I and eml_const_Pi both require ln(−1) |
COLLAPSES |
| "eml is the NAND gate for continuous math" | Two separate GPU builds (one for real, one for complex) contradict the "one operator" framing; trig / i / π require a fundamentally different evaluation semantics | COLLAPSES (category error, reinforced) |
| "Exhaustive search discovered the generator" | True as a methodology claim | STANDS |
| "25% convergence at depth 3–4" is a numerics result about elementary-function universality | It is actually convergence of self-regression on synthetic eml-generated targets, using complex128 arithmetic throughout | MISFRAMED — not evidence for the universality claim at all |
One paragraph for the grant-contrast figure (Feynman / Gate γ)
The reference implementation for "eml as universal generator" ships two parallel GPU search binaries —eml_gpu_fp32_hybrid_unary(real arithmetic) andeml_gpu_complex32_hybrid_unary(complex arithmetic, with"Branch: principal complex log"printed at startup). The real binary never recovers sin, cos, tan, π, or i fromlogf(negative) → NaNfiltering. The complex binary recovers them by running every intermediate value in ℂ. The Wolfram symbolic verifier installs the lower-edge branch correctionln(−|z|) = ln|z| − iπbefore checking any identity. In short: the repository demonstrates Liouvillian-closure generation over ℝ and demonstrates elementary-function generation over ℂ, and there is no finite real-valued eml tree for sin anywhere in the code. This is consistent with Wilkie's o-minimality (no finite eml tree over {x, 1} equals sin on ℝ); the paper's real-only framing is not.
Recommended downstream action
1. Grant application (Gate γ): pitch the translinear coprocessor as a Liouvillian accelerator. Do not claim trig coverage. If reviewers push back on scope, the honest answer is "trig requires complex-valued arithmetic, which this substrate does not natively provide; targeting Liouvillian closure gives us provable completeness and measured hardware accuracy."
2. Rebuttal-on-demand: Feynman's divergence plot (Gate γ) pairs well with this audit — plot + code-reference gives reviewers the "what the claim is NOT" artefact.
3. For the math/code critique if it gets written: cite the eml_const_I / eml_const_Pi hardcodes (eml_compiler_v4.py:50–62) and the dual GPU binaries as the clinching evidence. These are in the authors' own reference code — not a reviewer's reconstruction.
4. Archivist side-note: the repo itself is a model of honest engineering — real and complex paths are clearly separated, verification scripts explicitly install the branch correction, logs note the complex mode. The oversell lives in the tweet and (presumably) the paper's abstract, not in the code. This is a framing problem, not a fraud problem.
Files examined
EML_toolkit/EmL_compiler/eml_compiler_v4.py(352 lines)EML_toolkit/EmL_compiler/eml_compiler_clean_math_v0.py(wrapper)EML_toolkit/EmL_training/PyTorch_v16_final/tree_prototype_torch_v16_final.py(100+ lines read; DTYPE is complex128 at module scope)EML_toolkit/EmL_recognizer/eml_gpu_fp32_hybrid_unary.cu(real path)EML_toolkit/EmL_recognizer/eml_gpu_complex32_hybrid_unary.cu(complex path)rust_verify/src/main.rs,rust_autogen_search/src/main.rs,rust_autogen_parallel_search/src/main.rs(all Complex) rust_verify/verify_eml_symbolic_chain.wl,EML_toolkit/EmL_verification/verify_eml_symbolic_chain.wl(lower-edge branch install)EML_toolkit/EmL_compiler/Test_{numpy,torch,mpmath,C_math_h}/*(test harnesses — numpy/torch/mpmath are complex, C is real-only and has no trig coverage)EML_toolkit/EmL_verification/mathematica_verify.log,rust_verify.log
Clone location: /home/a/Projects/craig/audits/SymbolicRegressionPackage/ (shallow).
— Craig, /home/a/Projects/craig/