Skip to content

Commit

Permalink
fix '$skip_max_list'/4 (#1260)
Browse files Browse the repository at this point in the history
  • Loading branch information
mthom committed Feb 5, 2022
1 parent 99ff82e commit 2b09cb4
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 13 deletions.
2 changes: 1 addition & 1 deletion src/machine/machine_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -768,7 +768,7 @@ impl EvalError {
// used by '$skip_max_list'.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CycleSearchResult {
Cyclic(usize),
Cyclic(usize, usize),
EmptyList,
NotList,
PartialList(usize, Ref), // the list length (up to max), and an offset into the heap.
Expand Down
2 changes: 1 addition & 1 deletion src/machine/partial_string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
});

Expand Down
33 changes: 22 additions & 11 deletions src/machine/system_calls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,12 @@ impl BrentAlgState {

#[inline(always)]
pub fn step(&mut self, hare: usize) -> Option<CycleSearchResult> {
let prev_hare = self.hare;
self.hare = hare;
self.lam += 1;

if self.tortoise == self.hare {
return Some(CycleSearchResult::Cyclic(self.lam));
return Some(CycleSearchResult::Cyclic(self.lam, prev_hare));
} else {
self.teleport_tortoise();
}
Expand Down Expand Up @@ -431,8 +432,8 @@ impl MachineState {
}
}

fn skip_max_list_cycle(&mut self, lam: usize) {
fn step(heap: &Heap, mut value: HeapCellValue) -> usize {
fn skip_max_list_cycle(&mut self, lam: usize, hare: usize) {
fn step(heap: &[HeapCellValue], mut value: HeapCellValue) -> usize {
loop {
read_heap_cell!(value,
(HeapCellValueTag::PStrLoc, h) => {
Expand All @@ -455,27 +456,37 @@ impl MachineState {
}
}

let mut hare = step(&self.heap, self.registers[3]);
let mut brent_st = BrentAlgState::new(hare);

for _ in 0 .. lam {
self.brents_alg_step(&mut brent_st);
}

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]);

count += 1;
}

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]);
}
}

Expand Down Expand Up @@ -521,8 +532,8 @@ impl MachineState {
self.unify_fixnum(Fixnum::build_with(max_steps), n);
self.finalize_skip_max_list(max_steps, self.registers[3]);
}
CycleSearchResult::Cyclic(lam) => {
self.skip_max_list_cycle(lam);
CycleSearchResult::Cyclic(lam, hare) => {
self.skip_max_list_cycle(lam, hare);
}
};
}
Expand Down

0 comments on commit 2b09cb4

Please sign in to comment.