]> Repositorios git - scryer-prolog.git/commitdiff
fix '$skip_max_list'/4 (#1260)
authorMark Thom <[email protected]>
Sat, 5 Feb 2022 04:51:22 +0000 (21:51 -0700)
committerMark Thom <[email protected]>
Sun, 6 Feb 2022 01:33:30 +0000 (18:33 -0700)
src/machine/partial_string.rs
src/machine/system_calls.rs

index cb26ab1e80d4cffbe4093e36ef062c9dd8aa3923..0e25d7b5d858222cfe07097f82f417bf8661cce9 100644 (file)
@@ -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,
                 });
 
index 4f3ed6517a24286d71321b4e29c0d3d8566e4218..f2f8edd9814011874897a4591ce8feaa20c98cc3 100644 (file)
@@ -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]);
         }
     }