Skip to content

Add DAG-based constraint propagation (HC4Revise)#224

Open
dpsanders wants to merge 7 commits intomasterfrom
dag-propagation
Open

Add DAG-based constraint propagation (HC4Revise)#224
dpsanders wants to merge 7 commits intomasterfrom
dag-propagation

Conversation

@dpsanders
Copy link
Copy Markdown
Member

Summary

  • Adds an explicit DAG (directed acyclic graph) engine for forward-backward interval constraint propagation, as an alternative to the existing code-generation approach via ReversePropagation.jl
  • New types DAGContractor, DAGSeparator, and ConstraintDAG in src/dag/ that are drop-in replacements for Contractor and Separator
  • Implements iterative HC4Revise: forward evaluation (leaves→root) + backward contraction (root→leaves using IntervalContractors reverse functions), iterated to a fixed point

Motivation

The current approach compiles a symbolic expression into a Julia closure via eval(). This works but produces an opaque closure that can't be inspected, iterated, or shared across constraints. An explicit DAG enables:

  • Inspection/debugging — print or visualize the computation graph
  • Iterative narrowing — repeat forward-backward passes until convergence (important when variables appear multiple times)
  • Multi-constraint propagation (future) — share variable nodes across constraints so narrowing from one constraint benefits others
  • No eval() — avoids world-age issues

Current status

Both approaches produce identical paving results on all test cases. The DAG is ~10x slower currently due to DAG reconstruction per call and dynamic dispatch. Optimization paths are documented in CLAUDE.md.

Problem ϵ Codegen DAG Ratio
Unit disk 2D 0.1 287 μs 3.2 ms 11x
Unit disk 2D 0.01 2.3 ms 27 ms 12x
Annulus 2D 0.1 1.6 ms 14 ms 9x
3D torus 1.0 12 ms 120 ms 10x

Usage

# Existing (unchanged):
S = Separator(x^2 + y^2 <= 1, [x, y])

# New DAG-based:
S = DAGSeparator(x^2 + y^2 <= 1, [x, y])

# Both work with pave:
inner, boundary = pave(X, S, 0.1)

Test plan

  • 27 new tests in test/test_dag.jl — DAG construction, forward/backward propagation, contractor, separator, paving, comparison with original, combined separators, 3D
  • All existing tests in test/runtests.jl still pass
  • Benchmarks in benchmark/bench_dag_vs_codegen.jl confirm identical box counts

🤖 Generated with Claude Code

David Sanders and others added 7 commits April 2, 2026 03:35
…ompatibility

Update compat bounds: IntervalArithmetic 1, IntervalBoxes 0.3,
IntervalContractors 0.6, ReversePropagation 0.4, Symbolics 7.

IntervalArithmetic v1.0 follows IEEE 1788 and deliberately does not define
Base.isequal/Base.hash for Interval. This broke @register_symbolic x ∈ y::Interval
since SymbolicUtils needs isequal/hash for hash-consing. Instead of type-pirating
those methods, decompose x ∈ interval(a,b) into (x >= a) & (x <= b) at the
symbolic level.

Also fix pre-existing bug in separator() where & and | used Base.intersect/union
instead of ⊓/⊔ (defined for AbstractSeparator in set_operations.jl).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Cherry-pick infrastructure changes from PR #220:
- Update GitHub Actions versions (checkout v6, setup-julia v2, cache v3, codecov v6)
- Test on Julia 1.11 instead of 1.10
- Set julia compat to 1.11
- Remove obsolete REQUIRE file (Pkg.jl era)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Switch from the old Documenter HTML backend to DocumenterVitepress for a
modern VitePress-based documentation site. Add new pages explaining
contractors/separators and the internal architecture, update index.md to
the current API, add GitHub Actions workflow for doc deployment, and
remove stale mkdocs.yml and Manifest.toml.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Implements an explicit DAG (directed acyclic graph) for forward-backward
interval constraint propagation (HC4Revise), inspired by Schichl & Neumaier.
This provides an inspectable, iterable alternative to the existing
ReversePropagation code-generation approach.

New types: DAGContractor, DAGSeparator, ConstraintDAG
New files: src/dag/{nodes,build,propagate,contractor}.jl
Tests: test/test_dag.jl (27 tests)
Benchmarks: benchmark/bench_dag_vs_codegen.jl

Both approaches produce identical paving results. The DAG approach is
currently ~10x slower due to DAG reconstruction per call and dynamic
dispatch, with clear optimization paths documented in CLAUDE.md.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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