fix min/1, max/1

This commit is contained in:
Mark Thom
2019-05-13 18:11:27 -04:00
parent 59ab4cd67c
commit d5223b9bbd
3 changed files with 39 additions and 8 deletions

View File

@@ -1,6 +1,6 @@
[package]
name = "scryer-prolog"
version = "0.8.82"
version = "0.8.83"
authors = ["Mark Thom <markjordanthom@gmail.com>"]
repository = "https://github.com/mthom/scryer-prolog"
description = "A modern Prolog implementation written mostly in Rust."

View File

@@ -133,12 +133,13 @@ to my knowledge is not currently the case.
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`

View File

@@ -1290,11 +1290,41 @@ impl MachineState {
}
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>