Skip to content

Add SSAFunction type, refactor pipeline to accept SSA input#80

Open
dpsanders wants to merge 4 commits into
masterfrom
add-ssa-function
Open

Add SSAFunction type, refactor pipeline to accept SSA input#80
dpsanders wants to merge 4 commits into
masterfrom
add-ssa-function

Conversation

@dpsanders

Copy link
Copy Markdown
Member

Summary

  • Introduces SSAFunction struct to represent decomposed expressions in SSA form (a vector of Assignments + output variable)
  • cse_equations now returns SSAFunction instead of a (code, final) tuple
  • forward_backward_code, forward_backward_expr, and forward_backward_contractor each get an SSAFunction-accepting method; expression-accepting methods become thin wrappers
  • gradient_code similarly accepts SSAFunction
  • Fixes stale istree import → iscall

This enables passing pre-computed SSA (e.g. from gradient_code) into forward_backward_contractor, which is needed for derivative constraints (next PR).

Test plan

  • All 12 ReversePropagation tests pass (was 9, +3 new for SSAFunction path)
  • All 16 IntervalConstraintProgramming tests pass (downstream consumer)

🤖 Generated with Claude Code

dpsanders added a commit that referenced this pull request Apr 19, 2026
Five independent fixes plus a registry-wide regression test:

- Drop `sign`, `max`, `min` from `unary_functions`. `sign_rev` is not
  defined anywhere (the registration has always been broken), and
  `max`/`min` are binary, not unary — ChainRules' adjoint for them
  synthesises boolean branch selectors (`!(y<x)`) which aren't
  reversible ops.
- Override ChainRules' `abs` adjoint with `x/abs(x)`; the default uses
  `sign(x)`, whose `_rev_sign` we just removed.
- Override ChainRules' `exp2`/`exp10`/`log2`/`log10` adjoints to use
  plain `Float64` logs instead of the `IrrationalConstants.Logtwo`/
  `Logten` that `IntervalArithmetic` refuses to accept.
- Extend `IntervalArithmetic.intersect_interval` with `(Real, Interval)`
  and `(Real, BareInterval)` methods so the constraint intersect works
  when the output variable comes through as a plain `Real` (e.g. from
  `d/dx(x^exact(2))`).
- Promote integer seeds (`_ā := 1`, unassigned `:= 0`) in the binarized
  derivative SSA to intervals. Without this, identity-propagating
  gradients such as `d/dx(x-y) = 1` leave `Int`-valued entries that
  drive `IntervalContractors`' `mul_rev(a,b,c) = mul_rev(promote(a,b,c)...)`
  fallback into infinite recursion on `(Int, Int, Int)`.

Also fixes PR 81's stale destructuring of `gradient_code` (it now
returns an `SSAFunction` rather than a tuple, post-#80).

Adds a regression test that loops over every entry in the binary and
unary registries and builds+runs a `derivative_contractor` — catches
each of these regressions.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
dpsanders and others added 4 commits April 19, 2026 14:28
Introduce SSAFunction struct to represent decomposed expressions in SSA
form (a vector of Assignments + output variable). This enables passing
pre-computed SSA (e.g. from gradient_code) into forward_backward_contractor,
which is needed for derivative constraints.

- cse_equations now returns SSAFunction instead of (code, final) tuple
- forward_backward_code/expr/contractor accept SSAFunction
- gradient_code accepts SSAFunction
- Expression-accepting methods become thin wrappers that call cse_equations
- Fix stale istree import (renamed to iscall in newer SymbolicUtils)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
These functions now wrap their output in SSAFunction instead of returning
raw (code, final_var, ...) tuples. Also adds a text/plain show method
for SSAFunction that displays assignments as `_a := y^2`.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add `variables::NamedTuple` field to SSAFunction for extra named
  outputs (constraint, gradient). forward_backward_code and
  gradient_code now return a single SSAFunction instead of a tuple.
- Display reverse operations as rev(+)(...) instead of raw generated names.
- Bump version to 0.4.2.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Breaking changes to the SSA pipeline (cse_equations,
forward_backward_code, gradient_code now return SSAFunction instead of
tuples) warrant a minor bump under Julia's 0.x semver convention.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
dpsanders added a commit that referenced this pull request Apr 19, 2026
Five independent fixes plus a registry-wide regression test:

- Drop `sign`, `max`, `min` from `unary_functions`. `sign_rev` is not
  defined anywhere (the registration has always been broken), and
  `max`/`min` are binary, not unary — ChainRules' adjoint for them
  synthesises boolean branch selectors (`!(y<x)`) which aren't
  reversible ops.
- Override ChainRules' `abs` adjoint with `x/abs(x)`; the default uses
  `sign(x)`, whose `_rev_sign` we just removed.
- Override ChainRules' `exp2`/`exp10`/`log2`/`log10` adjoints to use
  plain `Float64` logs instead of the `IrrationalConstants.Logtwo`/
  `Logten` that `IntervalArithmetic` refuses to accept.
- Extend `IntervalArithmetic.intersect_interval` with `(Real, Interval)`
  and `(Real, BareInterval)` methods so the constraint intersect works
  when the output variable comes through as a plain `Real` (e.g. from
  `d/dx(x^exact(2))`).
- Promote integer seeds (`_ā := 1`, unassigned `:= 0`) in the binarized
  derivative SSA to intervals. Without this, identity-propagating
  gradients such as `d/dx(x-y) = 1` leave `Int`-valued entries that
  drive `IntervalContractors`' `mul_rev(a,b,c) = mul_rev(promote(a,b,c)...)`
  fallback into infinite recursion on `(Int, Int, Int)`.

Also fixes PR 81's stale destructuring of `gradient_code` (it now
returns an `SSAFunction` rather than a tuple, post-#80).

Adds a regression test that loops over every entry in the binary and
unary registries and builds+runs a `derivative_contractor` — catches
each of these regressions.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@dpsanders dpsanders changed the base branch from fix-symbolics7-ambiguity to master April 19, 2026 19:30
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.

1 participant