Skip to content

Commit

Permalink
Make UNIT_TYPE and UNIT_ATOM constant expressions
Browse files Browse the repository at this point in the history
  • Loading branch information
vsbogd committed Nov 14, 2024
1 parent d9b2649 commit d9aebbc
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 39 deletions.
4 changes: 2 additions & 2 deletions c/src/metta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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
Expand Down
18 changes: 12 additions & 6 deletions lib/src/atom/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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 }
}
Expand All @@ -157,9 +164,8 @@ pub struct ExpressionAtom {

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: CowArray<Atom>) -> Self {
/// used directly, use [expr!], [constexpr!] or [Atom::expr] instead.
pub const fn new(children: CowArray<Atom>) -> Self {
Self{ children }
}

Expand Down
22 changes: 12 additions & 10 deletions lib/src/metta/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Atom>, err_code: Option<Atom>, message: String) -> Atom {
Expand Down Expand Up @@ -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]));
}
}
6 changes: 3 additions & 3 deletions lib/src/metta/runner/builtin_mods/catalog_mods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand Down Expand Up @@ -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> {
Expand Down Expand Up @@ -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> {
Expand Down
32 changes: 16 additions & 16 deletions lib/src/metta/runner/stdlib_minimal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use super::arithmetics::*;
use super::string::*;

pub(crate) fn unit_result() -> Result<Vec<Atom>, ExecError> {
Ok(vec![UNIT_ATOM()])
Ok(vec![UNIT_ATOM])
}

pub(crate) fn regex(regex: &str) -> Regex {
Expand Down Expand Up @@ -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> {
Expand Down Expand Up @@ -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> {
Expand Down Expand Up @@ -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> {
Expand Down Expand Up @@ -363,7 +363,7 @@ grounded_op!(AddAtomOp, "add-atom");
impl Grounded for AddAtomOp {
fn type_(&self) -> Atom {
Atom::expr([ARROW_SYMBOL, rust_type_atom::<DynSpace>(),
ATOM_TYPE_ATOM, UNIT_TYPE()])
ATOM_TYPE_ATOM, UNIT_TYPE])
}

fn as_execute(&self) -> Option<&dyn CustomExecute> {
Expand All @@ -390,7 +390,7 @@ grounded_op!(RemoveAtomOp, "remove-atom");
impl Grounded for RemoveAtomOp {
fn type_(&self) -> Atom {
Atom::expr([ARROW_SYMBOL, rust_type_atom::<DynSpace>(),
ATOM_TYPE_ATOM, UNIT_TYPE()])
ATOM_TYPE_ATOM, UNIT_TYPE])
}

fn as_execute(&self) -> Option<&dyn CustomExecute> {
Expand Down Expand Up @@ -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> {
Expand Down Expand Up @@ -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> {
Expand Down Expand Up @@ -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> {
Expand Down Expand Up @@ -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> {
Expand All @@ -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])
}
}

Expand Down Expand Up @@ -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")],
Expand All @@ -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")],
Expand Down Expand Up @@ -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"))],
]));
Expand Down Expand Up @@ -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<Atom> = space.borrow().as_space().atom_iter().unwrap().cloned().collect();
assert_eq_no_order!(space_atoms, vec![expr!(("foo" "bar"))]);
}
Expand All @@ -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<Atom> = space.borrow().as_space().atom_iter().unwrap().cloned().collect();
assert_eq_no_order!(space_atoms, vec![expr!(("bar" "foo"))]);
}
Expand Down
2 changes: 1 addition & 1 deletion lib/tests/metta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]]));
}
2 changes: 1 addition & 1 deletion lib/tests/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down

0 comments on commit d9aebbc

Please sign in to comment.