Skip to content

Commit

Permalink
Merge branch 'main' of github.com:trueagi-io/hyperon-experimental int…
Browse files Browse the repository at this point in the history
…o edit_listening_agent
  • Loading branch information
sveta committed Dec 10, 2024
2 parents 41159d0 + 346648e commit 2ef9359
Show file tree
Hide file tree
Showing 29 changed files with 591 additions and 410 deletions.
44 changes: 44 additions & 0 deletions c/src/atom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ use std::collections::HashSet;
use std::sync::atomic::{AtomicPtr, Ordering};

use hyperon::matcher::{Bindings, BindingsSet};
use hyperon::metta::runner::bool::Bool;
use hyperon::metta::runner::number::Number;

// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
// Atom Interface
Expand Down Expand Up @@ -269,6 +271,36 @@ pub extern "C" fn atom_gnd(gnd: *mut gnd_t) -> atom_t {
Atom::gnd(CGrounded(AtomicPtr::new(gnd))).into()
}

/// @ingroup atom_group
/// @param[in] b boolean value
/// @return an `atom_t` for the Bool Grounded atom
/// @note The caller must take ownership responsibility for the returned `atom_t`
///
#[no_mangle]
pub extern "C" fn atom_bool(b: bool) -> atom_t {
Atom::gnd(Bool(b)).into()
}

/// @ingroup atom_group
/// @param[in] n integer number
/// @return an `atom_t` for the Number Grounded atom
/// @note The caller must take ownership responsibility for the returned `atom_t`
///
#[no_mangle]
pub extern "C" fn atom_int(n: i64) -> atom_t {
Atom::gnd(Number::Integer(n)).into()
}

/// @ingroup atom_group
/// @param[in] f float number
/// @return an `atom_t` for the Number Grounded atom
/// @note The caller must take ownership responsibility for the returned `atom_t`
///
#[no_mangle]
pub extern "C" fn atom_float(f: f64) -> atom_t {
Atom::gnd(Number::Float(f)).into()
}

/// @brief Creates a Grounded Atom referencing a Space
/// @ingroup atom_group
/// @param[in] space A pointer to an `space_t` for accessing the space
Expand Down Expand Up @@ -757,6 +789,18 @@ pub extern "C" fn exec_error_no_reduce() -> exec_error_t {
ExecError::NoReduce.into()
}

/// @brief Creates a new `exec_error_t` representing a "Incorrect Argument" status, telling the
/// MeTTa interpreter that argument was not recognized by the function implementation.
/// @ingroup grounded_atom_group
/// @return The newly created `exec_error_t`
/// @note The caller must take ownership responsibility for the returned `exec_error_t`, and ultimately free
/// it with `exec_error_free()` or return it from an `execute` function
///
#[no_mangle]
pub extern "C" fn exec_error_incorrect_argument() -> exec_error_t {
ExecError::IncorrectArgument.into()
}

/// @brief Creates a new `exec_error_t` representing a "No Error" status. This is the default interpreter status
/// @ingroup grounded_atom_group
/// @return The newly created `exec_error_t`
Expand Down
14 changes: 14 additions & 0 deletions c/src/metta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,20 @@ pub extern "C" fn atom_error_message(atom: *const atom_ref_t, buf: *mut c_char,
///
#[no_mangle] pub extern "C" fn ATOM_TYPE_UNIT() -> atom_t { hyperon::metta::UNIT_TYPE.into() }

/// @brief Creates an atom used to indicate that an atom's type is a Number type.
/// @ingroup metta_language_group
/// @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_NUMBER() -> atom_t { hyperon::metta::runner::number::ATOM_TYPE_NUMBER.into() }

/// @brief Creates an atom used to indicate that an atom's type is a Bool type.
/// @ingroup metta_language_group
/// @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_BOOL() -> atom_t { hyperon::metta::runner::bool::ATOM_TYPE_BOOL.into() }

/// @brief Creates a Symbol atom for the special MeTTa symbol used to indicate empty results
/// returned by function.
/// @ingroup metta_language_group
Expand Down
2 changes: 1 addition & 1 deletion lib/examples/sorted_list.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use hyperon::*;
use hyperon::metta::runner::*;
use hyperon::metta::runner::arithmetics::*;
use hyperon::metta::runner::number::Number;
use hyperon::metta::text::SExprParser;

fn main() -> Result<(), String> {
Expand Down
7 changes: 6 additions & 1 deletion lib/src/atom/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
/// ```
/// #[macro_use]
/// use hyperon::expr;
/// use hyperon::metta::runner::arithmetics::MulOp;
/// use hyperon::metta::runner::stdlib::arithmetics::MulOp;
///
/// let sym = expr!("A");
/// let var = expr!(x);
Expand Down Expand Up @@ -367,6 +367,11 @@ pub enum ExecError {
/// Returned intentionally to let [crate::metta::interpreter] algorithm
/// know that this expression should be returned "as is" without reducing.
NoReduce,
/// Argument is not recognized by function implementation. It can be
/// argument of incorrect type or in incorrect format. Interpreter handles
/// this error similarly to the situation when pure function definition
/// is not matched (see [crate::metta::interpreter]).
IncorrectArgument,
}

impl From<String> for ExecError {
Expand Down
34 changes: 33 additions & 1 deletion lib/src/metta/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,8 @@ fn eval_impl<'a, T: Space>(to_eval: Atom, space: T, bindings: Bindings, prev: Op
// TODO: we could remove ExecError::NoReduce and explicitly
// return NOT_REDUCIBLE_SYMBOL from the grounded function instead.
finished_result(return_not_reducible(), bindings, prev),
Err(ExecError::IncorrectArgument) =>
finished_result(return_not_reducible(), bindings, prev),
}
},
}
Expand Down Expand Up @@ -1464,7 +1466,13 @@ mod tests {
#[test]
fn interpret_atom_evaluate_grounded_expression_noreduce() {
let result = call_interpret(&space(""), &expr!("eval" ({NonReducible()} {6})));
assert_eq!(result, vec![expr!("NotReducible")]);
assert_eq!(result, vec![NOT_REDUCIBLE_SYMBOL]);
}

#[test]
fn interpret_atom_evaluate_grounded_expression_incorrect_argument() {
let result = call_interpret(&space(""), &expr!("eval" ({IncorrectArgument()} {6.5})));
assert_eq!(result, vec![NOT_REDUCIBLE_SYMBOL]);
}

#[test]
Expand Down Expand Up @@ -1831,6 +1839,30 @@ mod tests {
}
}

