clean up arithmetic.rs
This commit is contained in:
@@ -1,6 +1,5 @@
|
|||||||
use prolog::ast::*;
|
use prolog::ast::*;
|
||||||
use prolog::fixtures::*;
|
use prolog::fixtures::*;
|
||||||
use prolog::tabled_rc::*;
|
|
||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::cmp::{min, max};
|
use std::cmp::{min, max};
|
||||||
@@ -21,8 +20,8 @@ impl<'a> ArithInstructionIterator<'a> {
|
|||||||
let state = match term {
|
let state = match term {
|
||||||
&Term::AnonVar =>
|
&Term::AnonVar =>
|
||||||
return Err(ArithmeticError::InvalidTerm),
|
return Err(ArithmeticError::InvalidTerm),
|
||||||
&Term::Clause(_, _, ref terms, _) =>
|
&Term::Clause(_, ref name, ref terms, _) =>
|
||||||
TermIterState::Clause(0, ClauseType::Root, terms),
|
TermIterState::Clause(0, ClauseType::Root(name), terms),
|
||||||
&Term::Constant(ref cell, ref cons) =>
|
&Term::Constant(ref cell, ref cons) =>
|
||||||
TermIterState::Constant(Level::Shallow, cell, cons),
|
TermIterState::Constant(Level::Shallow, cell, cons),
|
||||||
&Term::Cons(_, _, _) =>
|
&Term::Cons(_, _, _) =>
|
||||||
@@ -37,7 +36,7 @@ impl<'a> ArithInstructionIterator<'a> {
|
|||||||
|
|
||||||
pub enum ArithTermRef<'a> {
|
pub enum ArithTermRef<'a> {
|
||||||
Constant(&'a Constant),
|
Constant(&'a Constant),
|
||||||
Op(ClauseType<'a>, &'a Vec<Box<Term>>),
|
Op(&'a str, usize), // name, arity.
|
||||||
Var(&'a Cell<VarReg>, &'a Var)
|
Var(&'a Cell<VarReg>, &'a Var)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,8 +49,10 @@ impl<'a> Iterator for ArithInstructionIterator<'a> {
|
|||||||
TermIterState::AnonVar(_) =>
|
TermIterState::AnonVar(_) =>
|
||||||
return Some(Err(ArithmeticError::UninstantiatedVar)),
|
return Some(Err(ArithmeticError::UninstantiatedVar)),
|
||||||
TermIterState::Clause(child_num, ct, child_terms) => {
|
TermIterState::Clause(child_num, ct, child_terms) => {
|
||||||
if child_num == child_terms.len() {
|
let arity = child_terms.len();
|
||||||
return Some(Ok(ArithTermRef::Op(ct, child_terms)));
|
|
||||||
|
if child_num == arity {
|
||||||
|
return Some(Ok(ArithTermRef::Op(ct.name(), arity)));
|
||||||
} else {
|
} else {
|
||||||
self.state_stack.push(TermIterState::Clause(child_num + 1, ct, child_terms));
|
self.state_stack.push(TermIterState::Clause(child_num + 1, ct, child_terms));
|
||||||
self.push_subterm(ct.level_of_subterms(), child_terms[child_num].as_ref());
|
self.push_subterm(ct.level_of_subterms(), child_terms[child_num].as_ref());
|
||||||
@@ -73,29 +74,21 @@ impl<'a> Iterator for ArithInstructionIterator<'a> {
|
|||||||
pub struct ArithmeticEvaluator<'a> {
|
pub struct ArithmeticEvaluator<'a> {
|
||||||
bindings: &'a AllocVarDict<'a>,
|
bindings: &'a AllocVarDict<'a>,
|
||||||
interm: Vec<ArithmeticTerm>,
|
interm: Vec<ArithmeticTerm>,
|
||||||
interm_c: usize
|
interm_c: usize
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ArithmeticTermIter<'a> {
|
pub trait ArithmeticTermIter<'a> {
|
||||||
type Iter : Iterator<Item=Result<ArithTermRef<'a>, ArithmeticError>>;
|
type Iter : Iterator<Item=Result<ArithTermRef<'a>, ArithmeticError>>;
|
||||||
|
|
||||||
fn iter(&self) -> Result<Self::Iter, ArithmeticError>;
|
fn iter(&self) -> Result<Self::Iter, ArithmeticError>;
|
||||||
fn root_name(&self) -> Result<TabledRc<Atom>, ArithmeticError>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ArithmeticTermIter<'a> for &'a Term {
|
impl<'a> ArithmeticTermIter<'a> for &'a Term {
|
||||||
type Iter = ArithInstructionIterator<'a>;
|
type Iter = ArithInstructionIterator<'a>;
|
||||||
|
|
||||||
fn iter(&self) -> Result<Self::Iter, ArithmeticError> {
|
fn iter(&self) -> Result<Self::Iter, ArithmeticError> {
|
||||||
ArithInstructionIterator::new(self)
|
ArithInstructionIterator::new(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn root_name(&self) -> Result<TabledRc<Atom>, ArithmeticError> {
|
|
||||||
match self {
|
|
||||||
&&Term::Clause(_, ref name, _, _) => Ok(name.clone()),
|
|
||||||
_ => Err(ArithmeticError::InvalidTerm)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ArithmeticEvaluator<'a>
|
impl<'a> ArithmeticEvaluator<'a>
|
||||||
@@ -103,20 +96,20 @@ impl<'a> ArithmeticEvaluator<'a>
|
|||||||
pub fn new(bindings: &'a AllocVarDict<'a>, target_int: usize) -> Self {
|
pub fn new(bindings: &'a AllocVarDict<'a>, target_int: usize) -> Self {
|
||||||
ArithmeticEvaluator { bindings, interm: Vec::new(), interm_c: target_int }
|
ArithmeticEvaluator { bindings, interm: Vec::new(), interm_c: target_int }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_unary_instr(name: &Atom, a1: ArithmeticTerm, t: usize)
|
fn get_unary_instr(name: &str, a1: ArithmeticTerm, t: usize)
|
||||||
-> Result<ArithmeticInstruction, ArithmeticError>
|
-> Result<ArithmeticInstruction, ArithmeticError>
|
||||||
{
|
{
|
||||||
match name.as_str() {
|
match name {
|
||||||
"-" => Ok(ArithmeticInstruction::Neg(a1, t)),
|
"-" => Ok(ArithmeticInstruction::Neg(a1, t)),
|
||||||
_ => Err(ArithmeticError::InvalidOp)
|
_ => Err(ArithmeticError::InvalidOp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_binary_instr(name: &Atom, a1: ArithmeticTerm, a2: ArithmeticTerm, t: usize)
|
fn get_binary_instr(name: &str, a1: ArithmeticTerm, a2: ArithmeticTerm, t: usize)
|
||||||
-> Result<ArithmeticInstruction, ArithmeticError>
|
-> Result<ArithmeticInstruction, ArithmeticError>
|
||||||
{
|
{
|
||||||
match name.as_str() {
|
match name {
|
||||||
"+" => Ok(ArithmeticInstruction::Add(a1, a2, t)),
|
"+" => Ok(ArithmeticInstruction::Add(a1, a2, t)),
|
||||||
"-" => Ok(ArithmeticInstruction::Sub(a1, a2, t)),
|
"-" => Ok(ArithmeticInstruction::Sub(a1, a2, t)),
|
||||||
"/" => Ok(ArithmeticInstruction::Div(a1, a2, t)),
|
"/" => Ok(ArithmeticInstruction::Div(a1, a2, t)),
|
||||||
@@ -134,7 +127,7 @@ impl<'a> ArithmeticEvaluator<'a>
|
|||||||
_ => Err(ArithmeticError::InvalidOp)
|
_ => Err(ArithmeticError::InvalidOp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn incr_interm(&mut self) -> usize {
|
fn incr_interm(&mut self) -> usize {
|
||||||
let temp = self.interm_c;
|
let temp = self.interm_c;
|
||||||
|
|
||||||
@@ -144,10 +137,10 @@ impl<'a> ArithmeticEvaluator<'a>
|
|||||||
temp
|
temp
|
||||||
}
|
}
|
||||||
|
|
||||||
fn instr_from_clause(&mut self, name: &Atom, terms: &Vec<Box<Term>>)
|
fn instr_from_clause(&mut self, name: &str, arity: usize)
|
||||||
-> Result<ArithmeticInstruction, ArithmeticError>
|
-> Result<ArithmeticInstruction, ArithmeticError>
|
||||||
{
|
{
|
||||||
match terms.len() {
|
match arity {
|
||||||
1 => {
|
1 => {
|
||||||
let a1 = self.interm.pop().unwrap();
|
let a1 = self.interm.pop().unwrap();
|
||||||
|
|
||||||
@@ -203,7 +196,7 @@ impl<'a> ArithmeticEvaluator<'a>
|
|||||||
where Iter: ArithmeticTermIter<'a>
|
where Iter: ArithmeticTermIter<'a>
|
||||||
{
|
{
|
||||||
let mut code = vec![];
|
let mut code = vec![];
|
||||||
|
|
||||||
for term_ref in src.iter()?
|
for term_ref in src.iter()?
|
||||||
{
|
{
|
||||||
match term_ref? {
|
match term_ref? {
|
||||||
@@ -221,15 +214,9 @@ impl<'a> ArithmeticEvaluator<'a>
|
|||||||
|
|
||||||
self.interm.push(ArithmeticTerm::Reg(r));
|
self.interm.push(ArithmeticTerm::Reg(r));
|
||||||
},
|
},
|
||||||
ArithTermRef::Op(ClauseType::Deep(_, _, name, _), terms) => {
|
ArithTermRef::Op(name, arity) => {
|
||||||
code.push(Line::Arithmetic(self.instr_from_clause(&*name, terms)?));
|
code.push(Line::Arithmetic(self.instr_from_clause(&*name, arity)?));
|
||||||
},
|
}
|
||||||
ArithTermRef::Op(ClauseType::Root, terms) => {
|
|
||||||
let name = src.root_name()?;
|
|
||||||
code.push(Line::Arithmetic(self.instr_from_clause(&*name, terms)?));
|
|
||||||
},
|
|
||||||
_ =>
|
|
||||||
return Err(ArithmeticError::InvalidTerm)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -366,15 +366,34 @@ pub struct Rule {
|
|||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub enum ClauseType<'a> {
|
pub enum ClauseType<'a> {
|
||||||
|
Arg,
|
||||||
CallN,
|
CallN,
|
||||||
Catch,
|
Catch,
|
||||||
Deep(Level, &'a Cell<RegType>, &'a TabledRc<Atom>, Option<Fixity>),
|
Deep(Level, &'a Cell<RegType>, &'a TabledRc<Atom>, Option<Fixity>),
|
||||||
|
Display,
|
||||||
|
DuplicateTerm,
|
||||||
|
Functor,
|
||||||
Is,
|
Is,
|
||||||
Root,
|
Root(&'a TabledRc<Atom>),
|
||||||
Throw,
|
Throw,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ClauseType<'a> {
|
impl<'a> ClauseType<'a> {
|
||||||
|
pub fn name(&self) -> &'a str {
|
||||||
|
match self {
|
||||||
|
&ClauseType::Arg => "arg",
|
||||||
|
&ClauseType::CallN => "call",
|
||||||
|
&ClauseType::Catch => "catch",
|
||||||
|
&ClauseType::Deep(_, _, name, _) => name.as_str(),
|
||||||
|
&ClauseType::Display => "display",
|
||||||
|
&ClauseType::DuplicateTerm => "duplicate_term",
|
||||||
|
&ClauseType::Functor => "functor",
|
||||||
|
&ClauseType::Is => "is",
|
||||||
|
&ClauseType::Root(name) => name.as_str(),
|
||||||
|
&ClauseType::Throw => "throw"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn level_of_subterms(self) -> Level {
|
pub fn level_of_subterms(self) -> Level {
|
||||||
match self {
|
match self {
|
||||||
ClauseType::Deep(..) => Level::Deep,
|
ClauseType::Deep(..) => Level::Deep,
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ impl<'a> QueryIterator<'a> {
|
|||||||
let state = match term {
|
let state = match term {
|
||||||
&Term::AnonVar =>
|
&Term::AnonVar =>
|
||||||
return QueryIterator { state_stack: vec![] },
|
return QueryIterator { state_stack: vec![] },
|
||||||
&Term::Clause(.., ref terms, _) =>
|
&Term::Clause(_, ref name, ref terms, _) =>
|
||||||
TermIterState::Clause(0, ClauseType::Root, terms),
|
TermIterState::Clause(0, ClauseType::Root(name), terms),
|
||||||
&Term::Cons(..) =>
|
&Term::Cons(..) =>
|
||||||
return QueryIterator { state_stack: vec![] },
|
return QueryIterator { state_stack: vec![] },
|
||||||
&Term::Constant(_, _) =>
|
&Term::Constant(_, _) =>
|
||||||
@@ -40,21 +40,27 @@ impl<'a> QueryIterator<'a> {
|
|||||||
let state = TermIterState::Clause(0, ClauseType::Catch, terms);
|
let state = TermIterState::Clause(0, ClauseType::Catch, terms);
|
||||||
QueryIterator { state_stack: vec![state] }
|
QueryIterator { state_stack: vec![state] }
|
||||||
},
|
},
|
||||||
&QueryTerm::Display(ref terms)
|
&QueryTerm::Display(ref terms) => {
|
||||||
| &QueryTerm::DuplicateTerm(ref terms) => {
|
let state = TermIterState::Clause(0, ClauseType::Display, terms);
|
||||||
let state = TermIterState::Clause(0, ClauseType::Root, terms);
|
|
||||||
QueryIterator { state_stack: vec![state] }
|
QueryIterator { state_stack: vec![state] }
|
||||||
},
|
},
|
||||||
&QueryTerm::Arg(ref terms)
|
&QueryTerm::DuplicateTerm(ref terms) => {
|
||||||
| &QueryTerm::Functor(ref terms) => {
|
let state = TermIterState::Clause(0, ClauseType::DuplicateTerm, terms);
|
||||||
let state = TermIterState::Clause(0, ClauseType::Root, terms);
|
QueryIterator { state_stack: vec![state] }
|
||||||
|
},
|
||||||
|
&QueryTerm::Arg(ref terms) => {
|
||||||
|
let state = TermIterState::Clause(0, ClauseType::Arg, terms);
|
||||||
|
QueryIterator { state_stack: vec![state] }
|
||||||
|
},
|
||||||
|
&QueryTerm::Functor(ref terms) => {
|
||||||
|
let state = TermIterState::Clause(0, ClauseType::Functor, terms);
|
||||||
QueryIterator { state_stack: vec![state] }
|
QueryIterator { state_stack: vec![state] }
|
||||||
},
|
},
|
||||||
&QueryTerm::Inlined(InlinedQueryTerm::CompareNumber(_, ref terms))
|
&QueryTerm::Inlined(InlinedQueryTerm::CompareNumber(_, ref terms))
|
||||||
| &QueryTerm::Is(ref terms) => {
|
| &QueryTerm::Is(ref terms) => {
|
||||||
let state = TermIterState::Clause(0, ClauseType::Is, terms);
|
let state = TermIterState::Clause(0, ClauseType::Is, terms);
|
||||||
QueryIterator { state_stack: vec![state] }
|
QueryIterator { state_stack: vec![state] }
|
||||||
},
|
},
|
||||||
&QueryTerm::Inlined(InlinedQueryTerm::IsAtomic(ref terms))
|
&QueryTerm::Inlined(InlinedQueryTerm::IsAtomic(ref terms))
|
||||||
| &QueryTerm::Inlined(InlinedQueryTerm::IsInteger(ref terms))
|
| &QueryTerm::Inlined(InlinedQueryTerm::IsInteger(ref terms))
|
||||||
| &QueryTerm::Inlined(InlinedQueryTerm::IsVar(ref terms)) =>
|
| &QueryTerm::Inlined(InlinedQueryTerm::IsVar(ref terms)) =>
|
||||||
@@ -78,7 +84,7 @@ impl QueryTerm {
|
|||||||
|
|
||||||
impl<'a> Iterator for QueryIterator<'a> {
|
impl<'a> Iterator for QueryIterator<'a> {
|
||||||
type Item = TermRef<'a>;
|
type Item = TermRef<'a>;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
while let Some(iter_state) = self.state_stack.pop() {
|
while let Some(iter_state) = self.state_stack.pop() {
|
||||||
match iter_state {
|
match iter_state {
|
||||||
@@ -113,7 +119,7 @@ impl<'a> Iterator for QueryIterator<'a> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,8 +136,8 @@ impl<'a> FactIterator<'a> {
|
|||||||
let states = match term {
|
let states = match term {
|
||||||
&Term::AnonVar =>
|
&Term::AnonVar =>
|
||||||
vec![TermIterState::AnonVar(Level::Shallow)],
|
vec![TermIterState::AnonVar(Level::Shallow)],
|
||||||
&Term::Clause(.., ref terms, _) =>
|
&Term::Clause(.., ref name, ref terms, _) =>
|
||||||
vec![TermIterState::Clause(0, ClauseType::Root, terms)],
|
vec![TermIterState::Clause(0, ClauseType::Root(name), terms)],
|
||||||
&Term::Cons(ref cell, ref head, ref tail) =>
|
&Term::Cons(ref cell, ref head, ref tail) =>
|
||||||
vec![TermIterState::InitialCons(Level::Shallow,
|
vec![TermIterState::InitialCons(Level::Shallow,
|
||||||
cell,
|
cell,
|
||||||
@@ -217,7 +223,7 @@ impl<'a> ChunkedIterator<'a>
|
|||||||
{
|
{
|
||||||
let inner_iter = Box::new(once(p1));
|
let inner_iter = Box::new(once(p1));
|
||||||
let iter = inner_iter.chain(clauses.iter());
|
let iter = inner_iter.chain(clauses.iter());
|
||||||
|
|
||||||
ChunkedIterator {
|
ChunkedIterator {
|
||||||
term_loc: GenContext::Last(0),
|
term_loc: GenContext::Last(0),
|
||||||
iter: Box::new(iter),
|
iter: Box::new(iter),
|
||||||
@@ -237,7 +243,7 @@ impl<'a> ChunkedIterator<'a>
|
|||||||
term_loc: GenContext::Head,
|
term_loc: GenContext::Head,
|
||||||
iter: Box::new(iter),
|
iter: Box::new(iter),
|
||||||
deep_cut_encountered: false,
|
deep_cut_encountered: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn encountered_deep_cut(&self) -> bool {
|
pub fn encountered_deep_cut(&self) -> bool {
|
||||||
@@ -257,21 +263,21 @@ impl<'a> ChunkedIterator<'a>
|
|||||||
let mut arity = 0;
|
let mut arity = 0;
|
||||||
let mut item = Some(term);
|
let mut item = Some(term);
|
||||||
let mut result = Vec::new();
|
let mut result = Vec::new();
|
||||||
|
|
||||||
while let Some(term) = item {
|
while let Some(term) = item {
|
||||||
match term {
|
match term {
|
||||||
&QueryTerm::Term(ref inner_term) =>
|
&QueryTerm::Term(ref inner_term) =>
|
||||||
if let GenContext::Head = self.term_loc {
|
if let GenContext::Head = self.term_loc {
|
||||||
result.push(term);
|
result.push(term);
|
||||||
self.term_loc = GenContext::Last(0);
|
self.term_loc = GenContext::Last(0);
|
||||||
} else {
|
} else {
|
||||||
result.push(term);
|
result.push(term);
|
||||||
|
|
||||||
if inner_term.is_callable() {
|
if inner_term.is_callable() {
|
||||||
arity = inner_term.arity();
|
arity = inner_term.arity();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
&QueryTerm::CallN(ref child_terms) => {
|
&QueryTerm::CallN(ref child_terms) => {
|
||||||
result.push(term);
|
result.push(term);
|
||||||
arity = child_terms.len() + 1;
|
arity = child_terms.len() + 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user