From: Mark Thom Date: Mon, 13 May 2019 22:11:27 +0000 (-0400) Subject: fix min/1, max/1 X-Git-Tag: v0.8.110~60 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=d5223b9bbd658e8d7cfd402d0a2c5f1e7dea1a78;p=scryer-prolog.git fix min/1, max/1 --- diff --git a/Cargo.toml b/Cargo.toml index 4fe658dc..72ea5275 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "scryer-prolog" -version = "0.8.82" +version = "0.8.83" authors = ["Mark Thom "] repository = "https://github.com/mthom/scryer-prolog" description = "A modern Prolog implementation written mostly in Rust." diff --git a/README.md b/README.md index 721d2f34..4982068f 100644 --- a/README.md +++ b/README.md @@ -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` diff --git a/src/prolog/machine/machine_state_impl.rs b/src/prolog/machine/machine_state_impl.rs index c378a54f..1cfbf9ad 100644 --- a/src/prolog/machine/machine_state_impl.rs +++ b/src/prolog/machine/machine_state_impl.rs @@ -1290,11 +1290,41 @@ impl MachineState { } fn max(&self, n1: Number, n2: Number) -> Result { - 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 { - 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