#[derive(PartialEq, Clone, Debug)]
struct IncorrectArgument();

impl Grounded for IncorrectArgument {
fn type_(&self) -> Atom {
expr!("->" "u32" "u32")
}
fn as_execute(&self) -> Option<&dyn CustomExecute> {
Some(self)
}
}

impl CustomExecute for IncorrectArgument {
fn execute(&self, _args: &[Atom]) -> Result<Vec<Atom>, ExecError> {
Err(ExecError::IncorrectArgument)
}
}

impl Display for IncorrectArgument {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "incorrect-argument")
}
}

#[derive(PartialEq, Clone, Debug)]
struct MulXUndefinedType(i32);

Expand Down
90 changes: 90 additions & 0 deletions lib/src/metta/runner/bool.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
use crate::*;
use crate::atom::serial;
use crate::atom::serial::ConvertingSerializer;

use std::fmt::Display;

pub const ATOM_TYPE_BOOL : Atom = sym!("Bool");

#[derive(Clone, PartialEq, Debug)]
pub struct Bool(pub bool);

impl Bool {
pub fn from_str(b: &str) -> Self {
match b {
"True" => Self(true),
"False" => Self(false),
_ => panic!("Could not parse Bool value: {}", b),
}
}

pub fn from_atom(atom: &Atom) -> Option<Self> {
BoolSerializer::convert(atom)
}
}

impl Into<Bool> for bool {
fn into(self) -> Bool {
Bool(self)
}
}

impl Display for Bool {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self.0 {
true => write!(f, "True"),
false => write!(f, "False"),
}
}
}

impl Grounded for Bool {
fn type_(&self) -> Atom {
ATOM_TYPE_BOOL
}

fn as_match(&self) -> Option<&dyn CustomMatch> {
Some(self)
}

fn serialize(&self, serializer: &mut dyn serial::Serializer) -> serial::Result {
serializer.serialize_bool(self.0)
}
}

impl CustomMatch for Bool {
fn match_(&self, other: &Atom) -> matcher::MatchResultIter {
match_by_bidirectional_equality(self, other)
}
}

#[derive(Default)]
struct BoolSerializer {
value: Option<Bool>,
}

impl serial::Serializer for BoolSerializer {
fn serialize_bool(&mut self, v: bool) -> serial::Result {
self.value = Some(Bool(v));
Ok(())
}
}

impl serial::ConvertingSerializer<Bool> for BoolSerializer {
fn into_type(self) -> Option<Bool> {
self.value
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn bool() {
assert_eq!(Bool::from_str("True"), Bool(true));
assert_eq!(Bool::from_str("False"), Bool(false));
assert_eq!(format!("{}", Bool(true)), "True");
assert_eq!(format!("{}", Bool(false)), "False");
}
}
6 changes: 3 additions & 3 deletions lib/src/metta/runner/environment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -455,8 +455,8 @@ fn git_catalog_from_cfg_atom(atom: &ExpressionAtom, env: &Environment) -> Result
let refresh_time = refresh_time.ok_or_else(|| format!("Error in environment.metta. \"refreshTime\" property required for #gitCatalog"))?
.parse::<u64>().map_err(|e| format!("Error in environment.metta. Error parsing \"refreshTime\": {e}"))?;

let catalog_name = crate::metta::runner::string::strip_quotes(catalog_name);
let catalog_url = crate::metta::runner::string::strip_quotes(catalog_url);
let catalog_name = crate::metta::runner::str::strip_quotes(catalog_name);
let catalog_url = crate::metta::runner::str::strip_quotes(catalog_url);

let mut managed_remote_catalog = LocalCatalog::new(caches_dir, catalog_name).unwrap();
let remote_catalog = GitCatalog::new(caches_dir, env.fs_mod_formats.clone(), catalog_name, catalog_url, refresh_time).unwrap();
Expand All @@ -474,7 +474,7 @@ fn include_path_from_cfg_atom(atom: &ExpressionAtom, env: &Environment) -> Resul
None => return Err(format!("Error in environment.metta. #includePath missing path value"))
};
let path = <&crate::SymbolAtom>::try_from(path_atom)?.name();
let path = crate::metta::runner::string::strip_quotes(path);
let path = crate::metta::runner::str::strip_quotes(path);

//TODO-FUTURE: In the future we may want to replace dyn-fmt with strfmt, and do something a
// little bit nicer than this
Expand Down
5 changes: 3 additions & 2 deletions lib/src/metta/runner/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,9 @@ use stdlib::CoreLibLoader;
mod builtin_mods;
use builtin_mods::*;

pub mod arithmetics;
pub mod string;
pub mod bool;
pub mod number;
pub mod str;

const EXEC_SYMBOL : Atom = sym!("!");

Expand Down
Loading

0 comments on commit 2ef9359

Please sign in to comment.