From: Mark Date: Sat, 5 Aug 2023 18:15:28 +0000 (-0600) Subject: retract discontiguous non-multifile predicates between consultations (#1202, #1058... X-Git-Tag: v0.9.2~12 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=094cf2ac5dc0533cf04e83c0068758aa74e50df1;p=scryer-prolog.git retract discontiguous non-multifile predicates between consultations (#1202, #1058, #1585) --- diff --git a/src/machine/compile.rs b/src/machine/compile.rs index 0faf34c3..a3575c7f 100644 --- a/src/machine/compile.rs +++ b/src/machine/compile.rs @@ -1258,7 +1258,7 @@ fn print_overwrite_warning( _ => {} } - println!("Warning: overwriting {}/{}", key.0.as_str(), key.1); + println!("Warning: overwriting {}/{} because the clauses are discontiguous", key.0.as_str(), key.1); } impl<'a, LS: LoadState<'a>> Loader<'a, LS> { @@ -2220,7 +2220,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> { let payload_compilation_target = self.payload.compilation_target; - let local_predicate_info = self + let mut local_predicate_info = self .wam_prelude .indices .get_local_predicate_skeleton( @@ -2242,6 +2242,8 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> { let is_cross_module_clause = payload_compilation_target != self.payload.predicates.compilation_target; + local_predicate_info.is_discontiguous = predicate_info.is_discontiguous; + if local_predicate_info.must_retract_local_clauses(is_cross_module_clause) { self.retract_local_clauses(&key, predicate_info.is_dynamic); } diff --git a/src/machine/loader.rs b/src/machine/loader.rs index 9d66ce64..0fe88cbb 100644 --- a/src/machine/loader.rs +++ b/src/machine/loader.rs @@ -32,8 +32,7 @@ use std::ops::{Deref, DerefMut}; * loader.pl does a few high-level things more easily handled from * Prolog that are not supported (or needed) during bootstrapping: * term and goal expansion, loading modules from different streams, - * verifying certain kinds of declarations, perhaps (in the future?) - * compiling inline disjunctions. + * and verifying certain kinds of declarations. * * Since the loader can operate incrementally, it uses an intermittent * structure to rebuild the loader between invocations. Preprocessor @@ -1279,6 +1278,17 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> { name: Atom, arity: usize, ) -> Result<(), SessionError> { + let key = (name, arity); + + let predicate_info = self + .wam_prelude + .indices + .get_predicate_skeleton(&self.payload.predicates.compilation_target, &key) + .map(|skeleton| skeleton.predicate_info()) + .unwrap_or_default(); + + self.retract_local_clauses(&key, predicate_info.is_dynamic); + self.add_extensible_predicate_declaration( compilation_target, name, diff --git a/src/machine/term_stream.rs b/src/machine/term_stream.rs index 8c6b055d..e352fc45 100644 --- a/src/machine/term_stream.rs +++ b/src/machine/term_stream.rs @@ -9,6 +9,7 @@ use crate::read::devour_whitespace; use crate::predicate_queue; +use fxhash::FxBuildHasher; use indexmap::IndexSet; use std::collections::VecDeque; @@ -19,7 +20,7 @@ pub struct LoadStatePayload { pub(super) compilation_target: CompilationTarget, pub(super) retraction_info: RetractionInfo, pub(super) module_op_exports: ModuleOpExports, - pub(super) non_counted_bt_preds: IndexSet, + pub(super) non_counted_bt_preds: IndexSet, pub(super) predicates: PredicateQueue, pub(super) clause_clauses: Vec<(Term, Term)>, } @@ -97,10 +98,10 @@ impl LoadStatePayload { compilation_target: CompilationTarget::default(), retraction_info: RetractionInfo::new(code_repo_len), module_op_exports: vec![], - non_counted_bt_preds: IndexSet::new(), + non_counted_bt_preds: IndexSet::with_hasher(FxBuildHasher::default()), predicates: predicate_queue![], clause_clauses: vec![], - } + } } }