Repository navigation
Conversation
Growth terms are now stored in log space as exp(sum of weight * atom), where an atom is a monomial over v and ln v (or ln ln v) and a weight is an exact combination of logarithms of symbolic bases. This represents 2^(n*m), 2^sqrt(n), 2^(n log n), k^n, (k+1)^n <= 2^n k^n, and factorial(x) <= x^x, which previously widened to unknown. Comparison decides the sign of each atom's weight difference (exactly, or in floating point with a 1e-9 margin) and requires every possibly-negative atom to be strictly dominated by a positive one. Decaying factors are kept exactly so they cancel. Adds 11 SymPy-oracle growth cases for the new shapes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1220 +/- ##
==========================================
+ Coverage 97.18% 97.19% +0.01%
==========================================
Files 1146 1146
Lines 151076 151464 +388
==========================================
+ Hits 146819 147213 +394
+ Misses 4257 4251 -6 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
- Compare terms in one pass: build the weight difference once, decide each sign once, and test growth in either direction with one helper. - Prune with a single comparison per pair. - Route Exp, Pow, and Factorial through one log_bound/power_growth path and share the positive-part monomial bound between variable bases and logs. - Render through Expr's own normalization (pow by one, unit factors, and canonical factor order), dropping the hand-written ordering helpers. - Take the lcm through num-rational's reduction instead of a local gcd, and drop the exact_growth alias and other dead helpers. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Retargeted onto |
…2::MAX Huge constant powers in an exponent now fail fast with RepresentedExponentOutOfRange rather than hanging. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tirling Growth::relation() returns ParameterRelation::Exact when the Big-O form is also a lower bound (Theta) and UpperBound when any step widened it. factorial(x) of an exact single monomial now uses x^(x+1/2) e^(-x). A lower-bound property harness with a seeded negative control checks every exact claim numerically; four Stirling cases join the SymPy oracle. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
log_term dropped negative-weight atoms, so log(exp(-n)) = -n got growth O(1): a signed bound, not a magnitude bound. That made the dominance rule in add report n + log(exp(-n)) + 1 as exact O(n), and log(exp(-n))^2 as O(1). Every atom now contributes regardless of sign. Also adds signed shapes to the property generator and checks that exact registered complexities stay exact on round trip. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GiggleLiu
left a comment
There was a problem hiding this comment.
Agentic Review Report
PR #1220. Reviewed head 2dc824e3da8f2c8b12103106206a2eed25ef6f2a against own base 0daa9a8265aefe40983beeba0464f8feea8c3316 (feat/binary-ilp-to-sat). Read-only review; no tracked edits, pushes, PR comments or merges.
Verdict
HOLD. The new support for decaying exponentials produces invalid magnitude upper bounds under logarithms. #1221 repairs the simplest case, but an additional cancellation case remains broken even in #1221.
Structural
Reviewed all growth-transfer/comparison implementation changes, revised tests and fixture generator changes against the exact base. New polynomial exponents and symbolic base coefficients preserve substantially more information than the former domain. The distinction between a signed logarithmic upper bound and an upper bound on magnitude is nevertheless not preserved.
Quality
The numerical property tests mostly probe positive growing expressions. A test that drops negative logarithmic terms can pass those checks despite failing on nonnegative monotone totals. The oracle fixtures test positive univariate asymptotics but not a logarithm of a decaying term squared.
Feature test
Compiled and executed a standalone Rust probe using the exact PR growth.rs, the shared expression implementation, and the actual dependency versions, with one build job and debug/incremental output disabled. This avoids a second full library build. Source is in /tmp/problemreductions-growth-probe; output is /tmp/problemreductions-pr-review-20261029/growth-probe.txt. This is an independent counterexample run, not a full exact-head unit suite. git diff --check BASE...HEAD passed.
Findings
- Critical: dropping negative atoms from a logarithm makes the output cease to be an upper bound.
src/growth.rs:1144-1146.Growth::from_expr(Expr::parse("log(exp(-n))^2"))returnsO(1)although the expression is exactly n², nonnegative and nondecreasing for n≥2.log(exp(-n))is −n, whose magnitude cannot be dropped before applying a square. Preserve a magnitude bound or return Unknown for the unsupported operation. The concrete #1221 follow-up fixes this case, so #1220 must not land independently. - Critical remaining in the combined stack:
log(n*(n+1)-n^2-n+exp(-n))^2is also exactly n² but returnsO(log(n)^2)both here and at #1221. An upper bound on a positive argument gives no bound on the magnitude of its logarithm near zero. This needs a lower bound on the argument or an Unknown result, not just the negative-atom adjustment. Full details and the false Exact consequence are in the #1221 report.
GitHub PR policy audit
GATE: PASS. This is the harm-signals gate only; it does not override the correctness verdict above.
- harm.secrets (
security.no-secrets): OK. No obvious credential/private-key/token addition detected in the own-base diff. - harm.dangerous-files (
git.harm-signals): OK. No conflict markers, unexplained archives or local scratch/config artifacts detected. - harm.generated-artifacts (
code.generated-artifacts): OK. No blacklisted generated graph/schema/example exports or build targets added. Test oracle fixtures are intentional test inputs; small browser contracts/fonts are intentional source assets. - harm.cache (
code.generated-cache): OK. No cache directories added. - harm.debug-leftovers (
code.debug-leftovers): OK. No debugger, breakpoint or temporary debug print addition detected. Browser performance marks are deliberate verification instrumentation. - pr.description-quality (
github.pr-description-quality): OK. Purpose, changes, validation and limitations are described. - pr.traceable (
github.prs-traceable): OK. The PR states its purpose and own stack context.
Policy evidence: own-base name/status, numstat and patch inspection; added-line secret/conflict/debug scan; git diff --check; gh-axi pr view 1220 --full --comments --reviews. No claim of exhaustive secret scanning. The parent reviewer owns the final head/base recheck before any merge.
…l-exponents # Conflicts: # src/growth.rs # src/unit_tests/growth.rs
Summary
The growth domain (
src/growth.rs) now supports two shapes that used to fall back toO(?): polynomial exponents and variable bases.Each growth term is now stored in log space as
exp(Σ weight · atom).∏ v^p (ln v)^l, orln ln v.Σ c_b · ln bof symbolic bases. Bases are never rounded through a floating-point logarithm.Under this scheme,
n^2is the atomln nwith weight 2,2^(n·m)is the atomn·mwith weightln 2, andk^nis the atomn·ln kwith weight 1.2^(n*m),2^sqrt(n),2^(log(n)^2),2^((n+m)^2)O(?)k^n,n^n,num_groups^(2*num_groups)O(?)(k+1)^nO(?)O(2^n * k^n). The baseB = Σ c_i μ_iis bounded byC·M, soB^E ≤ C^E · M^E.factorial(x)O(?)O(x^x)(upper bound)2^(n-m),0.5^nO(?)(decaying)2^n · 2^(-n)cancels toO(1)2^(2^n),(2^n)^mO(?)O(?)Comparison: to compare two terms, take the log-space difference and determine the sign of each atom's weight. The sign is decided exactly when all summands share a sign, otherwise by a floating-point estimate with a
1e-9relative margin, and otherwise by exact rational powers. One term dominates when every atom that might be negative is strictly dominated by a positive atom (componentwise in(power, log power)).Exactness: exponents expand exactly into polynomials over
vandln v. Fractional powers of sums and logs of sums are widened to upper bounds, which are tracked with an exactness flag and only ever combined monotonically.GrowthFailurevariants are renamed to match what can still fail:UnsupportedExponent,UnsupportedVariableBase,UnsupportedFactorialandDecayingWidenedExponent. No code outsidegrowth.rsmatched on the old variants.Verification
uv run --project scripts python scripts/generate_symbolic_expr_fixture.py.n, and checked against SymPy limits.cargo test --workspace, fmt and clippy all pass. The only clippy warning is the existingnormalized_nwarning onmain.Known limitation
A widened shape compares by its bound. For example,
factorial(n)compares as equal ton^neven thoughn!is smaller. Subtraction already worked this way (n - mwidens ton + m), so audit findings still need a manual check.🤖 Generated with Claude Code