From: Mark Thom Date: Fri, 19 Jan 2018 02:54:15 +0000 (-0700) Subject: clean up arithmetic.rs X-Git-Tag: v0.8.110~615 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=1b402b2673c1691dfcca2b50b2be65b955768e50;p=scryer-prolog.git clean up arithmetic.rs --- diff --git a/src/prolog/arithmetic.rs b/src/prolog/arithmetic.rs index 95cea1b0..91451fcb 100644 --- a/src/prolog/arithmetic.rs +++ b/src/prolog/arithmetic.rs @@ -1,6 +1,5 @@ use prolog::ast::*; use prolog::fixtures::*; -use prolog::tabled_rc::*; use std::cell::Cell; use std::cmp::{min, max}; @@ -21,8 +20,8 @@ impl<'a> ArithInstructionIterator<'a> { let state = match term { &Term::AnonVar => return Err(ArithmeticError::InvalidTerm), - &Term::Clause(_, _, ref terms, _) => - TermIterState::Clause(0, ClauseType::Root, terms), + &Term::Clause(_, ref name, ref terms, _) => + TermIterState::Clause(0, ClauseType::Root(name), terms), &Term::Constant(ref cell, ref cons) => TermIterState::Constant(Level::Shallow, cell, cons), &Term::Cons(_, _, _) => @@ -37,7 +36,7 @@ impl<'a> ArithInstructionIterator<'a> { pub enum ArithTermRef<'a> { Constant(&'a Constant), - Op(ClauseType<'a>, &'a Vec>), + Op(&'a str, usize), // name, arity. Var(&'a Cell, &'a Var) } @@ -50,8 +49,10 @@ impl<'a> Iterator for ArithInstructionIterator<'a> { TermIterState::AnonVar(_) => return Some(Err(ArithmeticError::UninstantiatedVar)), TermIterState::Clause(child_num, ct, child_terms) => { - if child_num == child_terms.len() { - return Some(Ok(ArithTermRef::Op(ct, child_terms))); + let arity = child_terms.len(); + + if child_num == arity { + return Some(Ok(ArithTermRef::Op(ct.name(), arity))); } else { 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()); @@ -73,29 +74,21 @@ impl<'a> Iterator for ArithInstructionIterator<'a> { pub struct ArithmeticEvaluator<'a> { bindings: &'a AllocVarDict<'a>, interm: Vec, - interm_c: usize + interm_c: usize } -pub trait ArithmeticTermIter<'a> { +pub trait ArithmeticTermIter<'a> { type Iter : Iterator, ArithmeticError>>; - + fn iter(&self) -> Result; - fn root_name(&self) -> Result, ArithmeticError>; } -impl<'a> ArithmeticTermIter<'a> for &'a Term { - type Iter = ArithInstructionIterator<'a>; +impl<'a> ArithmeticTermIter<'a> for &'a Term { + type Iter = ArithInstructionIterator<'a>; fn iter(&self) -> Result { ArithInstructionIterator::new(self) } - - fn root_name(&self) -> Result, ArithmeticError> { - match self { - &&Term::Clause(_, ref name, _, _) => Ok(name.clone()), - _ => Err(ArithmeticError::InvalidTerm) - } - } } impl<'a> ArithmeticEvaluator<'a> @@ -103,20 +96,20 @@ impl<'a> ArithmeticEvaluator<'a> pub fn new(bindings: &'a AllocVarDict<'a>, target_int: usize) -> Self { 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 { - match name.as_str() { + match name { "-" => Ok(ArithmeticInstruction::Neg(a1, t)), _ => 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 { - match name.as_str() { + match name { "+" => Ok(ArithmeticInstruction::Add(a1, a2, t)), "-" => Ok(ArithmeticInstruction::Sub(a1, a2, t)), "/" => Ok(ArithmeticInstruction::Div(a1, a2, t)), @@ -134,7 +127,7 @@ impl<'a> ArithmeticEvaluator<'a> _ => Err(ArithmeticError::InvalidOp) } } - + fn incr_interm(&mut self) -> usize { let temp = self.interm_c; @@ -144,10 +137,10 @@ impl<'a> ArithmeticEvaluator<'a> temp } - fn instr_from_clause(&mut self, name: &Atom, terms: &Vec>) + fn instr_from_clause(&mut self, name: &str, arity: usize) -> Result { - match terms.len() { + match arity { 1 => { let a1 = self.interm.pop().unwrap(); @@ -203,7 +196,7 @@ impl<'a> ArithmeticEvaluator<'a> where Iter: ArithmeticTermIter<'a> { let mut code = vec![]; - + for term_ref in src.iter()? { match term_ref? { @@ -221,15 +214,9 @@ impl<'a> ArithmeticEvaluator<'a> self.interm.push(ArithmeticTerm::Reg(r)); }, - ArithTermRef::Op(ClauseType::Deep(_, _, name, _), terms) => { - code.push(Line::Arithmetic(self.instr_from_clause(&*name, terms)?)); - }, - ArithTermRef::Op(ClauseType::Root, terms) => { - let name = src.root_name()?; - code.push(Line::Arithmetic(self.instr_from_clause(&*name, terms)?)); - }, - _ => - return Err(ArithmeticError::InvalidTerm) + ArithTermRef::Op(name, arity) => { + code.push(Line::Arithmetic(self.instr_from_clause(&*name, arity)?)); + } } } diff --git a/src/prolog/ast.rs b/src/prolog/ast.rs index c1ce933a..475792e6 100644 --- a/src/prolog/ast.rs +++ b/src/prolog/ast.rs @@ -366,15 +366,34 @@ pub struct Rule { #[derive(Clone, Copy)] pub enum ClauseType<'a> { + Arg, CallN, Catch, Deep(Level, &'a Cell, &'a TabledRc, Option), + Display, + DuplicateTerm, + Functor, Is, - Root, + Root(&'a TabledRc), Throw, } 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 { match self { ClauseType::Deep(..) => Level::Deep, diff --git a/src/prolog/iterators.rs b/src/prolog/iterators.rs index fa5a9f56..074d2bd5 100644 --- a/src/prolog/iterators.rs +++ b/src/prolog/iterators.rs @@ -17,8 +17,8 @@ impl<'a> QueryIterator<'a> { let state = match term { &Term::AnonVar => return QueryIterator { state_stack: vec![] }, - &Term::Clause(.., ref terms, _) => - TermIterState::Clause(0, ClauseType::Root, terms), + &Term::Clause(_, ref name, ref terms, _) => + TermIterState::Clause(0, ClauseType::Root(name), terms), &Term::Cons(..) => return QueryIterator { state_stack: vec![] }, &Term::Constant(_, _) => @@ -40,21 +40,27 @@ impl<'a> QueryIterator<'a> { let state = TermIterState::Clause(0, ClauseType::Catch, terms); QueryIterator { state_stack: vec![state] } }, - &QueryTerm::Display(ref terms) - | &QueryTerm::DuplicateTerm(ref terms) => { - let state = TermIterState::Clause(0, ClauseType::Root, terms); + &QueryTerm::Display(ref terms) => { + let state = TermIterState::Clause(0, ClauseType::Display, terms); QueryIterator { state_stack: vec![state] } }, - &QueryTerm::Arg(ref terms) - | &QueryTerm::Functor(ref terms) => { - let state = TermIterState::Clause(0, ClauseType::Root, terms); + &QueryTerm::DuplicateTerm(ref terms) => { + let state = TermIterState::Clause(0, ClauseType::DuplicateTerm, 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] } }, &QueryTerm::Inlined(InlinedQueryTerm::CompareNumber(_, ref terms)) | &QueryTerm::Is(ref terms) => { let state = TermIterState::Clause(0, ClauseType::Is, terms); QueryIterator { state_stack: vec![state] } - }, + }, &QueryTerm::Inlined(InlinedQueryTerm::IsAtomic(ref terms)) | &QueryTerm::Inlined(InlinedQueryTerm::IsInteger(ref terms)) | &QueryTerm::Inlined(InlinedQueryTerm::IsVar(ref terms)) => @@ -78,7 +84,7 @@ impl QueryTerm { impl<'a> Iterator for QueryIterator<'a> { type Item = TermRef<'a>; - + fn next(&mut self) -> Option { while let Some(iter_state) = self.state_stack.pop() { 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 { &Term::AnonVar => vec![TermIterState::AnonVar(Level::Shallow)], - &Term::Clause(.., ref terms, _) => - vec![TermIterState::Clause(0, ClauseType::Root, terms)], + &Term::Clause(.., ref name, ref terms, _) => + vec![TermIterState::Clause(0, ClauseType::Root(name), terms)], &Term::Cons(ref cell, ref head, ref tail) => vec![TermIterState::InitialCons(Level::Shallow, cell, @@ -217,7 +223,7 @@ impl<'a> ChunkedIterator<'a> { let inner_iter = Box::new(once(p1)); let iter = inner_iter.chain(clauses.iter()); - + ChunkedIterator { term_loc: GenContext::Last(0), iter: Box::new(iter), @@ -237,7 +243,7 @@ impl<'a> ChunkedIterator<'a> term_loc: GenContext::Head, iter: Box::new(iter), deep_cut_encountered: false, - } + } } pub fn encountered_deep_cut(&self) -> bool { @@ -257,21 +263,21 @@ impl<'a> ChunkedIterator<'a> let mut arity = 0; let mut item = Some(term); let mut result = Vec::new(); - + while let Some(term) = item { match term { - &QueryTerm::Term(ref inner_term) => + &QueryTerm::Term(ref inner_term) => if let GenContext::Head = self.term_loc { result.push(term); self.term_loc = GenContext::Last(0); } else { result.push(term); - + if inner_term.is_callable() { arity = inner_term.arity(); break; } - }, + }, &QueryTerm::CallN(ref child_terms) => { result.push(term); arity = child_terms.len() + 1;