Skip to content

Stop calling the deprecated AbstractAlgebra zeros - #138

Open
s-celles wants to merge 5 commits into
JuliaSymbolics:mainfrom
s-celles:refactor/replace-deprecated-zeros
Open

s-celles wants to merge 5 commits into
JuliaSymbolics:mainfrom
s-celles:refactor/replace-deprecated-zeros

Conversation

@s-celles

@s-celles s-celles commented Sep 13, 2026 •

Copy link
Copy Markdown
Contributor

Every test run prints

Warning: `zeros(R::NCRing, r::Int...)` is deprecated, use `zero_matrix(R, r...)` instead.
  caller = convolution(...) at frontend.jl:209

Why not zero_matrix

The deprecated method returns a plain Julia Array of ring elements (Array{elem_type(R)}(undef, dims) filled with zeros), while zero_matrix builds an AbstractAlgebra matrix type. That difference matters at these call sites:

  • in parametric_problems.jl, the arrays are concatenated with vcat/hcat next to A = ConstantSystem([coeff(q, i) for i=0:dc, q in qs], ...), an ordinary Julia Matrix, and then indexed elementwise (A[i+neq, i] = one(C));
  • in frontend.jl and general.jl, the result is used as a vector (c[t+1] += ..., and splatted into a call).

So substituting a matrix type would change the types flowing through those expressions.

What this does

Adds zero_array(R, dims...), which reproduces the old behaviour explicitly and documents why zero_matrix is not used, and switches the 18 ring-element call sites to it. zeros(Int, ...) calls are Base.zeros and are left untouched.

The helper depends only on AbstractAlgebra.elem_type and AbstractAlgebra.NCRing, so it works across the whole supported AbstractAlgebra range rather than tracking when the deprecation lands.

Validation

No behaviour change intended, and none measured:

  • TEST_GROUP=easy: 202 pass, 1 pre-existing broken — same as main.
  • TEST_GROUP=difficult: numbers identical to main, RuleBased 92 succeeded / 50 failed / 35 maybe failed / 0 errored, Risch 57 succeeded / 77 failed / 40 maybe failed / 3 errored (the three errors are the pre-existing buffered_operate_to! failures, unrelated to this change).
  • Deprecation warnings: gone (0 occurrences in the difficult run, which previously printed them).

Disclosure: this change was written with AI assistance, and tested locally before opening the PR. TEST_GROUP=easy and TEST_GROUP=difficult were run on this branch and against unmodified main, and the reported counts are the compared results of those runs; the deprecated method's own source was read to confirm it returns a plain Array rather than a matrix.

Changes since the first review

Added test/methods/risch/test_zero_array.jl, wired into the easy group. It covers the
allocator (shape, element type, zero values over QQ, a polynomial ring and a fraction
field, in vector / matrix / empty shapes; and that the entries are distinct objects, since a
shared mutable zero would make an in-place update to one entry visible in the others), that
convolution emits no warning, and that convolution still computes the same result.

The deprecation check is discriminating, as asked:

convolution builds c with result
zeros(R, ...) (before this PR) 28 passed, 1 failed — "zeros(R::NCRing, r::Int...) is deprecated"
zero_array(R, ...) (this PR) 29 passed

Two details that make it reliable: collect_test_logs installs a fresh logger, which resets
the maxlog = 1 budget of Base.depwarn, so a warning emitted earlier in the suite cannot
mask this one; and a positive control asserts the deprecated method still warns in the same
process, so the check cannot pass vacuously. It is skipped when the process does not enable
depwarn, rather than passing for the wrong reason.

