Skip to content

Commit

Permalink
Merge pull request #728 from vsbogd/rust-minimal
Browse files Browse the repository at this point in the history
Minimal MeTTa interpreter written mostly in Rust
  • Loading branch information
vsbogd authored Jul 10, 2024
2 parents 7844382 + e7e6dfa commit 4e56a8c
Show file tree
Hide file tree
Showing 23 changed files with 692 additions and 417 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# This workflow is intended to run tests on minimal MeTTa interpreter.
# This workflow is intended to run tests on old Rust MeTTa interpreter.
# It is indicative and temporary, it doesn't prevent any changes from merging.

# This workflow uses actions that are not certified by GitHub. They are
# provided by a third-party and are governed by separate terms of service,
# privacy policy, and support documentation.

name: minimal
name: old_interpreter

on:
push:
Expand All @@ -16,7 +16,7 @@ on:
- main

jobs:
minimal:
old_interpreter:
runs-on: "ubuntu-20.04"

steps:
Expand All @@ -32,13 +32,13 @@ jobs:
- name: Build Rust library
working-directory: ./lib
run: |
cargo check --features minimal
cargo build --features minimal
cargo check --features old_interpreter
cargo build --features old_interpreter
- name: Test Rust library
working-directory: ./lib
run: |
RUST_LOG=hyperon=debug cargo test --features minimal
RUST_LOG=hyperon=debug cargo test --features old_interpreter
- name: Install cbindgen
uses: actions-rs/[email protected]
Expand Down Expand Up @@ -106,7 +106,7 @@ jobs:
cd build
# specify C compiler as conan could not find it automatically
# see https://github.com/conan-io/conan/issues/4322
cmake -DCARGO_ARGS="--features hyperon/minimal" -DCMAKE_BUILD_TYPE=Release -DPython3_EXECUTABLE=`which python` -DCMAKE_C_COMPILER=gcc ..
cmake -DCARGO_ARGS="--features hyperon/old_interpreter" -DCMAKE_BUILD_TYPE=Release -DPython3_EXECUTABLE=`which python` -DCMAKE_C_COMPILER=gcc ..
- name: Build C API
working-directory: ./build
Expand Down
10 changes: 10 additions & 0 deletions c/src/metta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,16 @@ pub extern "C" fn atom_error_message(atom: *const atom_ref_t, buf: *mut c_char,
hyperon::metta::UNIT_ATOM().into()
}

/// @brief Creates a Symbol atom for the special MeTTa symbol used to indicate
/// calling MeTTa interpreter.
/// @ingroup metta_language_group
/// @return The `atom_t` representing the interpret atom
/// @note The returned `atom_t` must be freed with `atom_free()`
///
#[no_mangle] pub extern "C" fn METTA_ATOM() -> atom_t {
hyperon::metta::METTA_SYMBOL.into()
}

/// @brief Checks whether Atom `atom` has Type `typ` in context of `space`
/// @ingroup metta_language_group
/// @param[in] space A pointer to the `space_t` representing the space context in which to perform the check
Expand Down
17 changes: 17 additions & 0 deletions docs/minimal-metta.md
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,23 @@ used on each exit path while nothing in code of function points to this. Using
- functions which evaluate result in a loop and have to use `return`;
- functions which just replace the calling expression by their bodies.

# MeTTa interpreter written in Rust

MeTTa interpreter written in minimal MeTTa has poor performance. To fix this
the interpreter is rewritten in Rust. Rust implementation can be called using
`(metta <atom> <type> <space>)` operation. To be able represent process of the
interpretation as a list of steps and keep ability to control the inference
`metta` doesn't evaluate passed atom till the end but instead analyses the atom
and returns the plan written in minimal MeTTa. Plan includes steps written as a
Rust functions. These steps are called using `(call_native <name> <function>
<args>)` operation.

Both `metta` and `call_native` could be written as a grounded operations and be
a part of a standard library. But this requires grounded operations to be able
returning bindings as a results. Returning bindings as results is a nice to
have feature anyway to be able representing any functionality as a grounded
atom. But it is not implemented yet.

# Future work

## Explicit atomspace variable bindings
Expand Down
2 changes: 1 addition & 1 deletion lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ crate-type = ["lib"]
default = ["pkg_mgmt"]
# Add one of the features below into default list to enable.
# See https://doc.rust-lang.org/cargo/reference/features.html#the-features-section
minimal = [] # enables minimal MeTTa interpreter
old_interpreter = [] # enables old Rust interpreter
variable_operation = [] # enables evaluation of the expressions which have
# a variable on the first position
git = ["git2", "pkg_mgmt"]
Expand Down
2 changes: 1 addition & 1 deletion lib/benches/interpreter_minimal.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#![feature(test)]
#[cfg(feature = "minimal")]
#[cfg(not(feature = "old_interpreter"))]
mod interpreter_minimal_bench {

extern crate test;
Expand Down
16 changes: 15 additions & 1 deletion lib/src/atom/matcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1073,10 +1073,24 @@ impl BindingsSet {
}
}

pub trait BindingsResultIter: Iterator<Item=Bindings> {
fn clone_(&self) -> Box<dyn BindingsResultIter>;
}
impl<T: 'static + Clone + Iterator<Item=Bindings>> BindingsResultIter for T {
fn clone_(&self) -> Box<dyn BindingsResultIter> {
Box::new(self.clone())
}
}

/// Iterator over atom matching results. Each result is an instance of [Bindings].
//TODO: A situation where a MatchResultIter returns an unbounded (infinite) number of results
// will hang this implementation, on account of `.collect()`
pub type MatchResultIter = Box<dyn Iterator<Item=matcher::Bindings>>;
pub type MatchResultIter = Box<dyn BindingsResultIter>;
impl Clone for MatchResultIter {
fn clone(&self) -> Self {
self.clone_()
}
}

/// Matches two atoms and returns an iterator over results. Atoms are
/// treated symmetrically.
Expand Down
4 changes: 2 additions & 2 deletions lib/src/atom/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,12 @@
/// ```
/// #[macro_use]
/// use hyperon::expr;
/// use hyperon::common::MUL;
/// use hyperon::metta::runner::arithmetics::MulOp;
///
/// let sym = expr!("A");
/// let var = expr!(x);
/// let gnd = expr!({42});
/// let expr = expr!("=" ("*2" n) ({MUL} n {2}));
/// let expr = expr!("=" ("*2" n) ({MulOp{}} n {2}));
///
/// assert_eq!(sym.to_string(), "A");
/// assert_eq!(var.to_string(), "$x");
Expand Down
147 changes: 0 additions & 147 deletions lib/src/common/arithmetics.rs

This file was deleted.

3 changes: 0 additions & 3 deletions lib/src/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@ pub mod owned_or_borrowed;
mod flex_ref;
pub use flex_ref::FlexRef;

mod arithmetics;
pub use arithmetics::*;

use crate::*;
use crate::metta::text::{Tokenizer, SExprParser};
use std::cell::RefCell;
Expand Down
Loading

0 comments on commit 4e56a8c

Please sign in to comment.