Revert "remove Term"

This reverts commit 3b5879841aedecba5057c70c71da0ba23e5cd84a.
This commit is contained in:
Mark Thom
2025-03-15 13:19:26 -07:00
committed by Mark Thom
parent eef7b06919
commit 9e1e99f961
53 changed files with 3726 additions and 4517 deletions

View File

@@ -7,8 +7,6 @@ use crate::debray_allocator::*;
use crate::forms::*;
use crate::instructions::*;
use crate::iterators::*;
use crate::machine::disjuncts::*;
use crate::machine::stack::Stack;
use crate::targets::QueryInstruction;
use crate::types::*;
@@ -22,6 +20,7 @@ use dashu::base::BitTest;
use num_order::NumOrd;
use ordered_float::{Float, OrderedFloat};
use std::cell::Cell;
use std::cmp::{max, min, Ordering};
use std::convert::TryFrom;
use std::f64;
@@ -52,8 +51,89 @@ impl Default for ArithmeticTerm {
}
}
#[derive(Debug)]
pub(crate) struct ArithInstructionIterator<'a> {
state_stack: Vec<TermIterState<'a>>,
}
pub(crate) type ArithCont = (CodeDeque, Option<ArithmeticTerm>);
impl<'a> ArithInstructionIterator<'a> {
fn push_subterm(&mut self, lvl: Level, term: &'a Term) {
self.state_stack
.push(TermIterState::subterm_to_state(lvl, term));
}
fn from(term: &'a Term) -> Result<Self, ArithmeticError> {
let state = match term {
Term::AnonVar => return Err(ArithmeticError::UninstantiatedVar),
Term::Clause(cell, name, terms) => {
TermIterState::Clause(Level::Shallow, 0, cell, *name, terms)
}
Term::Literal(cell, cons) => TermIterState::Literal(Level::Shallow, cell, cons),
Term::Cons(..) | Term::PartialString(..) | Term::CompleteString(..) => {
return Err(ArithmeticError::NonEvaluableFunctor(
Literal::Atom(atom!(".")),
2,
))
}
Term::Var(cell, var_ptr) => TermIterState::Var(Level::Shallow, cell, var_ptr.clone()),
};
Ok(ArithInstructionIterator {
state_stack: vec![state],
})
}
}
#[derive(Debug)]
pub(crate) enum ArithTermRef<'a> {
Literal(Literal),
Op(Atom, usize), // name, arity.
Var(Level, &'a Cell<VarReg>, VarPtr),
}
impl<'a> Iterator for ArithInstructionIterator<'a> {
type Item = Result<ArithTermRef<'a>, ArithmeticError>;
fn next(&mut self) -> Option<Self::Item> {
while let Some(iter_state) = self.state_stack.pop() {
match iter_state {
TermIterState::AnonVar(_) => return Some(Err(ArithmeticError::UninstantiatedVar)),
TermIterState::Clause(lvl, child_num, cell, name, subterms) => {
let arity = subterms.len();
if child_num == arity {
return Some(Ok(ArithTermRef::Op(name, arity)));
} else {
self.state_stack.push(TermIterState::Clause(
lvl,
child_num + 1,
cell,
name,
subterms,
));
self.push_subterm(lvl.child_level(), &subterms[child_num]);
}
}
TermIterState::Literal(_, _, c) => return Some(Ok(ArithTermRef::Literal(*c))),
TermIterState::Var(lvl, cell, var_ptr) => {
return Some(Ok(ArithTermRef::Var(lvl, cell, var_ptr)));
}
_ => {
return Some(Err(ArithmeticError::NonEvaluableFunctor(
Literal::Atom(atom!(".")),
2,
)));
}
};
}
None
}
}
#[derive(Debug)]
pub(crate) struct ArithmeticEvaluator<'a> {
marker: &'a mut DebrayAllocator,
@@ -61,47 +141,37 @@ pub(crate) struct ArithmeticEvaluator<'a> {
interm_c: usize,
}
fn push_literal(interm: &mut Vec<ArithmeticTerm>, c: HeapCellValue) -> Result<(), ArithmeticError> {
let c = unmark_cell_bits!(c);
pub(crate) trait ArithmeticTermIter<'a> {
type Iter: Iterator<Item = Result<ArithTermRef<'a>, ArithmeticError>>;
read_heap_cell!(c,
(HeapCellValueTag::Fixnum, n) => {
interm.push(ArithmeticTerm::Number(Number::Fixnum(n)))
}
(HeapCellValueTag::Cons, cons_ptr) => {
match_untyped_arena_ptr!(cons_ptr,
(ArenaHeaderTag::Integer, n) => {
interm.push(ArithmeticTerm::Number(Number::Integer(n)));
}
(ArenaHeaderTag::Rational, n) => {
interm.push(ArithmeticTerm::Number(Number::Rational(n)));
}
_ => return Err(ArithmeticError::NonEvaluableFunctor(c, 0)),
);
}
(HeapCellValueTag::Atom, (name, arity)) => {
debug_assert_eq!(arity, 0);
fn iter(self) -> Result<Self::Iter, ArithmeticError>;
}
match name {
atom!("pi") => interm.push(ArithmeticTerm::Number(
Number::Float(OrderedFloat(std::f64::consts::PI)),
)),
atom!("epsilon") => interm.push(ArithmeticTerm::Number(
Number::Float(OrderedFloat(std::f64::EPSILON)),
)),
atom!("e") => interm.push(ArithmeticTerm::Number(
Number::Float(OrderedFloat(std::f64::consts::E)),
)),
_ => unreachable!(),
}
}
(HeapCellValueTag::F64, n) => {
interm.push(ArithmeticTerm::Number(Number::Float(*n)));
}
_ => {
return Err(ArithmeticError::NonEvaluableFunctor(c, 0));
}
);
impl<'a> ArithmeticTermIter<'a> for &'a Term {
type Iter = ArithInstructionIterator<'a>;
fn iter(self) -> Result<Self::Iter, ArithmeticError> {
ArithInstructionIterator::from(self)
}
}
fn push_literal(interm: &mut Vec<ArithmeticTerm>, c: &Literal) -> Result<(), ArithmeticError> {
match c {
Literal::Fixnum(n) => interm.push(ArithmeticTerm::Number(Number::Fixnum(*n))),
Literal::Integer(n) => interm.push(ArithmeticTerm::Number(Number::Integer(*n))),
Literal::Float(n) => interm.push(ArithmeticTerm::Number(Number::Float(*n.as_ptr()))),
Literal::Rational(n) => interm.push(ArithmeticTerm::Number(Number::Rational(*n))),
Literal::Atom(name) if name == &atom!("e") => interm.push(ArithmeticTerm::Number(
Number::Float(OrderedFloat(std::f64::consts::E)),
)),
Literal::Atom(name) if name == &atom!("pi") => interm.push(ArithmeticTerm::Number(
Number::Float(OrderedFloat(std::f64::consts::PI)),
)),
Literal::Atom(name) if name == &atom!("epsilon") => interm.push(ArithmeticTerm::Number(
Number::Float(OrderedFloat(f64::EPSILON)),
)),
_ => return Err(ArithmeticError::NonEvaluableFunctor(*c, 0)),
}
Ok(())
}
@@ -143,7 +213,7 @@ impl<'a> ArithmeticEvaluator<'a> {
atom!("float_fractional_part") => Ok(Instruction::FloatFractionalPart(a1, t)),
atom!("sign") => Ok(Instruction::Sign(a1, t)),
atom!("\\") => Ok(Instruction::BitwiseComplement(a1, t)),
_ => Err(ArithmeticError::NonEvaluableFunctor(atom_as_cell!(name), 1)),
_ => Err(ArithmeticError::NonEvaluableFunctor(Literal::Atom(name), 1)),
}
}
@@ -175,7 +245,7 @@ impl<'a> ArithmeticEvaluator<'a> {
atom!("rem") => Ok(Instruction::Rem(a1, a2, t)),
atom!("gcd") => Ok(Instruction::Gcd(a1, a2, t)),
atom!("atan2") => Ok(Instruction::ATan2(a1, a2, t)),
_ => Err(ArithmeticError::NonEvaluableFunctor(atom_as_cell!(name), 2)),
_ => Err(ArithmeticError::NonEvaluableFunctor(Literal::Atom(name), 2)),
}
}
@@ -231,7 +301,7 @@ impl<'a> ArithmeticEvaluator<'a> {
self.get_binary_instr(name, a1, a2, ninterm)
}
_ => Err(ArithmeticError::NonEvaluableFunctor(
atom_as_cell!(name),
Literal::Atom(name),
arity,
)),
}
@@ -239,62 +309,44 @@ impl<'a> ArithmeticEvaluator<'a> {
pub(crate) fn compile_is(
&mut self,
src: &mut FocusedHeapRefMut,
term_loc: usize,
context: GenContext,
src: &'a Term,
term_loc: GenContext,
arg: usize,
) -> Result<ArithCont, ArithmeticError> {
let mut code = CodeDeque::new();
let mut stack = Stack::uninitialized();
let mut iter = query_iterator::<false>(&mut src.heap, &mut stack, term_loc);
let chunk_num = context.chunk_num();
for term_ref in src.iter()? {
match term_ref? {
ArithTermRef::Literal(c) => push_literal(&mut self.interm, &c)?,
ArithTermRef::Var(lvl, cell, name) => {
let var_num = name.to_var_num().unwrap();
while let Some(term) = iter.next() {
read_heap_cell!(term,
(HeapCellValueTag::AttrVar | HeapCellValueTag::Var, term_loc) => {
let lvl = iter.level();
let r = if lvl == Level::Shallow {
self.marker
.mark_non_callable(var_num, arg, term_loc, cell, &mut code)
} else if term_loc.is_last() || cell.get().norm().reg_num() == 0 {
let r = self.marker.get_binding(var_num);
let r = match self.marker.var_data.var_locs_to_nums.get(VarPtrIndex { chunk_num, term_loc }) {
VarPtr::Numbered(var_num) => {
let old_r = self.marker.get_var_binding(var_num);
if lvl == Level::Root {
self.marker.mark_non_callable(var_num, arg, context, &mut code)
} else if context.is_last() || old_r.reg_num() == 0 {
let r = old_r;
if r.reg_num() == 0 {
self.marker.mark_var::<QueryInstruction>(
var_num, lvl, context, &mut code,
)
} else {
self.marker.increment_running_count(var_num);
r
}
} else {
self.marker.increment_running_count(var_num);
old_r
}
}
VarPtr::Anon => {
self.marker.mark_anon_var::<QueryInstruction>(lvl, context, &mut code)
if r.reg_num() == 0 {
self.marker.mark_var::<QueryInstruction>(
var_num, lvl, cell, term_loc, &mut code,
);
cell.get().norm()
} else {
self.marker.increment_running_count(var_num);
r
}
} else {
self.marker.increment_running_count(var_num);
cell.get().norm()
};
self.interm.push(ArithmeticTerm::Reg(r));
}
(HeapCellValueTag::Atom, (name, arity)) => {
if arity == 0 {
push_literal(&mut self.interm, atom_as_cell!(name))?;
} else {
code.push_back(self.instr_from_clause(name, arity)?);
}
ArithTermRef::Op(name, arity) => {
code.push_back(self.instr_from_clause(name, arity)?);
}
_ => {
push_literal(&mut self.interm, term)?;
}
);
}
}
Ok((code, self.interm.pop()))