From: Mark Date: Sat, 30 Sep 2023 22:00:15 +0000 (-0600) Subject: implement ListElisionPolicy to restore previous printer behavior X-Git-Tag: remove~66 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=62c23166fa8b5456859610d052deff9144b600f7;p=scryer-prolog.git implement ListElisionPolicy to restore previous printer behavior --- diff --git a/src/heap_iter.rs b/src/heap_iter.rs index 6005aa2e..ffb8df90 100644 --- a/src/heap_iter.rs +++ b/src/heap_iter.rs @@ -6,6 +6,7 @@ use crate::machine::heap::*; use crate::machine::stack::*; use crate::types::*; +use core::marker::PhantomData; use modular_bitfield::prelude::*; use std::ops::Deref; @@ -79,15 +80,40 @@ impl IterStackLoc { } } +pub trait ListElisionPolicy { + fn elide_lists() -> bool; +} + +#[derive(Debug)] +pub struct ListElider {} + +impl ListElisionPolicy for ListElider { + #[inline(always)] + fn elide_lists() -> bool { + true + } +} + #[derive(Debug)] -pub struct StackfulPreOrderHeapIter<'a> { +pub struct NonListElider {} + +impl ListElisionPolicy for NonListElider { + #[inline(always)] + fn elide_lists() -> bool { + false + } +} + +#[derive(Debug)] +pub struct StackfulPreOrderHeapIter<'a, ElideLists> { pub heap: &'a mut Vec, pub machine_stack: &'a mut Stack, stack: Vec, h: IterStackLoc, + _marker: PhantomData, } -impl<'a> Drop for StackfulPreOrderHeapIter<'a> { +impl<'a, ElideLists> Drop for StackfulPreOrderHeapIter<'a, ElideLists> { fn drop(&mut self) { while let Some(h) = self.stack.pop() { let cell = self.read_cell_mut(h); @@ -104,59 +130,14 @@ pub trait FocusedHeapIter: Iterator { fn focus(&self) -> IterStackLoc; } -impl<'a> FocusedHeapIter for StackfulPreOrderHeapIter<'a> { +impl<'a, ElideLists: ListElisionPolicy> FocusedHeapIter for StackfulPreOrderHeapIter<'a, ElideLists> { #[inline] fn focus(&self) -> IterStackLoc { self.h } } -impl<'a> StackfulPreOrderHeapIter<'a> { - #[inline] - fn new(heap: &'a mut Vec, stack: &'a mut Stack, cell: HeapCellValue) -> Self { - let h = IterStackLoc::iterable_loc(heap.len(), HeapOrStackTag::Heap); - heap.push(cell); - - Self { - heap, - h, - machine_stack: stack, - stack: vec![h], - } - } - - #[inline] - fn forward_if_referent_marked(&mut self, loc: IterStackLoc) { - let cell = self.read_cell(loc); - - read_heap_cell!(cell, - (HeapCellValueTag::Lis, vh) => { - if cell.get_mark_bit() && self.heap[vh].get_mark_bit() { - self.read_cell_mut(loc).set_forwarding_bit(true); - } - } - (HeapCellValueTag::Str | - HeapCellValueTag::AttrVar | - HeapCellValueTag::Var | - HeapCellValueTag::PStrLoc, vh) => { - if self.heap[vh].get_mark_bit() { - self.read_cell_mut(loc).set_forwarding_bit(true); - } - } - (HeapCellValueTag::StackVar, vs) => { - if self.machine_stack[vs].get_mark_bit() { - self.read_cell_mut(loc).set_forwarding_bit(true); - } - } - _ => {} - ); - } - - #[inline] - pub fn push_stack(&mut self, h: IterStackLoc) { - self.stack.push(h); - } - +impl<'a, ElideLists> StackfulPreOrderHeapIter<'a, ElideLists> { #[inline] pub fn read_cell_mut(&mut self, loc: IterStackLoc) -> &mut HeapCellValue { match loc.heap_or_stack() { @@ -173,6 +154,11 @@ impl<'a> StackfulPreOrderHeapIter<'a> { } } + #[inline] + pub fn push_stack(&mut self, h: IterStackLoc) { + self.stack.push(h); + } + #[inline] pub fn stack_last(&self) -> Option { for h in self.stack.iter().rev() { @@ -228,6 +214,51 @@ impl<'a> StackfulPreOrderHeapIter<'a> { )); } } +} + +impl<'a, ElideLists: ListElisionPolicy> StackfulPreOrderHeapIter<'a, ElideLists> { + #[inline] + fn new(heap: &'a mut Vec, stack: &'a mut Stack, cell: HeapCellValue) -> Self { + let h = IterStackLoc::iterable_loc(heap.len(), HeapOrStackTag::Heap); + heap.push(cell); + + Self { + heap, + h, + machine_stack: stack, + stack: vec![h], + _marker: PhantomData, + } + } + + #[inline] + fn forward_if_referent_marked(&mut self, loc: IterStackLoc) { + let cell = self.read_cell(loc); + + read_heap_cell!(cell, + (HeapCellValueTag::Lis, vh) => { + let forward = if ElideLists::elide_lists() { true } else { cell.get_mark_bit() }; + + if forward && self.heap[vh].get_mark_bit() { + self.read_cell_mut(loc).set_forwarding_bit(true); + } + } + (HeapCellValueTag::Str | + HeapCellValueTag::AttrVar | + HeapCellValueTag::Var | + HeapCellValueTag::PStrLoc, vh) => { + if self.heap[vh].get_mark_bit() { + self.read_cell_mut(loc).set_forwarding_bit(true); + } + } + (HeapCellValueTag::StackVar, vs) => { + if self.machine_stack[vs].get_mark_bit() { + self.read_cell_mut(loc).set_forwarding_bit(true); + } + } + _ => {} + ); + } fn follow(&mut self) -> Option { while let Some(h) = self.stack.pop() { @@ -330,7 +361,7 @@ impl<'a> StackfulPreOrderHeapIter<'a> { } } -impl<'a> Iterator for StackfulPreOrderHeapIter<'a> { +impl<'a, ElideLists: ListElisionPolicy> Iterator for StackfulPreOrderHeapIter<'a, ElideLists> { type Item = HeapCellValue; #[inline] @@ -349,11 +380,11 @@ pub(crate) fn stackless_preorder_iter( } #[inline(always)] -pub(crate) fn stackful_preorder_iter<'a>( +pub(crate) fn stackful_preorder_iter<'a, ElideLists: ListElisionPolicy>( heap: &'a mut Vec, stack: &'a mut Stack, cell: HeapCellValue, -) -> StackfulPreOrderHeapIter<'a> { +) -> StackfulPreOrderHeapIter<'a, ElideLists> { StackfulPreOrderHeapIter::new(heap, stack, cell) } @@ -460,9 +491,10 @@ impl PostOrderIterator { } } -pub(crate) type LeftistPostOrderHeapIter<'a> = PostOrderIterator>; +pub(crate) type LeftistPostOrderHeapIter<'a, ElideLists> = + PostOrderIterator>; -impl<'a> LeftistPostOrderHeapIter<'a> { +impl<'a, ElideLists: ListElisionPolicy> LeftistPostOrderHeapIter<'a, ElideLists> { #[inline] pub fn pop_stack(&mut self) { if let Some((child_count, ..)) = self.parent_stack.last() { @@ -481,11 +513,11 @@ impl<'a> LeftistPostOrderHeapIter<'a> { } #[inline] -pub(crate) fn stackful_post_order_iter<'a>( +pub(crate) fn stackful_post_order_iter<'a, ElideLists: ListElisionPolicy>( heap: &'a mut Heap, stack: &'a mut Stack, cell: HeapCellValue, -) -> LeftistPostOrderHeapIter<'a> { +) -> LeftistPostOrderHeapIter<'a, ElideLists> { PostOrderIterator::new(StackfulPreOrderHeapIter::new(heap, stack, cell)) } @@ -1555,7 +1587,7 @@ mod tests { .extend(functor!(f_atom, [atom(a_atom), atom(b_atom)])); { - let mut iter = StackfulPreOrderHeapIter::new( + let mut iter = StackfulPreOrderHeapIter::::new( &mut wam.machine_st.heap, &mut wam.machine_st.stack, str_loc_as_cell!(0), @@ -1590,7 +1622,7 @@ mod tests { )); for _ in 0..20 { - let mut iter = StackfulPreOrderHeapIter::new( + let mut iter = StackfulPreOrderHeapIter::::new( &mut wam.machine_st.heap, &mut wam.machine_st.stack, str_loc_as_cell!(0), @@ -1622,7 +1654,7 @@ mod tests { { wam.machine_st.heap.push(heap_loc_as_cell!(0)); - let mut iter = StackfulPreOrderHeapIter::new( + let mut iter = StackfulPreOrderHeapIter::::new( &mut wam.machine_st.heap, &mut wam.machine_st.stack, heap_loc_as_cell!(0), @@ -1649,7 +1681,7 @@ mod tests { wam.machine_st.heap.push(heap_loc_as_cell!(1)); wam.machine_st.heap.push(heap_loc_as_cell!(0)); - let mut iter = StackfulPreOrderHeapIter::new( + let mut iter = StackfulPreOrderHeapIter::::new( &mut wam.machine_st.heap, &mut wam.machine_st.stack, heap_loc_as_cell!(0), @@ -1673,7 +1705,7 @@ mod tests { wam.machine_st.heap.push(empty_list_as_cell!()); { - let mut iter = StackfulPreOrderHeapIter::new( + let mut iter = StackfulPreOrderHeapIter::::new( &mut wam.machine_st.heap, &mut wam.machine_st.stack, heap_loc_as_cell!(0), @@ -1709,7 +1741,7 @@ mod tests { wam.machine_st.heap.push(heap_loc_as_cell!(0)); { - let mut iter = StackfulPreOrderHeapIter::new( + let mut iter = StackfulPreOrderHeapIter::::new( &mut wam.machine_st.heap, &mut wam.machine_st.stack, heap_loc_as_cell!(0), @@ -1741,7 +1773,7 @@ mod tests { } { - let mut iter = StackfulPreOrderHeapIter::new( + let mut iter = StackfulPreOrderHeapIter::::new( &mut wam.machine_st.heap, &mut wam.machine_st.stack, heap_loc_as_cell!(0), @@ -1780,7 +1812,7 @@ mod tests { let pstr_cell = wam.machine_st.heap[pstr_var_cell.get_value() as usize]; { - let mut iter = StackfulPreOrderHeapIter::new( + let mut iter = StackfulPreOrderHeapIter::::new( &mut wam.machine_st.heap, &mut wam.machine_st.stack, heap_loc_as_cell!(0), @@ -1805,7 +1837,7 @@ mod tests { let pstr_second_cell = wam.machine_st.heap[pstr_second_var_cell.get_value() as usize]; { - let mut iter = stackful_preorder_iter( + let mut iter = stackful_preorder_iter::( &mut wam.machine_st.heap, &mut wam.machine_st.stack, heap_loc_as_cell!(0), @@ -1832,7 +1864,7 @@ mod tests { .push(fixnum_as_cell!(Fixnum::build_with(0i64))); { - let mut iter = stackful_preorder_iter( + let mut iter = stackful_preorder_iter::( &mut wam.machine_st.heap, &mut wam.machine_st.stack, pstr_loc_as_cell!(0), @@ -1867,7 +1899,7 @@ mod tests { .push(fixnum_as_cell!(Fixnum::build_with(1i64))); { - let mut iter = stackful_preorder_iter( + let mut iter = stackful_preorder_iter::( &mut wam.machine_st.heap, &mut wam.machine_st.stack, pstr_loc_as_cell!(0), @@ -1911,7 +1943,7 @@ mod tests { wam.machine_st.heap.extend(functor); { - let mut iter = StackfulPreOrderHeapIter::new( + let mut iter = StackfulPreOrderHeapIter::::new( &mut wam.machine_st.heap, &mut wam.machine_st.stack, heap_loc_as_cell!(0), @@ -1974,7 +2006,7 @@ mod tests { wam.machine_st.heap[4] = list_loc_as_cell!(1); { - let mut iter = stackful_preorder_iter( + let mut iter = stackful_preorder_iter::( &mut wam.machine_st.heap, &mut wam.machine_st.stack, heap_loc_as_cell!(0), @@ -2043,7 +2075,7 @@ mod tests { wam.machine_st.heap.push(list_loc_as_cell!(1)); { - let mut iter = StackfulPreOrderHeapIter::new( + let mut iter = StackfulPreOrderHeapIter::::new( &mut wam.machine_st.heap, &mut wam.machine_st.stack, heap_loc_as_cell!(0), @@ -2079,7 +2111,7 @@ mod tests { wam.machine_st.heap.push(empty_list_as_cell!()); { - let mut iter = stackful_preorder_iter( + let mut iter = stackful_preorder_iter::( &mut wam.machine_st.heap, &mut wam.machine_st.stack, heap_loc_as_cell!(0), @@ -2111,7 +2143,7 @@ mod tests { wam.machine_st.heap.push(empty_list_as_cell!()); { - let mut iter = stackful_preorder_iter( + let mut iter = stackful_preorder_iter::( &mut wam.machine_st.heap, &mut wam.machine_st.stack, heap_loc_as_cell!(0), @@ -2149,7 +2181,7 @@ mod tests { .extend(functor!(f_atom, [atom(a_atom), atom(b_atom)])); { - let mut iter = stackful_post_order_iter( + let mut iter = stackful_post_order_iter::( &mut wam.machine_st.heap, &mut wam.machine_st.stack, str_loc_as_cell!(0), @@ -2185,7 +2217,7 @@ mod tests { for _ in 0..20 { // 0000 { - let mut iter = stackful_post_order_iter( + let mut iter = stackful_post_order_iter::( &mut wam.machine_st.heap, &mut wam.machine_st.stack, str_loc_as_cell!(0), @@ -2219,7 +2251,7 @@ mod tests { { wam.machine_st.heap.push(heap_loc_as_cell!(0)); - let mut iter = stackful_post_order_iter( + let mut iter = stackful_post_order_iter::( &mut wam.machine_st.heap, &mut wam.machine_st.stack, heap_loc_as_cell!(0), @@ -2246,7 +2278,7 @@ mod tests { wam.machine_st.heap.push(heap_loc_as_cell!(1)); wam.machine_st.heap.push(heap_loc_as_cell!(0)); - let mut iter = stackful_post_order_iter( + let mut iter = stackful_post_order_iter::( &mut wam.machine_st.heap, &mut wam.machine_st.stack, heap_loc_as_cell!(0), @@ -2270,7 +2302,7 @@ mod tests { wam.machine_st.heap.push(empty_list_as_cell!()); { - let mut iter = stackful_post_order_iter( + let mut iter = stackful_post_order_iter::( &mut wam.machine_st.heap, &mut wam.machine_st.stack, heap_loc_as_cell!(0), @@ -2306,7 +2338,7 @@ mod tests { wam.machine_st.heap.push(heap_loc_as_cell!(0)); { - let mut iter = stackful_post_order_iter( + let mut iter = stackful_post_order_iter::( &mut wam.machine_st.heap, &mut wam.machine_st.stack, heap_loc_as_cell!(0), @@ -2338,7 +2370,7 @@ mod tests { } { - let mut iter = stackful_post_order_iter( + let mut iter = stackful_post_order_iter::( &mut wam.machine_st.heap, &mut wam.machine_st.stack, heap_loc_as_cell!(0), @@ -2377,7 +2409,7 @@ mod tests { let pstr_cell = wam.machine_st.heap[pstr_var_cell.get_value() as usize]; { - let mut iter = stackful_post_order_iter( + let mut iter = stackful_post_order_iter::( &mut wam.machine_st.heap, &mut wam.machine_st.stack, pstr_loc_as_cell!(0), @@ -2401,7 +2433,7 @@ mod tests { let pstr_second_cell = wam.machine_st.heap[pstr_second_var_cell.get_value() as usize]; { - let mut iter = stackful_post_order_iter( + let mut iter = stackful_post_order_iter::( &mut wam.machine_st.heap, &mut wam.machine_st.stack, pstr_loc_as_cell!(0), @@ -2428,7 +2460,7 @@ mod tests { .push(fixnum_as_cell!(Fixnum::build_with(0i64))); { - let mut iter = stackful_post_order_iter( + let mut iter = stackful_post_order_iter::( &mut wam.machine_st.heap, &mut wam.machine_st.stack, pstr_loc_as_cell!(0), @@ -2455,7 +2487,7 @@ mod tests { .push(fixnum_as_cell!(Fixnum::build_with(1i64))); { - let mut iter = stackful_post_order_iter( + let mut iter = stackful_post_order_iter::( &mut wam.machine_st.heap, &mut wam.machine_st.stack, pstr_loc_as_cell!(0), @@ -2489,7 +2521,7 @@ mod tests { wam.machine_st.heap.extend(functor); { - let mut iter = stackful_post_order_iter( + let mut iter = stackful_post_order_iter::( &mut wam.machine_st.heap, &mut wam.machine_st.stack, heap_loc_as_cell!(0), @@ -2553,7 +2585,7 @@ mod tests { wam.machine_st.heap[4] = list_loc_as_cell!(1); { - let mut iter = stackful_post_order_iter( + let mut iter = stackful_post_order_iter::( &mut wam.machine_st.heap, &mut wam.machine_st.stack, heap_loc_as_cell!(0), diff --git a/src/heap_print.rs b/src/heap_print.rs index 3c331b84..0e002c78 100644 --- a/src/heap_print.rs +++ b/src/heap_print.rs @@ -104,7 +104,7 @@ fn needs_bracketing(child_desc: OpDesc, op: &DirectedOp) -> bool { } } -impl<'a> StackfulPreOrderHeapIter<'a> { +impl<'a, ElideLists> StackfulPreOrderHeapIter<'a, ElideLists> { /* * descend into the subtree where the iterator is currently parked * and check that the leftmost leaf is a number, with every node @@ -407,7 +407,7 @@ fn is_numbered_var(name: Atom, arity: usize) -> bool { #[inline] fn negated_op_needs_bracketing( - iter: &StackfulPreOrderHeapIter, + iter: &StackfulPreOrderHeapIter, op_dir: &OpDir, op: &Option, ) -> bool { @@ -491,7 +491,7 @@ pub fn fmt_float(mut fl: f64) -> String { #[derive(Debug)] pub struct HCPrinter<'a, Outputter> { outputter: Outputter, - iter: StackfulPreOrderHeapIter<'a>, + iter: StackfulPreOrderHeapIter<'a, ListElider>, atom_tbl: Arc, op_dir: &'a OpDir, state_stack: Vec, diff --git a/src/machine/arithmetic_ops.rs b/src/machine/arithmetic_ops.rs index 69e48cad..149338b5 100644 --- a/src/machine/arithmetic_ops.rs +++ b/src/machine/arithmetic_ops.rs @@ -1208,7 +1208,8 @@ impl MachineState { value: HeapCellValue, ) -> Result { let stub_gen = || functor_stub(atom!("is"), 2); - let mut iter = stackful_post_order_iter(&mut self.heap, &mut self.stack, value); + let mut iter = stackful_post_order_iter:: + (&mut self.heap, &mut self.stack, value); while let Some(value) = iter.next() { if value.get_forwarding_bit() { diff --git a/src/machine/attributed_variables.rs b/src/machine/attributed_variables.rs index 0b08e8bb..a09a790e 100644 --- a/src/machine/attributed_variables.rs +++ b/src/machine/attributed_variables.rs @@ -133,7 +133,8 @@ impl MachineState { let mut seen_set = IndexSet::new(); let mut seen_vars = vec![]; - let mut iter = stackful_preorder_iter(&mut self.heap, &mut self.stack, cell); + let mut iter = stackful_preorder_iter:: + (&mut self.heap, &mut self.stack, cell); while let Some(value) = iter.next() { read_heap_cell!(value, diff --git a/src/machine/loader.rs b/src/machine/loader.rs index 467bfb80..07ba3078 100644 --- a/src/machine/loader.rs +++ b/src/machine/loader.rs @@ -1418,7 +1418,8 @@ impl MachineState { term_addr: HeapCellValue, ) -> Term { let mut term_stack = vec![]; - let mut iter = stackful_post_order_iter(&mut self.heap, &mut self.stack, term_addr); + let mut iter = stackful_post_order_iter:: + (&mut self.heap, &mut self.stack, term_addr); while let Some(addr) = iter.next() { let addr = unmark_cell_bits!(addr); diff --git a/src/machine/machine_state.rs b/src/machine/machine_state.rs index 0cb45e39..c09ba26b 100644 --- a/src/machine/machine_state.rs +++ b/src/machine/machine_state.rs @@ -588,7 +588,7 @@ impl MachineState { let mut singleton_var_set: IndexMap = IndexMap::new(); - for cell in stackful_preorder_iter(&mut self.heap, &mut self.stack, heap_loc) { + for cell in stackful_preorder_iter::(&mut self.heap, &mut self.stack, heap_loc) { let cell = unmark_cell_bits!(cell); if let Some(var) = cell.as_var() { diff --git a/src/machine/machine_state_impl.rs b/src/machine/machine_state_impl.rs index 2c909937..1ee0e20d 100644 --- a/src/machine/machine_state_impl.rs +++ b/src/machine/machine_state_impl.rs @@ -1135,7 +1135,8 @@ impl MachineState { return false; } - let mut iter = stackful_preorder_iter(&mut self.heap, &mut self.stack, value); + let mut iter = stackful_preorder_iter:: + (&mut self.heap, &mut self.stack, value); while let Some(value) = iter.next() { if value.get_forwarding_bit() { @@ -1633,7 +1634,7 @@ impl MachineState { } let mut visited = IndexSet::with_hasher(FxBuildHasher::default()); - let mut iter = stackful_preorder_iter(&mut self.heap, &mut self.stack, value); + let mut iter = stackful_preorder_iter::(&mut self.heap, &mut self.stack, value); let mut stack_len = 0; while let Some(value) = iter.next() { diff --git a/src/machine/system_calls.rs b/src/machine/system_calls.rs index daa119fc..cf1b060e 100644 --- a/src/machine/system_calls.rs +++ b/src/machine/system_calls.rs @@ -583,7 +583,7 @@ impl MachineState { seen_set: &mut IndexSet, value: HeapCellValue, ) { - let mut iter = stackful_preorder_iter(&mut self.heap, &mut self.stack, value); + let mut iter = stackful_preorder_iter::(&mut self.heap, &mut self.stack, value); while let Some(value) = iter.next() { let value = unmark_cell_bits!(value); @@ -793,7 +793,7 @@ impl MachineState { let mut seen_set = IndexSet::new(); { - let mut iter = stackful_post_order_iter(&mut self.heap, &mut self.stack, term); + let mut iter = stackful_post_order_iter::(&mut self.heap, &mut self.stack, term); while let Some(value) = iter.next() { if iter.parent_stack_len() >= max_depth { diff --git a/src/machine/unify.rs b/src/machine/unify.rs index 11e12654..f9c03189 100644 --- a/src/machine/unify.rs +++ b/src/machine/unify.rs @@ -1,6 +1,6 @@ use crate::arena::*; use crate::forms::*; -use crate::heap_iter::stackful_preorder_iter; +use crate::heap_iter::{NonListElider, stackful_preorder_iter}; use crate::machine::machine_state::*; use crate::machine::partial_string::*; use crate::machine::*; @@ -717,7 +717,7 @@ fn bind_with_occurs_check(unifier: &mut U, r: Ref, value: HeapCellVa if !value.is_constant() { let machine_st: &mut MachineState = unifier.deref_mut(); - for cell in stackful_preorder_iter(&mut machine_st.heap, &mut machine_st.stack, value) { + for cell in stackful_preorder_iter::(&mut machine_st.heap, &mut machine_st.stack, value) { let cell = unmark_cell_bits!(cell); if let Some(inner_r) = cell.as_var() {