delay premature set_switch_var_offset_* calls in retract_clause, add module resolution for asserta/assertz/retract/clause
This commit is contained in:
@@ -1448,13 +1448,6 @@ impl<'a> LoadState<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
set_switch_var_offset(
|
||||
code,
|
||||
later_indexing_loc,
|
||||
lower_bound_clause_start - later_indexing_loc,
|
||||
&mut self.retraction_info,
|
||||
);
|
||||
|
||||
result = merge_indexed_subsequences(
|
||||
code,
|
||||
skeleton,
|
||||
@@ -1470,15 +1463,15 @@ impl<'a> LoadState<'a> {
|
||||
&mut skeleton.clauses[lower_bound ..],
|
||||
&mut self.retraction_info,
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
set_switch_var_offset_to_choice_instr(
|
||||
|
||||
set_switch_var_offset(
|
||||
code,
|
||||
target_indexing_loc,
|
||||
lower_bound_clause_start - target_indexing_loc,
|
||||
later_indexing_loc,
|
||||
lower_bound_clause_start - later_indexing_loc,
|
||||
&mut self.retraction_info,
|
||||
);
|
||||
|
||||
}
|
||||
_ => {
|
||||
result = merge_indexed_subsequences(
|
||||
code,
|
||||
skeleton,
|
||||
@@ -1494,6 +1487,13 @@ impl<'a> LoadState<'a> {
|
||||
&mut skeleton.clauses[lower_bound ..],
|
||||
&mut self.retraction_info,
|
||||
);
|
||||
|
||||
set_switch_var_offset_to_choice_instr(
|
||||
code,
|
||||
target_indexing_loc,
|
||||
lower_bound_clause_start - target_indexing_loc,
|
||||
&mut self.retraction_info,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1581,6 +1581,7 @@ impl<'a, TS: TermStream> Loader<'a, TS> {
|
||||
fn compile_clause_clauses<ClauseIter: Iterator<Item=(Term, Term)>>(
|
||||
&mut self,
|
||||
key: PredicateKey,
|
||||
compilation_target: CompilationTarget,
|
||||
clause_clauses: ClauseIter,
|
||||
append_or_prepend: AppendOrPrepend,
|
||||
) -> Result<(), SessionError> {
|
||||
@@ -1596,9 +1597,19 @@ impl<'a, TS: TermStream> Loader<'a, TS> {
|
||||
)
|
||||
});
|
||||
|
||||
let compilation_target = mem::replace(
|
||||
let clause_clause_compilation_target =
|
||||
match compilation_target {
|
||||
CompilationTarget::User => {
|
||||
CompilationTarget::Module(clause_name!("builtins"))
|
||||
}
|
||||
_ => {
|
||||
compilation_target.clone()
|
||||
}
|
||||
};
|
||||
|
||||
let old_compilation_target = mem::replace(
|
||||
&mut self.load_state.compilation_target,
|
||||
CompilationTarget::Module(clause_name!("builtins")),
|
||||
clause_clause_compilation_target,
|
||||
);
|
||||
|
||||
let mut clause_clause_locs = sdeq![];
|
||||
@@ -1615,7 +1626,7 @@ impl<'a, TS: TermStream> Loader<'a, TS> {
|
||||
);
|
||||
|
||||
if let Err(e) = result {
|
||||
self.load_state.compilation_target = compilation_target;
|
||||
self.load_state.compilation_target = old_compilation_target;
|
||||
return Err(e);
|
||||
}
|
||||
}
|
||||
@@ -1676,7 +1687,7 @@ impl<'a, TS: TermStream> Loader<'a, TS> {
|
||||
}
|
||||
}
|
||||
|
||||
self.load_state.compilation_target = compilation_target;
|
||||
self.load_state.compilation_target = old_compilation_target;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1704,7 +1715,14 @@ impl<'a, TS: TermStream> Loader<'a, TS> {
|
||||
|
||||
if is_dynamic {
|
||||
let iter = mem::replace(&mut self.clause_clauses, vec![]).into_iter();
|
||||
self.compile_clause_clauses(key, iter, AppendOrPrepend::Append)?;
|
||||
let compilation_target = self.load_state.compilation_target.clone();
|
||||
|
||||
self.compile_clause_clauses(
|
||||
key,
|
||||
compilation_target,
|
||||
iter,
|
||||
AppendOrPrepend::Append,
|
||||
)?;
|
||||
}
|
||||
|
||||
Ok(self.predicates.clear())
|
||||
|
||||
@@ -1360,14 +1360,26 @@ impl Machine {
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn compile_user_assert(&mut self, append_or_prepend: AppendOrPrepend) {
|
||||
let key =
|
||||
self.machine_st.read_predicate_key(
|
||||
self.machine_st[temp_v!(3)],
|
||||
self.machine_st[temp_v!(4)],
|
||||
);
|
||||
fn compile_assert(&mut self, append_or_prepend: AppendOrPrepend) {
|
||||
let key = self.machine_st.read_predicate_key(
|
||||
self.machine_st[temp_v!(3)],
|
||||
self.machine_st[temp_v!(4)],
|
||||
);
|
||||
|
||||
let compile_user_assert = || {
|
||||
let module_name = atom_from!(
|
||||
self.machine_st,
|
||||
self.machine_st.store(self.machine_st.deref(
|
||||
self.machine_st[temp_v!(5)]
|
||||
))
|
||||
);
|
||||
|
||||
let compilation_target =
|
||||
match module_name.as_str() {
|
||||
"user" => CompilationTarget::User,
|
||||
_ => CompilationTarget::Module(module_name),
|
||||
};
|
||||
|
||||
let compile_assert = || {
|
||||
let mut loader = Loader::new(LiveTermStream::new(ListingSource::User), self);
|
||||
|
||||
let head = loader.read_term_from_heap(temp_v!(1))?;
|
||||
@@ -1384,23 +1396,28 @@ impl Machine {
|
||||
loader.incremental_compile_clause(
|
||||
key.clone(),
|
||||
asserted_clause,
|
||||
CompilationTarget::User,
|
||||
compilation_target.clone(),
|
||||
false,
|
||||
append_or_prepend,
|
||||
)?;
|
||||
|
||||
// if a new predicate was just created, make it dynamic.
|
||||
loader.load_state.wam.indices.get_predicate_skeleton(
|
||||
&loader.load_state.compilation_target,
|
||||
&compilation_target,
|
||||
&key,
|
||||
).map(|skeleton| skeleton.is_dynamic = true);
|
||||
|
||||
loader.compile_clause_clauses(key, std::iter::once((head, body)), append_or_prepend)?;
|
||||
loader.compile_clause_clauses(
|
||||
key,
|
||||
compilation_target,
|
||||
std::iter::once((head, body)),
|
||||
append_or_prepend,
|
||||
)?;
|
||||
|
||||
LiveTermStream::evacuate(loader)
|
||||
};
|
||||
|
||||
match compile_user_assert() {
|
||||
match compile_assert() {
|
||||
Ok(_) => {
|
||||
}
|
||||
Err(e) => {
|
||||
@@ -1416,7 +1433,7 @@ impl Machine {
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn retract_user_clause(&mut self) {
|
||||
fn retract_clause(&mut self) {
|
||||
let key =
|
||||
self.machine_st.read_predicate_key(
|
||||
self.machine_st[temp_v!(1)],
|
||||
@@ -1436,18 +1453,44 @@ impl Machine {
|
||||
unreachable!()
|
||||
};
|
||||
|
||||
let retract_user_clause = || {
|
||||
let module_name = atom_from!(
|
||||
self.machine_st,
|
||||
self.machine_st.store(self.machine_st.deref(
|
||||
self.machine_st[temp_v!(4)]
|
||||
))
|
||||
);
|
||||
|
||||
let compilation_target =
|
||||
match module_name.as_str() {
|
||||
"user" => CompilationTarget::User,
|
||||
_ => CompilationTarget::Module(module_name),
|
||||
};
|
||||
|
||||
let clause_clause_compilation_target =
|
||||
match &compilation_target {
|
||||
CompilationTarget::User => {
|
||||
CompilationTarget::Module(clause_name!("builtins"))
|
||||
}
|
||||
_ => {
|
||||
compilation_target.clone()
|
||||
}
|
||||
};
|
||||
|
||||
let retract_clause = || {
|
||||
let mut loader = Loader::new(LiveTermStream::new(ListingSource::User), self);
|
||||
loader.load_state.compilation_target = compilation_target;
|
||||
|
||||
let clause_clause_loc = loader.load_state.retract_clause(key, target_pos);
|
||||
|
||||
let clause_assert_margin =
|
||||
loader.load_state.wam.indices.modules.get(&clause_name!("builtins"))
|
||||
.map(|builtins| builtins.clause_assert_margin)
|
||||
loader.load_state.wam.indices.modules
|
||||
.get(&clause_clause_compilation_target.module_name())
|
||||
.map(|module| module.clause_assert_margin)
|
||||
.unwrap();
|
||||
|
||||
let target_pos =
|
||||
match loader.load_state.wam.indices.get_predicate_skeleton(
|
||||
&CompilationTarget::Module(clause_name!("builtins")),
|
||||
&clause_clause_compilation_target,
|
||||
&(clause_name!("$clause"), 2),
|
||||
) {
|
||||
Some(skeleton) => {
|
||||
@@ -1463,8 +1506,9 @@ impl Machine {
|
||||
});
|
||||
|
||||
if result < clause_assert_margin {
|
||||
loader.load_state.wam.indices.modules.get_mut(&clause_name!("builtins"))
|
||||
.map(|builtins| builtins.clause_assert_margin -= 1);
|
||||
loader.load_state.wam.indices.modules
|
||||
.get_mut(&clause_clause_compilation_target.module_name())
|
||||
.map(|module| module.clause_assert_margin -= 1);
|
||||
}
|
||||
|
||||
result
|
||||
@@ -1474,19 +1518,13 @@ impl Machine {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
let compilation_target = mem::replace(
|
||||
&mut loader.load_state.compilation_target,
|
||||
CompilationTarget::Module(clause_name!("builtins")),
|
||||
);
|
||||
|
||||
loader.load_state.compilation_target = clause_clause_compilation_target;
|
||||
loader.load_state.retract_clause((clause_name!("$clause"), 2), target_pos);
|
||||
loader.load_state.compilation_target = compilation_target;
|
||||
|
||||
LiveTermStream::evacuate(loader)
|
||||
};
|
||||
|
||||
match retract_user_clause() {
|
||||
match retract_clause() {
|
||||
Ok(_) => {
|
||||
}
|
||||
Err(e) => {
|
||||
|
||||
@@ -525,9 +525,9 @@ pub enum REPLCodePtr {
|
||||
DiscontiguousProperty,
|
||||
DynamicProperty,
|
||||
CompilePendingPredicates,
|
||||
UserAsserta,
|
||||
UserAssertz,
|
||||
UserRetract,
|
||||
Asserta,
|
||||
Assertz,
|
||||
Retract,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
|
||||
@@ -494,14 +494,14 @@ impl Machine {
|
||||
REPLCodePtr::CompilePendingPredicates => {
|
||||
self.compile_pending_predicates();
|
||||
}
|
||||
REPLCodePtr::UserAssertz => {
|
||||
self.compile_user_assert(AppendOrPrepend::Append);
|
||||
REPLCodePtr::Assertz => {
|
||||
self.compile_assert(AppendOrPrepend::Append);
|
||||
}
|
||||
REPLCodePtr::UserAsserta => {
|
||||
self.compile_user_assert(AppendOrPrepend::Prepend);
|
||||
REPLCodePtr::Asserta => {
|
||||
self.compile_assert(AppendOrPrepend::Prepend);
|
||||
}
|
||||
REPLCodePtr::UserRetract => {
|
||||
self.retract_user_clause();
|
||||
REPLCodePtr::Retract => {
|
||||
self.retract_clause();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user