-
Notifications
You must be signed in to change notification settings - Fork 54
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Min max size functions added #792
Conversation
lib/src/metta/runner/stdlib.metta
Outdated
(@doc min-atom | ||
(@desc "Returns atom with min value in the expression (first argument). Only numbers allowed") | ||
(@params ( | ||
(@param "Expression"))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(@param "Expression"))) | |
(@param "Expression which contains atoms of Number type"))) |
lib/src/metta/runner/stdlib.metta
Outdated
(@doc max-atom | ||
(@desc "Returns atom with max value in the expression (first argument). Only numbers allowed") | ||
(@params ( | ||
(@param "Expression"))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(@param "Expression"))) | |
(@param "Expression which contains atoms of Number type"))) |
(@doc min-atom | ||
(@desc "Returns atom with min value in the expression (first argument). Only numbers allowed") | ||
(@params ( | ||
(@param "Expression"))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(@param "Expression"))) | |
(@param "Expression which contains atoms of Number type"))) |
(@doc max-atom | ||
(@desc "Returns atom with max value in the expression (first argument). Only numbers allowed") | ||
(@params ( | ||
(@param "Expression"))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(@param "Expression"))) | |
(@param "Expression which contains atoms of Number type"))) |
lib/src/metta/runner/stdlib.rs
Outdated
for x in children.iter() { | ||
match AsPrimitive::from_atom(x).as_number() { | ||
None => Err(ExecError::from("Only numbers allowed in expression")), | ||
_ => Ok({}), | ||
}? | ||
}; | ||
match children.into_iter().map(|x| Into::<f64>::into(AsPrimitive::from_atom(x).as_number().unwrap())).reduce(f64::min) { | ||
Some(min) => Ok(vec![Atom::gnd(Number::Float(min))]), | ||
None => Err(ExecError::from("Empty expression")), | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- One doesn't need to iterate through children twice,
fold
allows doing this in one step Into::<>
is needed only when compiler cannot inference the proper type from context, here it is not needed
I would suggest replacing code by the following:
for x in children.iter() { | |
match AsPrimitive::from_atom(x).as_number() { | |
None => Err(ExecError::from("Only numbers allowed in expression")), | |
_ => Ok({}), | |
}? | |
}; | |
match children.into_iter().map(|x| Into::<f64>::into(AsPrimitive::from_atom(x).as_number().unwrap())).reduce(f64::min) { | |
Some(min) => Ok(vec![Atom::gnd(Number::Float(min))]), | |
None => Err(ExecError::from("Empty expression")), | |
} | |
if children.is_empty() { | |
Err(ExecError::from("Empty expression")) | |
} else { | |
children.into_iter().fold(Ok(f64::INFINITY), |res, x| { | |
match (res, AsPrimitive::from_atom(x).as_number()) { | |
(res @ Err(_), _) => res, | |
(_, None) => Err(ExecError::from("Only numbers are allowed in expression")), | |
(Ok(min), Some(x)) => Ok(f64::min(min, x.into())), | |
} | |
}) | |
}.map(|min| vec![Atom::gnd(Number::Float(min))]) |
lib/src/metta/runner/stdlib.rs
Outdated
|
||
impl Grounded for MaxAtomOp { | ||
fn type_(&self) -> Atom { | ||
Atom::expr([ARROW_SYMBOL, ATOM_TYPE_EXPRESSION, ATOM_TYPE_ATOM]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Atom::expr([ARROW_SYMBOL, ATOM_TYPE_EXPRESSION, ATOM_TYPE_ATOM]) | |
Atom::expr([ARROW_SYMBOL, ATOM_TYPE_EXPRESSION, ATOM_TYPE_NUMBER]) |
lib/src/metta/runner/stdlib.rs
Outdated
let res = MinAtomOp{}.execute(&mut vec![expr!({Number::Integer(5)} {Number::Integer(4)} {Number::Float(5.5)})]).expect("No result returned"); | ||
assert_eq!(res, vec![expr!({Number::Integer(4)})]); | ||
let res = MinAtomOp{}.execute(&mut vec![expr!({Number::Integer(5)} {Number::Integer(4)} "A")]); | ||
assert_eq!(res, Err(ExecError::from("Only numbers allowed in expression"))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assert_eq!(res, Err(ExecError::from("Only numbers allowed in expression"))); | |
assert_eq!(res, Err(ExecError::from("Only numbers are allowed in expression"))); |
lib/src/metta/runner/stdlib.rs
Outdated
let res = MaxAtomOp{}.execute(&mut vec![expr!({Number::Integer(5)} {Number::Integer(4)} {Number::Float(5.5)})]).expect("No result returned"); | ||
assert_eq!(res, vec![expr!({Number::Float(5.5)})]); | ||
let res = MaxAtomOp{}.execute(&mut vec![expr!({Number::Integer(5)} {Number::Integer(4)} "A")]); | ||
assert_eq!(res, Err(ExecError::from("Only numbers allowed in expression"))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assert_eq!(res, Err(ExecError::from("Only numbers allowed in expression"))); | |
assert_eq!(res, Err(ExecError::from("Only numbers are allowed in expression"))); |
fn metta_max_atom() { | ||
assert_eq!(run_program(&format!("!(max-atom (5 4 5.5))")), Ok(vec![vec![expr!({Number::Float(5.5)})]])); | ||
assert_eq!(run_program(&format!("!(max-atom ())")), Ok(vec![vec![expr!("Error" ({ stdlib::MaxAtomOp{} } ()) "Empty expression")]])); | ||
assert_eq!(run_program(&format!("!(max-atom (3 A B 5))")), Ok(vec![vec![expr!("Error" ({ stdlib::MaxAtomOp{} } ({Number::Integer(3)} "A" "B" {Number::Integer(5)})) "Only numbers allowed in expression")]])); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assert_eq!(run_program(&format!("!(max-atom (3 A B 5))")), Ok(vec![vec![expr!("Error" ({ stdlib::MaxAtomOp{} } ({Number::Integer(3)} "A" "B" {Number::Integer(5)})) "Only numbers allowed in expression")]])); | |
assert_eq!(run_program(&format!("!(max-atom (3 A B 5))")), Ok(vec![vec![expr!("Error" ({ stdlib::MaxAtomOp{} } ({Number::Integer(3)} "A" "B" {Number::Integer(5)})) "Only numbers are allowed in expression")]])); |
fn metta_min_atom() { | ||
assert_eq!(run_program(&format!("!(min-atom (5 4 5.5))")), Ok(vec![vec![expr!({Number::Integer(4)})]])); | ||
assert_eq!(run_program(&format!("!(min-atom ())")), Ok(vec![vec![expr!("Error" ({ stdlib::MinAtomOp{} } ()) "Empty expression")]])); | ||
assert_eq!(run_program(&format!("!(min-atom (3 A B 5))")), Ok(vec![vec![expr!("Error" ({ stdlib::MinAtomOp{} } ({Number::Integer(3)} "A" "B" {Number::Integer(5)})) "Only numbers allowed in expression")]])); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assert_eq!(run_program(&format!("!(min-atom (3 A B 5))")), Ok(vec![vec![expr!("Error" ({ stdlib::MinAtomOp{} } ({Number::Integer(3)} "A" "B" {Number::Integer(5)})) "Only numbers allowed in expression")]])); | |
assert_eq!(run_program(&format!("!(min-atom (3 A B 5))")), Ok(vec![vec![expr!("Error" ({ stdlib::MinAtomOp{} } ({Number::Integer(3)} "A" "B" {Number::Integer(5)})) "Only numbers are allowed in expression")]])); |
Overall looks good to me, added some suggestions for documentation and code change to eliminate double iteration through expression. |
…ental into min_max_size
Thanks for the code changes, now it looks much better. I've pushed those changes. |
So, I've added three functions: size-atom, max-atom and min-atom. Works as supposed by the name:
!(size-atom (5 4 3))
[3]
!(max-atom (4 3 4.4))
[4.4]
!(min-atom (3 5 2.9))
[2.9]
Documentation and tests are also added.