pub mod and; pub mod body; pub mod constraints; pub mod not; pub mod or; pub mod predicate; pub mod tracing; pub mod unification; use std::cell::Cell; use std::rc::Rc; use litemap::LiteMap; use crate::ast::Body; use crate::ast::Clause; use crate::ast::Module; use crate::ast::Predicate; use crate::prover::constraints::Constraints; use crate::prover::tracing::IndentedTracer; #[derive(Clone, Copy, Debug, Default)] pub struct Counter(usize); #[derive(Clone, Debug, Default)] pub struct GlobalCounter(Rc>); impl GlobalCounter { pub fn new() -> GlobalCounter { GlobalCounter(Rc::new(Cell::new(0))) } pub fn get(&self) -> usize { let val = self.0.get(); self.0.set(val + 1); val } pub fn snapshot(&self) -> Counter { Counter(self.0.get()) } pub fn restore(&mut self, snapshot: Counter) { self.0.set(snapshot.0); } } impl Module { pub fn prove<'a>(&'a self, body: &'a Body) -> BodyProver<'a> { BodyProver::new( self, GlobalCounter::new(), body.clone(), Constraints::none(), &mut IndentedTracer::new(), //&SimpleTracer::new(ProofType::Body), ) } } impl Clause { pub fn make_unique(&self, counter: GlobalCounter) -> Clause { let mut unique_map = LiteMap::new(); Clause { head: self.head.make_unique(counter.clone(), &mut unique_map), body: self .body .as_ref() .map(|body| body.make_unique(counter.clone(), &mut unique_map)), } } } impl Body { pub fn make_unique( &self, counter: GlobalCounter, unique_map: &mut LiteMap, ) -> Body { match self { Body::Term(predicate) => Body::Term(predicate.make_unique(counter.clone(), unique_map)), Body::And(items) => Body::And( items .iter() .map(|x| x.make_unique(counter.clone(), unique_map)) .collect(), ), Body::Or(items) => Body::Or( items .iter() .map(|x| x.make_unique(counter.clone(), unique_map)) .collect(), ), } } } impl Predicate { pub fn make_unique( &self, counter: GlobalCounter, unique_map: &mut LiteMap, ) -> Self { match self { Predicate::Variable(name) => Predicate::Variable(format!( "_{}[{}]", name, unique_map .entry(name.clone()) .or_insert_with(|| counter.get()) )), Predicate::Fixed(name, predicates) => Predicate::Fixed( name.clone(), predicates .iter() .map(|x| x.make_unique(counter.clone(), unique_map)) .collect(), ), } } }