Merge branch 'master' into library-use-case
This commit is contained in:
@@ -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
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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!();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user