pub mod constraint;
pub mod display;
pub mod generator;
pub mod hybrid;
pub mod ir;
pub mod learning;
pub mod lightning_strike;
pub mod meta_reasoning;
pub mod optimization;
pub mod router;
pub mod smt_stub;
pub mod z3_backend;
use serde::{Deserialize, Serialize};
pub use smt_stub as smt;
pub mod surrogate;
pub mod verify;
pub use constraint::*;
pub use generator::*;
pub use hybrid::*;
pub use ir::*;
pub use learning::*;
pub use lightning_strike::*;
pub use meta_reasoning::*;
pub use optimization::*;
pub use router::*;
pub use smt_stub::*; pub use surrogate::*;
pub use verify::*;
pub use z3_backend::*;
use anyhow::Result;
pub struct NeuroSymbolicEngine {
theory_generator: Box<dyn TheoryGenerator>,
solver_surrogate: Box<dyn SolverSurrogate>,
smt_backend: SmtBackend,
router: SpeculateVerifyRouter,
}
impl NeuroSymbolicEngine {
pub fn new(
theory_generator: Box<dyn TheoryGenerator>,
solver_surrogate: Box<dyn SolverSurrogate>,
smt_backend: SmtBackend,
) -> Result<Self> {
let router = SpeculateVerifyRouter::new();
Ok(Self {
theory_generator,
solver_surrogate,
smt_backend,
router,
})
}
pub async fn reason(&mut self, input: &Tensor) -> Result<ReasoningResult> {
let constraint_ir = self.theory_generator.generate_constraints(input)?;
let strategy = self.router.route(&constraint_ir)?;
match strategy {
ReasoningStrategy::Speculate => {
let result = self.solver_surrogate.predict_solution(&constraint_ir)?;
if self.validate_plausibility(&constraint_ir, &result)? {
Ok(ReasoningResult::Speculated(result))
} else {
self.verify_with_smt(&constraint_ir).await
}
}
ReasoningStrategy::Verify => {
self.verify_with_smt(&constraint_ir).await
}
ReasoningStrategy::Hybrid => {
let speculated = self.solver_surrogate.predict_solution(&constraint_ir)?;
let verified = self.verify_with_smt(&constraint_ir).await?;
Ok(ReasoningResult::Hybrid {
speculated,
verified: match verified {
ReasoningResult::Verified(sol) => sol,
_ => return Err(anyhow::anyhow!("Expected verified result")),
},
})
}
}
}
fn validate_plausibility(
&self,
constraint_ir: &ConstraintIR,
result: &SolutionResult,
) -> Result<bool> {
use crate::verify::{PlausibilityChecker, PlausibilityConfig};
let checker = PlausibilityChecker::new(PlausibilityConfig::default());
let plausibility_result = checker.check_plausibility(constraint_ir, result)?;
Ok(plausibility_result.plausible)
}
async fn verify_with_smt(&mut self, constraint_ir: &ConstraintIR) -> Result<ReasoningResult> {
let solution = self.smt_backend.solve(constraint_ir).await?;
Ok(ReasoningResult::Verified(solution))
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum ReasoningStrategy {
Speculate,
Verify,
Hybrid,
}
#[derive(Debug, Clone)]
pub enum ReasoningResult {
Speculated(SolutionResult),
Verified(SolutionResult),
Hybrid {
speculated: SolutionResult,
verified: SolutionResult,
},
}