From: Mark Thom Date: Thu, 4 Oct 2018 04:56:12 +0000 (-0600) Subject: divide atom tables by module X-Git-Tag: v0.8.110~353 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=8e4bb039f0800294ce0786f1912f8c1ae6edafe2;p=scryer-prolog.git divide atom tables by module --- diff --git a/Cargo.lock b/Cargo.lock index da798706..24feaf87 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -86,7 +86,7 @@ dependencies = [ [[package]] name = "prolog_parser" -version = "0.7.16" +version = "0.7.17" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -113,7 +113,7 @@ dependencies = [ "downcast 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "ordered-float 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "prolog_parser 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)", + "prolog_parser 0.7.17 (registry+https://github.com/rust-lang/crates.io-index)", "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -152,7 +152,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cacfcab5eb48250ee7d0c7896b51a2c5eec99c1feea5f32025635f5ae4b00070" "checksum num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "630de1ef5cc79d0cdd78b7e33b81f083cbfe90de0f4b2b2f07f905867c70e9fe" "checksum ordered-float 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "58d25b6c0e47b20d05226d288ff434940296e7e2f8b877975da32f862152241f" -"checksum prolog_parser 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)" = "71a1f33a90a68d4641143f591c9d97d6c939622d5bfbebed3630d7264f593736" +"checksum prolog_parser 0.7.17 (registry+https://github.com/rust-lang/crates.io-index)" = "221eed4744a63708fac45edb126b86f8ef2713757bc647dfcda4ee51c8ef57c1" "checksum redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ab105df655884ede59d45b7070c8a65002d921461ee813a024558ca16030eea0" "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" diff --git a/Cargo.toml b/Cargo.toml index 68282b9b..32e20b30 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ license = "BSD-3-Clause" downcast = "0.9.1" num = "0.2" ordered-float = "0.5.0" -prolog_parser = "0.7.16" +prolog_parser = "0.7.17" [dependencies.termion] version = "1.4.0" \ No newline at end of file diff --git a/src/prolog/compile.rs b/src/prolog/compile.rs index 557bb162..a55953e8 100644 --- a/src/prolog/compile.rs +++ b/src/prolog/compile.rs @@ -1,4 +1,5 @@ use prolog_parser::ast::*; +use prolog_parser::tabled_rc::TabledData; use prolog::instructions::*; use prolog::debray_allocator::*; @@ -98,7 +99,9 @@ fn compile_query(terms: Vec, queue: Vec, flags: MachineFlag fn package_term(wam: &mut Machine, term: Term) -> Result { let code_dir = wam.code_dir.clone(); - let indices = machine_code_indices!(&mut CodeDir::new(), &mut wam.op_dir, &mut wam.modules); + let indices = machine_code_indices!(&mut CodeDir::new(), + &mut wam.op_dir, + &mut wam.modules); consume_term(code_dir, term, indices) } @@ -132,8 +135,11 @@ pub struct ListingCompiler { } impl ListingCompiler { + #[inline] pub fn new() -> Self { - ListingCompiler { module: None, non_counted_bt_preds: HashSet::new() } + ListingCompiler { + module: None, non_counted_bt_preds: HashSet::new() + } } fn use_module(&mut self, submodule: Module, wam: &mut Machine, indices: &mut MachineCodeIndices) @@ -150,8 +156,7 @@ impl ListingCompiler { wam.remove_module(&submodule); } - wam.insert_module(submodule); - Ok(()) + Ok(wam.insert_module(submodule)) } fn use_qualified_module(&mut self, submodule: Module, wam: &mut Machine, @@ -169,8 +174,7 @@ impl ListingCompiler { wam.remove_module(&submodule); } - wam.insert_module(submodule); - Ok(()) + Ok(wam.insert_module(submodule)) } fn get_module_name(&self) -> ClauseName { @@ -255,7 +259,10 @@ impl ListingCompiler { }, Declaration::Module(module_decl) => if self.module.is_none() { - Ok(self.module = Some(Module::new(module_decl))) + let module_name = module_decl.name.clone(); + let atom_tbl = TabledData::new(module_name.to_rc()); + + Ok(self.module = Some(Module::new(module_decl, atom_tbl))) } else { Err(SessionError::from(ParserError::InvalidModuleDecl)) } @@ -278,9 +285,15 @@ fn compile_listing<'a, R: Read>(wam: &mut Machine, src: R, mut indices: MachineC toplevel_indices.copy_and_swap(&mut indices); mem::swap(&mut worker.results, &mut toplevel_results); worker.in_module = true; - } - try_eval_session!(compiler.process_decl(decl, wam, &mut indices)); + try_eval_session!(compiler.process_decl(decl, wam, &mut indices)); + + if let &Some(ref module) = &compiler.module { + worker.term_stream.set_atom_tbl(module.atom_tbl.clone()); + } + } else { + try_eval_session!(compiler.process_decl(decl, wam, &mut indices)); + } } let module_code = try_eval_session!(compiler.generate_code(worker.results, wam, @@ -305,6 +318,5 @@ fn setup_indices(wam: &Machine, indices: &mut MachineCodeIndices) -> Result<(), pub fn compile_user_module(wam: &mut Machine, src: R) -> EvalSession { let mut indices = default_machine_code_indices!(); try_eval_session!(setup_indices(&wam, &mut indices)); - compile_listing(wam, src, indices, default_machine_code_indices!()) } diff --git a/src/prolog/instructions.rs b/src/prolog/instructions.rs index e695992d..e2eaca31 100644 --- a/src/prolog/instructions.rs +++ b/src/prolog/instructions.rs @@ -1,4 +1,5 @@ use prolog_parser::ast::*; +use prolog_parser::tabled_rc::*; use std::cell::{Cell, RefCell}; use std::collections::{BTreeSet, HashMap, VecDeque}; @@ -207,6 +208,7 @@ pub struct ModuleDecl { } pub struct Module { + pub atom_tbl: TabledData, pub module_decl: ModuleDecl, pub code_dir: ModuleCodeDir, pub op_dir: OpDir @@ -807,7 +809,7 @@ impl CodeIndex { #[inline] pub fn module_name(&self) -> ClauseName { - self.0.borrow().1.clone() + self.0.borrow().1.clone() } } @@ -853,7 +855,7 @@ impl CodePtr { match self { &CodePtr::BuiltInClause(_, ref local) | &CodePtr::CallN(_, ref local) - | &CodePtr::Local(ref local) => local.clone() + | &CodePtr::Local(ref local) => local.clone() } } } @@ -926,7 +928,7 @@ impl AddAssign for LocalCodePtr { match self { &mut LocalCodePtr::UserTermExpansion(ref mut p) | &mut LocalCodePtr::DirEntry(ref mut p) - | &mut LocalCodePtr::TopLevel(_, ref mut p) => *p += rhs + | &mut LocalCodePtr::TopLevel(_, ref mut p) => *p += rhs } } } @@ -1038,8 +1040,8 @@ impl<'a> TermIterState<'a> { } impl Module { - pub fn new(module_decl: ModuleDecl) -> Self { - Module { module_decl, + pub fn new(module_decl: ModuleDecl, atom_tbl: TabledData) -> Self { + Module { module_decl, atom_tbl, code_dir: ModuleCodeDir::new(), op_dir: default_op_dir() } } @@ -1056,9 +1058,9 @@ pub fn as_module_code_dir(code_dir: CodeDir) -> ModuleCodeDir { pub trait SubModuleUser { fn op_dir(&mut self) -> &mut OpDir; - fn remove_code_index(&mut self, key: PredicateKey); - fn get_code_index(&self, key: PredicateKey, module: ClauseName) -> Option; - + fn remove_code_index(&mut self, PredicateKey); + fn get_code_index(&self, PredicateKey, ClauseName) -> Option; + fn insert_dir_entry(&mut self, ClauseName, usize, ModuleCodeIndex); fn remove_module(&mut self, mod_name: ClauseName, module: &Module) { @@ -1101,7 +1103,7 @@ pub trait SubModuleUser { }; } } - + // returns true on successful import. fn import_decl(&mut self, name: ClauseName, arity: usize, submodule: &Module) -> bool { let name = name.defrock_brackets(); @@ -1124,6 +1126,7 @@ pub trait SubModuleUser { } if let Some(code_data) = submodule.code_dir.get(&(name.clone(), arity)) { + let name = name.with_table(submodule.atom_tbl.clone()); self.insert_dir_entry(name, arity, code_data.clone()); true } else { @@ -1170,14 +1173,15 @@ impl SubModuleUser for Module { fn remove_code_index(&mut self, key: PredicateKey) { self.code_dir.remove(&key); } - - fn insert_dir_entry(&mut self, name: ClauseName, arity: usize, idx: ModuleCodeIndex) { + + fn insert_dir_entry(&mut self, name: ClauseName, arity: usize, idx: ModuleCodeIndex) + { self.code_dir.insert((name, arity), idx); } } -pub enum Declaration { - Hook(CompileTimeHook, PredicateClause), +pub enum Declaration { + Hook(CompileTimeHook, PredicateClause), Module(ModuleDecl), NonCountedBacktracking(ClauseName, usize), // name, arity Op(OpDecl), @@ -1194,10 +1198,10 @@ impl Declaration { pub enum TopLevel { Declaration(Declaration), - Fact(Term), + Fact(Term), Predicate(Predicate), Query(Vec), - Rule(Rule), + Rule(Rule), } impl TopLevel { diff --git a/src/prolog/lib/builtins.pl b/src/prolog/lib/builtins.pl index b07b7e96..66638a35 100644 --- a/src/prolog/lib/builtins.pl +++ b/src/prolog/lib/builtins.pl @@ -6,9 +6,8 @@ (=:=)/2, (-)/1, (>=)/2, (=<)/2, (,)/2, (->)/2, (;)/2, (=..)/2, (==)/2, (\==)/2, (@=<)/2, (@>=)/2, (@<)/2, (@>)/2, (=@=)/2, (\=@=)/2, (:)/2, call_with_inference_limit/3, catch/3, - current_prolog_flag/2, set_prolog_flag/2, - setup_call_cleanup/3, term_variables/2, throw/1, true/0, - false/0]). + current_prolog_flag/2, set_prolog_flag/2, term_variables/2, + setup_call_cleanup/3, throw/1, true/0, false/0]). /* this is an implementation specific declarative operator used to implement call_with_inference_limit/3 and setup_call_cleanup/3. switches to the default trust_me and retry_me_else. Indexing choice @@ -206,8 +205,12 @@ get_args([Arg|Args], Func, I0, N) :- '$call_with_default_policy'(I1 is I0 + 1), '$call_with_default_policy'(get_args(Args, Func, I1, N)). -term_variables(Term, Vars) :- '$term_variables'(Term, Vars). - +% term_variables. + +term_variables(Term, Vars) :- + error:can_be(list, Vars), + '$term_variables'(Term, Vars). + % setup_call_cleanup. setup_call_cleanup(S, G, C) :- '$get_b_value'(B), diff --git a/src/prolog/lib/terms.pl b/src/prolog/lib/terms.pl index 35cefa4b..8391457b 100644 --- a/src/prolog/lib/terms.pl +++ b/src/prolog/lib/terms.pl @@ -1,12 +1,16 @@ :- module(terms, [numbervars/3]). :- use_module(library(error)). - + numbervars(Term, N0, N) :- + catch(internal_numbervars(Term, N0, N), error(E,Ctx), + ( ( var(Ctx) -> Ctx = numbervars/3 ; true ), throw(error(E,Ctx) ) ) ). + +internal_numbervars(Term, N0, N) :- must_be(integer, N0), can_be(integer, N), term_variables(Term, Vars), - numberlist(Vars, N0,N). + numberlist(Vars, N0, N). numberlist([], N,N). numberlist(['$VAR'(N0)|Vars], N0,N) :- diff --git a/src/prolog/machine/machine_state.rs b/src/prolog/machine/machine_state.rs index 17d6bfea..efe74946 100644 --- a/src/prolog/machine/machine_state.rs +++ b/src/prolog/machine/machine_state.rs @@ -307,7 +307,7 @@ pub(crate) trait CallPolicy: Any { machine_st.pstr_tr = machine_st.or_stack[b].pstr_tr; machine_st.pstr_trail.truncate(machine_st.pstr_tr); - + machine_st.heap.truncate(machine_st.or_stack[b].h); machine_st.hb = machine_st.heap.h; @@ -334,7 +334,7 @@ pub(crate) trait CallPolicy: Any { let curr_tr = machine_st.tr; machine_st.unwind_trail(old_tr, curr_tr); - machine_st.tr = machine_st.or_stack[b].tr; + machine_st.tr = machine_st.or_stack[b].tr; machine_st.trail.truncate(machine_st.tr); @@ -345,7 +345,7 @@ pub(crate) trait CallPolicy: Any { machine_st.pstr_tr = machine_st.or_stack[b].pstr_tr; machine_st.pstr_trail.truncate(machine_st.pstr_tr); - + machine_st.heap.truncate(machine_st.or_stack[b].h); machine_st.hb = machine_st.heap.h; @@ -371,7 +371,7 @@ pub(crate) trait CallPolicy: Any { machine_st.unwind_trail(old_tr, curr_tr); machine_st.tr = machine_st.or_stack[b].tr; - + machine_st.trail.truncate(machine_st.tr); let old_pstr_tr = machine_st.or_stack[b].pstr_tr; @@ -381,7 +381,7 @@ pub(crate) trait CallPolicy: Any { machine_st.pstr_tr = machine_st.or_stack[b].pstr_tr; machine_st.pstr_trail.truncate(machine_st.pstr_tr); - + machine_st.heap.truncate(machine_st.or_stack[b].h); machine_st.b = machine_st.or_stack[b].b; @@ -410,7 +410,7 @@ pub(crate) trait CallPolicy: Any { machine_st.unwind_trail(old_tr, curr_tr); machine_st.tr = machine_st.or_stack[b].tr; - + machine_st.trail.truncate(machine_st.tr); let old_pstr_tr = machine_st.or_stack[b].pstr_tr; @@ -420,7 +420,7 @@ pub(crate) trait CallPolicy: Any { machine_st.pstr_tr = machine_st.or_stack[b].pstr_tr; machine_st.pstr_trail.truncate(machine_st.pstr_tr); - + machine_st.heap.truncate(machine_st.or_stack[b].h); machine_st.b = machine_st.or_stack[b].b; @@ -508,7 +508,7 @@ pub(crate) trait CallPolicy: Any { stub)); }, IndexPtr::Index(compiled_tl_index) => - execute_at_index(machine_st, arity, compiled_tl_index) + execute_at_index(machine_st, arity, compiled_tl_index) } Ok(()) @@ -685,12 +685,10 @@ pub(crate) trait CallPolicy: Any { } fn call_n<'a>(&mut self, machine_st: &mut MachineState, arity: usize, - indices: MachineCodeIndices<'a>) //code_dirs: CodeDirs) + indices: MachineCodeIndices<'a>) -> CallResult { if let Some((name, arity)) = machine_st.setup_call_n(arity) { - let user = clause_name!("user"); - match ClauseType::from(name.clone(), arity, None) { ClauseType::CallN => { machine_st.handle_internal_call_n(arity); @@ -707,15 +705,18 @@ pub(crate) trait CallPolicy: Any { }, ClauseType::Inlined(inlined) => machine_st.execute_inlined(&inlined), - ClauseType::Op(..) | ClauseType::Named(..) => - if let Some(idx) = indices.get_code_index((name.clone(), arity), user) { + ClauseType::Op(..) | ClauseType::Named(..) => { + let module = name.owning_module(); + + if let Some(idx) = indices.get_code_index((name.clone(), arity), module) { self.context_call(machine_st, name, arity, idx, indices)?; } else { let h = machine_st.heap.h; let stub = MachineError::functor_stub(clause_name!("call"), arity + 1); return Err(machine_st.error_form(MachineError::existence_error(h, name, arity), stub)); - }, + } + }, ClauseType::Hook(_) | ClauseType::System(_) => { let name = Addr::Con(Constant::Atom(name, None)); let stub = MachineError::functor_stub(clause_name!("call"), arity + 1); diff --git a/src/prolog/machine/machine_state_impl.rs b/src/prolog/machine/machine_state_impl.rs index 6b1015aa..493104b7 100644 --- a/src/prolog/machine/machine_state_impl.rs +++ b/src/prolog/machine/machine_state_impl.rs @@ -1,5 +1,6 @@ use prolog_parser::ast::*; use prolog_parser::string_list::StringList; +use prolog_parser::tabled_rc::TabledData; use prolog::instructions::*; use prolog::and_stack::*; @@ -14,7 +15,6 @@ use prolog::num::bigint::{BigInt, BigUint}; use prolog::num::rational::Ratio; use prolog::or_stack::*; -use std::cell::RefCell; use std::cmp::{max, Ordering}; use std::collections::{HashMap, HashSet}; use std::rc::Rc; @@ -34,7 +34,7 @@ macro_rules! try_or_fail { impl MachineState { pub(super) fn new() -> Self { MachineState { - atom_tbl: Rc::new(RefCell::new(HashSet::new())), + atom_tbl: TabledData::new(Rc::new("user".to_string())), s: 0, p: CodePtr::default(), b: 0, diff --git a/src/prolog/machine/mod.rs b/src/prolog/machine/mod.rs index 68cc08ec..5f53ffce 100644 --- a/src/prolog/machine/mod.rs +++ b/src/prolog/machine/mod.rs @@ -62,17 +62,6 @@ pub struct Machine { cached_query: Option } -fn get_code_index(code_dir: &CodeDir, modules: &ModuleDir, key: PredicateKey, module: ClauseName) - -> Option -{ - match module.as_str() { - "user" | "builtin" => code_dir.get(&key).cloned(), - _ => modules.get(&module).and_then(|ref module| { - module.code_dir.get(&key).cloned().map(CodeIndex::from) - }) - } -} - impl Index for Machine { type Output = Line; @@ -95,15 +84,22 @@ impl<'a> SubModuleUser for MachineCodeIndices<'a> { self.op_dir } - fn get_code_index(&self, key: PredicateKey, module: ClauseName) -> Option { - get_code_index(&self.code_dir, &self.modules, key, module) + fn get_code_index(&self, key: PredicateKey, module: ClauseName) -> Option + { + match module.as_str() { + "user" | "builtin" => self.code_dir.get(&key).cloned(), + _ => self.modules.get(&module).and_then(|ref module| { + module.code_dir.get(&key).cloned().map(CodeIndex::from) + }) + } } fn remove_code_index(&mut self, key: PredicateKey) { self.code_dir.remove(&key); } - fn insert_dir_entry(&mut self, name: ClauseName, arity: usize, idx: ModuleCodeIndex) { + fn insert_dir_entry(&mut self, name: ClauseName, arity: usize, idx: ModuleCodeIndex) + { if let Some(ref mut code_idx) = self.code_dir.get_mut(&(name.clone(), arity)) { if !code_idx.is_undefined() { println!("warning: overwriting {}/{}", &name, arity); @@ -120,7 +116,7 @@ impl<'a> SubModuleUser for MachineCodeIndices<'a> { static LISTS: &str = include_str!("../lib/lists.pl"); static CONTROL: &str = include_str!("../lib/control.pl"); static QUEUES: &str = include_str!("../lib/queues.pl"); -static ERROR: &str = include_str!("../lib/error.pl"); +static ERROR: &str = include_str!("../lib/error.pl"); static TERMS: &str = include_str!("../lib/terms.pl"); impl Machine { @@ -221,7 +217,8 @@ impl Machine { #[inline] pub fn remove_module(&mut self, module: &Module) { - let mut indices = machine_code_indices!(&mut self.code_dir.borrow_mut(), &mut self.op_dir, + let mut indices = machine_code_indices!(&mut self.code_dir.borrow_mut(), + &mut self.op_dir, &mut self.modules); indices.remove_module(clause_name!("user"), module); } @@ -259,15 +256,15 @@ impl Machine { { let key = (clause_name!("term_expansion"), 2); let preds = self.term_dir.entry(key).or_insert(Predicate(vec![])); - + preds.0.push(clause); - + let mut cg = CodeGenerator::::new(false, self.ms.flags); let code = cg.compile_predicate(&preds.0)?; Ok(self.term_expanders = code) } - + fn lookup_instr(&self, p: CodePtr) -> Option { match p { CodePtr::Local(LocalCodePtr::UserTermExpansion(p)) => diff --git a/src/prolog/machine/term_expansion.rs b/src/prolog/machine/term_expansion.rs index a743a555..48876337 100644 --- a/src/prolog/machine/term_expansion.rs +++ b/src/prolog/machine/term_expansion.rs @@ -24,6 +24,11 @@ impl TermStream { } } + #[inline] + pub fn set_atom_tbl(&mut self, atom_tbl: TabledData) { + self.parser.set_atom_tbl(atom_tbl); + } + #[inline] pub fn add_to_top(&mut self, buf: &str) { self.parser.add_to_top(buf); diff --git a/src/prolog/macros.rs b/src/prolog/macros.rs index c99c79fa..0d010334 100644 --- a/src/prolog/macros.rs +++ b/src/prolog/macros.rs @@ -210,16 +210,18 @@ macro_rules! set_code_index { } macro_rules! machine_code_indices { - ($code_dir:expr, $op_dir:expr, $modules:expr) => ( //, $modules:expr) => ( - MachineCodeIndices { code_dir: $code_dir, op_dir: $op_dir, - modules: $modules} //, modules: $modules } + ($code_dir:expr, $op_dir:expr, $modules:expr) => ( + MachineCodeIndices { code_dir: $code_dir, + op_dir: $op_dir, + modules: $modules } ) } macro_rules! default_machine_code_indices { () => ( - machine_code_indices!(&mut CodeDir::new(), &mut default_op_dir(), - &mut HashMap::new()); + machine_code_indices!(&mut CodeDir::new(), + &mut default_op_dir(), + &mut HashMap::new()) ) } diff --git a/src/prolog/toplevel.rs b/src/prolog/toplevel.rs index 2ec9c50c..95ebdf96 100644 --- a/src/prolog/toplevel.rs +++ b/src/prolog/toplevel.rs @@ -733,11 +733,11 @@ fn consume_term<'a>(static_code_dir: Rc>, term: Term, } pub struct TopLevelBatchWorker { - term_stream: TermStream, + pub(crate) term_stream: TermStream, rel_worker: RelationWorker, static_code_dir: Rc>, - pub results: Vec<(Predicate, VecDeque)>, - pub in_module: bool + pub(crate) results: Vec<(Predicate, VecDeque)>, + pub(crate) in_module: bool } impl TopLevelBatchWorker { diff --git a/src/prolog/write.rs b/src/prolog/write.rs index c39da26a..edb390b0 100644 --- a/src/prolog/write.rs +++ b/src/prolog/write.rs @@ -26,6 +26,12 @@ impl fmt::Display for IndexPtr { } } +impl fmt::Display for ModuleCodeIndex { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.0) + } +} + impl fmt::Display for FactInstruction { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self {