add preliminary multifile declaration support

This commit is contained in:
Mark Thom
2020-01-26 20:17:52 -07:00
parent 9c1064c1a3
commit dcf2eadcf2
6 changed files with 282 additions and 90 deletions

View File

@@ -203,6 +203,7 @@ pub enum Declaration {
Hook(CompileTimeHook, PredicateClause, VecDeque<TopLevel>), Hook(CompileTimeHook, PredicateClause, VecDeque<TopLevel>),
ModuleInitialization(Vec<QueryTerm>, VecDeque<TopLevel>), // goal ModuleInitialization(Vec<QueryTerm>, VecDeque<TopLevel>), // goal
Module(ModuleDecl), Module(ModuleDecl),
MultiFile(ClauseName, usize),
NonCountedBacktracking(ClauseName, usize), // name, arity NonCountedBacktracking(ClauseName, usize), // name, arity
Op(OpDecl), Op(OpDecl),
UseModule(ModuleSource), UseModule(ModuleSource),
@@ -371,6 +372,7 @@ pub struct Module {
pub module_decl: ModuleDecl, pub module_decl: ModuleDecl,
pub code_dir: CodeDir, pub code_dir: CodeDir,
pub op_dir: OpDir, pub op_dir: OpDir,
pub term_dir: TermDir, // this contains multifile predicates.
pub term_expansions: (Predicate, VecDeque<TopLevel>), pub term_expansions: (Predicate, VecDeque<TopLevel>),
pub goal_expansions: (Predicate, VecDeque<TopLevel>), pub goal_expansions: (Predicate, VecDeque<TopLevel>),
pub user_term_expansions: (Predicate, VecDeque<TopLevel>), // term expansions inherited from the user scope. pub user_term_expansions: (Predicate, VecDeque<TopLevel>), // term expansions inherited from the user scope.

View File

@@ -614,8 +614,10 @@ assertz_clause(Head, Body) :-
arg(1, Head, Module), arg(1, Head, Module),
arg(2, Head, F), arg(2, Head, F),
module_assertz_clause(F, Body, Module) module_assertz_clause(F, Body, Module)
; '$no_such_predicate'(Head) -> call_assertz(Head, Body, Name, Arity) ; '$no_such_predicate'(Head) ->
; '$head_is_dynamic'(Head) -> call_assertz(Head, Body, Name, Arity) call_assertz(Head, Body, Name, Arity)
; '$head_is_dynamic'(Head) ->
call_assertz(Head, Body, Name, Arity)
; throw(error(permission_error(modify, static_procedure, Name/Arity), assertz/1)) ; throw(error(permission_error(modify, static_procedure, Name/Arity), assertz/1))
) )
; throw(error(type_error(callable, Head), assertz/1)) ; throw(error(type_error(callable, Head), assertz/1))

View File

