From 594ce6ff79f6fe3ff9d4fe91e921f2db21f21844 Mon Sep 17 00:00:00 2001 From: Vitaly Bogdanov Date: Thu, 16 Nov 2023 14:17:01 +0300 Subject: [PATCH] Add quote, unify, empty into Rust interpreter's stdlib --- lib/src/metta/runner/stdlib.rs | 64 ++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/lib/src/metta/runner/stdlib.rs b/lib/src/metta/runner/stdlib.rs index f0be2b468..f57b50c80 100644 --- a/lib/src/metta/runner/stdlib.rs +++ b/lib/src/metta/runner/stdlib.rs @@ -1235,6 +1235,21 @@ pub static METTA_CODE: &'static str = " (= (if True $then $else) $then) (= (if False $then $else) $else) (: Error (-> Atom Atom ErrorType)) + + + ; quote prevents atom from being reduced + (: quote (-> Atom Atom)) + + ; unify matches two atoms and returns $then if they are matched + ; and $else otherwise. + (: unify (-> Atom Atom Atom Atom %Undefined%)) + (= (unify $a $a $then $else) $then) + (= (unify $a $b $then $else) + (case (let (quote $a) (quote $b) no-result) ((%void% $else))) ) + + ; empty removes current result from a non-deterministic result + (: empty (-> %Undefined%)) + (= (empty) (let a b never-happens)) "; #[cfg(all(test, not(feature = "minimal")))] @@ -1637,4 +1652,53 @@ mod tests { fn test_let_op_inside_other_operation() { assert_eq!(run_program("!(and True (let $x False $x))"), Ok(vec![vec![expr!({Bool(false)})]])); } + + #[test] + fn test_quote() { + let metta = Metta::new(Some(EnvBuilder::test_env())); + let parser = SExprParser::new(" + (= (foo) a) + (= (foo) b) + !(foo) + !(quote (foo)) + "); + + assert_eq_metta_results!(metta.run(parser), + Ok(vec![ + vec![expr!("a"), expr!("b")], + vec![expr!("quote" ("foo"))], + ])); + } + + #[test] + fn test_unify() { + let metta = Metta::new(Some(EnvBuilder::test_env())); + let parser = SExprParser::new(" + !(unify (a $b 1 (d)) (a $a 1 (d)) ok nok) + !(unify (a $b c) (a b $c) (ok $b $c) nok) + !(unify $a (a b c) (ok $a) nok) + !(unify (a b c) $a (ok $a) nok) + !(unify (a b c) (a b d) ok nok) + "); + + assert_eq_metta_results!(metta.run(parser), + Ok(vec![ + vec![expr!("ok")], + vec![expr!("ok" "b" "c")], + vec![expr!("ok" ("a" "b" "c"))], + vec![expr!("ok" ("a" "b" "c"))], + vec![expr!("nok")] + ])); + } + + #[test] + fn test_empty() { + let metta = Metta::new(Some(EnvBuilder::test_env())); + let parser = SExprParser::new(" + !(empty) + "); + + assert_eq_metta_results!(metta.run(parser), + Ok(vec![vec![]])); + } }