propagators_chirho/lib.rs
1// For God so loved the world that he gave his only begotten Son,
2// that whoever believes in him should not perish but have eternal life.
3// John 3:16
4
5//! # Propagators Chirho
6//!
7//! A Rust implementation of propagator networks for constraint propagation
8//! and bidirectional computation.
9//!
10//! ## Overview
11//!
12//! Propagators are a programming paradigm where autonomous agents (propagators)
13//! watch cells containing partial information and update other cells when they
14//! learn something new. Information flows in all directions, enabling powerful
15//! constraint-based programming.
16//!
17//! This implementation is based on the seminal work:
18//!
19//! > Radul, A., & Sussman, G. J. (2009). *The Art of the Propagator*.
20//! > MIT Computer Science and Artificial Intelligence Laboratory Technical Report.
21//! > <https://dspace.mit.edu/handle/1721.1/44215>
22//!
23//! ## Key Concepts
24//!
25//! ### Partial Information
26//!
27//! Cells hold partial information that can only grow monotonically. For numeric
28//! values, we use intervals `[lo, hi]` that narrow as we learn more:
29//!
30//! ```
31//! use propagators_chirho::{IntervalChirho, NumericInfoChirho};
32//!
33//! // "I know the value is between 0 and 100"
34//! let partial_chirho = NumericInfoChirho::interval_chirho(0.0, 100.0);
35//!
36//! // "Actually, it's between 20 and 50" - more precise!
37//! let refined_chirho = partial_chirho.merge_chirho(&NumericInfoChirho::interval_chirho(20.0, 50.0));
38//! ```
39//!
40//! ### Bidirectional Constraints
41//!
42//! Unlike traditional programming where data flows one way, propagators
43//! enforce constraints in all directions:
44//!
45//! ```
46//! use propagators_chirho::prelude_chirho::*;
47//!
48//! // Create a constraint system
49//! let mut system_chirho = ConstraintSystemChirho::new_chirho();
50//!
51//! // Create cells for Fahrenheit and Celsius
52//! let f_chirho = system_chirho.make_cell_chirho("fahrenheit");
53//! let c_chirho = system_chirho.make_cell_chirho("celsius");
54//!
55//! // F = C * 9/5 + 32 works BOTH ways!
56//! // (Implementation would use adder/multiplier propagators)
57//! ```
58//!
59//! ### Truth Maintenance
60//!
61//! Track beliefs with their supporting premises, enabling hypothetical reasoning:
62//!
63//! ```
64//! use propagators_chirho::{BeliefChirho, WorldviewChirho, NumericInfoChirho};
65//!
66//! // Create a belief supported by premise "sensor_a"
67//! let belief_chirho = BeliefChirho::with_premises_chirho(
68//! NumericInfoChirho::exact_chirho(25.0),
69//! vec!["sensor_a".to_string()].into_iter().collect(),
70//! "temperature reading",
71//! );
72//!
73//! // Query under different worldviews
74//! let worldview_chirho = WorldviewChirho::new_chirho();
75//! let with_sensor_chirho = worldview_chirho.assume_chirho("sensor_a".to_string());
76//! ```
77//!
78//! ## Features
79//!
80//! - **Interval Arithmetic**: Proper interval math with `+`, `-`, `*`, `/`, `sqrt`, `square`
81//! - **Bidirectional Propagators**: Constraints work in all directions
82//! - **Truth Maintenance System (TMS)**: Track beliefs and their justifications
83//! - **Worldviews**: Hypothetical reasoning with fork/assume/retract
84//! - **Amb Operator**: Nondeterministic choice with backtracking
85//! - **Scheduler**: Runs propagators to fixpoint
86//!
87//! ## Cargo Features
88//!
89//! - `arena`: High-performance arena-based cells (reduces Rc overhead)
90//! - `parallel`: Parallel propagation using rayon
91//! - `serde`: Serialization support for intervals and cells
92//! - `tracing`: Debugging instrumentation (adds overhead)
93//! - `tms-full`: Full TMS with justification tracking (memory overhead)
94//! - `no-std`: Embedded/no_std support (see below)
95//!
96//! ## no_std Support
97//!
98//! Enable the `no-std` feature for embedded or bare-metal environments:
99//!
100//! ```toml
101//! [dependencies]
102//! propagators-chirho = { version = "0.1", default-features = false, features = ["no-std"] }
103//! ```
104//!
105//! In no_std mode, only core modules are available:
106//! - `IntervalChirho` and `NumericInfoChirho` for interval arithmetic
107//! - `algebra_chirho` traits (`SemigroupChirho`, `MonoidChirho`, etc.)
108//! - `simd_chirho` for batch SIMD operations
109//!
110//! The full propagator network (cells, schedulers, TMS) requires `std`.
111//!
112//! **Note**: The `no-std` feature is mutually exclusive with other features.
113//!
114//! ## References
115//!
116//! 1. Radul, A., & Sussman, G. J. (2009). *The Art of the Propagator*.
117//! MIT CSAIL Technical Report. <https://dspace.mit.edu/handle/1721.1/44215>
118//!
119//! 2. Radul, A. (2009). *Propagation Networks: A Flexible and Expressive
120//! Substrate for Computation*. PhD Thesis, MIT.
121//! <https://dspace.mit.edu/handle/1721.1/54635>
122//!
123//! 3. Stallman, R. M., & Sussman, G. J. (1977). *Forward Reasoning and
124//! Dependency-Directed Backtracking in a System for Computer-Aided
125//! Circuit Analysis*. Artificial Intelligence, 9(2), 135-196.
126//!
127//! 4. de Kleer, J. (1986). *An Assumption-based TMS*. Artificial Intelligence,
128//! 28(2), 127-162.
129//!
130//! 5. Moore, R. E. (1966). *Interval Analysis*. Prentice-Hall.
131//!
132//! ## Example: Temperature Conversion
133//!
134//! ```
135//! use propagators_chirho::prelude_chirho::*;
136//!
137//! // Create scheduler and cells
138//! let scheduler_chirho = SchedulerChirho::new_chirho();
139//! let celsius_chirho: std::rc::Rc<CellChirho<NumericInfoChirho>> =
140//! CellChirho::new_chirho("celsius");
141//!
142//! // Add a known Celsius value
143//! celsius_chirho.add_content_chirho(
144//! NumericInfoChirho::exact_chirho(100.0),
145//! &scheduler_chirho
146//! );
147//!
148//! // With proper propagators set up, fahrenheit would become 212.0
149//! ```
150
151// no_std support: use core + alloc when std is not available
152// Note: Most modules require alloc for Vec, HashMap, etc.
153// Only the core interval arithmetic in interval_chirho works with just core.
154//
155// To use in a no_std environment, enable the "no-std" feature and provide
156// an alloc crate. Full propagator networks require alloc; only interval
157// arithmetic can work with just core.
158#![cfg_attr(feature = "no-std", no_std)]
159#![doc(html_root_url = "https://docs.rs/propagators-chirho/0.1.0")]
160#![cfg_attr(docsrs, feature(doc_cfg))]
161#![warn(missing_docs)]
162#![warn(rustdoc::missing_crate_level_docs)]
163#![warn(clippy::all)]
164#![warn(clippy::pedantic)]
165#![allow(clippy::module_name_repetitions)]
166#![allow(clippy::must_use_candidate)]
167#![allow(clippy::similar_names)]
168#![allow(clippy::doc_markdown)]
169#![allow(clippy::return_self_not_must_use)]
170#![allow(clippy::uninlined_format_args)]
171#![allow(clippy::missing_fields_in_debug)]
172#![allow(clippy::mixed_attributes_style)]
173#![allow(clippy::cloned_instead_of_copied)]
174#![allow(clippy::match_same_arms)]
175#![allow(clippy::derivable_impls)]
176#![allow(clippy::struct_field_names)]
177#![allow(clippy::needless_pass_by_value)]
178#![allow(clippy::missing_panics_doc)]
179#![allow(clippy::collapsible_if)]
180#![allow(clippy::manual_assert)]
181#![allow(clippy::unnecessary_literal_bound)]
182
183// Provide alloc crate when in no_std mode
184#[cfg(feature = "no-std")]
185extern crate alloc;
186
187// Core modules that work in no_std (with alloc)
188pub mod algebra_chirho;
189pub mod interval_chirho;
190pub mod simd_chirho;
191
192// Modules requiring std (cells, scheduling, propagators, etc.)
193#[cfg(not(feature = "no-std"))]
194pub mod amb_chirho;
195#[cfg(not(feature = "no-std"))]
196pub mod cell_chirho;
197#[cfg(not(feature = "no-std"))]
198pub mod constraint_system_chirho;
199#[cfg(not(feature = "no-std"))]
200pub mod finite_domain_chirho;
201#[cfg(not(feature = "no-std"))]
202pub mod generic_cell_chirho;
203#[cfg(not(feature = "no-std"))]
204pub mod lattice_chirho;
205#[cfg(not(feature = "no-std"))]
206pub mod propagator_chirho;
207#[cfg(not(feature = "no-std"))]
208pub mod scheduler_chirho;
209#[cfg(not(feature = "no-std"))]
210pub mod tms_chirho;
211#[cfg(not(feature = "no-std"))]
212pub mod tracing_chirho;
213#[cfg(not(feature = "no-std"))]
214pub mod worldview_chirho;
215
216/// High-performance arena-based implementation.
217///
218/// Enable with the `arena` feature for reduced allocation overhead.
219/// Not available in no_std mode.
220#[cfg(all(feature = "arena", not(feature = "no-std")))]
221#[cfg_attr(docsrs, doc(cfg(all(feature = "arena", not(feature = "no-std")))))]
222pub mod arena_chirho;
223
224/// Parallel propagation using rayon.
225///
226/// Enable with the `parallel` feature for concurrent propagation.
227/// Not available in no_std mode.
228#[cfg(all(feature = "parallel", not(feature = "no-std")))]
229#[cfg_attr(docsrs, doc(cfg(all(feature = "parallel", not(feature = "no-std")))))]
230pub mod parallel_chirho;
231
232/// WebAssembly bindings for browser/Node.js usage.
233///
234/// Enable with the `wasm` and `arena` features.
235/// Not available in no_std mode.
236#[cfg(all(feature = "wasm", feature = "arena", not(feature = "no-std")))]
237#[cfg_attr(
238 docsrs,
239 doc(cfg(all(feature = "wasm", feature = "arena", not(feature = "no-std"))))
240)]
241pub mod wasm_chirho;
242
243/// Python bindings via PyO3.
244///
245/// Enable with the `python` feature. Build with maturin.
246/// Not available in no_std mode.
247#[cfg(all(feature = "python", not(feature = "no-std")))]
248#[cfg_attr(docsrs, doc(cfg(all(feature = "python", not(feature = "no-std")))))]
249pub mod python_chirho;
250
251/// Kani formal verification proofs.
252///
253/// Enable with the `kani` feature and run with `cargo kani`.
254#[cfg(feature = "kani")]
255#[cfg_attr(docsrs, doc(cfg(feature = "kani")))]
256pub mod kani_proofs_chirho;
257
258// Re-exports for convenience
259// Core exports (always available)
260pub use algebra_chirho::{
261 BoundedJoinSemilatticeChirho, CommutativeSemigroupChirho, IdempotentSemigroupChirho,
262 JoinSemilatticeChirho, MonoidChirho, PropagatorErrorChirho, PropagatorResultChirho,
263 SemigroupChirho,
264};
265pub use interval_chirho::{IntervalChirho, NumericInfoChirho};
266pub use simd_chirho::{
267 batch_add_chirho, batch_intersect_chirho, batch_mul_chirho, batch_sqrt_chirho,
268 batch_square_chirho, batch_sub_chirho, IntervalVecChirho,
269};
270
271// Exports requiring std (not available in no_std mode)
272#[cfg(not(feature = "no-std"))]
273pub use amb_chirho::{
274 AmbChirho, BacktrackingSearchChirho, DependencyDirectedSearchChirho, SearchResultChirho,
275};
276#[cfg(not(feature = "no-std"))]
277pub use cell_chirho::{CellChirho, MergeableChirho};
278#[cfg(not(feature = "no-std"))]
279pub use constraint_system_chirho::ConstraintSystemChirho;
280#[cfg(not(feature = "no-std"))]
281pub use finite_domain_chirho::{
282 AllDifferentChirho, EqualsChirho, FiniteDomainChirho, LessThanChirho, NotEqualsChirho,
283};
284#[cfg(not(feature = "no-std"))]
285pub use generic_cell_chirho::{GenericCellChirho, GenericNetworkChirho};
286#[cfg(not(feature = "no-std"))]
287pub use lattice_chirho::{
288 AddPropagatorChirho, BoundedLatticeChirho, LatticeChirho, MulPropagatorChirho,
289 PropagatorComposeChirho, PropagatorFnChirho, SquarePropagatorChirho, SupportedValueChirho,
290};
291#[cfg(not(feature = "no-std"))]
292pub use propagator_chirho::{
293 AbsoluterChirho, ClampChirho, ConditionalChirho, ConstantChirho, ExpChirho,
294 IntervalAdderChirho, IntervalDividerChirho, IntervalMultiplierChirho, IntervalSubtractorChirho,
295 LnChirho, MaxChirho, MinChirho, NegaterChirho, PowerChirho, PropagatorChirho, SqrterChirho,
296 SquarerChirho,
297};
298#[cfg(not(feature = "no-std"))]
299pub use scheduler_chirho::SchedulerChirho;
300#[cfg(not(feature = "no-std"))]
301pub use tms_chirho::{
302 BeliefChirho, JustificationChirho, NogoodStoreChirho, PremiseSetChirho, SupportedChirho,
303 TmsCellChirho, TmsNetworkChirho,
304};
305#[cfg(not(feature = "no-std"))]
306pub use worldview_chirho::WorldviewChirho;
307
308// Feature-gated re-exports (requires std)
309#[cfg(all(feature = "arena", not(feature = "no-std")))]
310pub use arena_chirho::{ArenaNetworkChirho, CellIdChirho};
311
312#[cfg(all(feature = "parallel", not(feature = "no-std")))]
313pub use parallel_chirho::{
314 NumericParallelNetworkChirho, ParallelCellChirho, ParallelNetworkChirho,
315};
316
317/// Prelude module for convenient imports.
318///
319/// In no_std mode, only interval-related exports are available.
320///
321/// # Example
322///
323/// ```
324/// use propagators_chirho::prelude_chirho::*;
325/// ```
326#[cfg(not(feature = "no-std"))]
327pub mod prelude_chirho {
328 //! Convenient re-exports for common usage.
329
330 pub use crate::algebra_chirho::{
331 BoundedJoinSemilatticeChirho, JoinSemilatticeChirho, MonoidChirho, PropagatorErrorChirho,
332 PropagatorResultChirho, SemigroupChirho,
333 };
334 pub use crate::amb_chirho::{AmbChirho, BacktrackingSearchChirho, SearchResultChirho};
335 pub use crate::cell_chirho::{CellChirho, MergeableChirho};
336 pub use crate::constraint_system_chirho::ConstraintSystemChirho;
337 pub use crate::interval_chirho::{IntervalChirho, NumericInfoChirho};
338 pub use crate::propagator_chirho::{
339 AbsoluterChirho, ConditionalChirho, ConstantChirho, IntervalAdderChirho,
340 IntervalDividerChirho, IntervalMultiplierChirho, IntervalSubtractorChirho, MaxChirho,
341 MinChirho, PropagatorChirho, SqrterChirho, SquarerChirho,
342 };
343 pub use crate::scheduler_chirho::SchedulerChirho;
344 pub use crate::tms_chirho::{BeliefChirho, PremiseSetChirho, SupportedChirho, TmsCellChirho};
345 pub use crate::worldview_chirho::WorldviewChirho;
346}
347
348/// Minimal prelude for no_std mode.
349#[cfg(feature = "no-std")]
350pub mod prelude_chirho {
351 //! Minimal re-exports for no_std mode.
352 //!
353 //! Only interval arithmetic and algebraic traits are available.
354
355 pub use crate::algebra_chirho::{
356 BoundedJoinSemilatticeChirho, JoinSemilatticeChirho, MonoidChirho, PropagatorErrorChirho,
357 PropagatorResultChirho, SemigroupChirho,
358 };
359 pub use crate::interval_chirho::{IntervalChirho, NumericInfoChirho};
360}
361
362#[cfg(test)]
363#[cfg(not(feature = "no-std"))]
364mod tests_chirho {
365 use super::*;
366
367 #[test]
368 fn test_library_compiles_chirho() {
369 // Basic smoke test
370 let _interval_chirho = IntervalChirho::exact_chirho(42.0);
371 let _scheduler_chirho = SchedulerChirho::new_chirho();
372 }
373}