Starts proof cache infra
This commit is contained in:
25
src/ast.rs
25
src/ast.rs
@ -1,7 +1,9 @@
|
||||
use crate::prover::tracing::colored_var;
|
||||
use owo_colors::{OwoColorize, colors::css::Gray};
|
||||
|
||||
use std::fmt::Display;
|
||||
|
||||
pub type Variable = String;
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||
pub struct Variable(pub String, pub Option<usize>);
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Module
|
||||
@ -16,7 +18,7 @@ pub struct Clause
|
||||
pub body: Option<Body>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub enum Body
|
||||
{
|
||||
Term(Predicate),
|
||||
@ -24,7 +26,7 @@ pub enum Body
|
||||
Or(Vec<Body>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
|
||||
pub enum Predicate
|
||||
{
|
||||
Variable(Variable), // Upercase variable like X
|
||||
@ -55,13 +57,26 @@ impl Display for Body
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Variable
|
||||
{
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result
|
||||
{
|
||||
write!(f, "{}", self.0)?;
|
||||
if let Some(num) = self.1
|
||||
{
|
||||
write!(f, "{}", format!("[{}]", num).fg::<Gray>())?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Predicate
|
||||
{
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result
|
||||
{
|
||||
match self
|
||||
{
|
||||
Predicate::Variable(variable) => write!(f, "{}", colored_var(variable)),
|
||||
Predicate::Variable(variable) => write!(f, "{}", variable),
|
||||
Predicate::Fixed(name, predicates) =>
|
||||
{
|
||||
write!(f, "{}", name)?;
|
||||
|
||||
@ -15,6 +15,7 @@ use crate::ast::Body;
|
||||
use crate::ast::Clause;
|
||||
use crate::ast::Module;
|
||||
use crate::ast::Predicate;
|
||||
use crate::ast::Variable;
|
||||
|
||||
pub fn predicate_parse(input: &mut &str) -> Result<Predicate>
|
||||
{
|
||||
@ -23,7 +24,7 @@ pub fn predicate_parse(input: &mut &str) -> Result<Predicate>
|
||||
// Check if output is a variable
|
||||
if ident.chars().next().is_some_and(|char| char.is_uppercase())
|
||||
{
|
||||
Ok(Predicate::Variable(String::from(ident)))
|
||||
Ok(Predicate::Variable(Variable(String::from(ident), None)))
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@ -4,18 +4,20 @@ pub mod constraints;
|
||||
pub mod not;
|
||||
pub mod or;
|
||||
pub mod predicate;
|
||||
pub mod proof_cache;
|
||||
pub mod tracing;
|
||||
pub mod unification;
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::collections::HashMap;
|
||||
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::ast::Variable;
|
||||
use crate::prover::body::BodyProver;
|
||||
use crate::prover::constraints::Constraints;
|
||||
use crate::prover::tracing::IndentedTracer;
|
||||
|
||||
@ -69,7 +71,7 @@ impl Clause
|
||||
{
|
||||
pub fn make_unique(&self, counter: GlobalCounter) -> Clause
|
||||
{
|
||||
let mut unique_map = LiteMap::new();
|
||||
let mut unique_map = HashMap::new();
|
||||
Clause {
|
||||
head: self.head.make_unique(counter.clone(), &mut unique_map),
|
||||
body: self
|
||||
@ -85,7 +87,7 @@ impl Body
|
||||
pub fn make_unique(
|
||||
&self,
|
||||
counter: GlobalCounter,
|
||||
unique_map: &mut LiteMap<String, usize>,
|
||||
unique_map: &mut HashMap<Variable, usize>,
|
||||
) -> Body
|
||||
{
|
||||
match self
|
||||
@ -112,18 +114,15 @@ impl Predicate
|
||||
pub fn make_unique(
|
||||
&self,
|
||||
counter: GlobalCounter,
|
||||
unique_map: &mut LiteMap<String, usize>,
|
||||
unique_map: &mut HashMap<Variable, usize>,
|
||||
) -> Self
|
||||
{
|
||||
match self
|
||||
{
|
||||
Predicate::Variable(name) => Predicate::Variable(format!(
|
||||
"_{}[{}]",
|
||||
name,
|
||||
unique_map
|
||||
.entry(name.clone())
|
||||
.or_insert_with(|| counter.get())
|
||||
)),
|
||||
Predicate::Variable(var) =>
|
||||
{
|
||||
Predicate::Variable(var.make_unique(counter.clone(), unique_map))
|
||||
}
|
||||
Predicate::Fixed(name, predicates) => Predicate::Fixed(
|
||||
name.clone(),
|
||||
predicates
|
||||
@ -134,3 +133,22 @@ impl Predicate
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Variable
|
||||
{
|
||||
pub fn make_unique(
|
||||
&self,
|
||||
counter: GlobalCounter,
|
||||
unique_map: &mut HashMap<Variable, usize>,
|
||||
) -> Self
|
||||
{
|
||||
Variable(
|
||||
self.0.clone(),
|
||||
Some(
|
||||
*unique_map
|
||||
.entry(self.clone())
|
||||
.or_insert_with(|| counter.get()),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,16 +1,14 @@
|
||||
use std::collections::HashMap;
|
||||
use std::fmt::Display;
|
||||
|
||||
use litemap::LiteMap;
|
||||
|
||||
use crate::ast::Body;
|
||||
use crate::ast::Predicate;
|
||||
use crate::ast::Variable;
|
||||
use crate::prover::tracing::colored_var;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Constraints
|
||||
{
|
||||
set: LiteMap<Variable, Predicate>,
|
||||
set: HashMap<Variable, Predicate>,
|
||||
}
|
||||
|
||||
impl Constraints
|
||||
@ -18,7 +16,7 @@ impl Constraints
|
||||
pub fn none() -> Self
|
||||
{
|
||||
Constraints {
|
||||
set: LiteMap::new(),
|
||||
set: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -103,7 +101,7 @@ impl Constraints
|
||||
let mut stripped = max_sub.clone();
|
||||
'outer: for (var, _) in max_sub.set.iter()
|
||||
{
|
||||
if var.chars().next().is_some_and(|x| x == '_')
|
||||
if var.0.chars().next().is_some_and(|x| x == '_') || var.1.is_some()
|
||||
{
|
||||
for (_, other_pred) in max_sub.set.iter()
|
||||
{
|
||||
@ -147,7 +145,7 @@ impl Predicate
|
||||
}
|
||||
}
|
||||
|
||||
pub fn contains_variable(&self, name: &String) -> bool
|
||||
pub fn contains_variable(&self, name: &Variable) -> bool
|
||||
{
|
||||
match self
|
||||
{
|
||||
@ -188,7 +186,7 @@ impl Display for Constraints
|
||||
let len = self.set.len();
|
||||
for (i, (var, pred)) in self.set.iter().enumerate()
|
||||
{
|
||||
write!(f, "{} = {}", colored_var(var), pred)?;
|
||||
write!(f, "{} = {}", var, pred)?;
|
||||
if i != len - 1
|
||||
{
|
||||
write!(f, ", ")?;
|
||||
|
||||
150
src/prover/proof_cache.rs
Normal file
150
src/prover/proof_cache.rs
Normal file
@ -0,0 +1,150 @@
|
||||
use std::{cell::RefCell, num::NonZero, rc::Rc};
|
||||
|
||||
use bimap::BiHashMap;
|
||||
use lru::LruCache;
|
||||
|
||||
use crate::{
|
||||
ast::{Body, Predicate, Variable},
|
||||
prover::{
|
||||
body::{self, BodyProver},
|
||||
constraints::Constraints,
|
||||
},
|
||||
};
|
||||
|
||||
pub struct PartialProof<T: Iterator<Item = Constraints>>
|
||||
{
|
||||
proved: Vec<Constraints>,
|
||||
prover: T,
|
||||
}
|
||||
|
||||
pub struct CachedProver<'a>
|
||||
{
|
||||
cache: Rc<RefCell<LruCache<Body, PartialProof<BodyProver<'a>>>>>,
|
||||
body: Body,
|
||||
mapping: VariableMap,
|
||||
proof_counter: usize,
|
||||
}
|
||||
|
||||
pub struct ProofCache<'a>
|
||||
{
|
||||
cache: Rc<RefCell<LruCache<Body, PartialProof<BodyProver<'a>>>>>,
|
||||
}
|
||||
|
||||
impl<'a> ProofCache<'a>
|
||||
{
|
||||
pub fn new(size: NonZero<usize>) -> Self
|
||||
{
|
||||
ProofCache {
|
||||
cache: Rc::new(RefCell::new(LruCache::new(size))),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn prove(&mut self, body: &Body) -> CachedProver<'a>
|
||||
{
|
||||
let (varmap, normalized) = body.normalized();
|
||||
|
||||
// Check if in cache ?
|
||||
match self.cache.borrow().get(&normalized)
|
||||
{
|
||||
Some() => todo!(),
|
||||
None => todo!(),
|
||||
}
|
||||
|
||||
CachedProver {
|
||||
cache: self.cache.clone(),
|
||||
body: normalized,
|
||||
mapping: todo!(),
|
||||
proof_counter: todo!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Normalization
|
||||
|
||||
pub struct VariableMap(BiHashMap<Variable, Variable>);
|
||||
|
||||
pub trait Normalizable: Sized
|
||||
{
|
||||
fn normalized(&self) -> (VariableMap, Self)
|
||||
{
|
||||
let mut bimap = BiHashMap::new();
|
||||
let mut counter = 0;
|
||||
let normalized = self.normalized_with(&mut counter, &mut bimap);
|
||||
|
||||
(VariableMap(bimap), normalized)
|
||||
}
|
||||
|
||||
fn normalized_with(&self, counter: &mut usize, map: &mut BiHashMap<Variable, Variable>)
|
||||
-> Self;
|
||||
}
|
||||
|
||||
impl<T: Normalizable> Normalizable for Vec<T>
|
||||
{
|
||||
fn normalized_with(&self, counter: &mut usize, map: &mut BiHashMap<Variable, Variable>)
|
||||
-> Self
|
||||
{
|
||||
self.iter()
|
||||
.map(|x| x.normalized_with(counter, map))
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl Normalizable for Body
|
||||
{
|
||||
fn normalized_with(&self, counter: &mut usize, map: &mut BiHashMap<Variable, Variable>)
|
||||
-> Body
|
||||
{
|
||||
match self
|
||||
{
|
||||
Body::Term(predicate) => Body::Term(predicate.normalized_with(counter, map)),
|
||||
Body::And(items) => Body::And(items.normalized_with(counter, map)),
|
||||
Body::Or(items) => Body::Or(items.normalized_with(counter, map)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Normalizable for Predicate
|
||||
{
|
||||
fn normalized_with(
|
||||
&self,
|
||||
counter: &mut usize,
|
||||
map: &mut BiHashMap<Variable, Variable>,
|
||||
) -> Predicate
|
||||
{
|
||||
match self
|
||||
{
|
||||
Predicate::Variable(variable) =>
|
||||
{
|
||||
Predicate::Variable(variable.normalized_with(counter, map))
|
||||
}
|
||||
Predicate::Fixed(name, predicates) =>
|
||||
{
|
||||
Predicate::Fixed(name.clone(), predicates.normalized_with(counter, map))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Normalizable for Variable
|
||||
{
|
||||
fn normalized_with(
|
||||
&self,
|
||||
counter: &mut usize,
|
||||
map: &mut BiHashMap<Variable, Variable>,
|
||||
) -> Variable
|
||||
{
|
||||
match map.get_by_left(&self)
|
||||
{
|
||||
Some(normalized) => normalized.clone(),
|
||||
None =>
|
||||
{
|
||||
let val = *counter;
|
||||
*counter += 1;
|
||||
|
||||
let var = Variable(self.0.clone(), Some(val));
|
||||
map.insert(self.clone(), var.clone());
|
||||
var
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -132,18 +132,3 @@ impl Default for IndentedTracer
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn colored_var(var: &Variable) -> String
|
||||
{
|
||||
let mut idx = None;
|
||||
for (i, char) in var.chars().enumerate()
|
||||
{
|
||||
if char == '['
|
||||
{
|
||||
idx = Some(i);
|
||||
}
|
||||
}
|
||||
let (var, unique) = var.split_at(idx.unwrap_or(var.len()));
|
||||
let unique = unique.fg::<Gray>();
|
||||
format!("{}{}", var, unique)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user