eliminate QueryTermRef.
This commit is contained in:
@@ -39,26 +39,36 @@ pub enum PredicateClause {
|
||||
}
|
||||
|
||||
impl PredicateClause {
|
||||
pub fn name(&self) -> &Atom {
|
||||
match self {
|
||||
&PredicateClause::Fact(ref t) => t.name().unwrap(),
|
||||
&PredicateClause::Rule(ref rule) => rule.head.0.name().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn first_arg(&self) -> Option<&Term> {
|
||||
match self {
|
||||
&PredicateClause::Fact(ref t) => t.first_arg(),
|
||||
&PredicateClause::Rule(ref rule) => rule.head.0.first_arg()
|
||||
&PredicateClause::Fact(ref term) => term.first_arg(),
|
||||
&PredicateClause::Rule(ref rule) =>
|
||||
if let &QueryTerm::Term(ref term) = &rule.head.0 {
|
||||
term.first_arg()
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn arity(&self) -> usize {
|
||||
match self {
|
||||
&PredicateClause::Fact(ref t) => t.arity(),
|
||||
&PredicateClause::Fact(ref term) => term.arity(),
|
||||
&PredicateClause::Rule(ref rule) => rule.head.0.arity()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn name(&self) -> Option<&Atom> {
|
||||
match self {
|
||||
&PredicateClause::Fact(ref term) => term.name(),
|
||||
&PredicateClause::Rule(ref rule) =>
|
||||
if let &QueryTerm::Term(ref term) = &rule.head.0 {
|
||||
term.name()
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum Declaration {
|
||||
@@ -217,6 +227,7 @@ pub enum ParserError
|
||||
IncompleteReduction,
|
||||
InconsistentDeclaration,
|
||||
InconsistentPredicate,
|
||||
InvalidRuleHead,
|
||||
ParseBigInt,
|
||||
ParseFloat(ParseFloatError),
|
||||
// TokenTooLong,
|
||||
@@ -310,30 +321,22 @@ pub enum QueryTerm {
|
||||
}
|
||||
|
||||
impl QueryTerm {
|
||||
pub fn to_ref(&self) -> QueryTermRef {
|
||||
pub fn arity(&self) -> usize {
|
||||
match self {
|
||||
&QueryTerm::CallN(ref terms) =>
|
||||
QueryTermRef::CallN(terms),
|
||||
&QueryTerm::Catch(ref terms) =>
|
||||
QueryTermRef::Catch(terms),
|
||||
&QueryTerm::Cut =>
|
||||
QueryTermRef::Cut,
|
||||
&QueryTerm::Is(ref terms) =>
|
||||
QueryTermRef::Is(terms),
|
||||
&QueryTerm::IsAtomic(ref terms) =>
|
||||
QueryTermRef::IsAtomic(terms.first().unwrap()),
|
||||
&QueryTerm::IsVar(ref terms) =>
|
||||
QueryTermRef::IsVar(terms.first().unwrap()),
|
||||
&QueryTerm::Term(ref term) =>
|
||||
QueryTermRef::Term(term),
|
||||
&QueryTerm::Throw(ref t) =>
|
||||
QueryTermRef::Throw(t)
|
||||
&QueryTerm::Catch(_) => 3,
|
||||
&QueryTerm::Throw(_) => 1,
|
||||
&QueryTerm::Is(_) => 2,
|
||||
&QueryTerm::IsAtomic(_) => 1,
|
||||
&QueryTerm::IsVar(_) => 1,
|
||||
&QueryTerm::CallN(ref terms) => terms.len(),
|
||||
&QueryTerm::Cut => 0,
|
||||
&QueryTerm::Term(ref term) => term.arity(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Rule {
|
||||
pub head: (Term, QueryTerm),
|
||||
pub head: (QueryTerm, QueryTerm),
|
||||
pub clauses: Vec<QueryTerm>
|
||||
}
|
||||
|
||||
@@ -378,33 +381,6 @@ impl<'a> TermRef<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum QueryTermRef<'a> {
|
||||
CallN(&'a Vec<Box<Term>>),
|
||||
Catch(&'a Vec<Box<Term>>),
|
||||
Cut,
|
||||
Is(&'a Vec<Box<Term>>),
|
||||
IsAtomic(&'a Term),
|
||||
IsVar(&'a Term),
|
||||
Term(&'a Term),
|
||||
Throw(&'a Vec<Box<Term>>)
|
||||
}
|
||||
|
||||
impl<'a> QueryTermRef<'a> {
|
||||
pub fn arity(self) -> usize {
|
||||
match self {
|
||||
QueryTermRef::Catch(_) => 3,
|
||||
QueryTermRef::Throw(_) => 1,
|
||||
QueryTermRef::Is(_) => 2,
|
||||
QueryTermRef::IsAtomic(_) => 1,
|
||||
QueryTermRef::IsVar(_) => 1,
|
||||
QueryTermRef::CallN(terms) => terms.len(),
|
||||
QueryTermRef::Cut => 0,
|
||||
QueryTermRef::Term(term) => term.arity(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum ChoiceInstruction {
|
||||
RetryMeElse(usize),
|
||||
TrustMe,
|
||||
@@ -826,14 +802,6 @@ impl Term {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_clause(&self) -> bool {
|
||||
if let &Term::Clause(_, _, _) = self {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_callable(&self) -> bool {
|
||||
match self {
|
||||
&Term::Clause(_, _, _) | &Term::Constant(_, Constant::Atom(_)) =>
|
||||
|
||||
@@ -181,8 +181,8 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
|
||||
let mut vs = VariableFixtures::new();
|
||||
let at_rule_head = iter.at_rule_head();
|
||||
|
||||
while let Some((chunk_num, last_term_arity, terms)) = iter.next() {
|
||||
for (i, term_or_cut_ref) in terms.iter().enumerate() {
|
||||
while let Some((chunk_num, lt_arity, terms)) = iter.next() {
|
||||
for (i, query_term) in terms.iter().enumerate() {
|
||||
let term_loc = if chunk_num == 0 && i == 0 && at_rule_head {
|
||||
GenContext::Head
|
||||
} else if i < terms.len() - 1 {
|
||||
@@ -191,10 +191,8 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
|
||||
GenContext::Last(chunk_num)
|
||||
};
|
||||
|
||||
self.update_var_count(term_or_cut_ref.post_order_iter());
|
||||
vs.mark_vars_in_chunk(term_or_cut_ref.post_order_iter(),
|
||||
last_term_arity,
|
||||
term_loc);
|
||||
self.update_var_count(query_term.post_order_iter());
|
||||
vs.mark_vars_in_chunk(query_term.post_order_iter(), lt_arity, term_loc);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -209,26 +207,26 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
|
||||
ConjunctInfo::new(vs, num_of_chunks, has_deep_cut)
|
||||
}
|
||||
|
||||
fn add_conditional_call(compiled_query: &mut Code, qt: QueryTermRef, pvs: usize)
|
||||
fn add_conditional_call(compiled_query: &mut Code, qt: &QueryTerm, pvs: usize)
|
||||
{
|
||||
match qt {
|
||||
QueryTermRef::CallN(terms) => {
|
||||
&QueryTerm::CallN(ref terms) => {
|
||||
let call = ControlInstruction::CallN(terms.len());
|
||||
compiled_query.push(Line::Control(call));
|
||||
},
|
||||
QueryTermRef::Catch(_) =>
|
||||
&QueryTerm::Catch(_) =>
|
||||
compiled_query.push(Line::Control(ControlInstruction::CatchCall)),
|
||||
QueryTermRef::IsAtomic(_) | QueryTermRef::IsVar(_) =>
|
||||
&QueryTerm::IsAtomic(_) | &QueryTerm::IsVar(_) =>
|
||||
compiled_query.push(proceed!()),
|
||||
QueryTermRef::Term(&Term::Constant(_, Constant::Atom(ref atom))) => {
|
||||
&QueryTerm::Term(Term::Constant(_, Constant::Atom(ref atom))) => {
|
||||
let call = ControlInstruction::Call(atom.clone(), 0, pvs);
|
||||
compiled_query.push(Line::Control(call));
|
||||
},
|
||||
QueryTermRef::Term(&Term::Clause(_, ref atom, ref terms)) => {
|
||||
&QueryTerm::Term(Term::Clause(_, ref atom, ref terms)) => {
|
||||
let call = ControlInstruction::Call(atom.clone(), terms.len(), pvs);
|
||||
compiled_query.push(Line::Control(call));
|
||||
},
|
||||
QueryTermRef::Throw(_) =>
|
||||
&QueryTerm::Throw(_) =>
|
||||
compiled_query.push(Line::Control(ControlInstruction::ThrowCall)),
|
||||
_ => {}
|
||||
}
|
||||
@@ -276,22 +274,21 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
|
||||
GenContext::Last(chunk_num)
|
||||
};
|
||||
|
||||
match term {
|
||||
&QueryTermRef::Cut if i + 1 < terms.len() => {
|
||||
code.push(if chunk_num == 0 {
|
||||
Line::Cut(CutInstruction::NeckCut(Terminal::Non))
|
||||
match *term {
|
||||
&QueryTerm::Cut => {
|
||||
let term = if i + 1 < terms.len() {
|
||||
Terminal::Non
|
||||
} else {
|
||||
Line::Cut(CutInstruction::Cut(Terminal::Non))
|
||||
Terminal::Terminal
|
||||
};
|
||||
|
||||
code.push(if chunk_num == 0 {
|
||||
Line::Cut(CutInstruction::NeckCut(term))
|
||||
} else {
|
||||
Line::Cut(CutInstruction::Cut(term))
|
||||
});
|
||||
},
|
||||
&QueryTermRef::Cut => {
|
||||
code.push(if chunk_num == 0 {
|
||||
Line::Cut(CutInstruction::NeckCut(Terminal::Terminal))
|
||||
} else {
|
||||
Line::Cut(CutInstruction::Cut(Terminal::Terminal))
|
||||
});
|
||||
},
|
||||
&QueryTermRef::Is(terms) => {
|
||||
&QueryTerm::Is(ref terms) => {
|
||||
let mut arith_code = {
|
||||
let mut evaluator = ArithmeticEvaluator::new(self.marker.bindings());
|
||||
evaluator.eval(terms[1].as_ref())?
|
||||
@@ -335,8 +332,8 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
|
||||
}
|
||||
}
|
||||
},
|
||||
&QueryTermRef::IsAtomic(inner_term) =>
|
||||
match inner_term {
|
||||
&QueryTerm::IsAtomic(ref inner_term) =>
|
||||
match inner_term[0].as_ref() {
|
||||
&Term::AnonVar | &Term::Clause(_, _, _) | &Term::Cons(_, _, _) => {
|
||||
code.push(fail!());
|
||||
},
|
||||
@@ -361,8 +358,8 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
|
||||
}
|
||||
},
|
||||
},
|
||||
&QueryTermRef::IsVar(inner_term) =>
|
||||
match inner_term {
|
||||
&QueryTerm::IsVar(ref inner_term) =>
|
||||
match inner_term[0].as_ref() {
|
||||
&Term::Constant(_, _) | &Term::Clause(_, _, _) | &Term::Cons(_, _, _) => {
|
||||
code.push(fail!());
|
||||
},
|
||||
@@ -392,11 +389,11 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
|
||||
|
||||
let iter = term.post_order_iter();
|
||||
code.push(Line::Query(self.compile_target(iter, term_loc, is_exposed)));
|
||||
Self::add_conditional_call(code, *term, conjunct_info.perm_vars());
|
||||
Self::add_conditional_call(code, term, conjunct_info.perm_vars());
|
||||
},
|
||||
_ => {
|
||||
let num_vars = conjunct_info.perm_vs.vars_above_threshold(i + 1);
|
||||
self.compile_query_line(*term, term_loc, code, num_vars, is_exposed);
|
||||
self.compile_query_line(term, term_loc, code, num_vars, is_exposed);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -420,11 +417,11 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
|
||||
}
|
||||
}
|
||||
|
||||
fn compile_cleanup(code: &mut Code, conjunct_info: &ConjunctInfo, toc: QueryTermRef<'a>)
|
||||
fn compile_cleanup(code: &mut Code, conjunct_info: &ConjunctInfo, toc: &'a QueryTerm)
|
||||
{
|
||||
//TODO: temporary workaround for inlined builtins.
|
||||
match toc {
|
||||
QueryTermRef::IsAtomic(_) | QueryTermRef::IsVar(_) =>
|
||||
&QueryTerm::IsAtomic(_) | &QueryTerm::IsVar(_) =>
|
||||
code.push(proceed!()),
|
||||
_ => {}
|
||||
}
|
||||
@@ -447,8 +444,9 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
|
||||
self.marker.advance(GenContext::Head, p0.arity());
|
||||
self.compile_seq_prelude(&conjunct_info, &mut code);
|
||||
|
||||
if p0.is_clause() {
|
||||
let iter = FactInstruction::iter(p0);
|
||||
if let &QueryTerm::Term(ref term) = p0 {
|
||||
if let &Term::Clause(_, _, _) = term {
|
||||
let iter = FactInstruction::iter(term);
|
||||
code.push(Line::Fact(self.compile_target(iter, GenContext::Head, false)));
|
||||
}
|
||||
|
||||
@@ -463,12 +461,15 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
|
||||
};
|
||||
|
||||
if let &mut Line::Query(ref mut query) = &mut code[index] {
|
||||
conjunct_info.perm_vs.mark_unsafe_vars_in_rule(p0, query);
|
||||
conjunct_info.perm_vs.mark_unsafe_vars_in_rule(term, query);
|
||||
}
|
||||
}
|
||||
|
||||
Self::compile_cleanup(&mut code, &conjunct_info, clauses.last().unwrap_or(p1).to_ref());
|
||||
Self::compile_cleanup(&mut code, &conjunct_info, clauses.last().unwrap_or(p1));
|
||||
Ok(code)
|
||||
} else {
|
||||
Err(ParserError::InvalidRuleHead)
|
||||
}
|
||||
}
|
||||
|
||||
fn mark_unsafe_fact_vars(&self, fact: &mut CompiledFact)
|
||||
@@ -512,7 +513,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
|
||||
|
||||
let mut code = Vec::new();
|
||||
|
||||
if term.is_clause() {
|
||||
if let &Term::Clause(_, _, _) = term {
|
||||
let iter = FactInstruction::iter(term);
|
||||
let mut compiled_fact = self.compile_target(iter, GenContext::Head, false);
|
||||
|
||||
@@ -525,7 +526,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
|
||||
}
|
||||
|
||||
fn compile_query_line(&mut self,
|
||||
term: QueryTermRef<'a>,
|
||||
term: &'a QueryTerm,
|
||||
term_loc: GenContext,
|
||||
code: &mut Code,
|
||||
index: usize,
|
||||
@@ -564,7 +565,10 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
|
||||
}
|
||||
}
|
||||
|
||||
Self::compile_cleanup(&mut code, &conjunct_info, query.last().unwrap().to_ref());
|
||||
if let Some(query_term) = query.last() {
|
||||
Self::compile_cleanup(&mut code, &conjunct_info, query_term);
|
||||
}
|
||||
|
||||
Ok(code)
|
||||
}
|
||||
|
||||
|
||||
@@ -171,10 +171,7 @@ impl<'a> VariableFixtures<'a>
|
||||
var_count
|
||||
}
|
||||
|
||||
pub fn mark_vars_in_chunk<Iter>(&mut self,
|
||||
iter: Iter,
|
||||
last_term_arity: usize,
|
||||
term_loc: GenContext)
|
||||
pub fn mark_vars_in_chunk<Iter>(&mut self, iter: Iter, lt_arity: usize, term_loc: GenContext)
|
||||
where Iter: Iterator<Item=TermRef<'a>>
|
||||
{
|
||||
let chunk_num = term_loc.chunk_num();
|
||||
@@ -183,8 +180,7 @@ impl<'a> VariableFixtures<'a>
|
||||
for term_ref in iter {
|
||||
if let TermRef::Var(lvl, cell, var) = term_ref {
|
||||
let mut status = self.0.remove(var)
|
||||
.unwrap_or((VarStatus::Temp(chunk_num, TempVarData::new(last_term_arity)),
|
||||
Vec::new()));
|
||||
.unwrap_or((VarStatus::Temp(chunk_num, TempVarData::new(lt_arity)), Vec::new()));
|
||||
|
||||
status.1.push(cell);
|
||||
|
||||
|
||||
@@ -41,33 +41,35 @@ impl<'a> QueryIterator<'a> {
|
||||
QueryIterator { state_stack: vec![state] }
|
||||
}
|
||||
|
||||
fn new(term: QueryTermRef<'a>) -> Self {
|
||||
fn new(term: &'a QueryTerm) -> Self {
|
||||
match term {
|
||||
QueryTermRef::CallN(terms) => {
|
||||
&QueryTerm::CallN(ref terms) => {
|
||||
let state = IteratorState::Clause(1, ClauseType::CallN, terms);
|
||||
QueryIterator { state_stack: vec![state] }
|
||||
},
|
||||
QueryTermRef::Catch(terms) => {
|
||||
&QueryTerm::Catch(ref terms) => {
|
||||
let state = IteratorState::Clause(0, ClauseType::Catch, terms);
|
||||
QueryIterator { state_stack: vec![state] }
|
||||
},
|
||||
QueryTermRef::Is(terms) => {
|
||||
&QueryTerm::Is(ref terms) => {
|
||||
let state = IteratorState::Clause(0, ClauseType::Is, terms);
|
||||
QueryIterator { state_stack: vec![state] }
|
||||
},
|
||||
QueryTermRef::IsAtomic(term) | QueryTermRef::IsVar(term) | QueryTermRef::Term(term) =>
|
||||
&QueryTerm::IsAtomic(ref terms) | &QueryTerm::IsVar(ref terms) =>
|
||||
Self::from_term(terms[0].as_ref()),
|
||||
&QueryTerm::Term(ref term) =>
|
||||
Self::from_term(term),
|
||||
QueryTermRef::Throw(term) => {
|
||||
&QueryTerm::Throw(ref term) => {
|
||||
let state = IteratorState::Clause(0, ClauseType::Throw, term);
|
||||
QueryIterator { state_stack: vec![state] }
|
||||
},
|
||||
QueryTermRef::Cut => QueryIterator { state_stack: vec![] }
|
||||
&QueryTerm::Cut => QueryIterator { state_stack: vec![] }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> QueryTermRef<'a> {
|
||||
pub fn post_order_iter(self) -> QueryIterator<'a> {
|
||||
impl QueryTerm {
|
||||
pub fn post_order_iter<'a>(&'a self) -> QueryIterator<'a> {
|
||||
QueryIterator::new(self)
|
||||
}
|
||||
}
|
||||
@@ -183,7 +185,7 @@ impl<'a> Iterator for FactIterator<'a> {
|
||||
|
||||
impl Term {
|
||||
pub fn post_order_iter(&self) -> QueryIterator {
|
||||
QueryIterator::new(QueryTermRef::Term(self))
|
||||
QueryIterator::from_term(self)
|
||||
}
|
||||
|
||||
pub fn breadth_first_iter(&self) -> FactIterator {
|
||||
@@ -194,7 +196,7 @@ impl Term {
|
||||
pub struct ChunkedIterator<'a>
|
||||
{
|
||||
term_loc: GenContext,
|
||||
iter: Box<Iterator<Item=QueryTermRef<'a>> + 'a>,
|
||||
iter: Box<Iterator<Item=&'a QueryTerm> + 'a>,
|
||||
deep_cut_encountered: bool
|
||||
}
|
||||
|
||||
@@ -202,19 +204,17 @@ impl<'a> ChunkedIterator<'a>
|
||||
{
|
||||
pub fn from_term_sequence(terms: &'a [QueryTerm]) -> Self
|
||||
{
|
||||
let iter = terms.iter().map(|c| c.to_ref());
|
||||
|
||||
ChunkedIterator {
|
||||
term_loc: GenContext::Last(0),
|
||||
iter: Box::new(iter),
|
||||
iter: Box::new(terms.iter()),
|
||||
deep_cut_encountered: false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_rule_body(p1: &'a QueryTerm, clauses: &'a Vec<QueryTerm>) -> Self
|
||||
{
|
||||
let inner_iter = Box::new(once(p1.to_ref()));
|
||||
let iter = inner_iter.chain(clauses.iter().map(|c| c.to_ref()));
|
||||
let inner_iter = Box::new(once(p1));
|
||||
let iter = inner_iter.chain(clauses.iter());
|
||||
|
||||
ChunkedIterator {
|
||||
term_loc: GenContext::Last(0),
|
||||
@@ -227,14 +227,14 @@ impl<'a> ChunkedIterator<'a>
|
||||
{
|
||||
let &Rule { head: (ref p0, ref p1), ref clauses } = rule;
|
||||
|
||||
let iter = once(QueryTermRef::Term(p0));
|
||||
let inner_iter = Box::new(once(p1.to_ref()));
|
||||
let iter = iter.chain(inner_iter.chain(clauses.iter().map(|c| c.to_ref())));
|
||||
let iter = once(p0);
|
||||
let inner_iter = Box::new(once(p1));
|
||||
let iter = iter.chain(inner_iter.chain(clauses.iter()));
|
||||
|
||||
ChunkedIterator {
|
||||
term_loc: GenContext::Head,
|
||||
iter: Box::new(iter),
|
||||
deep_cut_encountered: false
|
||||
deep_cut_encountered: false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -250,18 +250,15 @@ impl<'a> ChunkedIterator<'a>
|
||||
self.term_loc.chunk_num()
|
||||
}
|
||||
|
||||
fn take_chunk(&mut self, term: QueryTermRef<'a>, mut result: Vec<QueryTermRef<'a>>)
|
||||
-> (usize, usize, Vec<QueryTermRef<'a>>)
|
||||
fn take_chunk(&mut self, term: &'a QueryTerm) -> (usize, usize, Vec<&'a QueryTerm>)
|
||||
{
|
||||
let mut arity = 0;
|
||||
let mut item = Some(term);
|
||||
let mut result = Vec::new();
|
||||
|
||||
while let Some(term) = item {
|
||||
match term {
|
||||
//TODO: This can refer to the term at the head of a
|
||||
// goal, not technically a QueryTerm (ie. a term in a
|
||||
// query). Think of a better name.
|
||||
QueryTermRef::Term(inner_term) => {
|
||||
&QueryTerm::Term(ref inner_term) =>
|
||||
if let GenContext::Head = self.term_loc {
|
||||
result.push(term);
|
||||
self.term_loc = GenContext::Last(0);
|
||||
@@ -272,26 +269,25 @@ impl<'a> ChunkedIterator<'a>
|
||||
arity = inner_term.arity();
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
QueryTermRef::CallN(child_terms) => {
|
||||
&QueryTerm::CallN(ref child_terms) => {
|
||||
result.push(term);
|
||||
arity = child_terms.len() + 1;
|
||||
break;
|
||||
},
|
||||
QueryTermRef::Catch(child_terms) | QueryTermRef::Throw(child_terms) => {
|
||||
&QueryTerm::Catch(ref child_terms) | &QueryTerm::Throw(ref child_terms) => {
|
||||
result.push(term);
|
||||
arity = child_terms.len();
|
||||
break;
|
||||
},
|
||||
QueryTermRef::Is(_) => {
|
||||
&QueryTerm::Is(_) => {
|
||||
result.push(term);
|
||||
arity = 2;
|
||||
break;
|
||||
},
|
||||
QueryTermRef::IsAtomic(_) | QueryTermRef::IsVar(_) =>
|
||||
&QueryTerm::IsAtomic(_) | &QueryTerm::IsVar(_) =>
|
||||
result.push(term),
|
||||
QueryTermRef::Cut => {
|
||||
&QueryTerm::Cut => {
|
||||
result.push(term);
|
||||
|
||||
if self.term_loc.chunk_num() > 0 {
|
||||
@@ -316,9 +312,9 @@ impl<'a> ChunkedIterator<'a>
|
||||
impl<'a> Iterator for ChunkedIterator<'a>
|
||||
{
|
||||
// the chunk number, last term arity, and vector of references.
|
||||
type Item = (usize, usize, Vec<QueryTermRef<'a>>);
|
||||
type Item = (usize, usize, Vec<&'a QueryTerm>);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.iter.next().map(|term| self.take_chunk(term, Vec::new()))
|
||||
self.iter.next().map(|term| self.take_chunk(term))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,22 +239,23 @@ impl Machine {
|
||||
|
||||
pub fn add_fact<'a>(&mut self, fact: &Term, mut code: Code) -> EvalSession<'a>
|
||||
{
|
||||
if let Some(name) = fact.name() {
|
||||
match fact {
|
||||
&Term::Clause(_, ref name, _) | &Term::Constant(_, Constant::Atom(ref name)) => {
|
||||
let p = self.code.len();
|
||||
|
||||
let name = name.clone();
|
||||
let arity = fact.arity();
|
||||
|
||||
self.code.append(&mut code);
|
||||
self.add_user_code(name, arity, p)
|
||||
} else {
|
||||
EvalSession::NamelessEntry
|
||||
self.add_user_code(name.clone(), arity, p)
|
||||
},
|
||||
_ => EvalSession::NamelessEntry
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_rule<'a>(&mut self, rule: &Rule, mut code: Code) -> EvalSession<'a>
|
||||
{
|
||||
if let Some(name) = rule.head.0.name() {
|
||||
match &rule.head.0 {
|
||||
&QueryTerm::Term(Term::Clause(_, ref name, _))
|
||||
| &QueryTerm::Term(Term::Constant(_, Constant::Atom(ref name))) => {
|
||||
let p = self.code.len();
|
||||
|
||||
let name = name.clone();
|
||||
@@ -262,8 +263,8 @@ impl Machine {
|
||||
|
||||
self.code.append(&mut code);
|
||||
self.add_user_code(name, arity, p)
|
||||
} else {
|
||||
EvalSession::NamelessEntry
|
||||
},
|
||||
_ => EvalSession::NamelessEntry
|
||||
}
|
||||
}
|
||||
|
||||
@@ -272,11 +273,18 @@ impl Machine {
|
||||
{
|
||||
let p = self.code.len();
|
||||
|
||||
let arity = clauses.first().unwrap().arity();
|
||||
let name = clauses.first().unwrap().name().clone();
|
||||
if let Some(ref clause) = clauses.first() {
|
||||
if let Some(name) = clause.name() {
|
||||
let arity = clause.arity();
|
||||
|
||||
self.code.append(&mut code);
|
||||
self.add_user_code(name, arity, p)
|
||||
self.add_user_code(name.clone(), arity, p)
|
||||
} else {
|
||||
EvalSession::NamelessEntry
|
||||
}
|
||||
} else {
|
||||
EvalSession::ImpermissibleEntry(String::from("predicate must have clauses."))
|
||||
}
|
||||
}
|
||||
|
||||
fn cached_query_size(&self) -> usize {
|
||||
|
||||
Submodule src/prolog/parser updated: ebecfec050...f01fe4feab
Reference in New Issue
Block a user