dereference bindings returned by stackful iterator (#1410, #1411)

This commit is contained in:
Mark Thom
2022-04-09 11:47:54 -06:00
parent b6504bf377
commit ed803d30cd
2 changed files with 31 additions and 19 deletions

View File

@@ -2047,16 +2047,16 @@ impl MachineState {
} }
#[inline] #[inline]
pub fn is_cyclic_term(&mut self, addr: HeapCellValue) -> bool { pub fn is_cyclic_term(&mut self, value: HeapCellValue) -> bool {
if addr.is_constant() { if value.is_constant() {
return false; return false;
} }
let addr = self.store(self.deref(addr)); let mut iter = stackful_preorder_iter(&mut self.heap, value);
let mut iter = stackful_preorder_iter(&mut self.heap, addr);
while let Some(value) = iter.next() { while let Some(value) = iter.next() {
if value.get_forwarding_bit() { if value.get_forwarding_bit() {
let value = unmark_cell_bits!(value);
let value = heap_bound_store(iter.heap, heap_bound_deref(iter.heap, value)); let value = heap_bound_store(iter.heap, heap_bound_deref(iter.heap, value));
if value.is_compound() { if value.is_compound() {
@@ -2514,13 +2514,22 @@ impl MachineState {
return true; return true;
} }
for v in stackful_preorder_iter(&mut self.heap, value) { let mut iter = stackful_preorder_iter(&mut self.heap, value);
let v = unmark_cell_bits!(v);
if v.is_var() { while let Some(value) = iter.next() {
let value = unmark_cell_bits!(value);
if value.is_var() {
let value = heap_bound_store(
iter.heap,
heap_bound_deref(iter.heap, value),
);
if value.is_var() {
return true; return true;
} }
} }
}
false false
} }

View File

@@ -609,7 +609,7 @@ impl MachineState {
let value = unmark_cell_bits!(value); let value = unmark_cell_bits!(value);
if value.is_var() && !seen_set.contains(&value) { if value.is_var() {
seen_set.insert(value); seen_set.insert(value);
} }
} }
@@ -4902,26 +4902,29 @@ impl Machine {
return; return;
} }
let mut seen_vec = vec![]; let mut seen_set = IndexSet::new();
{ {
let mut iter = stackful_preorder_iter(&mut self.machine_st.heap, stored_v); let mut iter = stackful_preorder_iter(&mut self.machine_st.heap, stored_v);
while let Some(addr) = iter.next() { while let Some(value) = iter.next() {
let addr = unmark_cell_bits!(addr); let value = unmark_cell_bits!(value);
if addr.is_var() { if value.is_var() {
seen_vec.push(addr); let value = heap_bound_store(
} iter.heap,
} heap_bound_deref(iter.heap, value)
} );
seen_vec.dedup_by(|v1, v2| { if value.is_var() {
compare_term_test!(self.machine_st, *v1, *v2) == Some(std::cmp::Ordering::Equal) seen_set.insert(value);
}); }
}
}
}
let outcome = heap_loc_as_cell!( let outcome = heap_loc_as_cell!(
iter_to_heap_list(&mut self.machine_st.heap, seen_vec.into_iter()) iter_to_heap_list(&mut self.machine_st.heap, seen_set.into_iter())
); );
unify_fn!(self.machine_st, a2, outcome); unify_fn!(self.machine_st, a2, outcome);