variable revision
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user