@@ -374,7 +374,17 @@ fn compile_into_module_impl<R: Read>(
let mut clause_code_generator = ClauseCodeGenerator::new(module_code.len(), module_name.clone()); let mut clause_code_generator = ClauseCodeGenerator::new(module_code.len(), module_name.clone());
clause_code_generator.generate_clause_code(&results.dynamic_clause_map, wam)?; clause_code_generator.generate_clause_code(&results.dynamic_clause_map, wam)?;
add_module_code(wam, compiler.module.take().unwrap(), module_code, indices);
let top_level_term_dir = results.top_level_term_dirs.consolidate();
add_module_code(
wam,
compiler.module.take().unwrap(),
module_code,
indices,
top_level_term_dir,
);
clause_code_generator.add_clause_code(wam, results.dynamic_clause_map); clause_code_generator.add_clause_code(wam, results.dynamic_clause_map);
Ok(compiler.drop_expansions(wam.machine_flags(), &mut wam.code_repo)) Ok(compiler.drop_expansions(wam.machine_flags(), &mut wam.code_repo))
@@ -386,7 +396,9 @@ pub struct GatherResult {
toplevel_results: Vec<PredicateCompileQueue>, toplevel_results: Vec<PredicateCompileQueue>,
toplevel_indices: IndexStore, toplevel_indices: IndexStore,
addition_results: ExpansionAdditionResult, addition_results: ExpansionAdditionResult,
top_level_terms: Vec<(Term, usize, usize)> top_level_terms: Vec<(Term, usize, usize)>,
top_level_term_dirs: TermDirQuantum,
module_term_dirs: TermDirQuantum,
} }
pub struct ClauseCodeGenerator { pub struct ClauseCodeGenerator {
@@ -489,16 +501,29 @@ pub struct ListingCompiler {
listing_src: ListingSource, // a file? a module? listing_src: ListingSource, // a file? a module?
} }
fn add_toplevel_code(wam: &mut Machine, code: Code, indices: IndexStore) { fn add_toplevel_code(
wam: &mut Machine,
code: Code,
indices: IndexStore,
term_dir: TermDir,
) {
wam.add_batched_code(code, indices.code_dir); wam.add_batched_code(code, indices.code_dir);
wam.add_batched_ops(indices.op_dir); wam.add_batched_ops(indices.op_dir);
wam.code_repo.term_dir.extend(term_dir.into_iter());
} }
#[inline] #[inline]
fn add_module_code(wam: &mut Machine, mut module: Module, code: Code, indices: IndexStore) fn add_module_code(
{ wam: &mut Machine,
mut module: Module,
code: Code,
indices: IndexStore,
term_dir: TermDir,
) {
module.code_dir.extend(indices.code_dir); module.code_dir.extend(indices.code_dir);
module.op_dir.extend(indices.op_dir.into_iter()); module.op_dir.extend(indices.op_dir.into_iter());
module.term_dir.extend(term_dir.into_iter());
wam.add_module(module, code); wam.add_module(module, code);
} }
@@ -508,13 +533,14 @@ fn add_non_module_code(
dynamic_clause_map: DynamicClauseMap, dynamic_clause_map: DynamicClauseMap,
code: Code, code: Code,
indices: IndexStore, indices: IndexStore,
term_dir: TermDir,
) -> Result<(), SessionError> { ) -> Result<(), SessionError> {
wam.check_toplevel_code(&indices)?; wam.check_toplevel_code(&indices)?;
let mut clause_code_generator = ClauseCodeGenerator::new(code.len(), clause_name!("user")); let mut clause_code_generator = ClauseCodeGenerator::new(code.len(), clause_name!("user"));
clause_code_generator.generate_clause_code(&dynamic_clause_map, wam)?; clause_code_generator.generate_clause_code(&dynamic_clause_map, wam)?;
add_toplevel_code(wam, code, indices); add_toplevel_code(wam, code, indices, term_dir);
clause_code_generator.add_clause_code(wam, dynamic_clause_map); clause_code_generator.add_clause_code(wam, dynamic_clause_map);
Ok(()) Ok(())
@@ -694,6 +720,7 @@ impl ListingCompiler {
let (name, arity) = decl let (name, arity) = decl
.predicate_indicator() .predicate_indicator()
.ok_or(SessionError::NamelessEntry)?; .ok_or(SessionError::NamelessEntry)?;
let non_counted_bt = self.non_counted_bt_preds.contains(&(name.clone(), arity)); let non_counted_bt = self.non_counted_bt_preds.contains(&(name.clone(), arity));
let p = code.len() + wam.code_repo.code.len() + code_offset; let p = code.len() + wam.code_repo.code.len() + code_offset;
@@ -797,7 +824,12 @@ impl ListingCompiler {
flags: MachineFlags, flags: MachineFlags,
) -> Result<(), SessionError> { ) -> Result<(), SessionError> {
match decl { match decl {
Declaration::EndOfFile => Ok(()), Declaration::Dynamic(..) => {
Ok(())
}
Declaration::EndOfFile => {
Ok(())
}
Declaration::Hook(hook, clause, queue) => { Declaration::Hook(hook, clause, queue) => {
let key = (hook.name(), hook.arity()); let key = (hook.name(), hook.arity());
let (len, queue_len) = let (len, queue_len) =
@@ -812,37 +844,6 @@ impl ListingCompiler {
result result
} }
Declaration::NonCountedBacktracking(name, arity) => {
Ok(self.add_non_counted_bt_flag(name, arity))
}
Declaration::Op(op_decl) => {
self.submit_op(wam, indices, &op_decl)
}
Declaration::UseModule(ModuleSource::Library(name)) => {
let name = if !wam.indices.modules.contains_key(&name) {
load_library(wam, name, true)?
} else {
name
};
self.use_module(name, &mut wam.code_repo, flags, &mut wam.indices, indices)
}
Declaration::UseQualifiedModule(ModuleSource::Library(name), exports) => {
let name = if !wam.indices.modules.contains_key(&name) {
load_library(wam, name, true)?
} else {
name
};
self.use_qualified_module(
name,
&mut wam.code_repo,
flags,
&exports,
&mut wam.indices,
indices
)
},
Declaration::Module(module_decl) => { Declaration::Module(module_decl) => {
if self.module.is_none() { if self.module.is_none() {
let module_name = module_decl.name.clone(); let module_name = module_decl.name.clone();
@@ -861,6 +862,30 @@ impl ListingCompiler {
Err(SessionError::from(ParserError::InvalidModuleDecl)) Err(SessionError::from(ParserError::InvalidModuleDecl))
} }
} }
Declaration::ModuleInitialization(query_terms, queue) => {
self.initialization_goals.0.extend(query_terms.into_iter());
self.initialization_goals.1.extend(queue.into_iter());
Ok(())
}
Declaration::MultiFile(..) => {
Ok(())
}
Declaration::NonCountedBacktracking(name, arity) => {
Ok(self.add_non_counted_bt_flag(name, arity))
}
Declaration::Op(op_decl) => {
self.submit_op(wam, indices, &op_decl)
}
Declaration::UseModule(ModuleSource::Library(name)) => {
let name = if !wam.indices.modules.contains_key(&name) {
load_library(wam, name, true)?
} else {
name
};
self.use_module(name, &mut wam.code_repo, flags, &mut wam.indices, indices)
}
Declaration::UseModule(ModuleSource::File(filename)) => { Declaration::UseModule(ModuleSource::File(filename)) => {
let mut path_buf = self.listing_src.path(); let mut path_buf = self.listing_src.path();
path_buf.push(filename.as_str()); path_buf.push(filename.as_str());
@@ -868,6 +893,22 @@ impl ListingCompiler {
let name = load_module_from_file(wam, path_buf, true)?; let name = load_module_from_file(wam, path_buf, true)?;
self.use_module(name, &mut wam.code_repo, flags, &mut wam.indices, indices) self.use_module(name, &mut wam.code_repo, flags, &mut wam.indices, indices)
} }
Declaration::UseQualifiedModule(ModuleSource::Library(name), exports) => {
let name = if !wam.indices.modules.contains_key(&name) {
load_library(wam, name, true)?
} else {
name
};
self.use_qualified_module(
name,
&mut wam.code_repo,
flags,
&exports,
&mut wam.indices,
indices
)
}
Declaration::UseQualifiedModule(ModuleSource::File(filename), exports) => { Declaration::UseQualifiedModule(ModuleSource::File(filename), exports) => {
let mut path_buf = self.listing_src.path(); let mut path_buf = self.listing_src.path();
path_buf.push(filename.as_str()); path_buf.push(filename.as_str());
@@ -883,14 +924,55 @@ impl ListingCompiler {
indices, indices,
) )
} }
Declaration::ModuleInitialization(query_terms, queue) => { }
self.initialization_goals.0.extend(query_terms.into_iter()); }
self.initialization_goals.1.extend(queue.into_iter());
Ok(()) fn setup_multifile_decl<R: Read>(
&self,
name: ClauseName,
arity: usize,
worker: &mut TopLevelBatchWorker<R>
) -> Result<(), SessionError> {
let module_name = name.owning_module();
let term_dir = match module_name.as_str() {
"user" => {
&worker.term_stream.wam.code_repo.term_dir
} }
Declaration::Dynamic(..) => Ok(()), _ => {
if let Some(ref module) = self.module {
&module.term_dir
} else {
match worker.term_stream.wam.indices.modules.get(&module_name) {
Some(ref module) => {
&module.term_dir
} }
None => {
return Err(SessionError::ModuleNotFound);
}
}
}
}
};
Ok(match term_dir.get(&(name.clone(), arity)) {
Some((ref preds, ref queue)) => {
let (preds, queue) = (preds.clone(), queue.clone());
worker.term_dirs.set_old(
(name.clone(), arity),
preds,
queue,
);
}
None => {
worker.term_dirs.set_old(
(name.clone(), arity),
Predicate::new(),
VecDeque::new(),
);
}
})
} }
fn process_and_commit_decl<R: Read>( fn process_and_commit_decl<R: Read>(
@@ -919,6 +1001,9 @@ impl ListingCompiler {
&Declaration::Hook(hook, _, ref queue) if !hook.has_module_scope() => { &Declaration::Hook(hook, _, ref queue) if !hook.has_module_scope() => {
worker.term_stream.incr_expansion_lens(hook, 1, queue.len()) worker.term_stream.incr_expansion_lens(hook, 1, queue.len())
} }
&Declaration::MultiFile(ref name, arity) => {
self.setup_multifile_decl(name.clone(), arity, worker)?;
}
&Declaration::UseModule(_) | &Declaration::UseQualifiedModule(..) => { &Declaration::UseModule(_) | &Declaration::UseQualifiedModule(..) => {
update_expansion_lengths = true update_expansion_lengths = true
} }
@@ -947,6 +1032,8 @@ impl ListingCompiler {
let mut toplevel_results = vec![]; let mut toplevel_results = vec![];
let mut toplevel_indices = default_index_store!(atom_tbl.clone()); let mut toplevel_indices = default_index_store!(atom_tbl.clone());
let mut top_level_term_dirs = TermDirQuantum::new();
while let Some(decl) = worker.consume(indices)? { while let Some(decl) = worker.consume(indices)? {
if decl.is_module_decl() { if decl.is_module_decl() {
toplevel_indices.copy_and_swap(indices); toplevel_indices.copy_and_swap(indices);
@@ -957,6 +1044,10 @@ impl ListingCompiler {
if let Some(ref module) = &self.module { if let Some(ref module) = &self.module {
worker.term_stream.set_atom_tbl(module.atom_tbl.clone()); worker.term_stream.set_atom_tbl(module.atom_tbl.clone());
top_level_term_dirs = mem::replace(
&mut worker.term_dirs,
TermDirQuantum::new(),
);
} }
} else if decl.is_end_of_file() { } else if decl.is_end_of_file() {
break; break;
@@ -967,6 +1058,13 @@ impl ListingCompiler {
let addition_results = worker.term_stream.rollback_expansion_code()?; let addition_results = worker.term_stream.rollback_expansion_code()?;
let module_term_dirs = if self.module.is_some() {
worker.term_dirs
} else {
top_level_term_dirs = worker.term_dirs;
TermDirQuantum::new()
};
Ok(GatherResult { Ok(GatherResult {
worker_results: worker.results, worker_results: worker.results,
dynamic_clause_map: worker.dynamic_clause_map, dynamic_clause_map: worker.dynamic_clause_map,
@@ -974,6 +1072,8 @@ impl ListingCompiler {
toplevel_indices, toplevel_indices,
addition_results, addition_results,
top_level_terms: worker.term_stream.top_level_terms(), top_level_terms: worker.term_stream.top_level_terms(),
top_level_term_dirs,
module_term_dirs,
}) })
} }
@@ -1016,6 +1116,9 @@ fn compile_work_impl(
} }
} }
let top_level_term_dir = results.top_level_term_dirs.consolidate();
let module_term_dir = results.module_term_dirs.consolidate();
let module_code = compiler.generate_code( let module_code = compiler.generate_code(
results.worker_results, results.worker_results,
wam, wam,
@@ -1062,24 +1165,25 @@ fn compile_work_impl(
} }
if module.is_impromptu_module { if module.is_impromptu_module {
add_module_code(wam, module, module_code, indices); add_module_code(wam, module, module_code, indices, module_term_dir);
let module = wam.indices.take_module(compiler.listing_src.name()).unwrap(); let module = wam.indices.take_module(compiler.listing_src.name()).unwrap();
wam.indices.use_module(&mut wam.code_repo, wam.machine_st.flags, &module)?; wam.indices.use_module(&mut wam.code_repo, wam.machine_st.flags, &module)?;
wam.indices.insert_module(module); wam.indices.insert_module(module);
} else { } else {
add_module_code(wam, module, module_code, indices); add_module_code(wam, module, module_code, indices, module_term_dir);
} }
add_toplevel_code(wam, toplvl_code, results.toplevel_indices); add_toplevel_code(wam, toplvl_code, results.toplevel_indices, top_level_term_dir);
clause_code_generator.add_clause_code(wam, results.dynamic_clause_map); clause_code_generator.add_clause_code(wam, results.dynamic_clause_map);
} else { } else {
add_non_module_code( add_non_module_code(
wam, wam,
results.dynamic_clause_map, results.dynamic_clause_map,
module_code, module_code,
indices indices,
top_level_term_dir,
)?; )?;
} }
@@ -1132,7 +1236,9 @@ pub fn compile_special_form<R: Read>(
let code = compiler.generate_code(results.worker_results, wam, &mut indices.code_dir, 0)?; let code = compiler.generate_code(results.worker_results, wam, &mut indices.code_dir, 0)?;
let p = wam.code_repo.code.len(); let p = wam.code_repo.code.len();
add_toplevel_code(wam, code, indices); let top_level_term_dir = results.top_level_term_dirs.consolidate();
add_toplevel_code(wam, code, indices, top_level_term_dir);
Ok(p) Ok(p)
} }

View File

@@ -270,8 +270,12 @@ impl Machine {
p: LocalCodePtr, p: LocalCodePtr,
) { ) {
match trans_type { match trans_type {
DynamicTransactionType::Abolish => self.abolish_dynamic_clause(temp_v!(1), temp_v!(2)), DynamicTransactionType::Abolish => {
DynamicTransactionType::Assert(place) => self.recompile_dynamic_predicate(place), self.abolish_dynamic_clause(temp_v!(1), temp_v!(2))
}
DynamicTransactionType::Assert(place) => {
self.recompile_dynamic_predicate(place)
}
DynamicTransactionType::ModuleAbolish => { DynamicTransactionType::ModuleAbolish => {
self.abolish_dynamic_clause_in_module(temp_v!(1), temp_v!(2), temp_v!(3)) self.abolish_dynamic_clause_in_module(temp_v!(1), temp_v!(2), temp_v!(3))
} }
@@ -281,7 +285,9 @@ impl Machine {
DynamicTransactionType::ModuleRetract => { DynamicTransactionType::ModuleRetract => {
self.retract_from_dynamic_predicate_in_module() self.retract_from_dynamic_predicate_in_module()
} }
DynamicTransactionType::Retract => self.retract_from_dynamic_predicate(), DynamicTransactionType::Retract => {
self.retract_from_dynamic_predicate()
}
} }
self.machine_st.p = CodePtr::Local(p); self.machine_st.p = CodePtr::Local(p);

View File

@@ -18,8 +18,9 @@ impl Module {
) -> Self ) -> Self
{ {
Module { Module {
module_decl,
atom_tbl, atom_tbl,
module_decl,
term_dir: TermDir::new(),
user_term_expansions: (Predicate::new(), VecDeque::from(vec![])), user_term_expansions: (Predicate::new(), VecDeque::from(vec![])),
user_goal_expansions: (Predicate::new(), VecDeque::from(vec![])), user_goal_expansions: (Predicate::new(), VecDeque::from(vec![])),
term_expansions: (Predicate::new(), VecDeque::from(vec![])), term_expansions: (Predicate::new(), VecDeque::from(vec![])),

View File

@@ -377,10 +377,6 @@ fn merge_clauses(tls: &mut VecDeque<TopLevel>) -> Result<TopLevel, ParserError>
} }
} }
fn append_preds(preds: &mut Vec<PredicateClause>) -> Predicate {
Predicate(mem::replace(preds, vec![]))
}
fn mark_cut_variables_as(terms: &mut Vec<Term>, name: ClauseName) { fn mark_cut_variables_as(terms: &mut Vec<Term>, name: ClauseName) {
for term in terms.iter_mut() { for term in terms.iter_mut() {
match term { match term {
@@ -493,20 +489,6 @@ fn setup_declaration<'a, 'b, 'c, R: Read>(
match term { match term {
Term::Clause(_, name, mut terms, _) => Term::Clause(_, name, mut terms, _) =>
match (name.as_str(), terms.len()) { match (name.as_str(), terms.len()) {
("op", 3) =>
Ok(Declaration::Op(setup_op_decl(terms, indices.atom_tbl())?)),
("module", 2) =>
Ok(Declaration::Module(setup_module_decl(terms, indices.atom_tbl())?)),
("use_module", 1) =>
Ok(Declaration::UseModule(setup_use_module_decl(terms)?)),
("use_module", 2) => {
let (name, exports) = setup_qualified_import(terms, indices.atom_tbl())?;
Ok(Declaration::UseQualifiedModule(name, exports))
}
("non_counted_backtracking", 1) => {
let (name, arity) = setup_predicate_indicator(&mut *terms.pop().unwrap())?;
Ok(Declaration::NonCountedBacktracking(name, arity))
}
("dynamic", 1) => { ("dynamic", 1) => {
let (name, arity) = setup_predicate_indicator(&mut *terms.pop().unwrap())?; let (name, arity) = setup_predicate_indicator(&mut *terms.pop().unwrap())?;
Ok(Declaration::Dynamic(name, arity)) Ok(Declaration::Dynamic(name, arity))
@@ -518,10 +500,30 @@ fn setup_declaration<'a, 'b, 'c, R: Read>(
Ok(Declaration::ModuleInitialization(query_terms, queue)) Ok(Declaration::ModuleInitialization(query_terms, queue))
} }
_ => ("module", 2) =>
Ok(Declaration::Module(setup_module_decl(terms, indices.atom_tbl())?)),
("op", 3) =>
Ok(Declaration::Op(setup_op_decl(terms, indices.atom_tbl())?)),
("non_counted_backtracking", 1) => {
let (name, arity) = setup_predicate_indicator(&mut *terms.pop().unwrap())?;
Ok(Declaration::NonCountedBacktracking(name, arity))
}
("multifile", 1) => {
let (name, arity) = setup_predicate_indicator(&mut *terms.pop().unwrap())?;
Ok(Declaration::MultiFile(name, arity))
}
("use_module", 1) => {
Ok(Declaration::UseModule(setup_use_module_decl(terms)?))
}
("use_module", 2) => {
let (name, exports) = setup_qualified_import(terms, indices.atom_tbl())?;
Ok(Declaration::UseQualifiedModule(name, exports))
}
_ => {
Err(ParserError::InconsistentEntry) Err(ParserError::InconsistentEntry)
}
}, },
_ => return Err(ParserError::InconsistentEntry), _ => Err(ParserError::InconsistentEntry),
} }
} }
@@ -943,7 +945,64 @@ impl RelationWorker {
} }
} }
pub type DynamicClauseMap = IndexMap<(ClauseName, usize), Vec<(Term, Term)>>; pub type DynamicClause = Vec<(Term, Term)>;
pub type DynamicClauseMap = IndexMap<(ClauseName, usize), DynamicClause>;
pub struct TermDirQuantum {
old_term_dir: TermDir,
new_term_dir: TermDir,
}
impl TermDirQuantum {
pub fn new() -> Self {
Self {
old_term_dir: TermDir::new(),
new_term_dir: TermDir::new()
}
}
#[inline]
fn get_old(&self, name: ClauseName, arity: usize) -> Option<&(Predicate, VecDeque<TopLevel>)>
{
self.old_term_dir.get(&(name, arity))
}
#[inline]
fn add_new(
&mut self,
key: PredicateKey,
preds: &mut Vec<PredicateClause>,
queue: VecDeque<TopLevel>
) {
let preds = Predicate(mem::replace(preds, vec![]));
self.new_term_dir.insert(key, (preds, queue));
}
pub fn consolidate(self) -> TermDir {
let mut term_dir = self.old_term_dir;
for (key, (preds, queue)) in self.new_term_dir {
let (prev_preds, prev_queue) =
term_dir.entry(key).or_insert((Predicate::new(), VecDeque::new()));
prev_preds.0.extend(preds.0.into_iter());
prev_queue.extend(queue.into_iter());
}
term_dir
}
#[inline]
pub fn set_old(
&mut self,
key: PredicateKey,
pred: Predicate,
queue: VecDeque<TopLevel>
) {
self.old_term_dir.insert(key, (pred, queue));
}
}
pub struct TopLevelBatchWorker<'a, R: Read> { pub struct TopLevelBatchWorker<'a, R: Read> {
pub(crate) term_stream: TermStream<'a, R>, pub(crate) term_stream: TermStream<'a, R>,
@@ -951,6 +1010,7 @@ pub struct TopLevelBatchWorker<'a, R: Read> {
pub(crate) results: Vec<(Predicate, VecDeque<TopLevel>)>, pub(crate) results: Vec<(Predicate, VecDeque<TopLevel>)>,
pub(crate) dynamic_clause_map: DynamicClauseMap, pub(crate) dynamic_clause_map: DynamicClauseMap,
pub(crate) in_module: bool, pub(crate) in_module: bool,
pub(crate) term_dirs: TermDirQuantum
} }
impl<'a, R: Read> TopLevelBatchWorker<'a, R> { impl<'a, R: Read> TopLevelBatchWorker<'a, R> {
@@ -971,6 +1031,7 @@ impl<'a, R: Read> TopLevelBatchWorker<'a, R> {
results: vec![], results: vec![],
dynamic_clause_map: IndexMap::new(), dynamic_clause_map: IndexMap::new(),
in_module: false, in_module: false,
term_dirs: TermDirQuantum::new(),
} }
} }
@@ -1006,8 +1067,22 @@ impl<'a, R: Read> TopLevelBatchWorker<'a, R> {
if self.in_module { None } else { Some(IndexSource::TermStream) } if self.in_module { None } else { Some(IndexSource::TermStream) }
); );
let (name, arity) = (preds[0].name().unwrap(), preds[0].arity());
let (mut prev_preds, mut prev_queue) =
match self.term_dirs.get_old(name.clone(), arity).cloned() {
Some((preds, queue)) => (preds, queue),
None => (Predicate::new(), VecDeque::new()),
};
let queue = self.rel_worker.parse_queue(&mut indices)?; let queue = self.rel_worker.parse_queue(&mut indices)?;
let result = (append_preds(preds), queue);
prev_preds.0.extend(preds.iter().cloned());
prev_queue.extend(queue.iter().cloned());
let result = (prev_preds, prev_queue);
self.term_dirs.add_new((name, arity), preds, queue);
let in_situ_code_dir = &mut indices.term_stream.wam.indices.in_situ_code_dir; let in_situ_code_dir = &mut indices.term_stream.wam.indices.in_situ_code_dir;