Starting tracer
This commit is contained in:
18
src/main.rs
18
src/main.rs
@ -1,3 +1,4 @@
|
||||
use log::info;
|
||||
use picolog::ast::Body;
|
||||
use picolog::ast::Module;
|
||||
use picolog::ast::Predicate;
|
||||
@ -21,14 +22,15 @@ fn main()
|
||||
"
|
||||
.into();
|
||||
|
||||
//let prop: Body = "integer(s(zero))".into();
|
||||
// let prop: Body = "mult(X, s(s(s(zero))), s(s(s(s(s(s(s(s(s(zero))))))))))".into();
|
||||
// for c in module.prove(&prop)
|
||||
// {
|
||||
// println!("true:");
|
||||
// println!("{}", c.simplified());
|
||||
// let _ = std::io::stdin().read_line(&mut String::new());
|
||||
// }
|
||||
//let prop: Body = "integer(s(X))".into();
|
||||
let prop: Body = "mult(X, s(s(s(zero))), s(s(s(s(s(s(s(s(s(zero))))))))))".into();
|
||||
for c in module.prove(&prop)
|
||||
{
|
||||
println!("true:");
|
||||
println!("{}", c.simplified());
|
||||
let _ = std::io::stdin().read_line(&mut String::new());
|
||||
}
|
||||
|
||||
// let p: Predicate = "add(s(zero), zero, Y)".into();
|
||||
// let p1: Predicate = "add(X, zero, X)".into();
|
||||
// // let p: Predicate = "integer(s(zero))".into();
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
pub mod constraints;
|
||||
pub mod trace;
|
||||
pub mod tracing;
|
||||
pub mod unification;
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::collections::VecDeque;
|
||||
use std::rc::Rc;
|
||||
|
||||
use litemap::LiteMap;
|
||||
@ -14,6 +13,9 @@ use crate::ast::Clause;
|
||||
use crate::ast::Module;
|
||||
use crate::ast::Predicate;
|
||||
use crate::prover::constraints::Constraints;
|
||||
use crate::prover::tracing::ProofType;
|
||||
use crate::prover::tracing::SimpleTracer;
|
||||
use crate::prover::tracing::Tracer;
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default)]
|
||||
pub struct Counter(usize);
|
||||
@ -46,45 +48,56 @@ impl GlobalCounter
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BodyProver<'a>
|
||||
pub struct BodyProver<'a, T: Tracer + 'a>
|
||||
{
|
||||
module: &'a Module,
|
||||
constraints: Constraints,
|
||||
|
||||
tracer: Option<T>,
|
||||
prover: Box<dyn Iterator<Item = Constraints> + 'a>,
|
||||
}
|
||||
|
||||
pub struct PredicateProver<'a>
|
||||
pub struct PredicateProver<'a, T: Tracer>
|
||||
{
|
||||
module: &'a Module,
|
||||
predicate: Predicate,
|
||||
constraints: Constraints,
|
||||
counter_snapshot: Counter,
|
||||
tracer: T,
|
||||
|
||||
global_counter: GlobalCounter,
|
||||
current_clause: usize,
|
||||
sub_proof: Option<BodyProver<'a>>,
|
||||
sub_proof: Option<BodyProver<'a, T>>,
|
||||
}
|
||||
|
||||
pub struct AndProver<'a>
|
||||
pub struct AndProver<'a, T: Tracer>
|
||||
{
|
||||
module: &'a Module,
|
||||
bodies: Vec<Body>,
|
||||
constraints: Constraints,
|
||||
tracer: T,
|
||||
|
||||
global_counter: GlobalCounter,
|
||||
sub_proofs: VecDeque<(Counter, BodyProver<'a>)>,
|
||||
sub_proofs: Vec<(Counter, BodyProver<'a, T>)>,
|
||||
}
|
||||
|
||||
impl BodyProver<'_>
|
||||
impl<'a, T: Tracer + 'a> BodyProver<'a, T>
|
||||
{
|
||||
pub fn new<'a>(
|
||||
pub fn new(
|
||||
module: &'a Module,
|
||||
global_counter: GlobalCounter,
|
||||
body: Body,
|
||||
constraints: Constraints,
|
||||
) -> BodyProver<'a>
|
||||
tracer: &T,
|
||||
) -> BodyProver<'a, T>
|
||||
{
|
||||
let body_tracer = if let Body::And(_) = body
|
||||
{
|
||||
Some(tracer.begin_proof(ProofType::Body, format!("Proving {}", body)))
|
||||
}
|
||||
else
|
||||
{
|
||||
None
|
||||
};
|
||||
let prover: Box<dyn Iterator<Item = Constraints>> = match &body
|
||||
{
|
||||
Body::Term(predicate) => Box::new(PredicateProver::new(
|
||||
@ -92,22 +105,26 @@ impl BodyProver<'_>
|
||||
global_counter,
|
||||
predicate.clone(),
|
||||
constraints.clone(),
|
||||
tracer,
|
||||
)),
|
||||
Body::And(items) => Box::new(AndProver::new(
|
||||
module,
|
||||
global_counter,
|
||||
items.clone(),
|
||||
constraints.clone(),
|
||||
tracer,
|
||||
)),
|
||||
Body::Or(items) => Box::new(BodyProver::new(
|
||||
module,
|
||||
global_counter,
|
||||
items[0].clone(),
|
||||
constraints.clone(),
|
||||
tracer,
|
||||
)),
|
||||
};
|
||||
info!(target: "BodyProver", "Proving {}", body);
|
||||
//info!(target: "BodyProver", "Proving {}", body);
|
||||
BodyProver {
|
||||
tracer: body_tracer,
|
||||
module,
|
||||
constraints,
|
||||
prover,
|
||||
@ -115,18 +132,20 @@ impl BodyProver<'_>
|
||||
}
|
||||
}
|
||||
|
||||
impl PredicateProver<'_>
|
||||
impl<'a, T: Tracer + 'a> PredicateProver<'a, T>
|
||||
{
|
||||
pub fn new<'a>(
|
||||
pub fn new(
|
||||
module: &'a Module,
|
||||
global_counter: GlobalCounter,
|
||||
predicate: Predicate,
|
||||
constraints: Constraints,
|
||||
) -> PredicateProver<'a>
|
||||
tracer: &T,
|
||||
) -> PredicateProver<'a, T>
|
||||
{
|
||||
info!(target: "PredicateProver", "Proving {}", predicate);
|
||||
//info!(target: "PredicateProver", "Proving {}", predicate);
|
||||
PredicateProver {
|
||||
module,
|
||||
tracer: tracer.begin_proof(ProofType::Predicate, format!("Proving {}", &predicate)),
|
||||
predicate,
|
||||
constraints,
|
||||
current_clause: 0,
|
||||
@ -137,28 +156,33 @@ impl PredicateProver<'_>
|
||||
}
|
||||
}
|
||||
|
||||
impl AndProver<'_>
|
||||
impl<T: Tracer> AndProver<'_, T>
|
||||
{
|
||||
pub fn new<'a>(
|
||||
module: &'a Module,
|
||||
global_counter: GlobalCounter,
|
||||
bodies: Vec<Body>,
|
||||
constraints: Constraints,
|
||||
) -> AndProver<'a>
|
||||
tracer: &T,
|
||||
) -> AndProver<'a, T>
|
||||
where
|
||||
T: 'a,
|
||||
{
|
||||
assert!(!bodies.is_empty());
|
||||
|
||||
AndProver {
|
||||
tracer: tracer.begin_proof(ProofType::And),
|
||||
module,
|
||||
sub_proofs: VecDeque::from(vec![(
|
||||
sub_proofs: vec![(
|
||||
global_counter.snapshot(),
|
||||
BodyProver::new(
|
||||
module,
|
||||
global_counter.clone(),
|
||||
bodies[0].clone(),
|
||||
constraints.clone(),
|
||||
tracer,
|
||||
),
|
||||
)]),
|
||||
)],
|
||||
bodies,
|
||||
constraints,
|
||||
global_counter,
|
||||
@ -166,7 +190,7 @@ impl AndProver<'_>
|
||||
}
|
||||
}
|
||||
|
||||
impl Iterator for PredicateProver<'_>
|
||||
impl<'a, T: Tracer + 'a> Iterator for PredicateProver<'a, T>
|
||||
{
|
||||
type Item = Constraints;
|
||||
|
||||
@ -184,17 +208,17 @@ impl Iterator for PredicateProver<'_>
|
||||
{
|
||||
let clause = &self.module.clauses[self.current_clause]
|
||||
.make_unique(self.global_counter.clone());
|
||||
info!(target: "PredicateProver", "Unifying '{}' against '{}'", self.predicate, clause);
|
||||
//info!(target: "PredicateProver", "Unifying '{}' against '{}'", self.predicate, clause);
|
||||
let uni = self.predicate.matches(&clause.head);
|
||||
let full_constraints = uni.and_then(|x| x.and(&self.constraints));
|
||||
|
||||
if let Some(c) = &full_constraints
|
||||
{
|
||||
info!(target: "PredicateProver", " => {}", c);
|
||||
//info!(target: "PredicateProver", " => {}", c);
|
||||
}
|
||||
else
|
||||
{
|
||||
info!(target: "PredicateProver", " => (Can't unify)");
|
||||
//info!(target: "PredicateProver", " => (Can't unify)");
|
||||
}
|
||||
match full_constraints
|
||||
{
|
||||
@ -212,6 +236,7 @@ impl Iterator for PredicateProver<'_>
|
||||
self.global_counter.clone(),
|
||||
clause.body.clone().unwrap(),
|
||||
constraints,
|
||||
&self.tracer,
|
||||
));
|
||||
self.next()
|
||||
}
|
||||
@ -241,7 +266,7 @@ impl Iterator for PredicateProver<'_>
|
||||
}
|
||||
}
|
||||
|
||||
impl Iterator for BodyProver<'_>
|
||||
impl<'a, T: Tracer + 'a> Iterator for BodyProver<'a, T>
|
||||
{
|
||||
type Item = Constraints;
|
||||
fn next(&mut self) -> Option<Constraints>
|
||||
@ -250,7 +275,7 @@ impl Iterator for BodyProver<'_>
|
||||
}
|
||||
}
|
||||
|
||||
impl Iterator for AndProver<'_>
|
||||
impl<'a, T: Tracer + 'a> Iterator for AndProver<'a, T>
|
||||
{
|
||||
type Item = Constraints;
|
||||
|
||||
@ -261,7 +286,7 @@ impl Iterator for AndProver<'_>
|
||||
return None;
|
||||
}
|
||||
|
||||
let (current_proof_snap, mut current_proof) = self.sub_proofs.pop_back().unwrap();
|
||||
let (current_proof_snap, mut current_proof) = self.sub_proofs.pop().unwrap();
|
||||
|
||||
match current_proof.next()
|
||||
{
|
||||
@ -269,21 +294,20 @@ impl Iterator for AndProver<'_>
|
||||
{
|
||||
if self.sub_proofs.len() == self.bodies.len() - 1
|
||||
{
|
||||
self.sub_proofs
|
||||
.push_back((current_proof_snap, current_proof));
|
||||
self.sub_proofs.push((current_proof_snap, current_proof));
|
||||
Some(constraints)
|
||||
}
|
||||
else
|
||||
{
|
||||
self.sub_proofs
|
||||
.push_back((current_proof_snap, current_proof));
|
||||
self.sub_proofs.push_back((
|
||||
self.sub_proofs.push((current_proof_snap, current_proof));
|
||||
self.sub_proofs.push((
|
||||
self.global_counter.snapshot(),
|
||||
BodyProver::new(
|
||||
self.module,
|
||||
self.global_counter.clone(),
|
||||
self.bodies[self.sub_proofs.len()].clone(),
|
||||
constraints,
|
||||
&self.tracer,
|
||||
),
|
||||
));
|
||||
self.next()
|
||||
@ -300,13 +324,14 @@ impl Iterator for AndProver<'_>
|
||||
|
||||
impl Module
|
||||
{
|
||||
pub fn prove<'a>(&'a self, body: &'a Body) -> BodyProver<'a>
|
||||
pub fn prove<'a>(&'a self, body: &'a Body) -> BodyProver<'a, SimpleTracer>
|
||||
{
|
||||
BodyProver::new(
|
||||
self,
|
||||
GlobalCounter::new(),
|
||||
body.clone(),
|
||||
Constraints::none(),
|
||||
&SimpleTracer::new(ProofType::Body),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ use std::fmt::Display;
|
||||
|
||||
use litemap::LiteMap;
|
||||
|
||||
use crate::ast::Body;
|
||||
use crate::ast::Predicate;
|
||||
use crate::ast::Variable;
|
||||
|
||||
@ -128,8 +129,7 @@ impl Predicate
|
||||
{
|
||||
if let Some(pred) = constraints.set.get(name)
|
||||
{
|
||||
let max_sub = pred.substitute(constraints);
|
||||
max_sub
|
||||
pred.substitute(constraints)
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -151,10 +151,23 @@ impl Predicate
|
||||
match self
|
||||
{
|
||||
Predicate::Variable(var_name) => name == var_name,
|
||||
Predicate::Fixed(_, predicates) => predicates
|
||||
.iter()
|
||||
.find(|x| x.contains_variable(name))
|
||||
.is_some(),
|
||||
Predicate::Fixed(_, predicates) => predicates.iter().any(|x| x.contains_variable(name)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Body
|
||||
{
|
||||
pub fn substitute(&self, constraints: &Constraints) -> Body
|
||||
{
|
||||
match self
|
||||
{
|
||||
Body::Term(predicate) => Body::Term(predicate.substitute(constraints)),
|
||||
Body::And(items) =>
|
||||
{
|
||||
Body::And(items.iter().map(|x| x.substitute(constraints)).collect())
|
||||
}
|
||||
Body::Or(items) => Body::Or(items.iter().map(|x| x.substitute(constraints)).collect()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use std::fmt::Display;
|
||||
use std::{default, fmt::Display};
|
||||
|
||||
use log::info;
|
||||
|
||||
@ -25,9 +25,9 @@ impl Display for ProofType
|
||||
|
||||
pub trait Tracer
|
||||
{
|
||||
fn next_step(&mut self, proof_type: ProofType) -> Self;
|
||||
fn milestone<T: Display>(&self, str: T);
|
||||
fn explain<T: Display>(&self, str: T);
|
||||
fn begin_proof<T: Display>(&self, proof_type: ProofType) -> Self;
|
||||
fn print_step<T: Display>(&self, show: T);
|
||||
fn end_proof(self);
|
||||
}
|
||||
|
||||
pub struct SimpleTracer
|
||||
@ -35,21 +35,29 @@ pub struct SimpleTracer
|
||||
proof_type: ProofType,
|
||||
}
|
||||
|
||||
impl SimpleTracer
|
||||
{
|
||||
pub fn new(proof_type: ProofType) -> Self
|
||||
{
|
||||
Self { proof_type }
|
||||
}
|
||||
}
|
||||
|
||||
impl Tracer for SimpleTracer
|
||||
{
|
||||
fn next_step(&mut self, proof_type: ProofType) -> Self
|
||||
fn begin_proof<T: Display>(&self, proof_type: ProofType) -> Self
|
||||
{
|
||||
SimpleTracer { proof_type }
|
||||
}
|
||||
|
||||
fn explain<T: Display>(&self, str: T)
|
||||
fn print_step<T: Display>(&self, show: T)
|
||||
{
|
||||
let proof_str = format!("{}", self.proof_type);
|
||||
info!(target: &proof_str, "{}", str);
|
||||
let str = format!("{}", self.proof_type);
|
||||
info!(target: &str, "{}", show);
|
||||
}
|
||||
|
||||
fn milestone<T: Display>(&self, str: T)
|
||||
fn end_proof(self)
|
||||
{
|
||||
self.explain(str);
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
use std::process::Output;
|
||||
|
||||
use log::debug;
|
||||
|
||||
use crate::ast::Predicate;
|
||||
@ -17,7 +15,7 @@ impl Predicate
|
||||
{
|
||||
Predicate::Variable(variable) =>
|
||||
{
|
||||
debug!("Unifying var {} against {}", self, other);
|
||||
//debug!("Unifying var {} against {}", self, other);
|
||||
// We are trying to see if X (any) matches the other Predicate.
|
||||
// This is always true if X = other_predicate
|
||||
Some(Constraints::with(variable.clone(), other.clone()))
|
||||
@ -32,7 +30,7 @@ impl Predicate
|
||||
// We are trying to see if something like "predicate(..., ...)" matches X
|
||||
// (any)
|
||||
// This is always true
|
||||
debug!("Unifying pred {} against var {}", self, other);
|
||||
//debug!("Unifying pred {} against var {}", self, other);
|
||||
Some(Constraints::with(var.clone(), self.clone()))
|
||||
}
|
||||
// Match pred(X, Y, Z, ...) with pred(_X, _Y, _Z, ...)
|
||||
@ -40,7 +38,7 @@ impl Predicate
|
||||
if other_name == name && other_arguments.len() == arguments.len() =>
|
||||
{
|
||||
// If there is no arguments, no constraints
|
||||
debug!("Unifying fixed {} against fixed {}", self, other);
|
||||
//debug!("Unifying fixed {} against fixed {}", self, other);
|
||||
if arguments.is_empty()
|
||||
{
|
||||
return Some(Constraints::none());
|
||||
|
||||
Reference in New Issue
Block a user