Merge branch 'master' into library-use-case

This commit is contained in:
Nicolas Luck
2023-10-16 13:43:26 +02:00
13 changed files with 1403 additions and 570 deletions

View File

@@ -1,5 +1,6 @@
use dashu::base::Abs;
use dashu::base::Gcd;
use dashu::base::{Abs, Gcd, UnsignedAbs};
use dashu::integer::IBig;
use dashu::integer::fast_div::ConstDivisor;
use divrem::*;
use num_order::NumOrd;
@@ -854,7 +855,9 @@ pub(crate) fn modulus(x: Number, y: Number, arena: &mut Arena) -> Result<Number,
} else if n1 < &Integer::ZERO && n2 > &Integer::ZERO {
((n1 + Integer::ONE) / n2) - Integer::ONE
} else {
n1 / n2
let ring = ConstDivisor::new(n2.unsigned_abs());
let n1 = n1.clone();
IBig::from(ring.reduce(n1).residue())
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1131,27 +1131,29 @@ impl MachineState {
#[inline]
pub fn is_cyclic_term(&mut self, value: HeapCellValue) -> bool {
if value.is_constant() {
let value = self.store(self.deref(value));
if value.is_constant() || value.is_stack_var() {
return false;
}
let mut iter = stackful_preorder_iter::<NonListElider>
(&mut self.heap, &mut self.stack, value);
let h = self.heap.len();
self.heap.push(value);
while let Some(value) = iter.next() {
if value.get_forwarding_bit() {
let value = unmark_cell_bits!(heap_bound_store(
iter.heap,
heap_bound_deref(iter.heap, value),
));
let found_cycle = {
let mut iter = cycle_detecting_stackless_preorder_iter(&mut self.heap, h);
if value.is_compound(iter.heap) {
return true;
while let Some(_) = iter.next() {
if iter.found_cycle() {
break;
}
}
}
false
iter.found_cycle()
};
self.heap.pop();
found_cycle
}
// arg(+N, +Term, ?Arg)
@@ -1621,56 +1623,12 @@ impl MachineState {
// returns true on failure.
pub fn ground_test(&mut self) -> bool {
use fxhash::FxBuildHasher;
let iter = eager_stackful_preorder_iter(&mut self.heap, self.registers[1]);
if self.registers[1].is_constant() {
return false;
}
let value = self.store(self.deref(self.registers[1]));
if value.is_stack_var() {
return true;
}
let mut visited = IndexSet::with_hasher(FxBuildHasher::default());
let mut iter = stackful_preorder_iter::<NonListElider>(&mut self.heap, &mut self.stack, value);
let mut stack_len = 0;
let is_var = |heap: &Heap, value: HeapCellValue| -> bool {
let value = unmark_cell_bits!(value);
if value.is_var() {
let value = heap_bound_store(heap, heap_bound_deref(heap, value));
if value.is_var() {
return true;
}
}
false
};
while let Some(value) = iter.next() {
if is_var(iter.heap, value) {
for term in iter {
if term.is_var() {
return true;
}
if value.is_ref() {
if visited.contains(&value) {
while iter.stack_len() > stack_len {
if let Some(value) = iter.pop_stack() {
if is_var(iter.heap, value) {
return true;
}
}
}
} else {
visited.insert(value);
}
}
stack_len = iter.stack_len();
}
false

View File

@@ -584,20 +584,11 @@ impl MachineState {
seen_set: &mut IndexSet<HeapCellValue, S>,
value: HeapCellValue,
) {
let mut iter = stackful_preorder_iter::<NonListElider>(&mut self.heap, &mut self.stack, value);
let iter = eager_stackful_preorder_iter(&mut self.heap, value);
while let Some(value) = iter.next() {
let value = unmark_cell_bits!(value);
if value.is_var() {
let value = unmark_cell_bits!(heap_bound_store(
iter.heap,
heap_bound_deref(iter.heap, value)
));
if value.is_var() {
seen_set.insert(value);
}
for term in iter {
if term.is_var() {
seen_set.insert(term);
}
}
}
@@ -6891,6 +6882,17 @@ impl Machine {
return;
}
let stored_v = if stored_v.is_stack_var() {
let h = self.machine_st.heap.len();
self.machine_st.heap.push(heap_loc_as_cell!(h));
self.machine_st.bind(Ref::heap_cell(h), stored_v);
heap_loc_as_cell!(h)
} else {
stored_v
};
let mut seen_set = IndexSet::with_hasher(FxBuildHasher::default());
self.machine_st.variable_set(&mut seen_set, stored_v);

View File

@@ -691,6 +691,9 @@ pub(crate) trait Unifier: DerefMut<Target = MachineState> {
(HeapCellValueTag::Cons, ptr_1) => {
Self::unify_constant(self, ptr_1, d2);
}
(HeapCellValueTag::CutPoint, n1) => {
Self::unify_fixnum(self, n1, d2);
}
_ => {
unreachable!();
}