propagators-chirho
"For God so loved the world that he gave his only begotten Son, that whoever believes in him should not perish but have eternal life." — John 3:16
A Rust implementation of propagator networks for constraint propagation and bidirectional computation, based on the seminal work by Radul and Sussman.
What Are Propagators?
Propagators are a programming paradigm where:
- Cells hold partial information that can only grow monotonically
- Propagators are autonomous agents that watch cells and update other cells
- Information flows in all directions — constraints are bidirectional
This enables powerful constraint-based programming where you can run computations "backwards."
use *;
// Temperature conversion: F = C × 9/5 + 32
// Works BOTH ways!
let mut system_chirho = new_chirho;
let celsius_chirho = system_chirho.make_cell_chirho;
let fahrenheit_chirho = system_chirho.make_cell_chirho;
// ... set up constraints ...
// Forward: given Celsius, compute Fahrenheit
system_chirho.set_exact_chirho;
system_chirho.run_chirho;
// fahrenheit is now 212.0
// Backward: given Fahrenheit, compute Celsius
system_chirho.set_exact_chirho;
system_chirho.run_chirho;
// celsius is now 0.0
Features
Core Infrastructure
CellChirho<T>— Cells with monotonic merge and neighbor notificationPropagatorChirhotrait — Interface for building custom propagatorsSchedulerChirho— Runs propagators to fixpoint
Interval Arithmetic
IntervalChirho— Partial numeric information as[lo, hi]bounds- Full interval arithmetic:
+,-,*,/,sqrt,square,abs - Intervals intersect on merge, detecting contradictions
Propagators
| Propagator | Constraint | Directions |
|---|---|---|
IntervalAdderChirho |
a + b = c | All 3 |
IntervalSubtractorChirho |
a - b = c | All 3 |
IntervalMultiplierChirho |
a × b = c | All 3 |
IntervalDividerChirho |
a ÷ b = c | All 3 |
SquarerChirho |
a² = b | Both |
SqrterChirho |
√a = b | Both |
AbsoluterChirho |
|a| = b | Both |
MaxChirho |
max(a,b) = c | All 3 |
MinChirho |
min(a,b) = c | All 3 |
ConditionalChirho |
if p > 0 then a else b | Forward |
Truth Maintenance System (TMS)
BeliefChirho— Values with supporting premisesTmsCellChirho— Cells that track multiple beliefsJustificationChirho— Track derivation chains (withtms-fullfeature)NogoodStoreChirho— Manage contradictory premise sets with minimal nogood computationTmsNetworkChirho— Full TMS-aware propagator networks
Worldviews (Hypothetical Reasoning)
WorldviewChirho— Set of active premises- Fork and explore alternate assumptions
- Retract premises when they lead to contradictions
Amb Operator (Nondeterministic Choice)
AmbChirho— Choice among valuesBacktrackingSearchChirho— Constraint satisfaction with backtrackingDependencyDirectedSearchChirho— Smart backtracking using nogood information (skips irrelevant choices)
High-Level API
ConstraintSystemChirho— Builder-style interface for constraint networks
Algebraic Traits (Kmett-style)
SemigroupChirho— Associative binary operationMonoidChirho— Semigroup with identity elementJoinSemilatticeChirho— Idempotent, commutative monoidBoundedJoinSemilatticeChirho— Semilattice with top elementPropagatorErrorChirho/PropagatorResultChirho— Proper error handling
Lattice Abstractions
LatticeChirhotrait — Join semilattice with partial orderBoundedLatticeChirhotrait — Lattice with top (contradiction) and bottom (nothing)PropagatorFnChirhotrait — Composable functional propagatorsSupportedValueChirho<L>— Values with provenance tracking
Finite Domains (for CSP)
FiniteDomainChirho— Set-based domains for discrete valuesAllDifferentChirho— Global constraint for Sudoku-like problemsLessThanChirho,EqualsChirho,NotEqualsChirho— Relational constraints
Generic Cells
GenericCellChirho<L>— Cells that work with any lattice typeGenericNetworkChirho<L>— Networks for custom lattice types
Parallel Propagation
ParallelNetworkChirho<L>— Thread-safe parallel propagation with rayon- Independent propagators run concurrently in batches
SIMD Batch Operations
batch_add_chirho,batch_mul_chirho,batch_intersect_chirho— Batch interval operationsIntervalVecChirho— Structure-of-Arrays format for optimal vectorization- Auto-vectorizes on modern compilers for 2-4x speedup on batch operations
Installation
Add to your Cargo.toml:
[]
= "0.1"
Cargo Features
| Feature | Description | Overhead |
|---|---|---|
arena |
High-performance arena-based cells | Faster, uses typed-arena |
parallel |
Parallel propagation with rayon | Thread-safe, uses rayon |
serde |
Serialization for intervals/cells | Adds serde dependency |
tracing |
Debug instrumentation | Runtime overhead when enabled |
tms-full |
Full TMS with justification tracking | Memory overhead |
backtrack |
Dependency-directed backtracking | Memory + CPU overhead |
no-std |
Embedded/bare-metal support | Limited modules |
no_std Support
For embedded or bare-metal environments:
[]
= { = "0.1", = false, = ["no-std"] }
Available modules in no_std mode:
IntervalChirho/NumericInfoChirho— Interval arithmeticalgebra_chirhotraits —SemigroupChirho,MonoidChirho, etc.simd_chirho— Batch SIMD operations
Note: no-std is mutually exclusive with other features.
Examples
Bidirectional Computation
use *;
let mut system_chirho = new_chirho;
let a_chirho = system_chirho.make_cell_chirho;
let b_chirho = system_chirho.make_cell_chirho;
let c_chirho = system_chirho.make_cell_chirho;
// Constraint: a + b = c
system_chirho.add_adder_chirho;
// Forward: 3 + 4 = ?
system_chirho.set_exact_chirho;
system_chirho.set_exact_chirho;
system_chirho.run_chirho;
// c = 7
// Backward: 3 + ? = 7
system_chirho.set_exact_chirho;
system_chirho.set_exact_chirho;
system_chirho.run_chirho;
// b = 4
Interval Propagation
use ;
// "The value is between 20 and 30"
let partial_chirho = interval_chirho;
// "Actually, it's between 25 and 35"
let more_info_chirho = interval_chirho;
// Merge: intersection is [25, 30]
let refined_chirho = partial_chirho.merge_chirho;
Pythagorean Theorem (Backwards!)
use *;
let mut system_chirho = new_chirho;
let a_chirho = system_chirho.make_cell_chirho;
let b_chirho = system_chirho.make_cell_chirho;
let c_chirho = system_chirho.make_cell_chirho;
// a² + b² = c²
system_chirho.add_pythagorean_chirho;
// Given c=13 and a=5, find b
system_chirho.set_exact_chirho;
system_chirho.set_exact_chirho;
system_chirho.set_interval_chirho; // b > 0
system_chirho.run_chirho;
// b = 12 (since 5² + 12² = 13²)
Truth Maintenance
use ;
let cell_chirho = new_chirho;
// Add beliefs from different sources
cell_chirho.add_belief_chirho;
cell_chirho.add_belief_chirho;
// Query under different worldviews
let wv_a_chirho = new_chirho.assume_chirho;
let value_a_chirho = cell_chirho.content_in_worldview_chirho;
// value_a = 25.0
Running Examples
Performance
Features
Enable high-performance arena mode for ~2x faster network operations:
[]
= { = "0.1", = ["arena"] }
use ArenaNetworkChirho;
let mut net_chirho = new_chirho;
let a_chirho = net_chirho.make_cell_chirho;
// ... faster due to contiguous storage and no Rc overhead
Benchmarks
Interval Primitives: propagators-chirho vs inari
| Operation | propagators-chirho | inari (IEEE 754) | Speedup |
|---|---|---|---|
| add | 0.42 ns | 0.69 ns | 1.6x |
| mul | 1.02 ns | 28.8 ns | 28x |
| intersect | 0.42 ns | 1.04 ns | 2.5x |
| square | 0.43 ns | 22.2 ns | 51x |
| sqrt | 0.43 ns | 0.68 ns | 1.6x |
IEEE 754-2019 Compliance: When Does It Matter?
inari provides IEEE 754-2019 compliant interval arithmetic. We don't. Here's when that matters:
| Use Case | Need IEEE? | Recommendation |
|---|---|---|
| Constraint solving / SAT | No | Use propagators-chirho |
| Bidirectional computation | No | Use propagators-chirho |
| Verified numerical proofs | Yes | Use inari |
| Safety-critical systems | Yes | Use inari |
| Financial calculations | Yes | Use inari |
| Game physics / graphics | No | Use propagators-chirho |
| Optimization / search | No | Use propagators-chirho |
What IEEE compliance guarantees:
- The true mathematical result is always within the computed interval
- Proper directed rounding (round toward ±∞)
- Correct handling of NaN, infinities, subnormals
- Reproducible results across platforms
What we sacrifice for speed:
- Use default round-to-nearest (may miss true value by ULP in edge cases)
- Simpler NaN/infinity handling
- Potentially tighter intervals that could theoretically exclude the true value
Bottom line: For constraint propagation and bidirectional computation (our primary use case), IEEE compliance is unnecessary overhead. If you need verified numerical computation, use inari and accept the 28-51x slowdown.
Network Propagation
| Operation | Default Mode | Arena Mode | Speedup |
|---|---|---|---|
| Simple add (3 cells) | 265 ns | 186 ns | 1.4x |
| Temperature (5 cells) | 899 ns | 348 ns | 2.6x |
Comparison to Other Systems
| System | Type | Typical Time | Notes |
|---|---|---|---|
| propagators-chirho (arena) | Rust | 182-348 ns | This library |
| Gecode | C++ | ~100-500 ns | Full CP solver |
| Chuffed | C++ | ~50-200 ns | Lazy clause gen |
| MiniZinc | Various | ~1-10 µs | Modeling layer |
Running Benchmarks
# Basic benchmarks
# With arena mode
# Comparison against other libraries (requires tmp-chirho/)
&&
Testing
Formal Verification (Kani)
Architecture
┌─────────────────────────────────────────────────────────────────┐
│ Constraint System │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ ┌──────────────┐ ┌──────────┐ │
│ │ Cell A │─────▶│ Propagator │─────▶│ Cell C │ │
│ │ [3, 5] │ │ a + b = c │ │ [7, 12] │ │
│ └──────────┘ └──────────────┘ └──────────┘ │
│ ▲ ▲ │ │
│ │ │ │ │
│ ┌──────────┐ │ │ │
│ │ Cell B │─────────────┘ │ │
│ │ [4, 7] │◀────────────────────────────────┘ │
│ └──────────┘ (bidirectional!) │
│ │
├─────────────────────────────────────────────────────────────────┤
│ Scheduler │
│ • Maintains queue of alerted propagators │
│ • Runs until fixpoint (no more changes) │
└─────────────────────────────────────────────────────────────────┘
Mathematical Foundations
Partial Information Lattice
Contradiction (⊤)
↑
┌─────────┴─────────┐
↑ ↑
Interval [a,b] Interval [c,d] ...
↑ ↑
└─────────┬─────────┘
↑
Nothing (⊥)
Key Properties
- Monotonicity: Information can only increase (intervals narrow)
- Confluence: Order of propagator execution doesn't affect final result
- Soundness: Propagated intervals always contain the true value
References
-
Radul, A., & Sussman, G. J. (2009). The Art of the Propagator. MIT CSAIL Technical Report. https://dspace.mit.edu/handle/1721.1/44215
-
Radul, A. (2009). Propagation Networks: A Flexible and Expressive Substrate for Computation. PhD Thesis, MIT. https://dspace.mit.edu/handle/1721.1/54635
-
Stallman, R. M., & Sussman, G. J. (1977). Forward Reasoning and Dependency-Directed Backtracking. Artificial Intelligence, 9(2).
-
de Kleer, J. (1986). An Assumption-based TMS. Artificial Intelligence, 28(2).
-
Moore, R. E. (1966). Interval Analysis. Prentice-Hall.
License
MIT License
Gloria in excelsis Deo 🕊️