preserve heap contents in between goal expansions (#240, #241)

This commit is contained in:
Mark Thom
2019-11-28 00:45:13 -07:00
parent 9ae901bd0d
commit 7eb0de7f52
4 changed files with 42 additions and 62 deletions

View File

@@ -60,8 +60,8 @@ impl<'a, 'b, 'c, R: Read> CompositeIndices<'a, 'b, 'c, R> {
IndexSource::TermStream => &mut self.term_stream.wam.indices.code_dir,
IndexSource::Local(ref mut indices) => &mut indices.code_dir,
}
}
}
fn static_code_dir(&self) -> Option<&CodeDir> {
match self.static_code_dir {
Some(IndexSource::TermStream) => Some(&self.term_stream.wam.indices.code_dir),
@@ -84,7 +84,7 @@ impl<'a, 'b, 'c, R: Read> CompositeIndices<'a, 'b, 'c, R> {
self.local_code_dir().insert((name.clone(), arity), idx.clone());
idx
} else {
let idx = CodeIndex::default();
let idx = CodeIndex::default();
self.local_code_dir().insert((name.clone(), arity), idx.clone());
idx
}
@@ -240,7 +240,7 @@ fn setup_module_export(
} else {
Err(ParserError::InvalidModuleDecl)
}
})
})
}
fn setup_module_decl(
@@ -259,7 +259,7 @@ fn setup_module_decl(
while let Term::Cons(_, t1, t2) = export_list {
let module_export = setup_module_export(*t1, atom_tbl.clone())?;
exports.push(module_export);
export_list = *t2;
}
@@ -327,9 +327,14 @@ fn setup_qualified_import(
}
}
fn is_consistent(tl: &TopLevel, clauses: &Vec<PredicateClause>) -> bool {
fn is_consistent(
name: Option<ClauseName>,
arity: usize,
clauses: &Vec<PredicateClause>,
) -> bool
{
match clauses.first() {
Some(ref cl) => tl.name() == cl.name() && tl.arity() == cl.arity(),
Some(ref cl) => name == cl.name() && arity == cl.arity(),
None => true,
}
}
@@ -342,18 +347,18 @@ fn merge_clauses(tls: &mut VecDeque<TopLevel>) -> Result<TopLevel, ParserError>
TopLevel::Query(_) if clauses.is_empty() && tls.is_empty() => return Ok(tl),
TopLevel::Declaration(_) if clauses.is_empty() => return Ok(tl),
TopLevel::Query(_) => return Err(ParserError::InconsistentEntry),
TopLevel::Fact(..) if is_consistent(&tl, &clauses) =>
TopLevel::Fact(..) if is_consistent(tl.name(), tl.arity(), &clauses) =>
if let TopLevel::Fact(fact, line_num, col_num) = tl {
let clause = PredicateClause::Fact(fact, line_num, col_num);
clauses.push(clause);
},
TopLevel::Rule(..) if is_consistent(&tl, &clauses) => {
TopLevel::Rule(..) if is_consistent(tl.name(), tl.arity(), &clauses) => {
if let TopLevel::Rule(rule, line_num, col_num) = tl {
let clause = PredicateClause::Rule(rule, line_num, col_num);
clauses.push(clause);
}
}
TopLevel::Predicate(_) if is_consistent(&tl, &clauses) => {
TopLevel::Predicate(_) if is_consistent(tl.name(), tl.arity(), &clauses) => {
if let TopLevel::Predicate(pred) = tl {
clauses.extend(pred.clauses().into_iter())
}
@@ -751,11 +756,11 @@ impl RelationWorker {
if name.as_str() == "," {
let term = Term::Clause(cell, name, terms, op_spec);
let mut subterms = unfold_by_str(term, ",");
while let Some(subterm) = subterms.pop() {
work_queue.push_front(Box::new(subterm));
}
continue;
} else {
term = Term::Clause(cell, name, terms, op_spec);
@@ -769,7 +774,7 @@ impl RelationWorker {
query_terms.push(self.pre_query_term(indices, term)?);
}
}
Ok(query_terms)
}
@@ -974,7 +979,7 @@ impl<'a, R: Read> TopLevelBatchWorker<'a, R> {
&mut self,
indices: &mut IndexStore,
preds: &mut Vec<PredicateClause>,
) -> Result<(), SessionError> {
) -> Result<(), SessionError> {
let mut indices = CompositeIndices::new(
&mut self.term_stream,
IndexSource::Local(indices),
@@ -1020,17 +1025,18 @@ impl<'a, R: Read> TopLevelBatchWorker<'a, R> {
while !self.term_stream.eof()? {
let term = self.term_stream.read_term(&indices.op_dir)?;
// if is_consistent is false, preds is non-empty.
if !is_consistent(term.predicate_name(), term.predicate_arity(), &preds) {
self.process_result(indices, &mut preds)?;
self.take_dynamic_clauses();
}
let (mut tl, new_rel_worker) = self.try_term_to_tl(indices, term)?;
if tl.is_end_of_file_atom() {
tl = TopLevel::Declaration(Declaration::EndOfFile);
}
// if is_consistent is false, preds is non-empty.
if !is_consistent(&tl, &preds) {
self.process_result(indices, &mut preds)?;
self.take_dynamic_clauses();
}
}
self.rel_worker.absorb(new_rel_worker);