diff --git a/c/src/atom.rs b/c/src/atom.rs index c49d4984a..d9b43e892 100644 --- a/c/src/atom.rs +++ b/c/src/atom.rs @@ -491,7 +491,7 @@ pub unsafe extern "C" fn atom_get_space(atom: *const atom_ref_t) -> space_t { } /// Private convenience function to call an `c_atom_vec_callback_t` callback with each atom in a vec -pub(crate) fn return_atoms(atoms: &Vec, callback: c_atom_vec_callback_t, context: *mut c_void) { +pub(crate) fn return_atoms(atoms: &[Atom], callback: c_atom_vec_callback_t, context: *mut c_void) { callback(&(&atoms[..]).into(), context); } diff --git a/c/src/metta.rs b/c/src/metta.rs index 1e59ed170..0c8595b8a 100644 --- a/c/src/metta.rs +++ b/c/src/metta.rs @@ -617,7 +617,7 @@ pub extern "C" fn atom_error_message(atom: *const atom_ref_t, buf: *mut c_char, /// @return The `atom_t` representing the atom /// @note The returned `atom_t` must be freed with `atom_free()` /// -#[no_mangle] pub extern "C" fn ATOM_TYPE_UNIT() -> atom_t { hyperon::metta::UNIT_TYPE().into() } +#[no_mangle] pub extern "C" fn ATOM_TYPE_UNIT() -> atom_t { hyperon::metta::UNIT_TYPE.into() } /// @brief Creates a Symbol atom for the special MeTTa symbol used to indicate empty results /// returned by function. @@ -636,7 +636,7 @@ pub extern "C" fn atom_error_message(atom: *const atom_ref_t, buf: *mut c_char, /// @note The returned `atom_t` must be freed with `atom_free()` /// #[no_mangle] pub extern "C" fn UNIT_ATOM() -> atom_t { - hyperon::metta::UNIT_ATOM().into() + hyperon::metta::UNIT_ATOM.into() } /// @brief Creates a Symbol atom for the special MeTTa symbol used to indicate diff --git a/lib/src/atom/mod.rs b/lib/src/atom/mod.rs index 962d222a3..34aa3aff5 100644 --- a/lib/src/atom/mod.rs +++ b/lib/src/atom/mod.rs @@ -83,8 +83,16 @@ macro_rules! expr { use $crate::*; (&&$crate::Wrap($x)).to_atom() }}; - (($($x:tt)*)) => { $crate::Atom::expr(vec![ $( expr!($x) , )* ]) }; - ($($x:tt)*) => { $crate::Atom::expr(vec![ $( expr!($x) , )* ]) }; + (($($x:tt)*)) => { $crate::Atom::expr([ $( expr!($x) , )* ]) }; + ($($x:tt)*) => { $crate::Atom::expr([ $( expr!($x) , )* ]) }; +} + +#[macro_export] +macro_rules! constexpr { + () => { $crate::Atom::Expression($crate::ExpressionAtom::new($crate::common::collections::CowArray::Literal(&[]))) }; + ($x:literal) => { $crate::Atom::Symbol($crate::SymbolAtom::new($crate::common::collections::ImmutableString::Literal($x))) }; + (($($x:tt)*)) => { $crate::Atom::Expression($crate::ExpressionAtom::new($crate::common::collections::CowArray::Literal(const { &[ $( constexpr!($x) , )* ] }))) }; + ($($x:tt)*) => { $crate::Atom::Expression($crate::ExpressionAtom::new($crate::common::collections::CowArray::Literal(const { &[ $( constexpr!($x) , )* ] }))) }; } /// Constructs new symbol atom. Can be used to construct `const` instances. @@ -117,7 +125,7 @@ use std::any::Any; use std::fmt::{Display, Debug}; use std::convert::TryFrom; -use crate::common::collections::ImmutableString; +use crate::common::collections::{ImmutableString, CowArray}; // Symbol atom @@ -130,7 +138,6 @@ pub struct SymbolAtom { impl SymbolAtom { /// Constructs new symbol from `name`. Not intended to be used directly, /// use [sym!] or [Atom::sym] instead. - #[doc(hidden)] pub const fn new(name: ImmutableString) -> Self { Self{ name } } @@ -152,14 +159,13 @@ impl Display for SymbolAtom { /// An expression atom structure. #[derive(Debug, Clone, PartialEq, Eq)] pub struct ExpressionAtom { - children: Vec, + children: CowArray, } impl ExpressionAtom { /// Constructs new expression from vector of sub-atoms. Not intended to be - /// used directly, use [Atom::expr] instead. - #[doc(hidden)] - pub(crate) fn new(children: Vec) -> Self { + /// used directly, use [expr!], [constexpr!] or [Atom::expr] instead. + pub const fn new(children: CowArray) -> Self { Self{ children } } @@ -169,18 +175,18 @@ impl ExpressionAtom { } /// Returns a reference to a vector of sub-atoms. - pub fn children(&self) -> &Vec { - &self.children + pub fn children(&self) -> &[Atom] { + self.children.as_slice() } /// Returns a mutable reference to a vector of sub-atoms. - pub fn children_mut(&mut self) -> &mut Vec { - &mut self.children + pub fn children_mut(&mut self) -> &mut [Atom] { + self.children.as_slice_mut() } /// Converts into a vector of sub-atoms. pub fn into_children(self) -> Vec { - self.children + self.children.into() } } @@ -837,7 +843,7 @@ impl Atom { /// assert_eq!(expr, same_expr); /// assert_ne!(expr, other_expr); /// ``` - pub fn expr>>(children: T) -> Self { + pub fn expr>>(children: T) -> Self { Self::Expression(ExpressionAtom::new(children.into())) } @@ -1013,7 +1019,7 @@ impl<'a> TryFrom<&'a Atom> for &'a [Atom] { type Error = &'static str; fn try_from(atom: &Atom) -> Result<&[Atom], &'static str> { match atom { - Atom::Expression(expr) => Ok(expr.children().as_slice()), + Atom::Expression(expr) => Ok(expr.children()), _ => Err("Atom is not an ExpressionAtom") } } @@ -1023,7 +1029,7 @@ impl<'a> TryFrom<&'a mut Atom> for &'a mut [Atom] { type Error = &'static str; fn try_from(atom: &mut Atom) -> Result<&mut [Atom], &'static str> { match atom { - Atom::Expression(expr) => Ok(expr.children_mut().as_mut_slice()), + Atom::Expression(expr) => Ok(expr.children_mut()), _ => Err("Atom is not an ExpressionAtom") } } @@ -1093,8 +1099,8 @@ mod test { } #[inline] - fn expression(children: Vec) -> Atom { - Atom::Expression(ExpressionAtom{ children }) + fn expression(children: [Atom; N]) -> Atom { + Atom::Expression(ExpressionAtom::new(CowArray::Allocated(Box::new(children)))) } #[inline] @@ -1175,15 +1181,15 @@ mod test { #[test] fn test_expr_expression() { assert_eq!(expr!("=" ("fact" n) ("*" n ("-" n "1"))), - expression(vec![symbol("="), expression(vec![symbol("fact"), variable("n")]), - expression(vec![symbol("*"), variable("n"), - expression(vec![symbol("-"), variable("n"), symbol("1") ]) ]) ])); + expression([symbol("="), expression([symbol("fact"), variable("n")]), + expression([symbol("*"), variable("n"), + expression([symbol("-"), variable("n"), symbol("1") ]) ]) ])); assert_eq!(expr!("=" n {[1, 2, 3]}), - expression(vec![symbol("="), variable("n"), value([1, 2, 3])])); + expression([symbol("="), variable("n"), value([1, 2, 3])])); assert_eq!(expr!("=" {6} ("fact" n)), - expression(vec![symbol("="), value(6), expression(vec![symbol("fact"), variable("n")])])); + expression([symbol("="), value(6), expression([symbol("fact"), variable("n")])])); assert_eq!(expr!({TestMulX(3)} {TestInteger(6)}), - expression(vec![grounded(TestMulX(3)), grounded(TestInteger(6))])); + expression([grounded(TestMulX(3)), grounded(TestInteger(6))])); } #[test] @@ -1239,8 +1245,8 @@ mod test { assert_eq!(Atom::gnd(TestMulX(3)).clone(), grounded(TestMulX(3))); assert_eq!(Atom::expr([Atom::sym("="), Atom::value(6), Atom::expr([Atom::sym("fact"), Atom::var("n")])]).clone(), - expression(vec![symbol("="), value(6), - expression(vec![symbol("fact"), variable("n")])])); + expression([symbol("="), value(6), + expression([symbol("fact"), variable("n")])])); } #[test] diff --git a/lib/src/common/collections.rs b/lib/src/common/collections.rs index da8f318d1..b1fb834cd 100644 --- a/lib/src/common/collections.rs +++ b/lib/src/common/collections.rs @@ -161,6 +161,97 @@ impl From for ImmutableString { } } +#[derive(Debug, Clone)] +pub enum CowArray { + Allocated(Box<[T]>), + Literal(&'static [T]), +} + +impl CowArray { + + pub fn new() -> Self { + Self::Literal(&[]) + } + + pub fn as_slice(&self) -> &[T] { + match self { + Self::Allocated(array) => &*array, + Self::Literal(array) => array, + } + } + + pub fn as_slice_mut(&mut self) -> &mut [T] where T: Clone { + match self { + Self::Allocated(array) => &mut *array, + Self::Literal(array) => { + *self = Self::Allocated((*array).into()); + self.as_slice_mut() + } + } + } + + pub fn len(&self) -> usize { + self.as_slice().len() + } + + pub fn iter(&self) -> impl Iterator { + self.as_slice().iter() + } +} + +impl PartialEq for CowArray { + fn eq(&self, other: &Self) -> bool { + self.as_slice() == other.as_slice() + } +} + +impl Eq for CowArray {} + +impl Display for CowArray { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "[") + .and_then(|_| self.as_slice().iter().take(1).fold(Ok(()), + |res, atom| res.and_then(|_| write!(f, "{}", atom)))) + .and_then(|_| self.as_slice().iter().skip(1).fold(Ok(()), + |res, atom| res.and_then(|_| write!(f, " {}", atom)))) + .and_then(|_| write!(f, "]")) + } +} + +impl From<&'static [T]> for CowArray { + fn from(a: &'static [T]) -> Self { + CowArray::Literal(a) + } +} + +impl From<[T; N]> for CowArray { + fn from(a: [T; N]) -> Self { + CowArray::Allocated(Box::new(a)) + } +} + +impl From> for CowArray { + fn from(v: Vec) -> Self { + CowArray::Allocated(v.into_boxed_slice()) + } +} + +impl Into> for CowArray { + fn into(self) -> Vec { + match self { + Self::Allocated(array) => array.into(), + Self::Literal(array) => array.into(), + } + } +} + +impl<'a, T> Into<&'a [T]> for &'a CowArray { + fn into(self) -> &'a [T] { + self.as_slice() + } +} + + #[cfg(test)] mod test { use super::*; diff --git a/lib/src/metta/interpreter_minimal.rs b/lib/src/metta/interpreter_minimal.rs index b682e0b11..650533e2d 100644 --- a/lib/src/metta/interpreter_minimal.rs +++ b/lib/src/metta/interpreter_minimal.rs @@ -7,6 +7,7 @@ use crate::space::*; use crate::metta::*; use crate::metta::types::*; use crate::metta::runner::stdlib_minimal::IfEqualOp; +use crate::common::collections::CowArray; use std::fmt::{Debug, Display, Formatter}; use std::convert::TryFrom; @@ -652,16 +653,18 @@ fn function_ret(stack: Rc>, atom: Atom, bindings: Bindings) -> Op } fn collapse_bind(stack: Stack, bindings: Bindings) -> Vec { - let Stack{ prev, atom: mut collapse, ret: _, finished: _, vars } = stack; + let Stack{ prev, atom: collapse, ret: _, finished: _, vars } = stack; let mut nested = Atom::expr([]); - match &mut collapse { + let collapse = match collapse { Atom::Expression(expr) => { - std::mem::swap(&mut nested, &mut expr.children_mut()[1]); - expr.children_mut().push(Atom::value(bindings.clone())) + let mut children = expr.into_children(); + std::mem::swap(&mut nested, &mut children[1]); + children.push(Atom::value(bindings.clone())); + Atom::expr(children) }, _ => panic!("Unexpected state"), - } + }; let prev = Stack::from_prev_with_vars(prev, collapse, vars, collapse_bind_ret); let prev = Rc::new(RefCell::new(prev)); @@ -672,16 +675,19 @@ fn collapse_bind(stack: Stack, bindings: Bindings) -> Vec { fn collapse_bind_ret(stack: Rc>, atom: Atom, bindings: Bindings) -> Option<(Stack, Bindings)> { let nested = atom; - { + if nested != EMPTY_SYMBOL { let stack_ref = &mut *stack.borrow_mut(); let Stack{ prev: _, atom: collapse, ret: _, finished: _, vars: _ } = stack_ref; - let finished = match atom_as_slice_mut(collapse) { - Some([_op, Atom::Expression(finished), _bindings]) => finished, + match atom_as_slice_mut(collapse) { + Some([_op, Atom::Expression(finished_placeholder), _bindings]) => { + let mut finished = ExpressionAtom::new(CowArray::new()); + std::mem::swap(&mut finished, finished_placeholder); + let mut finished = finished.into_children(); + finished.push(atom_bindings_into_atom(nested, bindings)); + std::mem::swap(&mut ExpressionAtom::new(finished.into()), finished_placeholder); + }, _ => panic!("Unexpected state"), }; - if nested != EMPTY_SYMBOL { - finished.children_mut().push(atom_bindings_into_atom(nested, bindings)); - } } // all alternatives are evaluated @@ -1105,9 +1111,9 @@ fn interpret_function(args: Atom, bindings: Bindings) -> MettaResult { let mut call = atom.clone().into_children(); let head = call.remove(0); let args = call; - let mut arg_types = op_type.clone(); - arg_types.children_mut().remove(0); - let arg_types = Atom::Expression(arg_types); + let mut arg_types: Vec = op_type.children().into(); + arg_types.remove(0); + let arg_types = Atom::expr(arg_types); let rop = Atom::Variable(VariableAtom::new("rop").make_unique()); let rargs = Atom::Variable(VariableAtom::new("rargs").make_unique()); let result = Atom::Variable(VariableAtom::new("result").make_unique()); diff --git a/lib/src/metta/mod.rs b/lib/src/metta/mod.rs index 9fd87623d..3064b8425 100644 --- a/lib/src/metta/mod.rs +++ b/lib/src/metta/mod.rs @@ -42,16 +42,8 @@ pub const SUPERPOSE_BIND_SYMBOL : Atom = sym!("superpose-bind"); pub const METTA_SYMBOL : Atom = sym!("metta"); pub const CALL_NATIVE_SYMBOL : Atom = sym!("call-native"); -//TODO: convert these from functions to static strcutures, when Atoms are Send+Sync -#[allow(non_snake_case)] -pub fn UNIT_ATOM() -> Atom { - Atom::expr([]) -} - -#[allow(non_snake_case)] -pub fn UNIT_TYPE() -> Atom { - Atom::expr([ARROW_SYMBOL]) -} +pub const UNIT_ATOM: Atom = constexpr!(); +pub const UNIT_TYPE: Atom = constexpr!(("->")); /// Initializes an error expression atom pub fn error_atom(err_atom: Option, err_code: Option, message: String) -> Atom { @@ -95,3 +87,13 @@ pub fn atom_error_message(atom: &Atom) -> &str { } } +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn unit_type() { + assert_eq!(UNIT_ATOM, Atom::expr([])); + assert_eq!(UNIT_TYPE, Atom::expr([ARROW_SYMBOL])); + } +} diff --git a/lib/src/metta/runner/builtin_mods/catalog_mods.rs b/lib/src/metta/runner/builtin_mods/catalog_mods.rs index e46a8b211..be850be1e 100644 --- a/lib/src/metta/runner/builtin_mods/catalog_mods.rs +++ b/lib/src/metta/runner/builtin_mods/catalog_mods.rs @@ -88,7 +88,7 @@ impl CatalogListOp { impl Grounded for CatalogListOp { fn type_(&self) -> Atom { //TODO-FUTURE, we may want to return the list as atoms, but now it just prints to stdout - Atom::expr([ARROW_SYMBOL, ATOM_TYPE_SYMBOL, UNIT_TYPE()]) + Atom::expr([ARROW_SYMBOL, ATOM_TYPE_SYMBOL, UNIT_TYPE]) } fn as_execute(&self) -> Option<&dyn CustomExecute> { @@ -153,7 +153,7 @@ impl CatalogUpdateOp { impl Grounded for CatalogUpdateOp { fn type_(&self) -> Atom { //TODO-FUTURE, we may want to return the list as atoms, but now it just prints to stdout - Atom::expr([ARROW_SYMBOL, ATOM_TYPE_SYMBOL, UNIT_TYPE()]) + Atom::expr([ARROW_SYMBOL, ATOM_TYPE_SYMBOL, UNIT_TYPE]) } fn as_execute(&self) -> Option<&dyn CustomExecute> { @@ -213,7 +213,7 @@ impl CatalogClearOp { impl Grounded for CatalogClearOp { fn type_(&self) -> Atom { //TODO-FUTURE, we may want to return the list as atoms, but now it just prints to stdout - Atom::expr([ARROW_SYMBOL, ATOM_TYPE_SYMBOL, UNIT_TYPE()]) + Atom::expr([ARROW_SYMBOL, ATOM_TYPE_SYMBOL, UNIT_TYPE]) } fn as_execute(&self) -> Option<&dyn CustomExecute> { diff --git a/lib/src/metta/runner/stdlib_minimal.rs b/lib/src/metta/runner/stdlib_minimal.rs index 9411caa85..03cdb8672 100644 --- a/lib/src/metta/runner/stdlib_minimal.rs +++ b/lib/src/metta/runner/stdlib_minimal.rs @@ -26,7 +26,7 @@ use super::arithmetics::*; use super::string::*; pub(crate) fn unit_result() -> Result, ExecError> { - Ok(vec![UNIT_ATOM()]) + Ok(vec![UNIT_ATOM]) } pub(crate) fn regex(regex: &str) -> Regex { @@ -68,7 +68,7 @@ impl Grounded for ImportOp { //TODO: Ideally the "import as" / "import into" part would be optional //A deeper discussion on arg semantics as it relates to import! is here: // https://github.com/trueagi-io/hyperon-experimental/pull/580#discussion_r1491332304 - Atom::expr([ARROW_SYMBOL, ATOM_TYPE_ATOM, ATOM_TYPE_ATOM, UNIT_TYPE()]) + Atom::expr([ARROW_SYMBOL, ATOM_TYPE_ATOM, ATOM_TYPE_ATOM, UNIT_TYPE]) } fn as_execute(&self) -> Option<&dyn CustomExecute> { @@ -279,7 +279,7 @@ impl PrintModsOp { impl Grounded for PrintModsOp { fn type_(&self) -> Atom { - Atom::expr([ARROW_SYMBOL, UNIT_TYPE()]) + Atom::expr([ARROW_SYMBOL, UNIT_TYPE]) } fn as_execute(&self) -> Option<&dyn CustomExecute> { @@ -309,7 +309,7 @@ impl BindOp { impl Grounded for BindOp { fn type_(&self) -> Atom { - Atom::expr([ARROW_SYMBOL, ATOM_TYPE_SYMBOL, ATOM_TYPE_UNDEFINED, UNIT_TYPE()]) + Atom::expr([ARROW_SYMBOL, ATOM_TYPE_SYMBOL, ATOM_TYPE_UNDEFINED, UNIT_TYPE]) } fn as_execute(&self) -> Option<&dyn CustomExecute> { @@ -363,7 +363,7 @@ grounded_op!(AddAtomOp, "add-atom"); impl Grounded for AddAtomOp { fn type_(&self) -> Atom { Atom::expr([ARROW_SYMBOL, rust_type_atom::(), - ATOM_TYPE_ATOM, UNIT_TYPE()]) + ATOM_TYPE_ATOM, UNIT_TYPE]) } fn as_execute(&self) -> Option<&dyn CustomExecute> { @@ -390,7 +390,7 @@ grounded_op!(RemoveAtomOp, "remove-atom"); impl Grounded for RemoveAtomOp { fn type_(&self) -> Atom { Atom::expr([ARROW_SYMBOL, rust_type_atom::(), - ATOM_TYPE_ATOM, UNIT_TYPE()]) + ATOM_TYPE_ATOM, UNIT_TYPE]) } fn as_execute(&self) -> Option<&dyn CustomExecute> { @@ -529,7 +529,7 @@ grounded_op!(PrintlnOp, "println!"); impl Grounded for PrintlnOp { fn type_(&self) -> Atom { - Atom::expr([ARROW_SYMBOL, ATOM_TYPE_UNDEFINED, UNIT_TYPE()]) + Atom::expr([ARROW_SYMBOL, ATOM_TYPE_UNDEFINED, UNIT_TYPE]) } fn as_execute(&self) -> Option<&dyn CustomExecute> { @@ -872,7 +872,7 @@ pub(crate) mod pkg_mgmt_ops { impl Grounded for RegisterModuleOp { fn type_(&self) -> Atom { - Atom::expr([ARROW_SYMBOL, ATOM_TYPE_ATOM, UNIT_TYPE()]) + Atom::expr([ARROW_SYMBOL, ATOM_TYPE_ATOM, UNIT_TYPE]) } fn as_execute(&self) -> Option<&dyn CustomExecute> { @@ -927,7 +927,7 @@ pub(crate) mod pkg_mgmt_ops { impl Grounded for GitModuleOp { fn type_(&self) -> Atom { - Atom::expr([ARROW_SYMBOL, ATOM_TYPE_ATOM, UNIT_TYPE()]) + Atom::expr([ARROW_SYMBOL, ATOM_TYPE_ATOM, UNIT_TYPE]) } fn as_execute(&self) -> Option<&dyn CustomExecute> { @@ -999,7 +999,7 @@ impl CustomExecute for UniqueAtomOp { let arg_error = || ExecError::from("unique expects single expression atom as an argument"); let expr = TryInto::<&ExpressionAtom>::try_into(args.get(0).ok_or_else(arg_error)?)?; - let mut atoms = expr.children().clone(); + let mut atoms: Vec = expr.children().into(); let mut set = GroundingSpace::new(); atoms.retain(|x| { let not_contained = set.query(x).is_empty(); @@ -1028,8 +1028,8 @@ impl Grounded for UnionAtomOp { impl CustomExecute for UnionAtomOp { fn execute(&self, args: &[Atom]) -> Result, ExecError> { let arg_error = || ExecError::from("union expects and executable LHS and RHS atom"); - let mut lhs = TryInto::<&ExpressionAtom>::try_into(args.get(0).ok_or_else(arg_error)?)?.children().clone(); - let rhs = TryInto::<&ExpressionAtom>::try_into(args.get(1).ok_or_else(arg_error)?)?.children().clone(); + let mut lhs: Vec = TryInto::<&ExpressionAtom>::try_into(args.get(0).ok_or_else(arg_error)?)?.children().into(); + let rhs: Vec = TryInto::<&ExpressionAtom>::try_into(args.get(1).ok_or_else(arg_error)?)?.children().into(); lhs.extend(rhs); @@ -1055,8 +1055,8 @@ impl Grounded for IntersectionAtomOp { impl CustomExecute for IntersectionAtomOp { fn execute(&self, args: &[Atom]) -> Result, ExecError> { let arg_error = || ExecError::from("intersection expects and executable LHS and RHS atom"); - let mut lhs = TryInto::<&ExpressionAtom>::try_into(args.get(0).ok_or_else(arg_error)?)?.children().clone(); - let rhs = TryInto::<&ExpressionAtom>::try_into(args.get(1).ok_or_else(arg_error)?)?.children().clone(); + let mut lhs: Vec = TryInto::<&ExpressionAtom>::try_into(args.get(0).ok_or_else(arg_error)?)?.children().into(); + let rhs = TryInto::<&ExpressionAtom>::try_into(args.get(1).ok_or_else(arg_error)?)?.children(); let mut rhs_index: MultiTrie> = MultiTrie::new(); for (index, rhs_item) in rhs.iter().enumerate() { @@ -1238,8 +1238,8 @@ impl Grounded for SubtractionAtomOp { impl CustomExecute for SubtractionAtomOp { fn execute(&self, args: &[Atom]) -> Result, ExecError> { let arg_error = || ExecError::from("subtraction expects and executable LHS and RHS atom"); - let mut lhs = TryInto::<&ExpressionAtom>::try_into(args.get(0).ok_or_else(arg_error)?)?.children().clone(); - let rhs = TryInto::<&ExpressionAtom>::try_into(args.get(1).ok_or_else(arg_error)?)?.children().clone(); + let mut lhs: Vec = TryInto::<&ExpressionAtom>::try_into(args.get(0).ok_or_else(arg_error)?)?.children().into(); + let rhs = TryInto::<&ExpressionAtom>::try_into(args.get(1).ok_or_else(arg_error)?)?.children(); let mut rhs_index: MultiTrie> = MultiTrie::new(); for (index, rhs_item) in rhs.iter().enumerate() { @@ -1356,7 +1356,7 @@ grounded_op!(PrintAlternativesOp, "print-alternatives!"); impl Grounded for PrintAlternativesOp { fn type_(&self) -> Atom { - Atom::expr([ARROW_SYMBOL, ATOM_TYPE_ATOM, ATOM_TYPE_EXPRESSION, UNIT_TYPE()]) + Atom::expr([ARROW_SYMBOL, ATOM_TYPE_ATOM, ATOM_TYPE_EXPRESSION, UNIT_TYPE]) } fn as_execute(&self) -> Option<&dyn CustomExecute> { @@ -1374,7 +1374,7 @@ impl CustomExecute for PrintAlternativesOp { .collect(); println!("{} {}:", args.len(), atom); args.iter().for_each(|arg| println!(" {}", arg)); - Ok(vec![UNIT_ATOM()]) + Ok(vec![UNIT_ATOM]) } } @@ -1558,7 +1558,7 @@ impl CustomExecute for AssertEqualToResultOp { let actual = interpret_no_error(self.space.clone(), actual_atom)?; - assert_results_equal(&actual, expected, actual_atom) + assert_results_equal(&actual, &expected.into(), actual_atom) } } @@ -2191,7 +2191,7 @@ mod tests { "; assert_eq!(metta.run(SExprParser::new(program)), Ok(vec![])); assert_eq!(metta.run(SExprParser::new("!(assertEqual (foo A) (bar A))")), Ok(vec![ - vec![UNIT_ATOM()], + vec![UNIT_ATOM], ])); assert_eq!(metta.run(SExprParser::new("!(assertEqual (foo A) (bar B))")), Ok(vec![ vec![expr!("Error" ({assert.clone()} ("foo" "A") ("bar" "B")) "\nExpected: [B]\nGot: [A]\nMissed result: B")], @@ -2214,7 +2214,7 @@ mod tests { "; assert_eq!(metta.run(SExprParser::new(program)), Ok(vec![])); assert_eq!(metta.run(SExprParser::new("!(assertEqualToResult (foo) (A B))")), Ok(vec![ - vec![UNIT_ATOM()], + vec![UNIT_ATOM], ])); assert_eq!(metta.run(SExprParser::new("!(assertEqualToResult (bar) (A))")), Ok(vec![ vec![expr!("Error" ({assert.clone()} ("bar") ("A")) "\nExpected: [A]\nGot: [C]\nMissed result: A")], @@ -2500,7 +2500,7 @@ mod tests { assert_eq_metta_results!(run_program(program), Ok(vec![ vec![expr!("baz")], - vec![UNIT_ATOM()], + vec![UNIT_ATOM], vec![expr!(("foo"))], vec![expr!(("bar"))], ])); @@ -2764,7 +2764,7 @@ mod tests { let space = DynSpace::new(GroundingSpace::new()); let satom = Atom::gnd(space.clone()); let res = AddAtomOp{}.execute(&mut vec![satom, expr!(("foo" "bar"))]).expect("No result returned"); - assert_eq!(res, vec![UNIT_ATOM()]); + assert_eq!(res, vec![UNIT_ATOM]); let space_atoms: Vec = space.borrow().as_space().atom_iter().unwrap().cloned().collect(); assert_eq_no_order!(space_atoms, vec![expr!(("foo" "bar"))]); } @@ -2778,7 +2778,7 @@ mod tests { let satom = Atom::gnd(space.clone()); let res = RemoveAtomOp{}.execute(&mut vec![satom, expr!(("foo" "bar"))]).expect("No result returned"); // REM: can return Bool in future - assert_eq!(res, vec![UNIT_ATOM()]); + assert_eq!(res, vec![UNIT_ATOM]); let space_atoms: Vec = space.borrow().as_space().atom_iter().unwrap().cloned().collect(); assert_eq_no_order!(space_atoms, vec![expr!(("bar" "foo"))]); } diff --git a/lib/src/metta/types.rs b/lib/src/metta/types.rs index 05c3915e4..df1111773 100644 --- a/lib/src/metta/types.rs +++ b/lib/src/metta/types.rs @@ -136,7 +136,7 @@ fn query_types(space: &dyn Space, atom: &Atom) -> Vec { pub fn get_arg_types<'a>(fn_typ: &'a Atom) -> (&'a [Atom], &'a Atom) { match fn_typ { Atom::Expression(expr) => { - let children = expr.children().as_slice(); + let children = expr.children(); match children { [op, args @ .., res] if *op == ARROW_SYMBOL => (args, res), _ => panic!("Incorrect function type: {}", fn_typ) @@ -151,7 +151,7 @@ fn get_op(expr: &ExpressionAtom) -> &Atom { } fn get_args(expr: &ExpressionAtom) -> &[Atom] { - &expr.children().as_slice()[1..] + &expr.children()[1..] } /// Returns vector of the types for the given `atom` in context of the given diff --git a/lib/tests/metta.rs b/lib/tests/metta.rs index 0d9081038..d16c067de 100644 --- a/lib/tests/metta.rs +++ b/lib/tests/metta.rs @@ -18,5 +18,5 @@ fn test_reduce_higher_order() { let result = metta.run(SExprParser::new(program)); - assert_eq!(result, Ok(vec![vec![UNIT_ATOM()]])); + assert_eq!(result, Ok(vec![vec![UNIT_ATOM]])); } diff --git a/lib/tests/types.rs b/lib/tests/types.rs index b76bd05aa..318798524 100644 --- a/lib/tests/types.rs +++ b/lib/tests/types.rs @@ -25,7 +25,7 @@ fn test_types_in_metta() { let metta = Metta::new(Some(EnvBuilder::test_env())); metta.tokenizer().borrow_mut().register_token(regex::Regex::new("is-int").unwrap(), |_t| Atom::gnd(IsInt{})); let result = metta.run(SExprParser::new(program)); - assert_eq!(result, Ok(vec![vec![UNIT_ATOM()], vec![UNIT_ATOM()], vec![UNIT_ATOM()], vec![UNIT_ATOM()], vec![UNIT_ATOM()], vec![UNIT_ATOM()]])); + assert_eq!(result, Ok(vec![vec![UNIT_ATOM], vec![UNIT_ATOM], vec![UNIT_ATOM], vec![UNIT_ATOM], vec![UNIT_ATOM], vec![UNIT_ATOM]])); } #[derive(Clone, Debug)]