From: Mark Thom Date: Sat, 5 Feb 2022 04:51:22 +0000 (-0700) Subject: fix '$skip_max_list'/4 (#1260) X-Git-Tag: v0.9.0^2~32 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=7b8001d060df8cfda1754b8bd850a15e9a8071ce;p=scryer-prolog.git fix '$skip_max_list'/4 (#1260) --- diff --git a/src/machine/partial_string.rs b/src/machine/partial_string.rs index cb26ab1e..0e25d7b5 100644 --- a/src/machine/partial_string.rs +++ b/src/machine/partial_string.rs @@ -372,7 +372,7 @@ impl<'a> HeapPStrIter<'a> { match self.brent_st.step(next_hare) { Some(cycle_result) => { debug_assert!(match cycle_result { - CycleSearchResult::Cyclic(_) => true, + CycleSearchResult::Cyclic(..) => true, _ => false, }); diff --git a/src/machine/system_calls.rs b/src/machine/system_calls.rs index 4f3ed651..f2f8edd9 100644 --- a/src/machine/system_calls.rs +++ b/src/machine/system_calls.rs @@ -432,7 +432,7 @@ impl MachineState { } fn skip_max_list_cycle(&mut self, lam: usize) { - fn step(heap: &Heap, mut value: HeapCellValue) -> usize { + fn step(heap: &[HeapCellValue], mut value: HeapCellValue) -> usize { loop { read_heap_cell!(value, (HeapCellValueTag::PStrLoc, h) => { @@ -455,27 +455,43 @@ impl MachineState { } } - let mut hare = step(&self.heap, self.registers[3]); + let h = self.heap.len(); + self.heap.push(self.registers[3]); + + let mut hare = h; let mut tortoise = hare; for _ in 0 .. lam { hare = step(&self.heap, self.heap[hare]); } - let mut count = 1; + let mut prev_hare = hare; while hare != tortoise { + prev_hare = hare; hare = step(&self.heap, self.heap[hare]); tortoise = step(&self.heap, self.heap[tortoise]); + } + + // now compute the num_steps of the list prefix until hare is + // reached in the fashion of a C do-while loop since hare + // may point to the beginning of a cycle. - count += 1; + let mut brent_st = BrentAlgState::new(h); + + self.brents_alg_step(&mut brent_st); + + while prev_hare != brent_st.hare { + self.brents_alg_step(&mut brent_st); } + self.heap.pop(); + let target_n = self.store(self.deref(self.registers[1])); - self.unify_fixnum(Fixnum::build_with(count), target_n); + self.unify_fixnum(Fixnum::build_with(brent_st.num_steps() as i64), target_n); if !self.fail { - unify!(self, self.registers[4], self.heap[hare]); + unify!(self, self.registers[4], self.heap[prev_hare]); } }