variable revision

This commit is contained in:
Mark Thom
2024-07-31 14:04:55 -06:00
committed by Mark Thom
parent 1ef681bd21
commit f7bbdfe73a
22 changed files with 738 additions and 894 deletions

View File

@@ -467,11 +467,20 @@ impl Iterator for QueryState<'_> {
// this should halt the search for solutions as it
// does in the Scryer top-level. the exception term is
// contained in self.machine_st.ball.
let h = machine.machine_st.heap.len();
machine
let h = machine.machine_st.heap.cell_len();
if let Err(resource_err_loc) = machine
.machine_st
.heap
.extend(machine.machine_st.ball.stub.clone());
.append(&machine.machine_st.ball.stub)
{
return Some(Err(Term::from_heapcell(
machine,
machine.machine_st.heap[resource_err_loc],
&mut IndexMap::new(),
)));
}
let exception_term =
Term::from_heapcell(machine, machine.machine_st.heap[h], &mut var_names.clone());
@@ -487,7 +496,7 @@ impl Iterator for QueryState<'_> {
}
if machine.machine_st.p == LIB_QUERY_SUCCESS {
if term_write_result.var_dict.is_empty() {
if term_write_result.inverse_var_locs.is_empty() {
self.machine.machine_st.backtrack();
return Some(Ok(LeafAnswer::True));
}
@@ -496,47 +505,39 @@ impl Iterator for QueryState<'_> {
}
let mut bindings: BTreeMap<String, Term> = BTreeMap::new();
let inverse_var_locs = &term_write_result.inverse_var_locs;
let var_dict = &term_write_result.var_dict;
for (var_key, term_to_be_printed) in var_dict.iter() {
let mut var_name = var_key.to_string();
for (var_loc, var_name) in inverse_var_locs.iter() {
if var_name.starts_with('_') {
let should_print = var_names.values().any(|x| match x.borrow().clone() {
Var::Named(v) => v == var_name,
_ => false,
});
let should_print = var_names.values().any(|v| v == var_name);
if !should_print {
continue;
}
}
let mut term =
Term::from_heapcell(machine, *term_to_be_printed, &mut var_names.clone());
let var_loc = *var_loc;
let term =
Term::from_heapcell(machine, heap_loc_as_cell!(var_loc), &mut var_names.clone());
if let Term::Var(ref term_str) = term {
if *term_str == var_name {
if *term_str == **var_name {
continue;
}
// Var dict is in the order things appear in the query. If var_name appears
// after term in the query, switch their places.
let var_name_idx = var_dict
.get_index_of(&VarKey::VarPtr(Var::Named(var_name.clone()).into()))
.unwrap();
let term_idx =
var_dict.get_index_of(&VarKey::VarPtr(Var::Named(term_str.clone()).into()));
if let Some(idx) = term_idx {
if idx < var_name_idx {
let new_term = Term::Var(var_name);
let new_var_name = term_str.into();
term = new_term;
var_name = new_var_name;
}
// inverse_var_locs is in the order things appear in
// the query. If var_name appears after term in the
// query, switch their places.
let var_cell = machine
.machine_st
.store(machine.machine_st.deref(machine.machine_st.heap[var_loc]));
if (var_cell.get_value() as usize) < var_loc {
bindings.insert(term_str.clone(), Term::Var(var_name.to_string()));
continue;
}
}
bindings.insert(var_name, term);
bindings.insert(var_name.to_string(), term);
}
// NOTE: there are outstanding choicepoints, backtrack
@@ -605,27 +606,10 @@ impl Machine {
self.allocate_stub_choice_point();
// Write parsed term to heap
let term_write_result =
write_term_to_heap(&term, &mut self.machine_st.heap, &self.machine_st.atom_tbl)
.expect("couldn't write term to heap");
let var_names: IndexMap<_, _> = term_write_result
.var_dict
.iter()
.map(|(var_key, cell)| match var_key {
// NOTE: not the intention behind Var::InSitu here but
// we can hijack it to store anonymous variables
// without creating problems.
VarKey::AnonVar(h) => (*cell, VarPtr::from(Var::InSitu(*h))),
VarKey::VarPtr(var_ptr) => (*cell, var_ptr.clone()),
})
.collect();
// Write term to heap
self.machine_st.registers[1] = self.machine_st.heap[term_write_result.heap_loc];
self.machine_st.registers[1] = self.machine_st.heap[term.focus];
self.machine_st.cp = LIB_QUERY_SUCCESS; // BREAK_FROM_DISPATCH_LOOP_LOC;
let call_index_p = self
.indices
.code_dir
@@ -634,12 +618,22 @@ impl Machine {
.local()
.unwrap();
let var_names: IndexMap<_, _> = term
.inverse_var_locs
.iter()
.map(|(var_loc, var)| {
let cell = self.machine_st.heap[*var_loc];
(cell, var.clone())
})
.collect();
self.machine_st.execute_at_index(1, call_index_p);
let stub_b = self.machine_st.b;
QueryState {
machine: self,
term: term_write_result,
term,
stub_b,
var_names,
called: false,