From 773d3f81fd38f413fc00e96af54cc68f13b3135e Mon Sep 17 00:00:00 2001 From: Mark Date: Tue, 24 Oct 2023 14:10:11 -0600 Subject: [PATCH] remove list remnants from stack iteration in printer when cyclic (#2131) --- src/heap_iter.rs | 2 -- src/heap_print.rs | 13 +++++++++++++ src/machine/cycle_detection.rs | 18 +++++++++--------- src/tests/acyclic_term.pl | 5 +++++ 4 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/heap_iter.rs b/src/heap_iter.rs index 75c8829b..2eeba007 100644 --- a/src/heap_iter.rs +++ b/src/heap_iter.rs @@ -2257,9 +2257,7 @@ mod tests { list_loc_as_cell!(1) ); assert_eq!(iter.next().unwrap(), cyclic_link); - assert_eq!(iter.next().unwrap(), cyclic_link); - assert_eq!(iter.next().unwrap(), cyclic_link); assert_eq!(iter.next(), None); diff --git a/src/heap_print.rs b/src/heap_print.rs index 1ad88f29..2d92cd2d 100644 --- a/src/heap_print.rs +++ b/src/heap_print.rs @@ -888,6 +888,19 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> { var_opt => { if is_cyclic && cell.is_compound(self.iter.heap) { // self-referential variables are marked "cyclic". + read_heap_cell!(cell, + (HeapCellValueTag::Lis, vh) => { + if self.iter.heap[vh].get_forwarding_bit() { + self.iter.pop_stack(); + } + + if self.iter.heap[vh+1].get_forwarding_bit() { + self.iter.pop_stack(); + } + } + _ => {} + ); + match var_opt { Some(var) => { // If the term is bound to a named variable, diff --git a/src/machine/cycle_detection.rs b/src/machine/cycle_detection.rs index 342dbdec..692186cb 100644 --- a/src/machine/cycle_detection.rs +++ b/src/machine/cycle_detection.rs @@ -175,6 +175,15 @@ impl<'a, const STOP_AT_CYCLES: bool> CycleDetectingIter<'a, STOP_AT_CYCLES> { None => return None, }; + if self.cycle_detection_active() { + for idx in (self.next as usize .. last_cell_loc).rev() { + if self.heap[idx].get_forwarding_bit() { + self.cycle_found = true; + return None; + } + } + } + if (last_cell_loc + 1) as u64 == self.next { if self.backward() { return None; @@ -186,15 +195,6 @@ impl<'a, const STOP_AT_CYCLES: bool> CycleDetectingIter<'a, STOP_AT_CYCLES> { self.heap[last_cell_loc].set_mark_bit(self.mark_phase); } - if self.cycle_detection_active() { - for idx in (self.next as usize .. last_cell_loc).rev() { - if self.heap[idx].get_forwarding_bit() { - self.cycle_found = true; - return None; - } - } - } - self.heap[last_cell_loc].set_forwarding_bit(true); self.next = self.heap[last_cell_loc].get_value(); diff --git a/src/tests/acyclic_term.pl b/src/tests/acyclic_term.pl index 3c2b9377..065a4d9f 100644 --- a/src/tests/acyclic_term.pl +++ b/src/tests/acyclic_term.pl @@ -255,6 +255,11 @@ test("acyclic_term#2130_2", ( \+ acyclic_term(T) )). +test("acyclic_term#2131", ( + A=[B],C=[B],C=[A], + \+ acyclic_term(C) +)). + main :- findall(test(Name, Goal), test(Name, Goal), Tests), run_tests(Tests, Failed), -- 2.54.0