-
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
Changes from 4 commits
dd00140
812154e
9eb027b
7ca3db4
bbc8cca
726194a
bfb15e0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -415,6 +415,24 @@ | |||||
(@param "Tail of an expression"))) | ||||||
(@return "New expression consists of two input arguments")) | ||||||
|
||||||
(@doc min-atom | ||||||
(@desc "Returns atom with min value in the expression (first argument). Only numbers allowed") | ||||||
(@params ( | ||||||
(@param "Expression"))) | ||||||
(@return "Min value in the expression. Error if expression contains non-numeric value or is empty")) | ||||||
|
||||||
(@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 commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
(@return "Max value in the expression. Error if expression contains non-numeric value or is empty")) | ||||||
|
||||||
(@doc size-atom | ||||||
(@desc "Returns size of an expression (first argument)") | ||||||
(@params ( | ||||||
(@param "Expression"))) | ||||||
(@return "Size of an expression")) | ||||||
|
||||||
(@doc index-atom | ||||||
(@desc "Returns atom from an expression (first argument) using index (second argument) or error if index is out of bounds") | ||||||
(@params ( | ||||||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -1161,6 +1161,94 @@ impl CustomExecute for IntersectionAtomOp { | |||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
#[derive(Clone, Debug)] | ||||||||||||||||||||||||||||||||||||||||||||
pub struct MaxAtomOp {} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
grounded_op!(MaxAtomOp, "max-atom"); | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
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 commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
fn as_execute(&self) -> Option<&dyn CustomExecute> { | ||||||||||||||||||||||||||||||||||||||||||||
Some(self) | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
impl CustomExecute for MaxAtomOp { | ||||||||||||||||||||||||||||||||||||||||||||
fn execute(&self, args: &[Atom]) -> Result<Vec<Atom>, ExecError> { | ||||||||||||||||||||||||||||||||||||||||||||
let arg_error = || ExecError::from("max-atom expects one argument: expression"); | ||||||||||||||||||||||||||||||||||||||||||||
let children = TryInto::<&ExpressionAtom>::try_into(args.get(0).ok_or_else(arg_error)?)?.children(); | ||||||||||||||||||||||||||||||||||||||||||||
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::max) { | ||||||||||||||||||||||||||||||||||||||||||||
Some(max) => Ok(vec![Atom::gnd(Number::Float(max))]), | ||||||||||||||||||||||||||||||||||||||||||||
None => Err(ExecError::from("Empty expression")), | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
#[derive(Clone, Debug)] | ||||||||||||||||||||||||||||||||||||||||||||
pub struct MinAtomOp {} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
grounded_op!(MinAtomOp, "min-atom"); | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
impl Grounded for MinAtomOp { | ||||||||||||||||||||||||||||||||||||||||||||
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 commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
fn as_execute(&self) -> Option<&dyn CustomExecute> { | ||||||||||||||||||||||||||||||||||||||||||||
Some(self) | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
impl CustomExecute for MinAtomOp { | ||||||||||||||||||||||||||||||||||||||||||||
fn execute(&self, args: &[Atom]) -> Result<Vec<Atom>, ExecError> { | ||||||||||||||||||||||||||||||||||||||||||||
let arg_error = || ExecError::from("min-atom expects one argument: expression"); | ||||||||||||||||||||||||||||||||||||||||||||
let children = TryInto::<&ExpressionAtom>::try_into(args.get(0).ok_or_else(arg_error)?)?.children(); | ||||||||||||||||||||||||||||||||||||||||||||
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 commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
#[derive(Clone, Debug)] | ||||||||||||||||||||||||||||||||||||||||||||
pub struct SizeAtomOp {} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
grounded_op!(SizeAtomOp, "size-atom"); | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
impl Grounded for SizeAtomOp { | ||||||||||||||||||||||||||||||||||||||||||||
fn type_(&self) -> Atom { | ||||||||||||||||||||||||||||||||||||||||||||
Atom::expr([ARROW_SYMBOL, ATOM_TYPE_EXPRESSION, ATOM_TYPE_NUMBER]) | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
fn as_execute(&self) -> Option<&dyn CustomExecute> { | ||||||||||||||||||||||||||||||||||||||||||||
Some(self) | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
impl CustomExecute for SizeAtomOp { | ||||||||||||||||||||||||||||||||||||||||||||
fn execute(&self, args: &[Atom]) -> Result<Vec<Atom>, ExecError> { | ||||||||||||||||||||||||||||||||||||||||||||
let arg_error = || ExecError::from("size-atom expects one argument: expression"); | ||||||||||||||||||||||||||||||||||||||||||||
let children = TryInto::<&ExpressionAtom>::try_into(args.get(0).ok_or_else(arg_error)?)?.children(); | ||||||||||||||||||||||||||||||||||||||||||||
let size = children.len(); | ||||||||||||||||||||||||||||||||||||||||||||
Ok(vec![Atom::gnd(Number::Integer(size as i64))]) | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
#[derive(Clone, Debug)] | ||||||||||||||||||||||||||||||||||||||||||||
pub struct IndexAtomOp {} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
|
@@ -1829,6 +1917,12 @@ mod non_minimal_only_stdlib { | |||||||||||||||||||||||||||||||||||||||||||
tref.register_token(regex(r"cdr-atom"), move |_| { cdr_atom_op.clone() }); | ||||||||||||||||||||||||||||||||||||||||||||
let cons_atom_op = Atom::gnd(ConsAtomOp{}); | ||||||||||||||||||||||||||||||||||||||||||||
tref.register_token(regex(r"cons-atom"), move |_| { cons_atom_op.clone() }); | ||||||||||||||||||||||||||||||||||||||||||||
let max_atom_op = Atom::gnd(MaxAtomOp{}); | ||||||||||||||||||||||||||||||||||||||||||||
tref.register_token(regex(r"max-atom"), move |_| { max_atom_op.clone() }); | ||||||||||||||||||||||||||||||||||||||||||||
let min_atom_op = Atom::gnd(MinAtomOp{}); | ||||||||||||||||||||||||||||||||||||||||||||
tref.register_token(regex(r"min-atom"), move |_| { min_atom_op.clone() }); | ||||||||||||||||||||||||||||||||||||||||||||
let size_atom_op = Atom::gnd(SizeAtomOp{}); | ||||||||||||||||||||||||||||||||||||||||||||
tref.register_token(regex(r"size-atom"), move |_| { size_atom_op.clone() }); | ||||||||||||||||||||||||||||||||||||||||||||
let index_atom_op = Atom::gnd(IndexAtomOp{}); | ||||||||||||||||||||||||||||||||||||||||||||
tref.register_token(regex(r"index-atom"), move |_| { index_atom_op.clone() }); | ||||||||||||||||||||||||||||||||||||||||||||
let random_int_op = Atom::gnd(RandomIntOp{}); | ||||||||||||||||||||||||||||||||||||||||||||
|
@@ -2122,6 +2216,34 @@ mod tests { | |||||||||||||||||||||||||||||||||||||||||||
assert_eq!(res, vec![expr!(("A" "F") ("B" "C") "D")]); | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
#[test] | ||||||||||||||||||||||||||||||||||||||||||||
fn size_atom_op() { | ||||||||||||||||||||||||||||||||||||||||||||
let res = SizeAtomOp{}.execute(&mut vec![expr!({Number::Integer(5)} {Number::Integer(4)} {Number::Integer(3)} {Number::Integer(2)} {Number::Integer(1)})]).expect("No result returned"); | ||||||||||||||||||||||||||||||||||||||||||||
assert_eq!(res, vec![expr!({Number::Integer(5)})]); | ||||||||||||||||||||||||||||||||||||||||||||
let res = SizeAtomOp{}.execute(&mut vec![expr!()]).expect("No result returned"); | ||||||||||||||||||||||||||||||||||||||||||||
assert_eq!(res, vec![expr!({Number::Integer(0)})]); | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
#[test] | ||||||||||||||||||||||||||||||||||||||||||||
fn min_atom_op() { | ||||||||||||||||||||||||||||||||||||||||||||
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 commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||
let res = MinAtomOp{}.execute(&mut vec![expr!()]); | ||||||||||||||||||||||||||||||||||||||||||||
assert_eq!(res, Err(ExecError::from("Empty expression"))); | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
#[test] | ||||||||||||||||||||||||||||||||||||||||||||
fn max_atom_op() { | ||||||||||||||||||||||||||||||||||||||||||||
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 commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||
let res = MaxAtomOp{}.execute(&mut vec![expr!()]); | ||||||||||||||||||||||||||||||||||||||||||||
assert_eq!(res, Err(ExecError::from("Empty expression"))); | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
#[test] | ||||||||||||||||||||||||||||||||||||||||||||
fn index_atom_op() { | ||||||||||||||||||||||||||||||||||||||||||||
let res = IndexAtomOp{}.execute(&mut vec![expr!({Number::Integer(5)} {Number::Integer(4)} {Number::Integer(3)} {Number::Integer(2)} {Number::Integer(1)}), expr!({Number::Integer(2)})]).expect("No result returned"); | ||||||||||||||||||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -72,6 +72,24 @@ | |||||
(@return "Deconsed expression")) | ||||||
(: decons-atom (-> Expression Expression)) | ||||||
|
||||||
(@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 commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
(@return "Min value in the expression. Error if expression contains non-numeric value or is empty")) | ||||||
|
||||||
(@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 commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
(@return "Max value in the expression. Error if expression contains non-numeric value or is empty")) | ||||||
|
||||||
(@doc size-atom | ||||||
(@desc "Returns size of an expression (first argument)") | ||||||
(@params ( | ||||||
(@param "Expression"))) | ||||||
(@return "Size of an expression")) | ||||||
|
||||||
(@doc index-atom | ||||||
(@desc "Returns atom from an expression (first argument) using index (second argument) or error if index is out of bounds") | ||||||
(@params ( | ||||||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -432,6 +432,12 @@ pub fn register_common_tokens(tref: &mut Tokenizer, _tokenizer: Shared<Tokenizer | |||||
tref.register_token(regex(r"nop"), move |_| { nop_op.clone() }); | ||||||
let match_op = Atom::gnd(stdlib::MatchOp{}); | ||||||
tref.register_token(regex(r"match"), move |_| { match_op.clone() }); | ||||||
let min_atom_op = Atom::gnd(stdlib::MinAtomOp{}); | ||||||
tref.register_token(regex(r"min-atom"), move |_| { min_atom_op.clone() }); | ||||||
let max_atom_op = Atom::gnd(stdlib::MaxAtomOp{}); | ||||||
tref.register_token(regex(r"max-atom"), move |_| { max_atom_op.clone() }); | ||||||
let size_atom_op = Atom::gnd(stdlib::SizeAtomOp{}); | ||||||
tref.register_token(regex(r"size-atom"), move |_| { size_atom_op.clone() }); | ||||||
let index_atom_op = Atom::gnd(stdlib::IndexAtomOp{}); | ||||||
tref.register_token(regex(r"index-atom"), move |_| { index_atom_op.clone() }); | ||||||
let random_int_op = Atom::gnd(stdlib::RandomIntOp{}); | ||||||
|
@@ -621,6 +627,26 @@ mod tests { | |||||
assert_eq!(run_program(&format!("!(cdr-atom $a)")), Ok(vec![vec![expr!("Error" ("cdr-atom" a) {Str::from_str("cdr-atom expects a non-empty expression as an argument")})]])); | ||||||
} | ||||||
|
||||||
#[test] | ||||||
fn metta_size_atom() { | ||||||
assert_eq!(run_program(&format!("!(size-atom (5 4 3 2 1))")), Ok(vec![vec![expr!({Number::Integer(5)})]])); | ||||||
assert_eq!(run_program(&format!("!(size-atom ())")), Ok(vec![vec![expr!({Number::Integer(0)})]])); | ||||||
} | ||||||
|
||||||
#[test] | ||||||
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 commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
} | ||||||
|
||||||
#[test] | ||||||
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 commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
} | ||||||
|
||||||
#[test] | ||||||
fn metta_index_atom() { | ||||||
assert_eq!(run_program(&format!("!(index-atom (5 4 3 2 1) 2)")), Ok(vec![vec![expr!({Number::Integer(3)})]])); | ||||||
|
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.