Also addressed the P3 items: the return Runic wants in zero_array, and the trailing
whitespace git diff --check flagged in parametric_problems.jl:934. The remaining Runic
complaints about general.jl are pre-existing on main (verified by running Runic against
main's copy of the file), so they are left out of this behaviour change.

TEST_GROUP=easy on this head: 231 passed, 1 broken (pre-existing), exit 0, with zero
deprecation warnings in the whole run. Julia 1.13.0, AbstractAlgebra 0.50.2, Nemo 0.56.1,
SymbolicUtils 4.48.0, Symbolics 7.41.1.

Two red checks on this PR are not caused by it: the difficult jobs fail on baseline entry
15, sin(sqrt(1+x))/sqrt(1+x), now filed as #145; and the Maxima qa jobs fail to resolve
because of the stale 0.2 bound fixed by #146.

Assisted by: AI

CI on head 6b2540a

33 pass, 2 fail — and the difficult group is green.

Before current main was merged in, this pull request failed nine difficult jobs. All
nine were the same single RuleBased regression, baseline entry 15,
sin(sqrt(1+x))/sqrt(1+x), which fails identically on main and which #147 fixes. Merging
main cleared them without touching a line of this change.

The two remaining failures are the SymbolicIntegrationMaxima qa jobs dying at
resolution on the stale 0.2 bound that #146 fixes; that has failed on main since the
0.3.0 release and nothing here touches it.

Every test run printed

    Warning: `zeros(R::NCRing, r::Int...)` is deprecated, use
    `zero_matrix(R, r...)` instead.

`zero_matrix` is not a replacement at these call sites. The deprecated
method returns a plain Julia `Array` of ring elements, while
`zero_matrix` builds a matrix type; the arrays built here are
concatenated with `vcat`/`hcat` alongside ordinary coefficient matrices,
indexed elementwise and returned as vectors, so swapping in a matrix type
would change those types.

Add `zero_array`, which reproduces the old behaviour explicitly, and use
it for the 18 ring-element call sites. `zeros(Int, ...)` calls are
`Base.zeros` and are left alone.

No behaviour change: `TEST_GROUP=easy` passes with the same 202 tests, and
`TEST_GROUP=difficult` reports numbers identical to `main` (Risch: 57
succeeded, 77 failed, 40 maybe failed, 3 errored), with the deprecation
warnings gone.

Assisted-by: AI
@ChrisRackauckas

Copy link
Copy Markdown
Member

🤖 Automated review from an AI agent running as @ChrisRackauckas — not written or reviewed by Chris. It is posted so that you can act on it. Chris or a maintainer may disagree.

Verdict: changes needed before merge (reviewed at 77c0649).

Replaces 18 deprecated ring-element zeros calls with an internal allocator that preserves ordinary Julia arrays. Local checks confirm warning removal and the easy suite passes, but the PR needs a committed regression test and formatting of the new helper.

Risk assessment

  • Risk: low

  • Blast radius: Internal Risch coefficient vectors and matrices, convolution, partial fractions, and polynomial root construction. No public API or dependency changes; the newly accessed AbstractAlgebra names are exported, and no SemVer or licensing issue was found.

  • Evidence: Head has no check runs or commit statuses, and no comments/reviews or linked issues. Thus there are no failing head CI checks to compare. Latest default-branch CI run 35223647633 passed all 27 Julia {1.10,1,pre} - {ubuntu-latest,macos-latest,windows-latest} - {easy,difficult,qa} - push jobs; it tested commit 278475d, not today's dependency resolution.

    Local Julia 1.12.4 resolved AbstractAlgebra 0.50.2, Nemo 0.56.1, Symbolics 7.41.1, and SymbolicUtils 4.48.0. TEST_GROUP=easy timeout 3600 julia --project=repo -e 'using Pkg; Pkg.test()' exited 0: 202 passed, 1 broken, 203 total (3m33.9s test execution). The existing broken assertion is unchanged. An independent run through repo/test/runtests.jl with compiled modules disabled returned the same counts.

    julia --depwarn=yes --project=repo regression.jl before tested the exact convolution function extracted from merge-base ea0d9e6: warning-free convolution | 1 pass, 1 fail, capturing the deprecated zeros(R::NCRing, ...) warning. The same assertion against the extracted head function passed 2/2. New-helper checks passed 46/46, covering rational, polynomial and fraction rings, vector/matrix/empty/scalar shapes, zero values, and distinct mutable polynomial elements. These are reviewer scratch tests, not tests supplied by the PR.

    TEST_GROUP=difficult timeout 3600 julia --project=repo -e 'using Pkg; Pkg.test()' exited 1: 15 passed, 1 failed (10m28.9s). RuleBased corpus totals were 91 succeeded / 52 failed / 34 maybe / 0 errors; Risch totals were 58 / 77 / 42 / 0. The failing assertion concerns RuleBased integration of sin(sqrt(1+x))/sqrt(1+x). A targeted reproducer also failed on clean current main b056ef3 with the same dependencies, returning an unresolved integral containing sin(x)*x/abs(x). A delegated investigation ran the same clean main with only SymbolicUtils changed to 4.46.7: the reproducer exited 0 and returned -2cos((1+x)^(1//2)). This establishes dependency drift, not a regression from this PR. Source history narrows the relevant simplification changes to two commits in SymbolicUtils 4.46.8; those commits were not individually runtime-bisected. No issue was filed because this review is read-only.

    Both complete head test logs contain zero occurrences of the deprecated ring-zeros warning. Runic --check --diff on all three modified files exited 1; the base general.jl also fails formatting, so broad existing drift is not attributed to this PR. QA, docs, other Julia versions, and the full base difficult corpus were not rerun locally. Logs and probes remain in the assigned scratch directory.

  • Merge: needs changes (commit a discriminating regression test; format the new helper).

Findings

  1. P2 — src/methods/risch/frontend.jl:149; src/methods/risch/general.jl:23 — No test file changes accompany the warning fix or new allocator. The existing easy suite passes without asserting warning removal, so reverting this change would not be caught. Add a warning-free convolution regression under enabled deprecation warnings to the existing test suite, plus focused allocator shape/type and non-aliasing checks. Include failing-before/passing-after output; the reviewer probe demonstrates that such a discriminating test is feasible.
  2. P3 — src/methods/risch/general.jl:28 — The new helper fails Runic's explicit-return formatting (A becomes return A). Format the new helper; keep unrelated legacy formatting out of this behavior-change PR. git diff --check also flags trailing whitespace on the edited parametric_problems.jl:934 line.

Push a fix and the PR is reviewed again automatically at the new head.


🤖 Posted by an AI agent — harness: Claude Code · model: claude-opus-5-5[1m] (fleet master); review by Codex CLI 0.157.1 / gpt-6-astra
Conversation: local Claude Code session 3cd6500a-1f81-46b5-ac0b-c466e15b6a53 on Chris's Mac (session ID, no URL)

s-celles and others added 2 commits September 27, 2026 04:02
The warning fix and the new allocator had no test, so reverting either would
have gone unnoticed.

`test/methods/risch/test_zero_array.jl` covers:

- shape, element type and zero values of `zero_array` over `QQ`, a polynomial
  ring and a fraction field, in vector, matrix and empty shapes;
- that the entries are distinct objects, since ring elements are mutable and a
  shared zero would make an in-place update to one entry visible in the others;
- that `convolution` emits no warning, which is the actual regression guard;
- that `convolution` still computes the same result.

The deprecation check is discriminating: restoring
`c = zeros(R, ...)` in `convolution` makes it fail with
"`zeros(R::NCRing, r::Int...)` is deprecated" (28 passed, 1 failed), and it
passes with `zero_array` (29 passed). `collect_test_logs` installs a fresh
logger, which resets the `maxlog = 1` budget of `Base.depwarn`, so a warning
emitted earlier in the suite cannot mask it. A positive control asserts the
deprecated method still warns in the same process, so the check cannot pass
vacuously; it is skipped when the process does not enable depwarn.

`TEST_GROUP=easy`: 231 passed, 1 broken (pre-existing), exit 0, with zero
deprecation warnings in the whole run.

Also add the `return` that Runic wants in `zero_array`, and drop the trailing
whitespace that `git diff --check` flagged in `parametric_problems.jl`. The
remaining Runic complaints about `general.jl` are pre-existing on main and are
left alone.

Assisted-by: AI
@codecov-commenter

codecov-commenter commented Sep 27, 2026 •

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 40.00000% with 12 lines in your changes missing coverage. Please review.
✅ Project coverage is 51.26%. Comparing base (8647f0d) to head (6b2540a).
⚠️ Report is 27 commits behind head on main.

Files with missing lines Patch % Lines
src/methods/risch/parametric_problems.jl 0.00% 11 Missing ⚠️
src/methods/risch/general.jl 87.50% 1 Missing ⚠️
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #138      +/-   ##
==========================================
+ Coverage   50.98%   51.26%   +0.28%     
==========================================
  Files          23       23              
  Lines        4309     4219      -90     
==========================================
- Hits         2197     2163      -34     
+ Misses       2112     2056      -56     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Brings in JuliaSymbolics#147, which fixes baseline entry 15,
`sin(sqrt(1+x))/sqrt(1+x)`. That entry was the single RuleBased regression
failing the `difficult` gate on this pull request, and it was never caused by
it: it fails the same way on `main` and on every other open pull request based
on the older `main`.

No conflict. `TEST_GROUP=easy`: 250 passed, 1 broken (pre-existing), exit 0,
with zero deprecation warnings in the whole run, which is what this pull request
is about.

Assisted-by: AI
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants