Files
picolog/src/prover.rs
2026-02-10 00:07:06 +01:00

137 lines
3.0 KiB
Rust

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<Cell<usize>>);
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<String, usize>,
) -> 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<String, usize>,
) -> 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(),
),
}
}
}