revamp evaluable functors, add missing evaluable functors
This commit is contained in:
@@ -4,7 +4,6 @@ use prolog::heap_print::*;
|
||||
use prolog::machine::*;
|
||||
use prolog::machine::compile::*;
|
||||
use prolog::machine::machine_errors::*;
|
||||
use prolog::num::ToPrimitive;
|
||||
|
||||
use std::io::Read;
|
||||
|
||||
@@ -47,7 +46,7 @@ impl Machine {
|
||||
};
|
||||
|
||||
let arity = match self.machine_st.store(self.machine_st.deref(arity)) {
|
||||
Addr::Con(Constant::Number(Number::Integer(arity))) =>
|
||||
Addr::Con(Constant::Integer(arity)) =>
|
||||
arity.to_usize().unwrap(),
|
||||
_ => unreachable!()
|
||||
};
|
||||
@@ -192,7 +191,7 @@ impl Machine {
|
||||
{
|
||||
let index = self.machine_st[temp_v!(3)].clone();
|
||||
let index = match self.machine_st.store(self.machine_st.deref(index)) {
|
||||
Addr::Con(Constant::Number(Number::Integer(n))) => n.to_usize().unwrap(),
|
||||
Addr::Con(Constant::Integer(n)) => n.to_usize().unwrap(),
|
||||
_ => unreachable!()
|
||||
};
|
||||
|
||||
@@ -227,7 +226,7 @@ impl Machine {
|
||||
{
|
||||
let index = self.machine_st[temp_v!(3)].clone();
|
||||
let index = match self.machine_st.store(self.machine_st.deref(index)) {
|
||||
Addr::Con(Constant::Number(Number::Integer(n))) => n.to_usize().unwrap(),
|
||||
Addr::Con(Constant::Integer(n)) => n.to_usize().unwrap(),
|
||||
_ => unreachable!()
|
||||
};
|
||||
|
||||
|
||||
@@ -3,9 +3,7 @@ use prolog_parser::string_list::*;
|
||||
|
||||
use prolog::machine::machine_indices::*;
|
||||
use prolog::machine::machine_state::*;
|
||||
use prolog::num::bigint::BigInt;
|
||||
|
||||
use std::rc::Rc;
|
||||
use prolog::rug::Integer;
|
||||
|
||||
pub(super) type MachineStub = Vec<HeapCellValue>;
|
||||
|
||||
@@ -23,7 +21,7 @@ pub(super) struct MachineError {
|
||||
impl MachineError {
|
||||
pub(super) fn functor_stub(name: ClauseName, arity: usize) -> MachineStub {
|
||||
let name = HeapCellValue::Addr(Addr::Con(Constant::Atom(name, None)));
|
||||
functor!("/", 2, [name, heap_integer!(arity)], SharedOpDesc::new(400, YFX))
|
||||
functor!("/", 2, [name, heap_integer!(Integer::from(arity))], SharedOpDesc::new(400, YFX))
|
||||
}
|
||||
|
||||
pub(super) fn evaluation_error(eval_error: EvalError) -> Self {
|
||||
@@ -47,7 +45,7 @@ impl MachineError {
|
||||
let mut stub = functor!("evaluation_error", 1, [HeapCellValue::Addr(Addr::HeapCell(h + 2))]);
|
||||
|
||||
stub.append(&mut functor!("/", 2, [HeapCellValue::Addr(Addr::HeapCell(h + 2 + 3)),
|
||||
heap_integer!(arity)],
|
||||
heap_integer!(Integer::from(arity))],
|
||||
SharedOpDesc::new(400, YFX)));
|
||||
stub.append(&mut functor!(":", 2, [mod_name, name], SharedOpDesc::new(600, XFY)));
|
||||
|
||||
@@ -99,7 +97,28 @@ impl MachineError {
|
||||
MachineError { stub, from: ErrorProvenance::Constructed }
|
||||
}
|
||||
|
||||
fn arithmetic_error(h: usize, err: ArithmeticError) -> Self {
|
||||
match err {
|
||||
ArithmeticError::UninstantiatedVar =>
|
||||
Self::instantiation_error(),
|
||||
ArithmeticError::NonEvaluableFunctor(name, arity) => {
|
||||
let name = HeapCellValue::Addr(Addr::Con(name));
|
||||
let culprit = functor!("/", 2, [name, heap_integer!(Integer::from(arity))],
|
||||
SharedOpDesc::new(400, YFX));
|
||||
|
||||
let mut stub = Self::type_error(ValidType::Evaluable, Addr::HeapCell(3+h)).stub;
|
||||
stub.extend(culprit.into_iter());
|
||||
|
||||
MachineError { stub, from: ErrorProvenance::Constructed }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn syntax_error(h: usize, err: ParserError) -> Self {
|
||||
if let ParserError::Arithmetic(err) = err {
|
||||
return Self::arithmetic_error(h, err);
|
||||
}
|
||||
|
||||
let err = vec![heap_atom!(err.as_str())];
|
||||
|
||||
let mut stub = if err.len() == 1 {
|
||||
@@ -175,7 +194,8 @@ pub enum ValidType {
|
||||
Callable,
|
||||
Character,
|
||||
Compound,
|
||||
// Evaluable,
|
||||
Evaluable,
|
||||
Float,
|
||||
// InByte,
|
||||
// InCharacter,
|
||||
Integer,
|
||||
@@ -196,7 +216,8 @@ impl ValidType {
|
||||
ValidType::Callable => "callable",
|
||||
ValidType::Character => "character",
|
||||
ValidType::Compound => "compound",
|
||||
// ValidType::Evaluable => "evaluable",
|
||||
ValidType::Evaluable => "evaluable",
|
||||
ValidType::Float => "float",
|
||||
// ValidType::InByte => "in_byte",
|
||||
// ValidType::InCharacter => "in_character",
|
||||
ValidType::Integer => "integer",
|
||||
@@ -249,21 +270,19 @@ impl RepFlag {
|
||||
// from 7.12.2 g) of 13211-1:1995
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum EvalError {
|
||||
// FloatOverflow,
|
||||
// Undefined,
|
||||
// FloatUnderflow,
|
||||
FloatOverflow,
|
||||
Undefined,
|
||||
// Underflow,
|
||||
ZeroDivisor,
|
||||
NoRoots
|
||||
}
|
||||
|
||||
impl EvalError {
|
||||
pub fn as_str(self) -> &'static str {
|
||||
match self {
|
||||
// EvalError::FloatOverflow => "float_overflow",
|
||||
// EvalError::Undefined => "undefined",
|
||||
EvalError::FloatOverflow => "float_overflow",
|
||||
EvalError::Undefined => "undefined",
|
||||
// EvalError::FloatUnderflow => "underflow",
|
||||
EvalError::ZeroDivisor => "zero_divisor",
|
||||
EvalError::NoRoots => "no_roots"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,8 +11,8 @@ use prolog::machine::machine_errors::*;
|
||||
use prolog::machine::machine_indices::*;
|
||||
use prolog::machine::modules::*;
|
||||
use prolog::machine::or_stack::*;
|
||||
use prolog::num::{BigInt, BigUint, One, ToPrimitive, Zero};
|
||||
use prolog::read::PrologStream;
|
||||
use prolog::rug::Integer;
|
||||
|
||||
use downcast::Any;
|
||||
|
||||
@@ -20,7 +20,6 @@ use std::cmp::Ordering;
|
||||
use std::io::{Write, stdout};
|
||||
use std::mem;
|
||||
use std::ops::{Index, IndexMut};
|
||||
use std::rc::Rc;
|
||||
|
||||
pub(super) struct Ball {
|
||||
pub(super) boundary: usize, // ball.0
|
||||
@@ -288,7 +287,7 @@ impl MachineState {
|
||||
},
|
||||
&Addr::Con(Constant::CharCode(c)) =>
|
||||
codes.push(c),
|
||||
&Addr::Con(Constant::Number(Number::Integer(ref n))) =>
|
||||
&Addr::Con(Constant::Integer(ref n)) =>
|
||||
if let Some(c) = n.to_u8() {
|
||||
codes.push(c);
|
||||
} else {
|
||||
@@ -741,7 +740,7 @@ pub(crate) trait CallPolicy: Any {
|
||||
let a1 = machine_st[r].clone();
|
||||
let a2 = machine_st.get_number(at)?;
|
||||
|
||||
machine_st.unify(a1, Addr::Con(Constant::Number(a2)));
|
||||
machine_st.unify(a1, Addr::Con(a2.to_constant()));
|
||||
return_from_clause!(machine_st.last_call, machine_st)
|
||||
},
|
||||
}
|
||||
@@ -875,8 +874,8 @@ impl CallPolicy for DefaultCallPolicy {}
|
||||
|
||||
pub(crate) struct CWILCallPolicy {
|
||||
pub(crate) prev_policy: Box<CallPolicy>,
|
||||
count: BigUint,
|
||||
limits: Vec<(BigUint, usize)>,
|
||||
count: Integer,
|
||||
limits: Vec<(Integer, usize)>,
|
||||
inference_limit_exceeded: bool
|
||||
}
|
||||
|
||||
@@ -887,7 +886,7 @@ impl CWILCallPolicy {
|
||||
mem::swap(&mut prev_policy, policy);
|
||||
|
||||
let new_policy = CWILCallPolicy { prev_policy,
|
||||
count: BigUint::zero(),
|
||||
count: Integer::from(0),
|
||||
limits: vec![],
|
||||
inference_limit_exceeded: false };
|
||||
*policy = Box::new(new_policy);
|
||||
@@ -904,35 +903,32 @@ impl CWILCallPolicy {
|
||||
return Err(functor!("inference_limit_exceeded", 1,
|
||||
[HeapCellValue::Addr(Addr::Con(Constant::Usize(bp)))]));
|
||||
} else {
|
||||
self.count += BigUint::one();
|
||||
self.count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn add_limit(&mut self, limit: Rc<BigInt>, b: usize) -> Rc<BigInt> {
|
||||
let limit = match limit.to_biguint() {
|
||||
Some(limit) => limit + &self.count,
|
||||
None => panic!("install_inference_counter: limit must be positive")
|
||||
};
|
||||
pub(crate) fn add_limit(&mut self, mut limit: Integer, b: usize) -> &Integer {
|
||||
limit += &self.count;
|
||||
|
||||
match self.limits.last().cloned() {
|
||||
Some((ref inner_limit, _)) if *inner_limit <= limit => {},
|
||||
_ => self.limits.push((limit, b))
|
||||
};
|
||||
|
||||
Rc::new(BigInt::from(self.count.clone()))
|
||||
&self.count
|
||||
}
|
||||
|
||||
pub(crate) fn remove_limit(&mut self, b: usize) -> Rc<BigInt> {
|
||||
pub(crate) fn remove_limit(&mut self, b: usize) -> &Integer {
|
||||
if let Some((_, bp)) = self.limits.last().cloned() {
|
||||
if bp == b {
|
||||
self.limits.pop();
|
||||
}
|
||||
}
|
||||
|
||||
Rc::new(BigInt::from(self.count.clone()))
|
||||
&self.count
|
||||
}
|
||||
|
||||
pub(crate) fn is_empty(&self) -> bool {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -11,10 +11,9 @@ use prolog::machine::machine_errors::*;
|
||||
use prolog::machine::machine_indices::*;
|
||||
use prolog::machine::machine_state::*;
|
||||
use prolog::machine::toplevel::{to_op_decl};
|
||||
use prolog::num::{FromPrimitive, ToPrimitive, Zero};
|
||||
use prolog::num::bigint::{BigInt};
|
||||
use prolog::ordered_float::OrderedFloat;
|
||||
use prolog::read::{PrologStream, readline};
|
||||
use prolog::rug::Integer;
|
||||
|
||||
use ref_thread_local::RefThreadLocal;
|
||||
|
||||
@@ -121,7 +120,7 @@ impl MachineState {
|
||||
|
||||
fn finalize_skip_max_list(&mut self, n: usize, addr: Addr) {
|
||||
let target_n = self[temp_v!(1)].clone();
|
||||
self.unify(Addr::Con(integer!(n)), target_n);
|
||||
self.unify(Addr::Con(Constant::Integer(Integer::from(n))), target_n);
|
||||
|
||||
if !self.fail {
|
||||
let xs = self[temp_v!(4)].clone();
|
||||
@@ -133,12 +132,12 @@ impl MachineState {
|
||||
let max_steps = self.store(self.deref(self[temp_v!(2)].clone()));
|
||||
|
||||
match max_steps {
|
||||
Addr::Con(Constant::Number(Number::Integer(ref max_steps))) =>
|
||||
Addr::Con(Constant::Integer(ref max_steps)) =>
|
||||
if max_steps.to_isize().map(|i| i >= -1).unwrap_or(false) {
|
||||
let n = self.store(self.deref(self[temp_v!(1)].clone()));
|
||||
|
||||
match n {
|
||||
Addr::Con(Constant::Number(Number::Integer(ref n))) if n.is_zero() => {
|
||||
Addr::Con(Constant::Integer(ref n)) if n == &0 => {
|
||||
let xs0 = self[temp_v!(3)].clone();
|
||||
let xs = self[temp_v!(4)].clone();
|
||||
|
||||
@@ -163,7 +162,7 @@ impl MachineState {
|
||||
self.finalize_skip_max_list(n + s.len(),
|
||||
Addr::Con(Constant::EmptyList))
|
||||
} else {
|
||||
let i = max_steps.to_usize().unwrap() - n;
|
||||
let i = (max_steps as usize) - n;
|
||||
|
||||
if s.len() < i {
|
||||
self.finalize_skip_max_list(n + s.len(),
|
||||
@@ -338,7 +337,7 @@ impl MachineState {
|
||||
}
|
||||
}
|
||||
|
||||
fn int_to_char_code(&mut self, n: Rc<BigInt>, stub: &'static str, arity: usize)
|
||||
fn int_to_char_code(&mut self, n: &Integer, stub: &'static str, arity: usize)
|
||||
-> Result<u8, MachineStub>
|
||||
{
|
||||
if let Some(c) = n.to_u8() {
|
||||
@@ -381,8 +380,12 @@ impl MachineState {
|
||||
|
||||
return Err(self.error_form(err, stub));
|
||||
},
|
||||
Ok(Term::Constant(_, Constant::Number(n))) =>
|
||||
self.unify(nx, Addr::Con(Constant::Number(n))),
|
||||
Ok(Term::Constant(_, Constant::Rational(n))) =>
|
||||
self.unify(nx, Addr::Con(Constant::Rational(n))),
|
||||
Ok(Term::Constant(_, Constant::Float(n))) =>
|
||||
self.unify(nx, Addr::Con(Constant::Float(n))),
|
||||
Ok(Term::Constant(_, Constant::Integer(n))) =>
|
||||
self.unify(nx, Addr::Con(Constant::Integer(n))),
|
||||
Ok(Term::Constant(_, Constant::CharCode(c))) =>
|
||||
self.unify(nx, Addr::Con(Constant::CharCode(c))),
|
||||
_ => {
|
||||
@@ -519,8 +522,8 @@ impl MachineState {
|
||||
|
||||
for addr in addrs.iter() {
|
||||
match addr {
|
||||
&Addr::Con(Constant::Number(Number::Integer(ref n))) => {
|
||||
let c = self.int_to_char_code(n.clone(), "atom_codes", 2)?;
|
||||
&Addr::Con(Constant::Integer(ref n)) => {
|
||||
let c = self.int_to_char_code(&n, "atom_codes", 2)?;
|
||||
chars.push(c as char);
|
||||
},
|
||||
&Addr::Con(Constant::CharCode(c)) =>
|
||||
@@ -550,10 +553,10 @@ impl MachineState {
|
||||
_ => unreachable!()
|
||||
};
|
||||
|
||||
let len = Number::Integer(Rc::new(BigInt::from_usize(atom.as_str().len()).unwrap()));
|
||||
let len = Integer::from(atom.as_str().len());
|
||||
let a2 = self[temp_v!(2)].clone();
|
||||
|
||||
self.unify(a2, Addr::Con(Constant::Number(len)));
|
||||
self.unify(a2, Addr::Con(Constant::Integer(len)));
|
||||
},
|
||||
&SystemClauseType::CharsToNumber => {
|
||||
let stub = MachineError::functor_stub(clause_name!("number_chars"), 2);
|
||||
@@ -574,9 +577,9 @@ impl MachineState {
|
||||
let chs = self[temp_v!(2)].clone();
|
||||
|
||||
let string = match self.store(self.deref(n)) {
|
||||
Addr::Con(Constant::Number(Number::Float(OrderedFloat(n)))) =>
|
||||
Addr::Con(Constant::Float(OrderedFloat(n))) =>
|
||||
format!("{0:<20?}", n),
|
||||
Addr::Con(Constant::Number(Number::Integer(n))) =>
|
||||
Addr::Con(Constant::Integer(n)) =>
|
||||
n.to_string(),
|
||||
_ => unreachable!()
|
||||
};
|
||||
@@ -591,9 +594,9 @@ impl MachineState {
|
||||
let chs = self[temp_v!(2)].clone();
|
||||
|
||||
let string = match self.store(self.deref(n)) {
|
||||
Addr::Con(Constant::Number(Number::Float(OrderedFloat(n)))) =>
|
||||
Addr::Con(Constant::Float(OrderedFloat(n))) =>
|
||||
format!("{0:<20?}", n),
|
||||
Addr::Con(Constant::Number(Number::Integer(n))) =>
|
||||
Addr::Con(Constant::Integer(n)) =>
|
||||
n.to_string(),
|
||||
_ => unreachable!()
|
||||
};
|
||||
@@ -659,8 +662,8 @@ impl MachineState {
|
||||
match self.store(self.deref(a2)) {
|
||||
Addr::Con(Constant::CharCode(code)) =>
|
||||
self.unify(Addr::Con(Constant::Char(code as char)), addr.clone()),
|
||||
Addr::Con(Constant::Number(Number::Integer(n))) => {
|
||||
let c = self.int_to_char_code(n, "char_code", 2)?;
|
||||
Addr::Con(Constant::Integer(n)) => {
|
||||
let c = self.int_to_char_code(&n, "char_code", 2)?;
|
||||
self.unify(Addr::Con(Constant::Char(c as char)), addr.clone());
|
||||
},
|
||||
_ => self.fail = true
|
||||
@@ -967,12 +970,12 @@ impl MachineState {
|
||||
let a2 = self[temp_v!(2)].clone();
|
||||
let a3 = self[temp_v!(3)].clone();
|
||||
|
||||
let arity = Number::Integer(Rc::new(BigInt::from_usize(arity).unwrap()));
|
||||
let arity = Integer::from(arity);
|
||||
|
||||
self.unify(a2, Addr::Con(Constant::Atom(name, spec)));
|
||||
|
||||
if !self.fail {
|
||||
self.unify(a3, Addr::Con(Constant::Number(arity)));
|
||||
self.unify(a3, Addr::Con(Constant::Integer(arity)));
|
||||
}
|
||||
},
|
||||
_ => self.fail = true
|
||||
@@ -1007,11 +1010,11 @@ impl MachineState {
|
||||
}
|
||||
};
|
||||
|
||||
let a2 = Number::Integer(Rc::new(BigInt::from_usize(priority).unwrap()));
|
||||
let a2 = Integer::from(priority);
|
||||
let a3 = Addr::Con(Constant::Atom(clause_name!(spec), None));
|
||||
let a4 = Addr::Con(Constant::Atom(name, Some(shared_op_desc)));
|
||||
|
||||
self.unify(Addr::Con(Constant::Number(a2)), prec);
|
||||
self.unify(Addr::Con(Constant::Integer(a2)), prec);
|
||||
|
||||
if !self.fail {
|
||||
self.unify(a3, specifier);
|
||||
@@ -1032,7 +1035,7 @@ impl MachineState {
|
||||
let op = self[temp_v!(3)].clone();
|
||||
|
||||
let priority = match self.store(self.deref(priority)) {
|
||||
Addr::Con(Constant::Number(Number::Integer(n))) => n.to_usize().unwrap(),
|
||||
Addr::Con(Constant::Integer(n)) => n.to_usize().unwrap(),
|
||||
_ => unreachable!()
|
||||
};
|
||||
|
||||
@@ -1251,11 +1254,11 @@ impl MachineState {
|
||||
|
||||
match (a1, a2.clone()) {
|
||||
(Addr::Con(Constant::Usize(bp)),
|
||||
Addr::Con(Constant::Number(Number::Integer(n)))) =>
|
||||
Addr::Con(Constant::Integer(n))) =>
|
||||
match call_policy.downcast_mut::<CWILCallPolicy>().ok() {
|
||||
Some(call_policy) => {
|
||||
let count = call_policy.add_limit(n, bp);
|
||||
let count = Addr::Con(Constant::Number(Number::Integer(count)));
|
||||
let count = Addr::Con(Constant::Integer(count.clone()));
|
||||
|
||||
let a3 = self[temp_v!(3)].clone();
|
||||
|
||||
@@ -1369,7 +1372,7 @@ impl MachineState {
|
||||
|
||||
if let Addr::Con(Constant::Usize(bp)) = a1 {
|
||||
let count = call_policy.remove_limit(bp);
|
||||
let count = Addr::Con(Constant::Number(Number::Integer(count)));
|
||||
let count = Addr::Con(Constant::Integer(count.clone()));
|
||||
|
||||
let a2 = self[temp_v!(2)].clone();
|
||||
|
||||
@@ -1692,7 +1695,7 @@ impl MachineState {
|
||||
if var_names.contains_key(&var) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
var_names.insert(var, atom);
|
||||
},
|
||||
_ => unreachable!()
|
||||
|
||||
@@ -3,7 +3,8 @@ use prolog_parser::parser::*;
|
||||
|
||||
use prolog::machine::*;
|
||||
use prolog::machine::machine_indices::HeapCellValue;
|
||||
use prolog::num::*;
|
||||
use prolog::rug::Integer;
|
||||
use prolog::rug::ops::Pow;
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::collections::VecDeque;
|
||||
@@ -306,7 +307,7 @@ impl MachineState {
|
||||
// names in the pre-expansion term. This formula ensures that all generated "numbervars"-
|
||||
// style variable names will be longer than the keys of the var_dict, and therefore
|
||||
// not equal to any of them.
|
||||
printer.numbervars_offset = pow(BigInt::from(10), max_var_length) * 26;
|
||||
printer.numbervars_offset = Integer::from(10).pow(max_var_length as u32) * 26;
|
||||
printer.drop_toplevel_spec();
|
||||
|
||||
printer.see_all_locs();
|
||||
|
||||
@@ -9,7 +9,6 @@ use prolog::machine::machine_errors::*;
|
||||
use prolog::machine::machine_indices::*;
|
||||
use prolog::machine::machine_state::MachineState;
|
||||
use prolog::machine::term_expansion::*;
|
||||
use prolog::num::*;
|
||||
|
||||
use std::borrow::BorrowMut;
|
||||
use std::collections::{HashMap, HashSet, VecDeque};
|
||||
@@ -142,7 +141,7 @@ fn setup_op_decl(mut terms: Vec<Box<Term>>) -> Result<OpDecl, ParserError>
|
||||
};
|
||||
|
||||
let prec = match *terms.pop().unwrap() {
|
||||
Term::Constant(_, Constant::Number(Number::Integer(bi))) =>
|
||||
Term::Constant(_, Constant::Integer(bi)) =>
|
||||
match bi.to_usize() {
|
||||
Some(n) if n <= 1200 => n,
|
||||
_ => return Err(ParserError::InconsistentEntry)
|
||||
@@ -162,7 +161,7 @@ fn setup_predicate_indicator(mut term: Term) -> Result<PredicateKey, ParserError
|
||||
let name = *terms.pop().unwrap();
|
||||
|
||||
let arity = arity.to_constant().and_then(|c| c.to_integer())
|
||||
.and_then(|n| if !n.is_negative() { n.to_usize() } else { None })
|
||||
.and_then(|n| n.to_usize())
|
||||
.ok_or(ParserError::InvalidModuleExport)?;
|
||||
|
||||
let name = name.to_constant().and_then(|c| c.to_atom())
|
||||
|
||||
Reference in New Issue
Block a user