Format code using 'cargo fmt'

This commit is contained in:
Atul Bhosale
2019-09-23 19:35:37 +07:00
parent 8207fdea40
commit 1273e2d52d
36 changed files with 8738 additions and 6375 deletions

View File

@@ -10,60 +10,66 @@ use prolog::machine::machine_errors::*;
use prolog::machine::machine_indices::*;
use prolog::ordered_float::*;
use prolog::rug::{Assign, Integer, Rational};
use prolog::rug::ops::PowAssign;
use prolog::rug::{Assign, Integer, Rational};
use std::cell::Cell;
use std::cmp::{Ordering, min, max};
use std::cmp::{max, min, Ordering};
use std::f64;
use std::num::FpCategory;
use std::ops::{Add, Sub, Div, Mul, Neg};
use std::ops::{Add, Div, Mul, Neg, Sub};
use std::rc::Rc;
use std::vec::Vec;
pub struct ArithInstructionIterator<'a> {
state_stack: Vec<TermIterState<'a>>
state_stack: Vec<TermIterState<'a>>,
}
pub type ArithCont = (Code, 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));
self.state_stack
.push(TermIterState::subterm_to_state(lvl, term));
}
fn new(term: &'a Term) -> Result<Self, ArithmeticError> {
let state = match term {
&Term::AnonVar =>
return Err(ArithmeticError::UninstantiatedVar),
&Term::Clause(ref cell, ref name, ref terms, ref fixity) =>
&Term::AnonVar => return Err(ArithmeticError::UninstantiatedVar),
&Term::Clause(ref cell, ref name, ref terms, ref fixity) => {
match ClauseType::from(name.clone(), terms.len(), fixity.clone()) {
ct @ ClauseType::Named(..) | ct @ ClauseType::Op(..) =>
Ok(TermIterState::Clause(Level::Shallow, 0, cell, ct, terms)),
ct @ ClauseType::Named(..) | ct @ ClauseType::Op(..) => {
Ok(TermIterState::Clause(Level::Shallow, 0, cell, ct, terms))
}
ClauseType::Inlined(InlinedClauseType::IsFloat(_)) => {
let ct = ClauseType::Named(clause_name!("float"), 1, CodeIndex::default());
Ok(TermIterState::Clause(Level::Shallow, 0, cell, ct, terms))
},
_ => Err(ArithmeticError::NonEvaluableFunctor(Constant::Atom(name.clone(),
fixity.clone()),
terms.len()))
}?,
&Term::Constant(ref cell, ref cons) =>
TermIterState::Constant(Level::Shallow, cell, cons),
&Term::Cons(_, _, _) =>
return Err(ArithmeticError::NonEvaluableFunctor(atom!("'.'"), 2)),
&Term::Var(ref cell, ref var) =>
TermIterState::Var(Level::Shallow, cell, var.clone())
}
_ => Err(ArithmeticError::NonEvaluableFunctor(
Constant::Atom(name.clone(), fixity.clone()),
terms.len(),
)),
}?
}
&Term::Constant(ref cell, ref cons) => {
TermIterState::Constant(Level::Shallow, cell, cons)
}
&Term::Cons(_, _, _) => {
return Err(ArithmeticError::NonEvaluableFunctor(atom!("'.'"), 2))
}
&Term::Var(ref cell, ref var) => TermIterState::Var(Level::Shallow, cell, var.clone()),
};
Ok(ArithInstructionIterator { state_stack: vec![state] })
Ok(ArithInstructionIterator {
state_stack: vec![state],
})
}
}
pub enum ArithTermRef<'a> {
Constant(&'a Constant),
Op(ClauseName, usize), // name, arity.
Var(&'a Cell<VarReg>, Rc<Var>)
Var(&'a Cell<VarReg>, Rc<Var>),
}
impl<'a> Iterator for ArithInstructionIterator<'a> {
@@ -72,24 +78,28 @@ impl<'a> Iterator for ArithInstructionIterator<'a> {
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::AnonVar(_) => return Some(Err(ArithmeticError::UninstantiatedVar)),
TermIterState::Clause(lvl, child_num, cell, ct, subterms) => {
let arity = subterms.len();
if child_num == arity {
return Some(Ok(ArithTermRef::Op(ct.name(), arity)));
} else {
self.state_stack.push(TermIterState::Clause(lvl, child_num + 1, cell, ct, subterms));
self.state_stack.push(TermIterState::Clause(
lvl,
child_num + 1,
cell,
ct,
subterms,
));
self.push_subterm(lvl, subterms[child_num].as_ref());
}
},
TermIterState::Constant(_, _, c) =>
return Some(Ok(ArithTermRef::Constant(c))),
TermIterState::Var(_, cell, var) =>
return Some(Ok(ArithTermRef::Var(cell, var.clone()))),
_ =>
return Some(Err(ArithmeticError::NonEvaluableFunctor(atom!("'.'"), 2)))
}
TermIterState::Constant(_, _, c) => return Some(Ok(ArithTermRef::Constant(c))),
TermIterState::Var(_, cell, var) => {
return Some(Ok(ArithTermRef::Var(cell, var.clone())))
}
_ => return Some(Err(ArithmeticError::NonEvaluableFunctor(atom!("'.'"), 2))),
};
}
@@ -100,11 +110,11 @@ impl<'a> Iterator for ArithInstructionIterator<'a> {
pub struct ArithmeticEvaluator<'a> {
bindings: &'a AllocVarDict,
interm: Vec<ArithmeticTerm>,
interm_c: usize
interm_c: usize,
}
pub trait ArithmeticTermIter<'a> {
type Iter : Iterator<Item=Result<ArithTermRef<'a>, ArithmeticError>>;
type Iter: Iterator<Item = Result<ArithTermRef<'a>, ArithmeticError>>;
fn iter(self) -> Result<Self::Iter, ArithmeticError>;
}
@@ -117,15 +127,20 @@ impl<'a> ArithmeticTermIter<'a> for &'a Term {
}
}
impl<'a> ArithmeticEvaluator<'a>
{
impl<'a> ArithmeticEvaluator<'a> {
pub fn new(bindings: &'a AllocVarDict, target_int: usize) -> Self {
ArithmeticEvaluator { bindings, interm: Vec::new(), interm_c: target_int }
ArithmeticEvaluator {
bindings,
interm: Vec::new(),
interm_c: target_int,
}
}
fn get_unary_instr(name: ClauseName, a1: ArithmeticTerm, t: usize)
-> Result<ArithmeticInstruction, ArithmeticError>
{
fn get_unary_instr(
name: ClauseName,
a1: ArithmeticTerm,
t: usize,
) -> Result<ArithmeticInstruction, ArithmeticError> {
match name.as_str() {
"abs" => Ok(ArithmeticInstruction::Abs(a1, t)),
"-" => Ok(ArithmeticInstruction::Neg(a1, t)),
@@ -145,34 +160,43 @@ impl<'a> ArithmeticEvaluator<'a>
"ceiling" => Ok(ArithmeticInstruction::Ceiling(a1, t)),
"floor" => Ok(ArithmeticInstruction::Floor(a1, t)),
"\\" => Ok(ArithmeticInstruction::BitwiseComplement(a1, t)),
_ => Err(ArithmeticError::NonEvaluableFunctor(Constant::Atom(name, None), 1))
_ => Err(ArithmeticError::NonEvaluableFunctor(
Constant::Atom(name, None),
1,
)),
}
}
fn get_binary_instr(name: ClauseName, a1: ArithmeticTerm, a2: ArithmeticTerm, t: usize)
-> Result<ArithmeticInstruction, ArithmeticError>
{
fn get_binary_instr(
name: ClauseName,
a1: ArithmeticTerm,
a2: ArithmeticTerm,
t: usize,
) -> Result<ArithmeticInstruction, ArithmeticError> {
match name.as_str() {
"+" => Ok(ArithmeticInstruction::Add(a1, a2, t)),
"-" => Ok(ArithmeticInstruction::Sub(a1, a2, t)),
"/" => Ok(ArithmeticInstruction::Div(a1, a2, t)),
"//" => Ok(ArithmeticInstruction::IDiv(a1, a2, t)),
"max" => Ok(ArithmeticInstruction::Max(a1, a2, t)),
"min" => Ok(ArithmeticInstruction::Min(a1, a2, t)),
"div" => Ok(ArithmeticInstruction::IntFloorDiv(a1, a2, t)),
"+" => Ok(ArithmeticInstruction::Add(a1, a2, t)),
"-" => Ok(ArithmeticInstruction::Sub(a1, a2, t)),
"/" => Ok(ArithmeticInstruction::Div(a1, a2, t)),
"//" => Ok(ArithmeticInstruction::IDiv(a1, a2, t)),
"max" => Ok(ArithmeticInstruction::Max(a1, a2, t)),
"min" => Ok(ArithmeticInstruction::Min(a1, a2, t)),
"div" => Ok(ArithmeticInstruction::IntFloorDiv(a1, a2, t)),
"rdiv" => Ok(ArithmeticInstruction::RDiv(a1, a2, t)),
"*" => Ok(ArithmeticInstruction::Mul(a1, a2, t)),
"**" => Ok(ArithmeticInstruction::Pow(a1, a2, t)),
"^" => Ok(ArithmeticInstruction::IntPow(a1, a2, t)),
">>" => Ok(ArithmeticInstruction::Shr(a1, a2, t)),
"<<" => Ok(ArithmeticInstruction::Shl(a1, a2, t)),
"/\\" => Ok(ArithmeticInstruction::And(a1, a2, t)),
"\\/" => Ok(ArithmeticInstruction::Or(a1, a2, t)),
"xor" => Ok(ArithmeticInstruction::Xor(a1, a2, t)),
"mod" => Ok(ArithmeticInstruction::Mod(a1, a2, t)),
"rem" => Ok(ArithmeticInstruction::Rem(a1, a2, t)),
"*" => Ok(ArithmeticInstruction::Mul(a1, a2, t)),
"**" => Ok(ArithmeticInstruction::Pow(a1, a2, t)),
"^" => Ok(ArithmeticInstruction::IntPow(a1, a2, t)),
">>" => Ok(ArithmeticInstruction::Shr(a1, a2, t)),
"<<" => Ok(ArithmeticInstruction::Shl(a1, a2, t)),
"/\\" => Ok(ArithmeticInstruction::And(a1, a2, t)),
"\\/" => Ok(ArithmeticInstruction::Or(a1, a2, t)),
"xor" => Ok(ArithmeticInstruction::Xor(a1, a2, t)),
"mod" => Ok(ArithmeticInstruction::Mod(a1, a2, t)),
"rem" => Ok(ArithmeticInstruction::Rem(a1, a2, t)),
"atan2" => Ok(ArithmeticInstruction::ATan2(a1, a2, t)),
_ => Err(ArithmeticError::NonEvaluableFunctor(Constant::Atom(name, None), 2))
_ => Err(ArithmeticError::NonEvaluableFunctor(
Constant::Atom(name, None),
2,
)),
}
}
@@ -185,9 +209,11 @@ impl<'a> ArithmeticEvaluator<'a>
temp
}
fn instr_from_clause(&mut self, name: ClauseName, arity: usize)
-> Result<ArithmeticInstruction, ArithmeticError>
{
fn instr_from_clause(
&mut self,
name: ClauseName,
arity: usize,
) -> Result<ArithmeticInstruction, ArithmeticError> {
match arity {
1 => {
let a1 = self.interm.pop().unwrap();
@@ -200,7 +226,7 @@ impl<'a> ArithmeticEvaluator<'a>
};
Self::get_unary_instr(name, a1, ninterm)
},
}
2 => {
let a2 = self.interm.pop().unwrap();
let a1 = self.interm.pop().unwrap();
@@ -224,35 +250,44 @@ impl<'a> ArithmeticEvaluator<'a>
};
Self::get_binary_instr(name, a1, a2, ninterm)
},
_ => Err(ArithmeticError::NonEvaluableFunctor(Constant::Atom(name, None), arity))
}
_ => Err(ArithmeticError::NonEvaluableFunctor(
Constant::Atom(name, None),
arity,
)),
}
}
fn push_constant(&mut self, c: &Constant) -> Result<(), ArithmeticError> {
match c {
&Constant::Integer(ref n) =>
self.interm.push(ArithmeticTerm::Number(Number::Integer(n.clone()))),
&Constant::Float(ref n) =>
self.interm.push(ArithmeticTerm::Number(Number::Float(n.clone()))),
&Constant::Rational(ref n) =>
self.interm.push(ArithmeticTerm::Number(Number::Rational(n.clone()))),
&Constant::Atom(ref name, _) if name.as_str() == "pi" =>
self.interm.push(ArithmeticTerm::Number(Number::Float(OrderedFloat(f64::consts::PI)))),
_ =>
return Err(ArithmeticError::NonEvaluableFunctor(c.clone(), 0))
&Constant::Integer(ref n) => self
.interm
.push(ArithmeticTerm::Number(Number::Integer(n.clone()))),
&Constant::Float(ref n) => self
.interm
.push(ArithmeticTerm::Number(Number::Float(n.clone()))),
&Constant::Rational(ref n) => self
.interm
.push(ArithmeticTerm::Number(Number::Rational(n.clone()))),
&Constant::Atom(ref name, _) if name.as_str() == "pi" => {
self.interm
.push(ArithmeticTerm::Number(Number::Float(OrderedFloat(
f64::consts::PI,
))))
}
_ => return Err(ArithmeticError::NonEvaluableFunctor(c.clone(), 0)),
}
Ok(())
}
pub fn eval<Iter>(&mut self, src: Iter) -> Result<ArithCont, ArithmeticError>
where Iter: ArithmeticTermIter<'a>
where
Iter: ArithmeticTermIter<'a>,
{
let mut code = vec![];
for term_ref in src.iter()?
{
for term_ref in src.iter()? {
match term_ref? {
ArithTermRef::Constant(c) => self.push_constant(c)?,
ArithTermRef::Var(cell, name) => {
@@ -260,14 +295,14 @@ impl<'a> ArithmeticEvaluator<'a>
match self.bindings.get(&name) {
Some(&VarData::Temp(_, t, _)) if t != 0 => RegType::Temp(t),
Some(&VarData::Perm(p)) if p != 0 => RegType::Perm(p),
_ => return Err(ArithmeticError::UninstantiatedVar)
_ => return Err(ArithmeticError::UninstantiatedVar),
}
} else {
cell.get().norm()
};
self.interm.push(ArithmeticTerm::Reg(r));
},
}
ArithTermRef::Op(name, arity) => {
code.push(Line::Arithmetic(self.instr_from_clause(name, arity)?));
}
@@ -281,10 +316,10 @@ impl<'a> ArithmeticEvaluator<'a>
// integer division rounding function -- 9.1.3.1.
pub fn rnd_i<'a>(n: &'a Number) -> RefOrOwned<'a, Integer> {
match n {
&Number::Integer(ref n) =>
RefOrOwned::Borrowed(n),
&Number::Float(OrderedFloat(f)) =>
RefOrOwned::Owned(Integer::from_f64(f.floor()).unwrap_or_else(|| Integer::from(0))),
&Number::Integer(ref n) => RefOrOwned::Borrowed(n),
&Number::Float(OrderedFloat(f)) => {
RefOrOwned::Owned(Integer::from_f64(f.floor()).unwrap_or_else(|| Integer::from(0)))
}
&Number::Rational(ref r) => {
let r_ref = r.fract_floor_ref();
let (mut fract, mut floor) = (Rational::new(), Integer::new());
@@ -300,24 +335,25 @@ pub fn rnd_f(n: &Number) -> f64 {
match n {
&Number::Integer(ref n) => n.to_f64(),
&Number::Float(OrderedFloat(f)) => f,
&Number::Rational(ref r) => r.to_f64()
&Number::Rational(ref r) => r.to_f64(),
}
}
// floating point result function -- 9.1.4.2.
pub fn result_f<Round>(n: &Number, round: Round) -> Result<f64, EvalError>
where Round: Fn(&Number) -> f64
where
Round: Fn(&Number) -> f64,
{
let f = rnd_f(n);
classify_float(f, round)
}
fn classify_float<Round>(f: f64, round: Round) -> Result<f64, EvalError>
where Round: Fn(&Number) -> f64
where
Round: Fn(&Number) -> f64,
{
match f.classify() {
FpCategory::Normal | FpCategory::Zero =>
Ok(round(&Number::Float(OrderedFloat(f)))),
FpCategory::Normal | FpCategory::Zero => Ok(round(&Number::Float(OrderedFloat(f)))),
FpCategory::Infinite => {
let f = round(&Number::Float(OrderedFloat(f)));
@@ -326,9 +362,9 @@ fn classify_float<Round>(f: f64, round: Round) -> Result<f64, EvalError>
} else {
Err(EvalError::FloatOverflow)
}
},
}
FpCategory::Nan => Err(EvalError::Undefined),
_ => Ok(round(&Number::Float(OrderedFloat(f))))
_ => Ok(round(&Number::Float(OrderedFloat(f)))),
}
}
@@ -361,21 +397,23 @@ impl Add<Number> for Number {
fn add(self, rhs: Number) -> Self::Output {
match (self, rhs) {
(Number::Integer(n1), Number::Integer(n2)) =>
Ok(Number::Integer(n1 + n2)), // add_i
(Number::Integer(n1), Number::Integer(n2)) => Ok(Number::Integer(n1 + n2)), // add_i
(Number::Integer(n1), Number::Float(OrderedFloat(n2)))
| (Number::Float(OrderedFloat(n2)), Number::Integer(n1)) =>
Ok(Number::Float(add_f(float_i_to_f(&n1)?, n2)?)),
| (Number::Float(OrderedFloat(n2)), Number::Integer(n1)) => {
Ok(Number::Float(add_f(float_i_to_f(&n1)?, n2)?))
}
(Number::Integer(n1), Number::Rational(n2))
| (Number::Rational(n2), Number::Integer(n1)) =>
Ok(Number::Rational(Rational::from(n1) + n2)),
| (Number::Rational(n2), Number::Integer(n1)) => {
Ok(Number::Rational(Rational::from(n1) + n2))
}
(Number::Rational(n1), Number::Float(OrderedFloat(n2)))
| (Number::Float(OrderedFloat(n2)), Number::Rational(n1)) =>
Ok(Number::Float(add_f(float_r_to_f(&n1)?, n2)?)),
(Number::Float(OrderedFloat(f1)), Number::Float(OrderedFloat(f2))) =>
Ok(Number::Float(add_f(f1, f2)?)),
(Number::Rational(r1), Number::Rational(r2)) =>
Ok(Number::Rational(r1 + r2))
| (Number::Float(OrderedFloat(n2)), Number::Rational(n1)) => {
Ok(Number::Float(add_f(float_r_to_f(&n1)?, n2)?))
}
(Number::Float(OrderedFloat(f1)), Number::Float(OrderedFloat(f2))) => {
Ok(Number::Float(add_f(f1, f2)?))
}
(Number::Rational(r1), Number::Rational(r2)) => Ok(Number::Rational(r1 + r2)),
}
}
}
@@ -387,7 +425,7 @@ impl Neg for Number {
match self {
Number::Integer(n) => Number::Integer(-n),
Number::Float(OrderedFloat(f)) => Number::Float(OrderedFloat(-f)),
Number::Rational(r) => Number::Rational(-r)
Number::Rational(r) => Number::Rational(-r),
}
}
}
@@ -405,21 +443,23 @@ impl Mul<Number> for Number {
fn mul(self, rhs: Number) -> Self::Output {
match (self, rhs) {
(Number::Integer(n1), Number::Integer(n2)) =>
Ok(Number::Integer(n1 * n2)), // mul_i
(Number::Integer(n1), Number::Integer(n2)) => Ok(Number::Integer(n1 * n2)), // mul_i
(Number::Integer(n1), Number::Float(OrderedFloat(n2)))
| (Number::Float(OrderedFloat(n2)), Number::Integer(n1)) =>
Ok(Number::Float(mul_f(float_i_to_f(&n1)?, n2)?)),
| (Number::Float(OrderedFloat(n2)), Number::Integer(n1)) => {
Ok(Number::Float(mul_f(float_i_to_f(&n1)?, n2)?))
}
(Number::Integer(n1), Number::Rational(n2))
| (Number::Rational(n2), Number::Integer(n1)) =>
Ok(Number::Rational(Rational::from(n1) * n2)),
| (Number::Rational(n2), Number::Integer(n1)) => {
Ok(Number::Rational(Rational::from(n1) * n2))
}
(Number::Rational(n1), Number::Float(OrderedFloat(n2)))
| (Number::Float(OrderedFloat(n2)), Number::Rational(n1)) =>
Ok(Number::Float(mul_f(float_r_to_f(&n1)?, n2)?)),
(Number::Float(OrderedFloat(f1)), Number::Float(OrderedFloat(f2))) =>
Ok(Number::Float(mul_f(f1, f2)?)),
(Number::Rational(r1), Number::Rational(r2)) =>
Ok(Number::Rational(r1 * r2))
| (Number::Float(OrderedFloat(n2)), Number::Rational(n1)) => {
Ok(Number::Float(mul_f(float_r_to_f(&n1)?, n2)?))
}
(Number::Float(OrderedFloat(f1)), Number::Float(OrderedFloat(f2))) => {
Ok(Number::Float(mul_f(f1, f2)?))
}
(Number::Rational(r1), Number::Rational(r2)) => Ok(Number::Rational(r1 * r2)),
}
}
}
@@ -429,24 +469,37 @@ impl Div<Number> for Number {
fn div(self, rhs: Number) -> Self::Output {
match (self, rhs) {
(Number::Integer(n1), Number::Integer(n2)) =>
Ok(Number::Float(div_f(float_i_to_f(&n1)?, float_i_to_f(&n2)?)?)),
(Number::Integer(n1), Number::Float(OrderedFloat(n2))) =>
Ok(Number::Float(div_f(float_i_to_f(&n1)?, n2)?)),
(Number::Float(OrderedFloat(n2)), Number::Integer(n1)) =>
Ok(Number::Float(div_f(n2, float_i_to_f(&n1)?)?)),
(Number::Integer(n1), Number::Rational(n2)) =>
Ok(Number::Float(div_f(float_i_to_f(&n1)?, float_r_to_f(&n2)?)?)),
(Number::Rational(n2), Number::Integer(n1)) =>
Ok(Number::Float(div_f(float_r_to_f(&n2)?, float_i_to_f(&n1)?)?)),
(Number::Rational(n1), Number::Float(OrderedFloat(n2))) =>
Ok(Number::Float(div_f(float_r_to_f(&n1)?, n2)?)),
(Number::Float(OrderedFloat(n2)), Number::Rational(n1)) =>
Ok(Number::Float(div_f(n2, float_r_to_f(&n1)?)?)),
(Number::Float(OrderedFloat(f1)), Number::Float(OrderedFloat(f2))) =>
Ok(Number::Float(div_f(f1, f2)?)),
(Number::Rational(r1), Number::Rational(r2)) =>
Ok(Number::Float(div_f(float_r_to_f(&r1)?, float_r_to_f(&r2)?)?))
(Number::Integer(n1), Number::Integer(n2)) => Ok(Number::Float(div_f(
float_i_to_f(&n1)?,
float_i_to_f(&n2)?,
)?)),
(Number::Integer(n1), Number::Float(OrderedFloat(n2))) => {
Ok(Number::Float(div_f(float_i_to_f(&n1)?, n2)?))
}
(Number::Float(OrderedFloat(n2)), Number::Integer(n1)) => {
Ok(Number::Float(div_f(n2, float_i_to_f(&n1)?)?))
}
(Number::Integer(n1), Number::Rational(n2)) => Ok(Number::Float(div_f(
float_i_to_f(&n1)?,
float_r_to_f(&n2)?,
)?)),
(Number::Rational(n2), Number::Integer(n1)) => Ok(Number::Float(div_f(
float_r_to_f(&n2)?,
float_i_to_f(&n1)?,
)?)),
(Number::Rational(n1), Number::Float(OrderedFloat(n2))) => {
Ok(Number::Float(div_f(float_r_to_f(&n1)?, n2)?))
}
(Number::Float(OrderedFloat(n2)), Number::Rational(n1)) => {
Ok(Number::Float(div_f(n2, float_r_to_f(&n1)?)?))
}
(Number::Float(OrderedFloat(f1)), Number::Float(OrderedFloat(f2))) => {
Ok(Number::Float(div_f(f1, f2)?))
}
(Number::Rational(r1), Number::Rational(r2)) => Ok(Number::Float(div_f(
float_r_to_f(&r1)?,
float_r_to_f(&r2)?,
)?)),
}
}
}
@@ -454,24 +507,15 @@ impl Div<Number> for Number {
impl PartialOrd for Number {
fn partial_cmp(&self, rhs: &Number) -> Option<Ordering> {
match (self, rhs) {
(&Number::Integer(ref n1), &Number::Integer(ref n2)) =>
Some(n1.cmp(n2)),
(&Number::Integer(_), Number::Float(_)) =>
Some(Ordering::Greater),
(&Number::Float(_), &Number::Integer(_)) =>
Some(Ordering::Less),
(&Number::Integer(_), &Number::Rational(_)) =>
Some(Ordering::Greater),
(&Number::Rational(_), &Number::Integer(_)) =>
Some(Ordering::Less),
(&Number::Rational(_), Number::Float(_)) =>
Some(Ordering::Greater),
(&Number::Float(_), &Number::Rational(_)) =>
Some(Ordering::Less),
(&Number::Float(f1), &Number::Float(f2)) =>
Some(f1.cmp(&f2)),
(&Number::Rational(ref r1), &Number::Rational(ref r2)) =>
Some(r1.cmp(&r2))
(&Number::Integer(ref n1), &Number::Integer(ref n2)) => Some(n1.cmp(n2)),
(&Number::Integer(_), Number::Float(_)) => Some(Ordering::Greater),
(&Number::Float(_), &Number::Integer(_)) => Some(Ordering::Less),
(&Number::Integer(_), &Number::Rational(_)) => Some(Ordering::Greater),
(&Number::Rational(_), &Number::Integer(_)) => Some(Ordering::Less),
(&Number::Rational(_), Number::Float(_)) => Some(Ordering::Greater),
(&Number::Float(_), &Number::Rational(_)) => Some(Ordering::Less),
(&Number::Float(f1), &Number::Float(f2)) => Some(f1.cmp(&f2)),
(&Number::Rational(ref r1), &Number::Rational(ref r2)) => Some(r1.cmp(&r2)),
}
}
}
@@ -479,31 +523,21 @@ impl PartialOrd for Number {
impl Ord for Number {
fn cmp(&self, rhs: &Number) -> Ordering {
match (self, rhs) {
(&Number::Integer(ref n1), &Number::Integer(ref n2)) =>
n1.cmp(n2),
(&Number::Integer(_), Number::Float(_)) =>
Ordering::Greater,
(&Number::Float(_), &Number::Integer(_)) =>
Ordering::Less,
(&Number::Integer(_), &Number::Rational(_)) =>
Ordering::Greater,
(&Number::Rational(_), &Number::Integer(_)) =>
Ordering::Less,
(&Number::Rational(_), Number::Float(_)) =>
Ordering::Greater,
(&Number::Float(_), &Number::Rational(_)) =>
Ordering::Less,
(&Number::Float(f1), &Number::Float(f2)) =>
f1.cmp(&f2),
(&Number::Rational(ref r1), &Number::Rational(ref r2)) =>
r1.cmp(&r2)
(&Number::Integer(ref n1), &Number::Integer(ref n2)) => n1.cmp(n2),
(&Number::Integer(_), Number::Float(_)) => Ordering::Greater,
(&Number::Float(_), &Number::Integer(_)) => Ordering::Less,
(&Number::Integer(_), &Number::Rational(_)) => Ordering::Greater,
(&Number::Rational(_), &Number::Integer(_)) => Ordering::Less,
(&Number::Rational(_), Number::Float(_)) => Ordering::Greater,
(&Number::Float(_), &Number::Rational(_)) => Ordering::Less,
(&Number::Float(f1), &Number::Float(f2)) => f1.cmp(&f2),
(&Number::Rational(ref r1), &Number::Rational(ref r2)) => r1.cmp(&r2),
}
}
}
// Computes n ^ power. Ignores the sign of power.
pub fn binary_pow(mut n: Integer, power: Integer) -> Integer
{
pub fn binary_pow(mut n: Integer, power: Integer) -> Integer {
let mut power = power.abs();
if power == 0 {