]> Repositorios git - scryer-prolog.git/commitdiff
split dynamic database keys across modules
authorMark Thom <[email protected]>
Sat, 9 Mar 2019 04:22:15 +0000 (21:22 -0700)
committerMark Thom <[email protected]>
Sat, 9 Mar 2019 04:22:15 +0000 (21:22 -0700)
src/prolog/clause_types.rs
src/prolog/forms.rs
src/prolog/lib/builtins.pl
src/prolog/machine/compile.rs
src/prolog/machine/dynamic_database.rs
src/prolog/machine/machine_errors.rs
src/prolog/machine/machine_indices.rs
src/prolog/machine/mod.rs
src/prolog/machine/modules.rs
src/prolog/machine/system_calls.rs
src/prolog/write.rs

index c526c2d5902fd50d537c53dc327484f5d362ee1d..022ced677e9477d006eebd615ff72251441a522a 100644 (file)
@@ -159,6 +159,7 @@ pub enum SystemClauseType {
     GetClause,
     GetCurrentPredicateList,
     GetModuleClause,
+    ModuleHeadIsDynamic,
     GetLiftedHeapFromOffset,
     GetLiftedHeapFromOffsetDiff,
     GetSCCCleaner,
@@ -233,6 +234,7 @@ impl SystemClauseType {
             &SystemClauseType::InstallSCCCleaner => clause_name!("$install_scc_cleaner"),
             &SystemClauseType::InstallInferenceCounter => clause_name!("$install_inference_counter"),
             &SystemClauseType::LiftedHeapLength => clause_name!("$lh_length"),
+            &SystemClauseType::ModuleHeadIsDynamic => clause_name!("$module_head_is_dynamic"),
             &SystemClauseType::ModuleOf => clause_name!("$module_of"),
             &SystemClauseType::NoSuchPredicate => clause_name!("$no_such_predicate"),
             &SystemClauseType::RedoAttrVarBindings => clause_name!("$redo_attr_var_bindings"),
@@ -299,6 +301,7 @@ impl SystemClauseType {
             ("$lh_length", 1) => Some(SystemClauseType::LiftedHeapLength),
             ("$module_of", 2) => Some(SystemClauseType::ModuleOf),
             ("$module_retract_clause", 5) => Some(SystemClauseType::ModuleRetractClause),
+            ("$module_head_is_dynamic", 2) => Some(SystemClauseType::ModuleHeadIsDynamic),
             ("$no_such_predicate", 1) => Some(SystemClauseType::NoSuchPredicate),
             ("$redo_attr_var_bindings", 0) => Some(SystemClauseType::RedoAttrVarBindings),
             ("$remove_call_policy_check", 1) => Some(SystemClauseType::RemoveCallPolicyCheck),
index c2bf01a50d370438ee535c9a446cf6842c02fddb..863fd4cef91f30de6cd86a41229aac14900e941e 100644 (file)
@@ -222,7 +222,6 @@ impl OpDecl {
     }
 }
 
-pub type ModuleCodeDir = HashMap<PredicateKey, ModuleCodeIndex>;
 pub type ModuleDir = HashMap<ClauseName, Module>;
 
 #[derive(Clone)]
@@ -234,12 +233,9 @@ pub struct ModuleDecl {
 pub struct Module {
     pub atom_tbl: TabledData<Atom>,
     pub module_decl: ModuleDecl,
-    pub code_dir: ModuleCodeDir,
+    pub code_dir: CodeDir,
     pub op_dir: OpDir,
     pub term_expansions: (Predicate, VecDeque<TopLevel>),
     pub goal_expansions: (Predicate, VecDeque<TopLevel>),
     pub inserted_expansions: bool // has the module been successfully inserted into toplevel??
 }
-
-#[derive(Clone)]
-pub struct ModuleCodeIndex(pub IndexPtr, pub ClauseName);
index df0ee77a57f87f7d5bc12c55d69fee4dad1c9ee3..d5d61c1a7ecb0a21be121f46894430ef61f07b50 100644 (file)
@@ -468,8 +468,9 @@ setof(Template, Goal, Solution) :-
 '$module_clause'(H, B, Module) :-
     (  var(H) -> throw(error(instantiation_error, clause/2))
     ;  functor(H, Name, Arity) -> (  Name == '.' -> throw(error(type_error(callable, H), clause/2))
-                                 ;  '$head_is_dynamic'(H) -> '$clause_body_is_valid'(B),
-                                                             '$get_module_clause'(H, B, Module)
+                                 ;  '$module_head_is_dynamic'(H, Module) ->
+                                    '$clause_body_is_valid'(B),
+                                    '$get_module_clause'(H, B, Module)
                                  ;  throw(error(permission_error(access, private_procedure, Name/Arity),
                                                 clause/2))
                                  )
@@ -508,7 +509,7 @@ call_asserta(Head, Body, Name, Arity) :-
 module_asserta_clause(Head, Body, Module) :-
     (  var(Head) -> throw(error(instantiation_error, asserta/1))
     ;  functor(Head, Name, Arity), atom(Name), Name \== '.' ->
-       (  '$head_is_dynamic'(Head) -> call_module_asserta(Head, Body, Name, Arity, Module)
+       (  '$module_head_is_dynamic'(Head, Module) -> call_module_asserta(Head, Body, Name, Arity, Module)
        ;  throw(error(permission_error(modify, static_procedure, Name/Arity), asserta/1))
        )
     ;  throw(error(type_error(callable, Head), asserta/1))
@@ -548,7 +549,7 @@ call_assertz(Head, Body, Name, Arity) :-
 module_assertz_clause(Head, Body, Module) :-
     (  var(Head) -> throw(error(instantiation_error, assertz/1))
     ;  functor(Head, Name, Arity), atom(Name), Name \== '.' ->
-       (  '$head_is_dynamic'(Head) -> call_module_assertz(Head, Body, Name, Arity, Module)
+       (  '$module_head_is_dynamic'(Head, Module) -> call_module_assertz(Head, Body, Name, Arity, Module)
        ;  throw(error(permission_error(modify, static_procedure, Name/Arity), assertz/1))
        )
     ;  throw(error(type_error(callable, Head), assertz/1))
@@ -612,7 +613,8 @@ call_module_retract(Head, Body, Name, Arity, Module) :-
 retract_module_clause(Head, Body, Module) :-
     (  var(Head) -> throw(error(instantiation_error, retract/1))
     ;  functor(Head, Name, Arity), atom(Name), Name \== '.' ->
-       ( '$head_is_dynamic'(Head) -> call_module_retract(Head, Body, Name, Arity, Module)
+       ( '$module_head_is_dynamic'(Head, Module) ->
+        call_module_retract(Head, Body, Name, Arity, Module)
        ; throw(error(permission_error(modify, static_procedure, Name/Arity), retract/1))
        )
     ;  throw(error(type_error(callable, Head), retract/1))
@@ -646,7 +648,8 @@ module_abolish(Pred, Module) :-
          ; Arity < 0 -> throw(domain_error(not_less_than_zero, Arity), abolish/1)
          ; max_arity(N), Arity > N -> throw(representation_error(max_arity), abolish/1)
          ; functor(Head, Name, Arity) ->
-           (  '$head_is_dynamic'(Head) -> '$abolish_module_clause'(Name, Arity, Module)
+           (  '$module_head_is_dynamic'(Head, Module) ->
+              '$abolish_module_clause'(Name, Arity, Module)
            ;  throw(error(permission_error(modify, static_procedure, Pred), abolish/1))
            )
          )
index 5d6fbdc37fd86023f99b61b370f34c5ee7cd3627..d34f92918a202af38a2f18dcf96e6fafdd85fe27 100644 (file)
@@ -149,7 +149,7 @@ pub fn compile_term(wam: &mut Machine, packet: TopLevelPacket) -> EvalSession
             let mut compiler = ListingCompiler::new(&wam.code_repo);
             let indices = try_eval_session!(compile_decl(wam, &mut compiler, decl));
 
-            try_eval_session!(wam.check_toplevel_code(&indices, &DynamicClauseMap::new()));
+            try_eval_session!(wam.check_toplevel_code(&indices));
             add_toplevel_code(wam, vec![], indices);
 
             EvalSession::EntrySuccess
@@ -173,14 +173,13 @@ fn compile_into_module<R: Read>(wam: &mut Machine, module_name: ClauseName, src:
                                                                &mut indices.code_dir, 0));
 
     let mut clause_code_generator = ClauseCodeGenerator::new(module_code.len());
-    try_eval_session!(clause_code_generator.generate_clause_code(module_name.clone(),
-                                                                 results.dynamic_clause_map,
+    try_eval_session!(clause_code_generator.generate_clause_code(results.dynamic_clause_map,
                                                                  wam));
 
     match wam.indices.modules.get_mut(&module_name) {
         Some(module) => {
             let code_dir = mem::replace(&mut indices.code_dir, CodeDir::new());
-            module.code_dir.extend(as_module_code_dir(code_dir));
+            module.code_dir.extend(code_dir);
 
             if module.module_decl.exports.contains(&(name.clone(), arity)) {
                 if let Some(idx) = wam.indices.code_dir.get(&(name.clone(), arity)) {
@@ -199,7 +198,7 @@ fn compile_into_module<R: Read>(wam: &mut Machine, module_name: ClauseName, src:
     };
 
     wam.code_repo.code.extend(module_code.into_iter());
-    clause_code_generator.add_clause_code(module_name, wam);
+    clause_code_generator.add_clause_code(wam);
 
     EvalSession::EntrySuccess
 }
@@ -224,8 +223,7 @@ impl ClauseCodeGenerator {
         ClauseCodeGenerator { len_offset, code: vec![], pi_to_loc: HashMap::new() }
     }
 
-    fn generate_clause_code(&mut self, module: ClauseName, dynamic_clause_map: DynamicClauseMap,
-                            wam: &Machine)
+    fn generate_clause_code(&mut self, dynamic_clause_map: DynamicClauseMap, wam: &Machine)
                             -> Result<(), SessionError>
     {
         for ((name, arity), heads_and_tails) in dynamic_clause_map {
@@ -233,8 +231,6 @@ impl ClauseCodeGenerator {
                 continue;
             }
 
-            wam.check_dynamic_clause_overwrite(name.clone(), arity, module.clone())?;
-
             let predicate = Predicate(heads_and_tails.into_iter().map(|(head, tail)| {
                 let clause = Term::Clause(Cell::default(), clause_name!("clause"),
                                           vec![Box::new(head), Box::new(tail)],
@@ -255,15 +251,14 @@ impl ClauseCodeGenerator {
         Ok(())
     }
 
-    fn add_clause_code(self, module: ClauseName, wam: &mut Machine) {
+    fn add_clause_code(self, wam: &mut Machine) {
         wam.code_repo.code.extend(self.code.into_iter());
 
         for ((name, arity), p) in self.pi_to_loc {
-            let entry = wam.indices.dynamic_code_dir.entry((name, arity))
+            let entry = wam.indices.dynamic_code_dir.entry((name.owning_module(), name, arity))
                            .or_insert(DynamicPredicateInfo::default());
 
             entry.clauses_subsection_p = p;
-            entry.module_src = module.clone();
         }
     }
 }
@@ -291,7 +286,7 @@ fn add_module_code(wam: &mut Machine, mut module: Module, code: Code, mut indice
     let code_dir = mem::replace(&mut indices.code_dir, CodeDir::new());
     let op_dir   = mem::replace(&mut indices.op_dir, OpDir::new());
 
-    module.code_dir.extend(as_module_code_dir(code_dir));
+    module.code_dir.extend(code_dir);
     module.op_dir.extend(op_dir.into_iter());
 
     wam.add_module(module, code);
@@ -301,13 +296,13 @@ fn add_non_module_code(wam: &mut Machine, dynamic_clause_map: DynamicClauseMap,
                        indices: IndexStore)
                        -> Result<(), SessionError>
 {
-    wam.check_toplevel_code(&indices, &dynamic_clause_map)?;
+    wam.check_toplevel_code(&indices)?;
 
     let mut clause_code_generator = ClauseCodeGenerator::new(code.len());
-    clause_code_generator.generate_clause_code(clause_name!("user"), dynamic_clause_map, wam)?;
+    clause_code_generator.generate_clause_code(dynamic_clause_map, wam)?;
 
     add_toplevel_code(wam, code, indices);
-    clause_code_generator.add_clause_code(clause_name!("user"), wam);
+    clause_code_generator.add_clause_code(wam);
 
     Ok(())
 }
@@ -609,17 +604,15 @@ fn compile_work<R: Read>(compiler: &mut ListingCompiler, wam: &mut Machine, src:
 
     if let Some(module) = compiler.module.take() {
         let mut clause_code_generator = ClauseCodeGenerator::new(module_code.len() + toplvl_code.len());
-        let module_name = module.module_decl.name.clone();
 
-        try_eval_session!(wam.check_toplevel_code(&results.toplevel_indices, &results.dynamic_clause_map));
-        try_eval_session!(clause_code_generator.generate_clause_code(module_name.clone(),
-                                                                     results.dynamic_clause_map,
+        try_eval_session!(wam.check_toplevel_code(&results.toplevel_indices));
+        try_eval_session!(clause_code_generator.generate_clause_code(results.dynamic_clause_map,
                                                                      wam));
 
         add_module_code(wam, module, module_code, indices);
         add_toplevel_code(wam, toplvl_code, results.toplevel_indices);
 
-        clause_code_generator.add_clause_code(module_name, wam);
+        clause_code_generator.add_clause_code(wam);
     } else {
         try_eval_session!(add_non_module_code(wam, results.dynamic_clause_map, module_code,
                                               indices));
index 77410c70762bdbd9d6696d4e8bcfc094beac84ca..94aec56781d471e80cb0ff0a7ab043807f1931fd 100644 (file)
@@ -80,7 +80,7 @@ impl Machine {
         }
 
         self.indices.remove_code_index((name.clone(), arity));
-        self.indices.dynamic_code_dir.remove(&(name, arity));
+        self.indices.remove_clause_subsection(name.owning_module(), name, arity);
     }
 
     fn abolish_dynamic_clause_in_module(&mut self, name: RegType, arity: RegType, module: RegType)
@@ -110,7 +110,7 @@ impl Machine {
         }
 
         self.indices.remove_code_index((name.clone(), arity));
-        self.indices.dynamic_code_dir.remove(&(name, arity));
+        self.indices.remove_clause_subsection(module_name, name, arity);
     }
 
     fn handle_eval_result_from_dynamic_compile(&mut self, pred_str: String, name: ClauseName,
index 772f02194c8c37e1a4c0597f2972e3c2871891f1..5502688a0a3a4ad251b6be4471a8181d820c73df 100644 (file)
@@ -66,8 +66,7 @@ impl MachineError {
     pub(super) fn session_error(h: usize, err: SessionError) -> Self {
         match err {
             SessionError::ParserError(err) => Self::syntax_error(h, err),
-            SessionError::CannotOverwriteDynamicClause(pred_str)
-          | SessionError::CannotOverwriteBuiltIn(pred_str)
+            SessionError::CannotOverwriteBuiltIn(pred_str)
           | SessionError::CannotOverwriteImport(pred_str) =>
                 Self::permission_error(PermissionError::Modify, pred_str),
             SessionError::ModuleDoesNotContainExport =>
@@ -372,7 +371,6 @@ impl MachineState {
 
 pub enum SessionError {
     CannotOverwriteBuiltIn(ClauseName),
-    CannotOverwriteDynamicClause(ClauseName),
     CannotOverwriteImport(ClauseName),
     ModuleDoesNotContainExport,
     ModuleNotFound,
index bc66e878db23e2213a1667b00bd83bc4d6669240..9be8619b9c44f2007cc37c1fddc0e54ed4a64765 100644 (file)
@@ -193,6 +193,13 @@ impl CodeIndex {
     pub fn module_name(&self) -> ClauseName {
         self.0.borrow().1.clone()
     }
+
+    pub fn local(&self) -> Option<usize> {
+        match self.0.borrow().0 {
+            IndexPtr::Index(i) => Some(i),
+            _ => None
+        }
+    }
 }
 
 impl Default for CodeIndex {
@@ -371,18 +378,17 @@ pub type AllocVarDict = HashMap<Rc<Var>, VarData>;
 #[derive(Clone)]
 pub struct DynamicPredicateInfo {
     pub(super) clauses_subsection_p: usize, // a LocalCodePtr::DirEntry value.
-    pub(super) module_src: ClauseName // the module the predicate is defined within.
 }
 
 impl Default for DynamicPredicateInfo {
     fn default() -> Self {
-        DynamicPredicateInfo { clauses_subsection_p: 0,
-                               module_src: clause_name!("user") }
+        DynamicPredicateInfo { clauses_subsection_p: 0 }
     }
 }
 
 pub type InSituCodeDir  = HashMap<PredicateKey, usize>;
-pub type DynamicCodeDir = HashMap<PredicateKey, DynamicPredicateInfo>;
+// key type: module name, predicate indicator.
+pub type DynamicCodeDir = HashMap<(ClauseName, ClauseName, usize), DynamicPredicateInfo>;
 
 pub struct IndexStore {
     pub(super) atom_tbl: TabledData<Atom>,
@@ -421,10 +427,18 @@ impl IndexStore {
     }
 
     #[inline]
-    pub fn get_clause_subsection(&self, name: ClauseName, arity: usize) -> Option<DynamicPredicateInfo> {
-        self.dynamic_code_dir.get(&(name, arity)).cloned()
+    pub fn remove_clause_subsection(&mut self, module: ClauseName, name: ClauseName, arity: usize)
+    {
+        self.dynamic_code_dir.remove(&(module, name, arity));
+    }
+
+    #[inline]
+    pub fn get_clause_subsection(&self, module: ClauseName, name: ClauseName, arity: usize)
+                                 -> Option<DynamicPredicateInfo>
+    {
+        self.dynamic_code_dir.get(&(module, name, arity)).cloned()
     }
-    
+
     #[inline]
     pub fn take_module(&mut self, name: ClauseName) -> Option<Module> {
         self.modules.remove(&name)
@@ -458,8 +472,7 @@ impl IndexStore {
     }
 
     #[inline]
-    fn get_internal(&self, name: ClauseName, arity: usize, in_mod: ClauseName)
-                    -> Option<ModuleCodeIndex>
+    fn get_internal(&self, name: ClauseName, arity: usize, in_mod: ClauseName) -> Option<CodeIndex>
     {
         self.modules.get(&in_mod)
             .and_then(|ref module| module.code_dir.get(&(name, arity)))
index 09fbd7588748b9ab3e639d671893a9aeb9ac237f..079bf8ba042e9236449d0a862e5a48d7aa622474 100644 (file)
@@ -32,7 +32,6 @@ use prolog::machine::machine_errors::*;
 use prolog::machine::machine_indices::*;
 use prolog::machine::machine_state::*;
 use prolog::machine::modules::*;
-use prolog::machine::toplevel::*;
 
 use std::collections::{HashMap, VecDeque};
 use std::mem;
@@ -104,21 +103,23 @@ impl SubModuleUser for IndexStore {
 
     fn remove_code_index(&mut self, key: PredicateKey)
     {
-        self.code_dir.remove(&key);        
+        self.code_dir.remove(&key);
+        self.dynamic_code_dir.remove(&(key.0.owning_module(), key.0, key.1));
     }
 
-    fn insert_dir_entry(&mut self, name: ClauseName, arity: usize, idx: ModuleCodeIndex)
+    fn insert_dir_entry(&mut self, name: ClauseName, arity: usize, idx: CodeIndex)
     {
-        if let Some(ref mut code_idx) = self.code_dir.get_mut(&(name.clone(), arity)) {
+        if let Some(ref code_idx) = self.code_dir.get(&(name.clone(), arity)) {
             if !code_idx.is_undefined() {
                 println!("warning: overwriting {}/{}", &name, arity);
             }
 
-            set_code_index!(code_idx, idx.0, idx.1);
+            let (p, module_name) = idx.0.borrow().clone();
+            set_code_index!(code_idx, p, module_name);
             return;
         }
 
-        self.code_dir.insert((name, arity), CodeIndex::from(idx));
+        self.code_dir.insert((name, arity), idx);
     }
 
     fn use_qualified_module(&mut self, code_repo: &mut CodeRepo, flags: MachineFlags,
@@ -210,23 +211,7 @@ impl Machine {
         self.machine_st.flags
     }
 
-    pub fn check_dynamic_clause_overwrite(&self, name: ClauseName, arity: usize, module: ClauseName)
-                                          -> Result<(), SessionError>
-    {
-        if let Some(info) = self.indices.dynamic_code_dir.get(&(name.clone(), arity)) {
-            if info.module_src != module {
-                let err_str = format!("{}/{}", name.as_str(), arity);
-                let err_str = clause_name!(err_str, self.indices.atom_tbl());
-
-                return Err(SessionError::CannotOverwriteDynamicClause(err_str));
-            }
-        }
-
-        Ok(())
-    }
-
-    pub fn check_toplevel_code(&self, indices: &IndexStore, dynamic_clause_map: &DynamicClauseMap)
-                               -> Result<(), SessionError>
+    pub fn check_toplevel_code(&self, indices: &IndexStore) -> Result<(), SessionError>
     {
         for (key, idx) in &indices.code_dir {
             match ClauseType::from(key.0.clone(), key.1, None) {
@@ -239,11 +224,6 @@ impl Machine {
                     return Err(SessionError::CannotOverwriteBuiltIn(err_str));
                 }
             };
-
-            if dynamic_clause_map.contains_key(&key) {
-                let module = idx.0.borrow().1.clone();
-                self.check_dynamic_clause_overwrite(key.0.clone(), key.1, module)?;
-            }
             
             if let Some(ref existing_idx) = self.indices.code_dir.get(&key) {
                 // ensure we don't try to overwrite an existing predicate from a different module.
index 03e868994df3728bd967fc064e42712adc319ba5..ebdc4c24ef3a46cd28e909744c52c6df560665b9 100644 (file)
@@ -6,24 +6,7 @@ use prolog::machine::code_repo::*;
 use prolog::machine::machine_errors::*;
 use prolog::machine::machine_indices::*;
 
-use std::cell::RefCell;
 use std::collections::{VecDeque};
-use std::rc::Rc;
-
-impl ModuleCodeIndex {
-    pub fn local(&self) -> Option<usize> {
-        match self.0 {
-            IndexPtr::Index(i) => Some(i),
-            _ => None
-        }
-    }
-}
-
-impl From<ModuleCodeIndex> for CodeIndex {
-    fn from(value: ModuleCodeIndex) -> Self {
-        CodeIndex(Rc::new(RefCell::new((value.0, value.1))))
-    }
-}
 
 // Module's and related types are defined in forms.
 impl Module {
@@ -31,7 +14,7 @@ impl Module {
         Module { module_decl, atom_tbl,
                  term_expansions: (Predicate::new(), VecDeque::from(vec![])),
                  goal_expansions: (Predicate::new(), VecDeque::from(vec![])),
-                 code_dir: ModuleCodeDir::new(),
+                 code_dir: CodeDir::new(),
                  op_dir: default_op_dir(),
                  inserted_expansions: false }
     }
@@ -69,7 +52,7 @@ pub trait SubModuleUser
     fn remove_code_index(&mut self, PredicateKey);
     fn get_code_index(&self, PredicateKey, ClauseName) -> Option<CodeIndex>;
 
-    fn insert_dir_entry(&mut self, ClauseName, usize, ModuleCodeIndex);
+    fn insert_dir_entry(&mut self, ClauseName, usize, CodeIndex);
 
     fn remove_module(&mut self, mod_name: ClauseName, module: &Module)
     {
@@ -141,9 +124,6 @@ pub trait SubModuleUser
             
             atom_tbl.borrow_mut().insert(name.to_rc());
             
-            let mut code_data = code_data.clone();
-            code_data.1 = submodule.module_decl.name.clone();
-            
             self.insert_dir_entry(name, arity, code_data.clone());
             true
         } else {
@@ -203,7 +183,7 @@ impl SubModuleUser for Module {
         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: CodeIndex) {
         self.code_dir.insert((name, arity), idx);
     }
 
@@ -236,12 +216,3 @@ impl SubModuleUser for Module {
         Ok(())
     }
 }
-
-pub fn as_module_code_dir(code_dir: CodeDir) -> ModuleCodeDir {
-    code_dir.into_iter()
-        .map(|(k, code_idx)| {
-            let (idx, module_name) = code_idx.0.borrow().clone();
-            (k, ModuleCodeIndex(idx, module_name))
-        })
-        .collect()
-}
index 91fef9ccebc21a8bf28b7b160d2134acbc0c523d..9d4d9737eef82223eb46df521142b3c68f4d27b4 100644 (file)
@@ -294,27 +294,47 @@ impl MachineState {
                     Addr::Str(s) =>
                         match self.heap[s].clone() {
                             HeapCellValue::NamedStr(arity, name, ..) =>
-                                indices.get_clause_subsection(name, arity),
+                                indices.get_clause_subsection(module, name, arity),
                             _ => unreachable!()
                         },
                     Addr::Con(Constant::Atom(name, _)) =>
-                        indices.get_clause_subsection(name, 0),
+                        indices.get_clause_subsection(module, name, 0),
                     _ => unreachable!()
                 };
 
                 match subsection {
                     Some(dynamic_predicate_info) => {
-                        if dynamic_predicate_info.module_src != module {
-                            self.fail = true;
-                        } else {
-                            self.execute_at_index(2, dynamic_predicate_info.clauses_subsection_p);
-                        }
-
+                        self.execute_at_index(2, dynamic_predicate_info.clauses_subsection_p);
                         return Ok(());
                     },
                     None => self.fail = true
                 }
             },
+            &SystemClauseType::ModuleHeadIsDynamic => {
+                let module = self[temp_v!(2)].clone();
+                let head = self[temp_v!(1)].clone();
+
+                let module = match self.store(self.deref(module)) {
+                    Addr::Con(Constant::Atom(module, _)) =>
+                        module,
+                    _ => {
+                        self.fail = true;
+                        return Ok(());
+                    }
+                };
+                
+                self.fail = !match self.store(self.deref(head)) {
+                    Addr::Str(s) =>
+                        match self.heap[s].clone() {
+                            HeapCellValue::NamedStr(arity, name, ..) =>
+                                indices.get_clause_subsection(module, name, arity).is_some(),
+                            _ => unreachable!()
+                        },
+                    Addr::Con(Constant::Atom(name, _)) =>
+                        indices.get_clause_subsection(module, name, 0).is_some(),
+                    _ => unreachable!()
+                };                
+            },
             &SystemClauseType::HeadIsDynamic => {
                 let head = self[temp_v!(1)].clone();
 
@@ -322,11 +342,11 @@ impl MachineState {
                     Addr::Str(s) =>
                         match self.heap[s].clone() {
                             HeapCellValue::NamedStr(arity, name, ..) =>
-                                indices.get_clause_subsection(name, arity).is_some(),
+                                indices.get_clause_subsection(name.owning_module(), name, arity).is_some(),
                             _ => unreachable!()
                         },
                     Addr::Con(Constant::Atom(name, _)) =>
-                        indices.get_clause_subsection(name, 0).is_some(),
+                        indices.get_clause_subsection(name.owning_module(), name, 0).is_some(),
                     _ => unreachable!()
                 };
             },
@@ -877,11 +897,11 @@ impl MachineState {
                     Addr::Str(s) =>
                         match self.heap[s].clone() {
                             HeapCellValue::NamedStr(arity, name, ..) =>
-                                indices.get_clause_subsection(name, arity),
+                                indices.get_clause_subsection(name.owning_module(), name, arity),
                             _ => unreachable!()
                         },
                     Addr::Con(Constant::Atom(name, _)) =>
-                        indices.get_clause_subsection(name, 0),
+                        indices.get_clause_subsection(name.owning_module(), name, 0),
                     _ => unreachable!()
                 };
 
index 9d3dd8e5e89bee2afa9cae6140728ac5bef475e6..b59dbf20281e0845680af15ef2a03f2c6f26311d 100644 (file)
@@ -45,12 +45,6 @@ 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 {
@@ -249,8 +243,6 @@ impl fmt::Display for IndexingInstruction {
 impl fmt::Display for SessionError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match self {
-            &SessionError::CannotOverwriteDynamicClause(ref msg) =>
-                write!(f, "cannot overwrite dynamic predicate {}", msg),
             &SessionError::CannotOverwriteBuiltIn(ref msg) =>
                 write!(f, "cannot overwrite {}", msg),
             &SessionError::CannotOverwriteImport(ref msg) =>