The following predicates are built-in to Scryer.
* Arithmetic support:
- * `is/2` works for `(+)/2`, `(-)/{1,2}`, `(*)/2`, `(//)/2`,
- `(**)/2`, `(^)/2`, `(div)/2`, `(/)/2`, `(rdiv)/2`, `(xor)/2`,
- `(rem)/2`, `(mod)/2`, `(/\)/2`, `(\/)/2`, `(>>)/2`,`(<<)/2`,
- `(\)/1`, `abs/1`, `sin/1`, `cos/1`, `tan/1`, `asin/1`, `acos/1`,
+ * `is/2` works for `(+)/{1,2}`, `(-)/{1,2}`, `(*)/2`, `(//)/2`, `(**)/2`,
+ `(^)/2`, `(div)/2`, `(/)/2`, `(rdiv)/2`, `(xor)/2`, `(rem)/2`,
+ `(mod)/2`, `(/\)/2`, `(\/)/2`, `(>>)/2`,`(<<)/2`, `(\)/1`,
+ `abs/1`, `sin/1`, `cos/1`, `tan/1`, `asin/1`, `acos/1`,
`atan/1`, `atan2/2`, `log/1`, `exp/1`, `sqrt/1`, `float/1`,
- `truncate/1`, `round/1`, `floor/1`, `ceiling/1`, `pi/0`
+ `truncate/1`, `round/1`, `floor/1`, `ceiling/1`, `pi/0`,
+ `min/1`, `max/1`
* Comparison operators: `>`, `<`, `=<`, `>=`, `=:=`, `=\=`.
* `(:)/2`
* `(@>)/2`
}
fn max(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
- Ok(max(n1, n2))
+ match (n1, n2) {
+ (Number::Integer(n1), Number::Integer(n2)) =>
+ if n1 > n2 {
+ Ok(Number::Integer(n1))
+ } else {
+ Ok(Number::Integer(n2))
+ },
+ (n1, n2) => {
+ let stub = MachineError::functor_stub(clause_name!("max"), 2);
+
+ let f1 = try_numeric_result!(self, result_f(n1, rnd_f), stub.clone())?;
+ let f2 = try_numeric_result!(self, result_f(n2, rnd_f), stub)?;
+
+ Ok(Number::Float(max(OrderedFloat(f1), OrderedFloat(f2))))
+ }
+ }
}
fn min(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
- Ok(min(n1, n2))
+ match (n1, n2) {
+ (Number::Integer(n1), Number::Integer(n2)) =>
+ if n1 < n2 {
+ Ok(Number::Integer(n1))
+ } else {
+ Ok(Number::Integer(n2))
+ },
+ (n1, n2) => {
+ let stub = MachineError::functor_stub(clause_name!("max"), 2);
+
+ let f1 = try_numeric_result!(self, result_f(n1, rnd_f), stub.clone())?;
+ let f2 = try_numeric_result!(self, result_f(n2, rnd_f), stub)?;
+
+ Ok(Number::Float(min(OrderedFloat(f1), OrderedFloat(f2))))
+ }
+ }
}
fn remainder(&self, n1: Number, n2: Number) -> Result<Integer, MachineStub>