From 1520da8ede748cd389e24ec73b114de95ad79fae Mon Sep 17 00:00:00 2001 From: logicmoo Date: Sun, 1 Sep 2024 03:05:14 -0700 Subject: [PATCH] src/swi_analyse_metta/convert_rust_tests_to_metta_tests_prompt.txt --- ...nvert_rust_tests_to_metta_tests_prompt.txt | 182 ++ .../minimal-metta/stdlib_minimal_test.metta | 1654 ++++++++++++++--- .../stdlib_minimal_test.metta.answers | 12 - .../stdlib_mettalog_test.metta | 1143 +++++++++--- .../stdlib_mettalog_test_pt2.metta | 1245 +++++++++++++ 5 files changed, 3745 insertions(+), 491 deletions(-) create mode 100644 src/swi_analyse_metta/convert_rust_tests_to_metta_tests_prompt.txt delete mode 100644 tests/more-anti-regression/minimal-metta/stdlib_minimal_test.metta.answers mode change 100755 => 100644 tests/more-anti-regression/stdlib-mettalog/stdlib_mettalog_test.metta create mode 100644 tests/more-anti-regression/stdlib-mettalog/stdlib_mettalog_test_pt2.metta diff --git a/src/swi_analyse_metta/convert_rust_tests_to_metta_tests_prompt.txt b/src/swi_analyse_metta/convert_rust_tests_to_metta_tests_prompt.txt new file mode 100644 index 00000000000..554f2e8b80c --- /dev/null +++ b/src/swi_analyse_metta/convert_rust_tests_to_metta_tests_prompt.txt @@ -0,0 +1,182 @@ +This template shows the format you need for converting Rust test code into Metta-compatible syntax, with the original Rust code included as comments. + +### Template Example: + +```rust +;; Original: +;; #[test] +;; fn metta_type_cast() { +;; assert_eq!(run_program("(: a A) !(eval (type-cast a A &self))"), Ok(vec![vec![expr!("a")]])); +;; assert_eq!(run_program("(: a A) !(eval (type-cast a B &self))"), Ok(vec![vec![expr!("Error" "a" "BadType")]])); +;; assert_eq!(run_program("(: a A) !(eval (type-cast a %Undefined% &self))"), Ok(vec![vec![expr!("a")]])); +;; assert_eq!(run_program("!(eval (type-cast a B &self))"), Ok(vec![vec![expr!("a")]])); +;; assert_eq!(run_program("!(eval (type-cast 42 Number &self))"), Ok(vec![vec![expr!({Number::Integer(42)})]])); +;; assert_eq!(run_program("!(eval (type-cast 42 %Undefined% &self))"), Ok(vec![vec![expr!({Number::Integer(42)})]])); +;; assert_eq!(run_program("(: a A) !(eval (type-cast a Atom &self))"), Ok(vec![vec![expr!("a")]])); +;; assert_eq!(run_program("(: a A) !(eval (type-cast a Symbol &self))"), Ok(vec![vec![expr!("a")]])); +;; assert_eq!(run_program("!(eval (type-cast 42 Grounded &self))"), Ok(vec![vec![expr!({Number::Integer(42)})]])); +;; assert_eq!(run_program("!(eval (type-cast () Expression &self))"), Ok(vec![vec![expr!()]])); +;; assert_eq!(run_program("!(eval (type-cast (a b) Expression &self))"), Ok(vec![vec![expr!("a" "b")]])); +;; } + +;; Converted: +!(assertEqual (eval (type-cast a A &self)) (a)) +!(assertEqual (eval (type-cast a B &self)) ("Error" "a" "BadType")) +!(assertEqual (eval (type-cast a %Undefined% &self)) (a)) +!(assertEqual (eval (type-cast 42 Number &self)) ({Number::Integer(42)})) +!(assertEqual (eval (type-cast 42 %Undefined% &self)) ({Number::Integer(42)})) +!(assertEqual (eval (type-cast a Atom &self)) (a)) +!(assertEqual (eval (type-cast a Symbol &self)) (a)) +!(assertEqual (eval (type-cast 42 Grounded &self)) ({Number::Integer(42)})) +!(assertEqual (eval (type-cast () Expression &self)) ()) +!(assertEqual (eval (type-cast (a b) Expression &self)) (a b)) +``` + +--- + +```rust +;; Original: +;; #[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"))], +;; ])); +;; } + +;; Converted: +(= (foo) a) +(= (foo) b) +!(assertEqualToResults (foo) (a b)) +!(assertEqualToResults (quote (foo)) (quote (foo))) +``` + +--- + +```rust +;; Original: +;; #[test] +;; fn trace_op() { +;; assert_eq!(TraceOp{}.execute(&mut vec![sym!("\"Here?\""), sym!("42")]), +;; Ok(vec![sym!("42")])); +;; } + +;; Converted: +!(assertEqual (trace! "Here?" 42) 42) +``` + +--- + +```rust +;; Original: +;; #[test] +;; fn intersection_op() { +;; let space = DynSpace::new(metta_space(" +;; (= (foo) Z) +;; (= (foo) (A (B C))) +;; (= (foo) (f g)) +;; (= (bar) (f g)) +;; (= (bar) (A (B C))) +;; (= (bar) p) +;; (= (bar) (Q a)) +;; (= (bar) Z) +;; +;; (= (nsl) 5) +;; (= (nsl) 4) +;; (= (nsl) 3) +;; (= (nsl) 2) +;; (= (nsr) 5) +;; (= (nsr) 3) +;; ")); +;; let intersection_op = IntersectionOp::new(space); +;; let actual = intersection_op.execute(&mut vec![expr!(("foo")), expr!(("bar"))]).unwrap(); +;; assert_eq_no_order!(actual, +;; vec![expr!("A" ("B" "C")), expr!("f" "g"), expr!("Z")]); +;; +;; assert_eq_no_order!(intersection_op.execute(&mut vec![expr!(("nsl")), expr!(("nsr"))]).unwrap(), +;; vec![expr!("5"), expr!("3")]); +;; } + +;; Converted: + (= (foo) Z) + (= (foo) (A (B C))) + (= (foo) (f g)) + (= (bar) (f g)) + (= (bar) (A (B C))) + (= (bar) p) + (= (bar) (Q a)) + (= (bar) Z) + (= (nsl) 5) + (= (nsl) 4) + (= (nsl) 3) + (= (nsl) 2) + (= (nsr) 5) + (= (nsr) 3) +!(assertEqualNoOrder (intersection (foo) (bar)) ((A (B C)) (f g) Z)) +!(assertEqualNoOrder (intersection (nsl) (nsr)) (5 3)) +``` + +--- + +### Final Prompt Example: + +With these examples, you can build a comprehensive prompt for future Rust-to-Metta conversions: + +--- + +**Prompt:** + +I have some Rust test code that I need to convert into Metta-compatible syntax. The format should include the original Rust code as comments and the converted Metta syntax below. The converted code should look like the examples below: + +```rust +;; Original: +;; #[test] +;; fn trace_op() { +;; assert_eq!(TraceOp{}.execute(&mut vec![sym!("\"Here?\""), sym!("42")]), +;; Ok(vec![sym!("42")])); +;; } + +;; Converted: +!(assertEqual (trace! "Here?" 42) 42) +``` + +```rust +;; Original: +;; #[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"))], +;; ])); +;; } + +;; Converted: +(= (foo) a) +(= (foo) b) +!(assertEqualToResults (foo) (a b)) +!(assertEqualToResults (quote (foo)) (quote (foo))) +``` + +Here is the Rust code to convert: + + + + diff --git a/tests/more-anti-regression/minimal-metta/stdlib_minimal_test.metta b/tests/more-anti-regression/minimal-metta/stdlib_minimal_test.metta index ff7b68e5359..bed52c8faf6 100644 --- a/tests/more-anti-regression/minimal-metta/stdlib_minimal_test.metta +++ b/tests/more-anti-regression/minimal-metta/stdlib_minimal_test.metta @@ -1,5 +1,256 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Converted Rust Tests with Original Source +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + !(include! &corelib stdlib_minimal) +; !(include! &corelib stdlib_mettalog) +; !(import! &self stdlib_mettalog) + + +; This script demonstrates how one can document MeTTa code and get +; help using the documenatation. + +; Let's document a function which has two arguments and returns value. +; One can use `@doc` expression to do it. First argument of the expression is an +; atom being documented. Other arguments describe the atom, describe function +; parameters and return value. +(@doc some-func + (@desc "Test function") + (@params ( + (@param "First argument") + (@param "Second argument") + )) + (@return "Return value")) + +; Function type is required to document the function +(: Arg1Type Type) +(: Arg2Type Type) +(: ReturnType Type) +(: some-func (-> Arg1Type Arg2Type ReturnType)) + +; `get-doc` function returns a `@doc-formal` expression which contains the full +; documentation of the atom including user defined description and types. +!(assertEqual + (get-doc some-func) + (@doc-formal (@item some-func) (@kind function) + (@type (-> Arg1Type Arg2Type ReturnType)) + (@desc "Test function") + (@params ( + (@param (@type Arg1Type) (@desc "First argument")) + (@param (@type Arg2Type) (@desc "Second argument")))) + (@return (@type ReturnType) (@desc "Return value")))) + +; Same approach can be used to document single atom of any @kind. +(@doc SomeSymbol (@desc "Test symbol atom having specific type")) +(: SomeSymbol SomeType) + +!(assertEqual + (get-doc SomeSymbol) + (@doc-formal (@item SomeSymbol) (@kind atom) (@type SomeType) + (@desc "Test symbol atom having specific type"))) + +; Grounded atoms are also can be documented using `@doc` expressions. Type of +; the grounded atom is a part of its implementation. +(@doc some-gnd-atom + (@desc "Test function") + (@params ( + (@param "First argument") + (@param "Second argument") + )) + (@return "Return value") + ) + +; As some-gnd-function is not imported really in this example type is not +; available and @doc-formal contains %Undefined% instead. +!(assertEqual + (get-doc some-gnd-atom) + (@doc-formal (@item some-gnd-atom) (@kind function) + (@type %Undefined%) + (@desc "Test function") + (@params ( + (@param (@type %Undefined%) (@desc "First argument")) + (@param (@type %Undefined%) (@desc "Second argument")))) + (@return (@type %Undefined%) (@desc "Return value")))) + +; If atom is not documented then `get-doc` returns "No documentation" +; description. +!(assertEqual + (get-doc NoSuchAtom) + (@doc-formal (@item NoSuchAtom) (@kind atom) (@type %Undefined%) (@desc "No documentation"))) + +; Same result is returned if for instance documentation for the function +; application is queried. +!(assertEqual + (get-doc (some-func arg1 arg2)) + (@doc-formal (@item (some-func arg1 arg2)) (@kind atom) (@type ReturnType) (@desc "No documentation"))) + +; `help!` function gets the documentation and prints it in a human readable +; format. +!(help! some-func) +; Output: +; +; Function some-func: (-> Arg1Type Arg2Type ReturnType) Test function +; Parameters: +; Arg1Type First argument +; Arg2Type Second argument +; Return: (@type ReturnType) Return value +; + +!(help! SomeSymbol) +; Output: +; +; Atom SomeSymbol: SomeType Test symbol atom having specific type +; + +!(help! some-gnd-atom) +; Output: +; +; Function some-gnd-atom: %Undefined% Test function +; Parameters: +; %Undefined% First argument +; %Undefined% Second argument +; Return: (@type %Undefined%) Return value +; + + +!(help! NoSuchAtom) +; Output: +; +; Atom NoSuchAtom: %Undefined% No documentation +; + +!(help! (some-func arg1 arg2)) +; Output: +; +; Atom (some-func arg1 arg2): ReturnType No documentation +; + + + +;;#[test] +;;fn mod_space_op() { +;; let program = r#" +;; !(bind! &new_space (new-space)) +;; !(add-atom &new_space (mod-space! stdlib)) +;; !(get-atoms &new_space) +;; "#; +;; let runner = Metta::new(Some(runner::environment::EnvBuilder::test_env())); +;; let result = runner.run(SExprParser::new(program)).unwrap(); +;; +;; let stdlib_space = runner.module_space(runner.get_module_by_name("stdlib").unwrap()); +;; assert_eq!(result[2], vec![Atom::gnd(stdlib_space)]); +;;} +;; Converted: +!(bind! &new_space (new-space)) +!(add-atom &new_space (mod-space! stdlib)) +!(assertEqualToResult (get-atoms &new_space) (&stdlib)) + + +;; #[test] +;; fn match_op() { +;; let space = DynSpace::new(metta_space("(A B)")); +;; let match_op = MatchOp{}; +;; assert_eq!(match_op.execute(&mut vec![expr!({space}), expr!("A" "B"), expr!("B" "A")]), +;; Ok(vec![expr!("B" "A")])); +;; } +;; Converted: +(let space (A B)) +!(assertEqual (match! space (A B) (B A)) (B A)) + + +;; #[test] +;; fn match_op_issue_530() { +;; let space = DynSpace::new(metta_space("(A $a $a)")); +;; let match_op = MatchOp{}; +;; let result = match_op.execute(&mut vec![expr!({space}), expr!("A" x y), expr!("A" x y)]).unwrap(); +;; assert_eq!(result.len(), 1); +;; assert!(atoms_are_equivalent(&result[0], &expr!("A" x x)), +;; "atoms are not equivalent: expected: {}, actual: {}", expr!("A" x x), result[0]); +;; } +;; Converted: +(let space (A $a $a)) +(let result (match! space (A x y) (A x y))) +!(assertEqual (length result) 1) +!(assertEqual (atoms_are_equivalent (first result) (A x x)) true) + + +;; #[test] +;; fn new_space_op() { +;; let res = NewSpaceOp{}.execute(&mut vec![]).expect("No result returned"); +;; let space = res.get(0).expect("Result is empty"); +;; let space = space.as_gnd::().expect("Result is not space"); +;; let space_atoms: Vec = space.borrow().as_space().atom_iter().unwrap().cloned().collect(); +;; assert_eq_no_order!(space_atoms, Vec::::new()); +;; } +;; Converted: +!(bind! &space (new-space)) +!(assertEqualNoOrder (get-atoms &space) ()) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Converted Rust Tests with Original Source +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; Original: +;; #[test] +;; fn test_error_is_used_as_an_argument() { +;; let metta = Metta::new(Some(EnvBuilder::test_env())); +;; let parser = SExprParser::new(r#" +;;!(get-type Error) +;;!(get-metatype Error) +;;!(get-type (Error Foo Boo)) +;;!(Error (+ 1 2) (+ 1 +)) +;; "#); +;; assert_eq_metta_results!(metta.run(parser), Ok(vec![ +;; vec![expr!("->" "Atom" "Atom" "ErrorType")], +;; vec![expr!("Symbol")], +;; vec![expr!("ErrorType")], +;; vec![expr!("Error" ({SumOp{}} {Number::Integer(1)} {Number::Integer(2)}) ({SumOp{}} {Number::Integer(1)} {SumOp{}}))], +;; ])); +;; } +;; Converted: +!(assertEqualToResult (get-type Error) (-> Atom Atom ErrorType)) +!(assertEqualToResult (get-metatype Error) (Symbol)) +!(assertEqualToResult (get-type (Error Foo Boo)) (ErrorType)) +!(assertEqualToResult (Error (+ 1 2) (+ 1 +)) (Error ({SumOp{}} {Number::Integer(1)} {Number::Integer(2)}) ({SumOp{}} {Number::Integer(1)} {SumOp{}}))) + + + + + + + + + + + + + + + + + + +;;;;;;;;;;;;;;;;;;;;;; +; Unify +;;;;;;;;;;;;;;;;;;;;;; +!(assertEqual (eval (unify (a $b 1 (d)) (a $a 1 (d)) ok nok)) ok) +!(assertEqual (eval (unify (a $b c) (a b $c) (ok $b $c) nok)) (ok b c)) +!(assertEqual (eval (unify $a (a b c) (ok $a) nok)) (ok (a b c))) +!(assertEqual (eval (unify (a b c) $a (ok $a) nok)) (ok (a b c))) +!(assertEqual (eval (unify (a b c) (a b d) ok nok)) nok) +!(assertEqual (eval (unify ($x a) (b $x) ok nok)) nok) + + +!(assertEqual (decons-atom (a b c)) (a (b c))) +!(assertEqual (decons-atom (a b)) (a (b))) +!(assertEqual (decons-atom (a)) (a ())) +;> !(decons-atom ()) +;[(Error (decons-atom ()) expected: (decons-atom (: Expression)), found: (decons-atom ()))] + + + + ;;;;;;;;;;;;;;;;;;;;;; ; Metta GetTypeOp @@ -7,28 +258,54 @@ ;; #[test] ;; fn get_type_op() { ;; let space = DynSpace::new(metta_space(" -(: B Type) -(: C Type) -(: A B) -(: A C) +;; (: B Type) +;; (: C Type) +;; (: A B) +;; (: A C) ;; ")); ;; ;; let get_type_op = GetTypeOp::new(space.clone()); ;; assert_eq_no_order!(get_type_op.execute(&mut vec![sym!("A"), expr!({space.clone()})]).unwrap(), ;; vec![sym!("B"), sym!("C")]); ;; } +;; Converted: +(let space (new-space)) +(: B Type) +(: C Type) +(: A B) +(: A C) ;; Defines a type space and checks if A belongs to types B and C using GetTypeOp. -!(assertEqualNoOrder (eval (get-type A space)) (B C)) +!(assertEqualToResult (eval (get-type A &self)) (B C)) + + + + + + + + + + + + + + + + + + ;;;;;;;;;;;;;;;;;;;;;; ; Metta GetTypeOp Non-Valid Atom ;;;;;;;;;;;;;;;;;;;;;; + +;; Original: ;; #[test] ;; fn get_type_op_non_valid_atom() { ;; let space = DynSpace::new(metta_space(" -(: f (-> Number String)) -(: 42 Number) -(: "test" String) +;; (: f (-> Number String)) +;; (: 42 Number) +;; (: \"test\" String) ;; ")); ;; ;; let get_type_op = GetTypeOp::new(space.clone()); @@ -37,8 +314,50 @@ ;; assert_eq_no_order!(get_type_op.execute(&mut vec![expr!("f" "\"test\""), expr!({space.clone()})]).unwrap(), ;; vec![EMPTY_SYMBOL]); ;; } -!(assertEqualNoOrder (eval (get-type (f 42) space)) (String)) -!(assertEqualNoOrder (eval (get-type (f "test") space)) (Empty)) +;; Converted: +(let space (new-space)) +(: f (-> Number String)) +(: 42 Number) +(: "test" String) +!(assertEqualToResult (eval (get-type (f 42) &self)) (String)) +!(assertEqual (eval (get-type (f "test") &self)) (empty)) + +;; Original: +;; #[test] +;; fn metta_car_atom() { +;; let result = run_program("!(eval (car-atom (A $b)))"); +;; assert_eq!(result, Ok(vec![vec![expr!("A")]])); +;; let result = run_program("!(eval (car-atom ($a B)))"); +;; assert_eq!(result, Ok(vec![vec![expr!(a)]])); +;; let result = run_program("!(eval (car-atom ()))"); +;; assert_eq!(result, Ok(vec![vec![expr!("Error" ("car-atom" ()) {Str::from_str("car-atom expects a non-empty expression as an argument")})]])); +;; let result = run_program("!(eval (car-atom A))"); +;; assert_eq!(result, Ok(vec![vec![expr!("Error" ("car-atom" "A") {Str::from_str("car-atom expects a non-empty expression as an argument")})]])); +;; } + +;; Converted: +!(assertEqual (eval (car-atom (A $b))) (A)) +!(assertEqual (eval (car-atom ($a B))) (a)) +!(assertEqual (eval (car-atom ())) (Error (car-atom ()) "car-atom expects a non-empty expression as an argument")) +!(assertEqual (eval (car-atom A)) (Error (car-atom "A") "car-atom expects a non-empty expression as an argument")) + +;; Original: +;; #[test] +;; fn metta_cdr_atom() { +;; assert_eq!(run_program(&format!("!(cdr-atom (a b c))")), Ok(vec![vec![expr!("b" "c")]])); +;; assert_eq!(run_program(&format!("!(cdr-atom ($a b $c))")), Ok(vec![vec![expr!("b" c)]])); +;; assert_eq!(run_program(&format!("!(cdr-atom ())")), Ok(vec![vec![expr!("Error" ("cdr-atom" ()) {Str::from_str("cdr-atom expects a non-empty expression as an argument")})]])); +;; assert_eq!(run_program(&format!("!(cdr-atom a)")), Ok(vec![vec![expr!("Error" ("cdr-atom" "a") {Str::from_str("cdr-atom expects a non-empty expression as an argument")})]])); +;; assert_eq!(run_program(&format!("!(cdr-atom $a)")), Ok(vec![vec![expr!("Error" ("cdr-atom" a) {Str::from_str("cdr-atom expects a non-empty expression as an argument")})]])); +;; } + +;; Converted: +!(assertEqual (eval (cdr-atom (a b c))) (b c)) +!(assertEqual (eval (cdr-atom ($a b $c))) (b c)) +!(assertEqual (eval (cdr-atom ())) (Error (cdr-atom ()) "cdr-atom expects a non-empty expression as an argument")) +!(assertEqual (eval (cdr-atom a)) (Error (cdr-atom "a") "cdr-atom expects a non-empty expression as an argument")) +!(assertEqual (eval (cdr-atom $a)) (Error (cdr-atom a) "cdr-atom expects a non-empty expression as an argument")) + ;;;;;;;;;;;;;;;;;;;;;; ; Metta Switch @@ -53,9 +372,18 @@ ;; assert_eq!(result, Ok(vec![vec![]])); ;; } ;; Tests the switch operation with various patterns and variables. -!(assertEqual (eval (switch (A $b) (((B C) (C B)) (($a B) ($b $a))))) (B A)) -!(assertEqual (eval (switch (A $b) (((B C) (C B)) (($a B) ($b $a))))) (B A)) -!(assertEqual (eval (switch (A $b) (((B C) (C B)) ((D E) (E B))))) ()) + +!(assertEqual (eval (case (A $b) ( (($a B) ($b $a)) ((B C) (C B)) ))) (B A)) +!(assertEqual (eval (case (A $b) ( ((B C) (C B)) (($a B) ($b $a)) ))) (B A)) +!(assertEqual (eval (case (A $b) ( ((B C) (C B)) ((D E) (E B)) ))) ()) + +;!(assertEqualToResult (switch (A $b) ( (($a B) ($b $a)) ((B C) (C B)) )) ((B A)(B A)(B A)(B A))) +;!(assertEqualToResult (case (A $b) ( (($a B) ($b $a)) ((B C) (C B)) )) ((B A)(B A)(B A)(B A))) + +!(assertEqual (eval (switch (A $b) ( ((B C) (C B)) (($a B) ($b $a))) )) (B A)) +!(assertEqual (eval (switch (A $b) ( (($a B) ($b $a)) ((B C) (C B)) ))) (B A)) +!(assertEqual (eval (switch (A $b) ( ((B C) (C B)) (($a B) ($b $a)) ))) (B A)) +!(assertEqual (eval (switch (A $b) ( ((B C) (C B)) ((D E) (E B)) ))) ()) ;;;;;;;;;;;;;;;;;;;;;; ; Metta Case Empty @@ -77,6 +405,29 @@ !(assertEqual (eval (case (unify (B C) (C B) ok nok) ((ok ok) (nok nok)))) nok) !(assertEqual (eval (case (unify (B C) (C B) ok Empty) ((ok ok) (%void% nok)))) nok) + +;;;;;;;;;;;;;;;;;;;;;; +; Metta Case Empty +;;;;;;;;;;;;;;;;;;;;;; +;; #[test] +;; fn metta_case_empty() { +;; let result = run_program("!(case Empty ( (ok ok) (Empty nok) ))"); +;; assert_eq!(result, Ok(vec![vec![expr!("nok")]])); +;; let result = run_program("!(case (unify (C B) (C B) ok Empty) ( (ok ok) (Empty nok) ))"); +;; assert_eq!(result, Ok(vec![vec![expr!("ok")]])); +;; let result = run_program("!(case (unify (B C) (C B) ok nok) ( (ok ok) (nok nok) ))"); +;; assert_eq!(result, Ok(vec![vec![expr!("nok")]])); +;; let result = run_program("!(case (unify (B C) (C B) ok Empty) ( (ok ok) (Empty nok) ))"); +;; assert_eq!(result, Ok(vec![vec![expr!("nok")]])); +;; } +;; Converted: +!(assertEqual (case Empty ( (ok ok) (Empty nok) )) (nok)) +!(assertEqual (case (unify (C B) (C B) ok Empty) ( (ok ok) (Empty nok) )) (ok)) +!(assertEqual (case (unify (B C) (C B) ok nok) ( (ok ok) (nok nok) )) (nok)) +!(assertEqual (case (unify (B C) (C B) ok Empty) ( (ok ok) (Empty nok) )) (nok)) + + + ;;;;;;;;;;;;;;;;;;;;;; ; Metta Is-Function ;;;;;;;;;;;;;;;;;;;;;; @@ -90,9 +441,9 @@ ;; assert_eq!(result, Ok(vec![vec![expr!({Bool(false)})]])); ;; } ;; Evaluates if given expressions are recognized as functions. -!(assertEqual (eval (is-function (-> $t))) (Bool True)) -!(assertEqual (eval (is-function (A $t))) (Bool False)) -!(assertEqual (eval (is-function %Undefined%)) (Bool False)) +!(assertEqual (eval (is-function (-> $t))) True) +!(assertEqual (eval (is-function (A $t))) False) +!(assertEqual (eval (is-function %Undefined%)) False) ;;;;;;;;;;;;;;;;;;;;;; ; Metta Type-Cast @@ -110,9 +461,12 @@ ;; assert_eq!(run_program("!(eval (type-cast 42 Grounded &self))"), Ok(vec![vec![expr!({(42)})]])); ;; assert_eq!(run_program("!(eval (type-cast () Expression &self))"), Ok(vec![vec![expr!()]])); ;; assert_eq!(run_program("!(eval (type-cast (a b) Expression &self))"), Ok(vec![vec![expr!("a" "b")]])); +;; NEW TODO assert_eq!(run_program("!(eval (type-cast $v Variable &self))"), Ok(vec![vec![expr!(v)]])); +;; NEW TODO assert_eq!(run_program("(: a A) (: b B) !(eval (type-cast (a b) (A B) &self))"), Ok(vec![vec![expr!("a" "b")]])); +;; NEW TODO assert_eq!(run_program("(: a A) (: a B) !(eval (type-cast a A &self))"), Ok(vec![vec![expr!("a")]])); ;; } ;; Type-cast operations with various types and validation checks. -!(assertEqual (eval (type-cast a B &self)) (Error "a" "BadType")) +!(assertEqual (eval (type-cast a B &self)) (Error a BadType)) !(assertEqual (eval (type-cast 42 Number &self)) 42) !(assertEqual (eval (type-cast 42 %Undefined% &self)) 42) !(assertEqual (eval (type-cast 42 Grounded &self)) 42) @@ -120,11 +474,18 @@ !(assertEqual (eval (type-cast (a b) Expression &self)) (a b)) (: a A) !(assertEqual (eval (type-cast a A &self)) a) -!(assertEqual (eval (type-cast a B &self)) (Error "a" "BadType")) +!(assertEqual (eval (type-cast a B &self)) (Error a BadType)) !(assertEqual (eval (type-cast a %Undefined% &self)) a) !(assertEqual (eval (type-cast a Atom &self)) a) !(assertEqual (eval (type-cast a Symbol &self)) a) +;; NEW TODOs +!(assertEqual (eval (type-cast $v Variable &self)) $v) +(: a A) (: b B) +!(assertEqual (eval (type-cast (a b) (A B) &self)) (a b)) +(: a A) (: a B) +!(assertEqual (eval (type-cast a A &self)) a) + ;;;;;;;;;;;;;;;;;;;;;; ; Metta Filter-Atom ;;;;;;;;;;;;;;;;;;;;;; @@ -135,6 +496,8 @@ ;; assert_eq!(run_program("!(eval (filter-atom (a (b) $c) $x (eval (if-error $x False True))))"), Ok(vec![vec![expr!("a" ("b") c)]])); ;; assert_eq!(run_program("!(eval (filter-atom (a (Error (b) \"Test error\") $c) $x (eval (if-error $x False True))))"), Ok(vec![vec![expr!("a" c)]])); ;; } + +;; Converted: !(assertEqual (eval (filter-atom () $x (eval (if-error $x False True)))) ()) !(assertEqual (eval (filter-atom (a (b) $c) $x (eval (if-error $x False True)))) (a (b) c)) !(assertEqual (eval (filter-atom (a (Error (b) "Test error") $c) $x (eval (if-error $x False True)))) (a c)) @@ -149,7 +512,7 @@ ;; } ;; Applying a function to each atom in a list and returning a new list with the results. !(assertEqual (eval (map-atom () $x ($x 'mapped))) ()) -!(assertEqual (eval (map-atom (a (b) $c) $x (mapped $x))) (("mapped" a) ("mapped" (b)) ("mapped" c))) +!(assertEqual (eval (map-atom (a (b) $c) $x (mapped $x))) ((mapped a) (mapped (b)) (mapped c))) ;;;;;;;;;;;;;;;;;;;;;; ; Metta Foldl-Atom @@ -193,14 +556,64 @@ ;;;;;;;;;;;;;;;;;;;;;; ; Metta Interpret Symbol or Grounded Value As Type ;;;;;;;;;;;;;;;;;;;;;; +;; Original: +;; #[test] +;; fn metta_map_atom() { +;; assert_eq!(run_program("!(eval (map-atom () $x ($x mapped)))"), Ok(vec![vec![expr!()]])); +;; assert_eq!(run_program("!(eval (map-atom (a (b) $c) $x (mapped $x)))"), Ok(vec![vec![expr!(("mapped" "a") ("mapped" ("b")) ("mapped" c))]])); +;; } + +;; Converted: +!(assertEqual (eval (map-atom () $x ($x mapped))) ()) +!(assertEqual (eval (map-atom (a (b) $c) $x (mapped $x))) ((mapped a) (mapped (b)) (mapped c))) + +;; Original: +;; #[test] +;; fn metta_foldl_atom() { +;; assert_eq!(run_program("!(eval (foldl-atom () 1 $a $b (eval (+ $a $b))))"), Ok(vec![vec![expr!({Number::Integer(1)})]])); +;; assert_eq!(run_program("!(eval (foldl-atom (1 2 3) 0 $a $b (eval (+ $a $b))))"), Ok(vec![vec![expr!({Number::Integer(6)})]])); +;; } + +;; Converted: +!(assertEqual (eval (foldl-atom () 1 $a $b (eval (+ $a $b)))) {Number::Integer(1)}) +!(assertEqual (eval (foldl-atom (1 2 3) 0 $a $b (eval (+ $a $b)))) {Number::Integer(6)}) + +;; Original: +;; #[test] +;; fn metta_interpret_single_atom_as_atom() { +;; let result = run_program("!(metta A Atom &self)"); +;; assert_eq!(result, Ok(vec![vec![expr!("A")]])); +;; } + +;; Converted: +!(assertEqual (metta A Atom &self) A) + +;; Original: +;; #[test] +;; fn metta_interpret_single_atom_as_meta_type() { +;; assert_eq!(run_program("!(metta A Symbol &self)"), Ok(vec![vec![expr!("A")]])); +;; assert_eq!(run_program("!(metta $x Variable &self)"), Ok(vec![vec![expr!(x)]])); +;; assert_eq!(run_program("!(metta (A B) Expression &self)"), Ok(vec![vec![expr!("A" "B")]])); +;; assert_eq!(run_program("!(metta 42 Grounded &self)"), Ok(vec![vec![expr!({Number::Integer(42)})]])); +;; } + +;; Converted: +!(assertEqual (metta A Symbol &self) A) +!(assertEqual (metta $x Variable &self) x) +!(assertEqual (metta (A B) Expression &self) (A B)) +!(assertEqual (metta 42 Grounded &self) {Number::Integer(42)}) + +;; Original: ;; #[test] ;; fn metta_interpret_symbol_or_grounded_value_as_type() { -;; assert_eq!(run_program("(: a A) !(eval (interpret a A &self))"), Ok(vec![vec![expr!("a")]])); -;; assert_eq!(run_program("(: a A) !(eval (interpret a B &self))"), Ok(vec![vec![expr!("Error" "a" "BadType")]])); -;; assert_eq!(run_program("!(eval (interpret 42 Number &self))"), Ok(vec![vec![expr!({(42)})]])); +;; assert_eq!(run_program("(: a A) !(metta a A &self)"), Ok(vec![vec![expr!("a")]])); +;; assert_eq!(run_program("(: a A) !(metta a B &self)"), Ok(vec![vec![expr!("Error" "a" "BadType")]])); +;; assert_eq!(run_program("!(metta 42 Number &self)"), Ok(vec![vec![expr!({Number::Integer(42)})]])); ;; } ;; Interpreting symbols or grounded values as specified types. +;; Converted: (: a A) +!(assertEqual (metta a A &self) a) !(assertEqual (eval (interpret a A &self)) a) !(assertEqual (eval (interpret a B &self)) (Error "a" "BadType")) !(assertEqual (eval (interpret 42 Number &self)) 42) @@ -248,6 +661,31 @@ ;; #[test] ;; fn metta_interpret_func() { ;; let result = run_program(" +;; (: a T) +;; (: foo (-> T T)) +;; (= (foo $x) $x) +;; (= (bar $x) $x) +;; !(metta (foo (bar a)) %Undefined% &self) +;; "); +;; assert_eq!(result, Ok(vec![vec![expr!("a")]])); +;; let result = run_program(" +;; (: b B) +;; (: foo (-> T T)) +;; (= (foo $x) $x) +;; !(metta (foo b) %Undefined% &self) +;; "); +;; assert_eq!(result, Ok(vec![vec![expr!("Error" "b" "BadType")]])); +;; let result = run_program(" +;; (: Nil (List $t)) +;; (: Z Nat) +;; (: S (-> Nat Nat)) +;; (: Cons (-> $t (List $t) (List $t))) +;; !(metta (Cons S (Cons Z Nil)) %Undefined% &self) +;; "); +;; assert_eq!(result, Ok(vec![vec![expr!("Error" ("Cons" "Z" "Nil") "BadType")]])); +;; } + +;; Converted: (: a T) (: foo (-> T T)) (= (foo $x) $x) @@ -335,8 +773,8 @@ ;; let metta = Metta::new(Some(EnvBuilder::test_env())); ;; let assert = AssertEqualOp::new(metta.space().clone()); ;; let program = " -(= (foo $x) $x) -(= (bar $x) $x) +;; (= (foo $x) $x) +;; (= (bar $x) $x) ;; "; ;; assert_eq!(metta.run(SExprParser::new(program)), Ok(vec![])); ;; assert_eq!(metta.run(SExprParser::new("!(assertEqual (foo A) (bar A))")), Ok(vec![ @@ -349,6 +787,10 @@ ;; vec![expr!("Error" ({assert.clone()} ("foo" "A") "Empty") "\nExpected: []\nGot: [A]\nExcessive result: A")] ;; ])); ;; } + +;; Converted: +(= (foo $x) $x) +(= (bar $x) $x) !(assertEqual (eval (assertEqual (foo A) (bar A))) ()) !(assertEqual (eval (assertEqual (foo A) (bar B))) (Error "Expected: [B] Got: [A] Missed result: B")) !(assertEqual (eval (assertEqual (foo A) Empty)) (Error "Expected: [] Got: [A] Excessive result: A")) @@ -361,11 +803,11 @@ ;; let metta = Metta::new(Some(EnvBuilder::test_env())); ;; let assert = AssertEqualToResultOp::new(metta.space().clone()); ;; let program = " -(= (foo) A) -(= (foo) B) -(= (bar) C) -(= (baz) D) -(= (baz) D) +;; (= (foo) A) +;; (= (foo) B) +;; (= (bar) C) +;; (= (baz) D) +;; (= (baz) D) ;; "; ;; assert_eq!(metta.run(SExprParser::new(program)), Ok(vec![])); ;; assert_eq!(metta.run(SExprParser::new("!(assertEqualToResult (foo) (A B))")), Ok(vec![ @@ -378,227 +820,985 @@ ;; vec![expr!("Error" ({assert.clone()} ("baz") ("D")) "\nExpected: [D]\nGot: [D, D]\nExcessive result: D")] ;; ])); ;; } -;; More granular assertion comparing operation results to expected outcomes. -!(assertEqualToResult (foo) (A B) (())) -!(assertEqualToResult (bar) (A) (Error "Expected: [A] Got: [C] Missed result: A")) -!(assertEqualToResult (baz) (D) (Error "Expected: [D] Got: [D, D] Excessive result: D")) + +;; Converted: +(= (foo) A) +(= (foo) B) +(= (bar) C) +(= (baz) D) +(= (baz) D) +!(assertEqualToResult (foo) (A B)) +!(assertEqualToResult (bar) ("Error" ("bar") ("A") "\nExpected: [A]\nGot: [C]\nMissed result: A")) +!(assertEqualToResult (baz) ("Error" ("baz") ("D") "\nExpected: [D]\nGot: [D, D]\nExcessive result: D")) + +;; Original: +;; #[test] +;; fn metta_superpose() { +;; assert_eq_metta_results!(run_program("!(superpose (red yellow green))"), +;; Ok(vec![vec![expr!("red"), expr!("yellow"), expr!("green")]])); +;; let program = " +;; (= (foo) FOO) +;; (= (bar) BAR) +;; !(superpose ((foo) (bar) BAZ)) +;; "; +;; assert_eq_metta_results!(run_program(program), +;; Ok(vec![vec![expr!("FOO"), expr!("BAR"), expr!("BAZ")]])); +;; } + +;; Converted: +!(assertEqual (superpose (red yellow green)) (red yellow green)) +(= (foo) FOO) +(= (bar) BAR) +!(assertEqual (superpose ((foo) (bar) BAZ)) (FOO BAR BAZ)) + +;; Original: +;; #[test] +;; fn metta_collapse() { +;; let program = " +;; (= (color) red) +;; (= (color) green) +;; (= (color) blue) +;; !(collapse (color)) +;; "; +;; let result = run_program(program).expect("Successful result is expected"); +;; assert_eq!(result.len(), 1); +;; let result = result.get(0).unwrap(); +;; assert_eq!(result.len(), 1); +;; let result = result.get(0).unwrap(); +;; let actual = <&ExpressionAtom>::try_from(result) +;; .expect("Expression atom is expected").children(); +;; assert_eq_no_order!(actual, vec![expr!("red"), expr!("green"), expr!("blue")]); +;; } + +;; Converted: +(= (color) red) +(= (color) green) +(= (color) blue) +!(assertEqualNoOrder (collapse (color)) (red green blue)) + +;; Original: +;; #[test] +;; fn metta_let_novar() { +;; let result = run_program("!(let (P A $b) (P $a B) (P $b $a))"); +;; assert_eq!(result, Ok(vec![vec![expr!("P" "B" "A")]])); +;; let result = run_program(" +;; (= (foo) (P A B)) +;; !(let (P A $b) (foo) (P $b A)) +;; "); +;; assert_eq!(result, Ok(vec![vec![expr!("P" "B" "A")]])); +;; let result = run_program(" +;; (= (foo) (P A B)) +;; !(let (foo) (P A $b) (P $b A)) +;; "); +;; assert_eq!(result, Ok(vec![vec![]])); +;; let result = run_program("!(let (P A $b) (P B C) (P C B))"); +;; assert_eq!(result, Ok(vec![vec![]])); +;; } + +;; Converted: +!(assertEqual (let (P A $b) (P $a B) (P $b $a)) (P B A)) +(= (foo) (P A B)) +!(assertEqual (let (P A $b) (foo) (P $b A)) (P B A)) +(= (foo) (P A B)) +!(assertEqual (let (foo) (P A $b) (P $b A)) ()) +!(assertEqual (let (P A $b) (P B C) (P C B)) ()) + +;; Original: +;; #[test] +;; fn metta_let_var() { +;; let result = run_program("!(let* () result)"); +;; assert_eq!(result, Ok(vec![vec![expr!("result")]])); +;; let result = run_program("!(let* ( ((P A $b) (P $a B)) ) (P $b $a))"); +;; assert_eq!(result, Ok(vec![vec![expr!("P" "B" "A")]])); +;; let result = run_program("!(let* ( ((P $a) (P A)) ((P B) (P $b)) ) (P $b $a))"); +;; assert_eq!(result, Ok(vec![vec![expr!("P" "B" "A")]])); +;; let result = run_program("!(let* ( ((P $a) (P A)) ((P B) (P C)) ) (P $b $a))"); +;; assert_eq!(result, Ok(vec![vec![]])); +;; } + +;; Converted: +!(assertEqual (let* () result) result) +!(assertEqual (let* (((P A $b) (P $a B))) (P $b $a)) (P B A)) +!(assertEqual (let* (((P $a) (P A)) ((P B) (P $b))) (P $b $a)) (P B A)) +!(assertEqual (let* (((P $a) (P A)) ((P B) (P C))) (P $b $a)) ()) + +;; Original: +;; #[test] +;; fn metta_quote_unquote() { +;; let header = " +;; (= (foo) A) +;; (= (bar $x) $x) +;; "; +;; assert_eq!(run_program(&format!("{header} !(bar (foo))")), Ok(vec![vec![sym!("A")]]), "sanity check"); +;; assert_eq!(run_program(&format!("{header} !(bar (quote (foo)))")), Ok(vec![vec![expr!("quote" ("foo"))]]), "quote"); +;; assert_eq!(run_program(&format!("{header} !(bar (unquote (quote (foo))))")), Ok(vec![vec![expr!("A")]]), "unquote before call"); +;; assert_eq!(run_program(&format!("{header} !(unquote (bar (quote (foo))))")), Ok(vec![vec![expr!("A")]]), "unquote after call"); +;; } + +;; Converted: +(= (foo) A) +(= (bar $x) $x) +!(assertEqual (bar (foo)) A) ;; Sanity check +!(assertEqual (bar (quote (foo))) ("quote" ("foo"))) ;; Quote +!(assertEqual (bar (unquote (quote (foo)))) A) ;; Unquote before call +!(assertEqual (unquote (bar (quote (foo)))) A) ;; Unquote after call +;; Original: +;; #[test] +;; fn test_frog_reasoning() { +;; let program = " +;; (= (is Fritz croaks) True) +;; (= (is Fritz eats-flies) True) +;; +;; (= (is Tweety chirps) True) +;; (= (is Tweety yellow) True) +;; (= (is Tweety eats-flies) True) +;; +;; !(metta (if (and (is $x croaks) (is $x eats-flies)) (= (is $x frog) True) Empty) %Undefined% &self) +;; "; +;; +;; assert_eq!(run_program(program), +;; Ok(vec![vec![expr!("=" ("is" "Fritz" "frog") {Bool(true)})]])); +;; } + +;; Converted: +(= (is Fritz croaks) True) +(= (is Fritz eats-flies) True) +(= (is Tweety chirps) True) +(= (is Tweety yellow) True) +(= (is Tweety eats-flies) True) +!(assertEqual (metta (if (and (is $x croaks) (is $x eats-flies)) (= (is $x frog) True) Empty) %Undefined% &self) ("=" ("is" "Fritz" "frog") True)) + +;; Original: +;; #[test] +;; fn test_match_all() { +;; let program = " +;; (= (color) blue) +;; (= (color) red) +;; (= (color) green) +;; +;; !(metta (color) %Undefined% &self) +;; "; +;; +;; assert_eq_metta_results!(run_program(program), +;; Ok(vec![vec![expr!("blue"), expr!("red"), expr!("green")]])); +;; } + +;; Converted: +(= (color) blue) +(= (color) red) +(= (color) green) +!(assertEqual (metta (color) %Undefined% &self) (blue red green)) + +;; Original: +;; #[test] +;; fn test_variable_keeps_value_in_different_sub_expressions() { +;; let program = " +;; (= (eq $x $x) True) +;; (= (plus Z $y) $y) +;; (= (plus (S $k) $y) (S (plus $k $y))) +;; +;; !(metta (eq (plus Z $n) $n) %Undefined% &self) +;; !(metta (eq (plus (S Z) $n) $n) %Undefined% &self) +;; "; +;; +;; assert_eq_metta_results!(run_program(program), +;; Ok(vec![vec![expr!({Bool(true)})], vec![expr!("eq" ("S" n) n)]])); +;; } + +;; Converted: +(= (eq $x $x) True) +(= (plus Z $y) $y) +(= (plus (S $k) $y) (S (plus $k $y))) +!(assertEqual (metta (eq (plus Z $n) $n) %Undefined% &self) (True)) +!(assertEqual (metta (eq (plus (S Z) $n) $n) %Undefined% &self) (eq (S $n) $n)) + +;; Original: +;; #[test] +;; fn test_variable_defined_via_variable() { +;; let program = " +;; (= (myif T $y) $y) +;; (= (mynot F) T) +;; (= (a $z) (mynot (b $z))) +;; (= (b d) F) +;; +;; !(metta (myif (a $x) $x) %Undefined% &self) +;; "; +;; +;; assert_eq_metta_results!(run_program(program), +;; Ok(vec![vec![expr!("d")]])); +;; } + +;; Converted: +(= (myif T $y) $y) +(= (mynot F) T) +(= (a $z) (mynot (b $z))) +(= (b d) F) +!(assertEqual (metta (myif (a $x) $x) %Undefined% &self) d) + +;; Original: +;; #[test] +;; fn test_variable_name_conflict() { +;; let program = " +;; (= (a ($W)) True) +;; +;; !(metta (a $W) %Undefined% &self) +;; "; +;; +;; assert_eq_metta_results!(run_program(program), +;; Ok(vec![vec![expr!({Bool(true)})]])); +;; } + +;; Converted: +(= (a ($W)) True) +!(assertEqual (metta (a $W) %Undefined% &self) True) + +;; Original: +;; #[test] +;; fn test_variable_name_conflict_renaming() { +;; let program = " +;; (= (b ($x $y)) (c $x $y)) +;; +;; !(metta (a (b $a) $x $y) %Undefined% &self) +;; "; +;; +;; let result = run_program(program); +;; assert!(result.is_ok_and(|res| res.len() == 1 && res[0].len() == 1 && +;; atoms_are_equivalent(&res[0][0], &expr!("a" ("c" a b) c d)))); +;; } + +;; Converted: +(= (b ($x $y)) (c $x $y)) +!(assertEqual (metta (a (b $a) $x $y) %Undefined% &self) (a (c a b) c d)) + +;; Original: +;; #[test] +;; fn test_operation_is_expression() { +;; let program = " +;; (: foo (-> (-> A A))) +;; (: a A) +;; (= (foo) bar) +;; (= (bar $x) $x) +;; +;; !(metta ((foo) a) %Undefined% &self) +;; "; +;; +;; assert_eq_metta_results!(run_program(program), Ok(vec![vec![expr!("a")]])); +;; } + +;; Converted: +(: foo (-> (-> A A))) +(: a A) +(= (foo) bar) +(= (bar $x) $x) +!(assertEqual (metta ((foo) a) %Undefined% &self) a) + +;; Original: +;; static ID_NUM: &Operation = &Operation{ +;; name: "id_num", +;; execute: |_, args| { +;; let arg_error = || ExecError::from("id_num expects one argument: number"); +;; let num = args.get(0).ok_or_else(arg_error)?; +;; Ok(vec![num.clone()]) +;; }, +;; typ: "(-> Number Number)", +;; }; + +;; Converted: +;; (Not directly translatable to MeTTa, as it's Rust-specific operation) + +;; Original: +;; #[test] +;; fn test_return_bad_type_error() { +;; let program1 = " +;; (: myAtom myType) +;; (: id_a (-> A A)) +;; (= (id_a $a) $a) +;; +;; !(metta (id_a myAtom) %Undefined% &self) +;; "; +;; +;; let metta = Metta::new(Some(EnvBuilder::test_env())); +;; metta.tokenizer().borrow_mut().register_token(Regex::new("id_num").unwrap(), +;; |_| Atom::gnd(ID_NUM)); +;; +;; assert_eq!(metta.run(SExprParser::new(program1)), +;; Ok(vec![vec![expr!("Error" "myAtom" "BadType")]])); +;; +;; let program2 = " +;; !(metta (id_num myAtom) %Undefined% &self) +;; "; +;; +;; assert_eq!(metta.run(SExprParser::new(program2)), +;; Ok(vec![vec![expr!("Error" "myAtom" "BadType")]])); +;; } + +;; Converted: +(: myAtom myType) +(: id_a (-> A A)) +(= (id_a $a) $a) +!(assertEqual (metta (id_a myAtom) %Undefined% &self) (Error myAtom BadType)) +!(assertEqual (metta (id_num myAtom) %Undefined% &self) (Error myAtom BadType)) + +;; Original: +;; #[test] +;; fn test_return_incorrect_number_of_args_error() { +;; let program1 = " +;; (: a A) +;; (: b B) +;; (: c C) +;; (: foo (-> A B C)) +;; (= (foo $a $b) c) +;; +;; !(metta (foo a b) %Undefined% &self) +;; "; +;; +;; let metta = Metta::new(Some(EnvBuilder::test_env())); +;; metta.tokenizer().borrow_mut().register_token(Regex::new("id_num").unwrap(), +;; |_| Atom::gnd(ID_NUM)); +;; +;; assert_eq!(metta.run(SExprParser::new(program1)), +;; Ok(vec![vec![expr!("c")]])); +;; +;; let program2 = "!(metta (foo a) %Undefined% &self)"; +;; +;; assert_eq!(metta.run(SExprParser::new(program2)), +;; Ok(vec![vec![expr!("Error" ("foo" "a") "IncorrectNumberOfArguments")]])); +;; +;; let program3 = "!(metta (foo a b c) %Undefined% &self)"; +;; +;; assert_eq!(metta.run(SExprParser::new(program3)), +;; Ok(vec![vec![expr!("Error" ("foo" "a" "b" "c") "IncorrectNumberOfArguments")]])); +;; } + +;; Converted: +(: a A) +(: b B) +(: c C) +(: foo (-> A B C)) +(= (foo $a $b) c) +!(assertEqual (metta (foo a b) %Undefined% &self) c) +!(assertEqual (metta (foo a) %Undefined% &self) (Error (foo a) IncorrectNumberOfArguments)) +!(assertEqual (metta (foo a b c) %Undefined% &self) (Error (foo a b c) IncorrectNumberOfArguments)) + +;; Original: +;; #[test] +;; fn use_sealed_to_make_scoped_variable() { +;; assert_eq!(run_program("!(let $x (input $x) (output $x))"), Ok(vec![vec![]])); +;; assert_eq!(run_program("!(let (quote ($sv $st)) (sealed ($x) (quote ($x (output $x)))) +;; (let $sv (input $x) $st))"), Ok(vec![vec![expr!("output" ("input" x))]])); +;; } + +;; Converted: +!(assertEqual (let $x (input $x) (output $x)) ()) +!(assertEqual (let (quote ($sv $st)) (sealed ($x) (quote ($x (output $x)))) (let $sv (input $x) $st)) (output (input $x))) ;;;;;;;;;;;;;;;;;;;;;; ; Test Pragma Interpreter Bare Minimal ;;;;;;;;;;;;;;;;;;;;;; + + +;; Original: ;; #[test] ;; fn test_pragma_interpreter_bare_minimal() { ;; let program = " -(= (bar) baz) -(= (foo) (bar)) -;; !(eval (foo)) +;; (= (bar) baz) +;; (= (foo) (bar)) +;; !(foo) ;; !(pragma! interpreter bare-minimal) +;; !(foo) ;; !(eval (foo)) ;; "; -;; assert_eq!(metta_results!(run_program(program)), +;; +;; assert_eq_metta_results!(run_program(program), ;; Ok(vec![ ;; vec![expr!("baz")], ;; vec![UNIT_ATOM()], +;; vec![expr!(("foo"))], ;; vec![expr!(("bar"))], ;; ])); ;; } -!(assertEqual (eval (foo)) baz) +(= (bar) baz) +(= (foo) (bar)) +!(assertEqual (foo) baz) !(assertEqual (pragma! interpreter bare-minimal) ()) -!(assertEqual (eval (foo)) bar) +!(assertEqual (foo) (foo)) +!(assertEqual (eval (foo)) (bar)) + + + + + + + + + + + ;;;; tref.register_token(regex(r"if-equal"), move |_| { is_equivalent.clone() }); ;;;; tref.register_token(regex(r"register-module!"), move |_| { register_module_op.clone() }); ;;;; tref.register_token(regex(r"mod-space!"), move |_| { mod_space_op.clone() }); ;;;; tref.register_token(regex(r"print-mods!"), move |_| { print_mods_op.clone() }); +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Un-commented Rust Tests with Original Source +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; Original: +;; #[test] +;; fn println_op() { +;; assert_eq!(PrintlnOp{}.execute(&mut vec![sym!("A")]), unit_result()); +;; } +;; Converted: +!(assertEqual (println! "A") ()) + +;; Original: +;; #[test] +;; fn trace_op() { +;; assert_eq!(TraceOp{}.execute(&mut vec![sym!("\"Here?\""), sym!("42")]), +;; Ok(vec![sym!("42")])); +;; } +;; Converted: +!(assertEqual (trace! "Here?" 42) 42) + +;; Original: +;; #[test] +;; fn nop_op() { +;; assert_eq!(NopOp{}.execute(&mut vec![]), unit_result()); +;; } +;; Converted: +!(assertEqual (nop) ()) + +;; Original: +;; #[test] +;; fn let_op() { +;; assert_eq!(LetOp{}.execute(&mut vec![expr!(a b), expr!("A" "B"), expr!(b a)]), +;; Ok(vec![expr!("B" "A")])); +;; } +;; Converted: +!(assertEqual (let ($a $b) (A B) ($b $a)) (B A)) + +;; Original: +;; #[test] +;; fn let_op_external_vars_at_right_are_kept_untouched() { +;; assert_eq!(LetOp{}.execute(&mut vec![expr!(t), expr!(ext), expr!(t)]), +;; Ok(vec![expr!(ext)])); +;; assert_eq!(LetOp{}.execute(&mut vec![expr!(t), expr!(ext "A"), expr!(t)]), +;; Ok(vec![expr!(ext "A")])); +;; } +;; Converted: +!(assertEqual (let $t $ext $t) $ext) +!(assertEqual (let $t ("ext" "A") $t) ("ext" "A")) + +;; Original: +;; #[test] +;; fn let_op_internal_variables_has_priority_in_template() { +;; assert_eq!(LetOp{}.execute(&mut vec![expr!(x), expr!(x "A"), expr!(x)]), +;; Ok(vec![expr!(x "A")])); +;; } +;; Converted: +!(assertEqual (let $x ($x A) $x) ($x A)) + +;; Original: +;; #[test] +;; fn let_op_keep_variables_equalities_issue290() { +;; assert_eq_metta_results!(run_program("!(let* (($f f) ($f $x)) $x)"), Ok(vec![vec![expr!("f")]])); +;; assert_eq_metta_results!(run_program("!(let* (($f $x) ($f f)) $x)"), Ok(vec![vec![expr!("f")]])); +;; assert_eq_metta_results!(run_program("!(let (quote ($x $x)) (quote ($z $y)) (let $y A ($z $y)))"), Ok(vec![vec![expr!("A" "A")]])); +;; assert_eq_metta_results!(run_program("!(let (quote ($x $x)) (quote ($z $y)) (let $z A ($z $y)))"), Ok(vec![vec![expr!("A" "A")]])); +;; } +;; Converted: +!(assertEqualToResult (let* (($f f) ($f $x)) $x) (f)) +!(assertEqualToResult (let* (($f $x) ($f f)) $x) (f)) +!(assertEqualToResult (let (quote ($x $x)) (quote ($z $y)) (let $y A ($z $y))) (A A)) +!(assertEqualToResult (let (quote ($x $x)) (quote ($z $y)) (let $z A ($z $y))) (A A)) + + +;; Original: +;; #[test] +;; fn let_op_variables_visibility_pr262() { +;; let program = " +;; ;; Knowledge +;; (→ P Q) +;; (→ Q R) +;; +;; ;; Rule +;; (= (rule (→ $p $q) (→ $q $r)) (→ $p $r)) +;; +;; ;; Query (does not work as expected) +;; (= (query $kb) +;; (let* (($pq (→ $p $q)) +;; ($qr (→ $q $r))) +;; (match $kb +;; ;; Premises +;; (, $pq $qr) +;; ;; Conclusion +;; (rule $pq $qr)))) +;; +;; ;; Call +;; !(query &self) +;; ;; [(→ P R)] +;; "; +;; assert_eq_metta_results!(run_program(program), Ok(vec![vec![expr!("→" "P" "R")]])); +;; } +;; Converted: +(→ P Q) +(→ Q R) +(= (rule (→ $p $q) (→ $q $r)) (→ $p $r)) +!(assertEqualToResult (query (let* (($pq (→ $p $q)) ($qr (→ $q $r))) (match $kb (, $pq $qr) (rule $pq $qr)))) (→ P R)) + + +;; Original: +;; #[test] +;; fn let_var_op() { +;; assert_eq!(LetVarOp{}.execute(&mut vec![expr!(), sym!("B")]), +;; Ok(vec![sym!("B")])); +;; assert_eq!(LetVarOp{}.execute(&mut vec![expr!(((a "A"))), expr!(a)]), +;; Ok(vec![expr!({LetOp{}} a "A" a)])); +;; assert_eq!(LetVarOp{}.execute(&mut vec![expr!((a "A") (b "B")), expr!(b a)]), +;; Ok(vec![expr!({LetOp{}} a "A" ({LetVarOp{}} ((b "B")) (b a)))])); +;; } +;; Converted: +!(assertEqual (let* () B) B) +!(assertEqual (let* (($a A)) $a) (let $a A $a)) +!(assertEqual (let* (($a A) ($b B)) ($b $a)) (let $a A (let* (($b B)) ($b $a)))) + +;; Original: +;; #[test] +;; fn state_ops() { +;; let result = NewStateOp{}.execute(&mut vec![expr!("A" "B")]).unwrap(); +;; let old_state = result.get(0).ok_or("error").unwrap(); +;; assert_eq!(old_state, &Atom::gnd(StateAtom::new(expr!("A" "B")))); +;; let result = ChangeStateOp{}.execute(&mut vec!(old_state.clone(), expr!("C" "D"))).unwrap(); +;; let new_state = result.get(0).ok_or("error").unwrap(); +;; assert_eq!(old_state, new_state); +;; assert_eq!(new_state, &Atom::gnd(StateAtom::new(expr!("C" "D")))); +;; let result = GetStateOp{}.execute(&mut vec![new_state.clone()]); +;; assert_eq!(result, Ok(vec![expr!("C" "D")])) +;; } +;; Converted: +!(bind! result (new-state! (A B))) +!(bind! old-state (first result)) +!(bind! result (change-state! old-state (C D))) +!(bind! new-state (first result)) +!(assertEqual old-state new-state) +!(assertEqual (get-state! new-state) ((C D))) + + +;; Original: +;; #[test] +;; fn test_stdlib_uses_rust_grounded_tokens() { +;; assert_eq!(run_program("!(if True ok nok)"), Ok(vec![vec![Atom::sym("ok")]])); +;; } +;; Converted: +!(assertEqualToResult (if True ok nok) (ok)) + +;; Original: +;; #[test] +;; fn test_let_op_inside_other_operation() { +;; assert_eq!(run_program("!(and True (let $x False $x))"), Ok(vec![vec![expr!({Bool(false)})]])); +;; } +;; Converted: +!(assertEqualToResult (and True (let $x False $x)) (False)) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Converted Rust Tests with Original Source +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Original: +;; #[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"))], +;; ])); +;; } +;; Converted: +(= (foo) a) +(= (foo) b) +!(assertEqualToResult (foo) (a b)) +!(assertEqualToResult (quote (foo)) (quote (foo))) + +;; Original: +;; #[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) +;; !(unify ($x a) (b $x) 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")], +;; vec![expr!("nok")] +;; ])); +;; } +;; Converted: +!(assertEqualToResult (unify (a $b 1 (d)) (a $a 1 (d)) ok nok) (ok)) +!(assertEqualToResult (unify (a $b c) (a b $c) (ok $b $c) nok) (ok b c)) +!(assertEqualToResult (unify $a (a b c) (ok $a) nok) (ok (a b c))) +!(assertEqualToResult (unify (a b c) $a (ok $a) nok) (ok (a b c))) +!(assertEqualToResult (unify (a b c) (a b d) ok nok) (nok)) +!(assertEqualToResult (unify ($x a) (b $x) ok nok) (nok)) + +;; Original: +;; #[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![]])); +;; } +;; Converted: +!(assertEqualToResult (empty) ()) +!(assertNotEqual (empty) ()) + +;; Original: +;; #[test] +;; fn sealed_op_runner() { +;; let nested = run_program("!(sealed ($x) (sealed ($a $b) (quote (= ($a $x $c) ($b)))))"); +;; let simple_replace = run_program("!(sealed ($x $y) (quote (= ($y $z))))"); +;; +;; assert!(crate::atom::matcher::atoms_are_equivalent(&nested.unwrap()[0][0], &expr!("quote" ("=" (a b c) (z))))); +;; assert!(crate::atom::matcher::atoms_are_equivalent(&simple_replace.unwrap()[0][0], &expr!("quote" ("=" (y z))))); +;; } +;; Converted: +!(assertEqual (sealed ($x) (sealed ($a $b) (quote (= ($a $x $c) ($b))))) (quote (= (a b c) (z)))) +!(assertEqual (sealed ($x $y) (quote (= ($y $z)))) (quote (= (y z)))) + +;; Original: +;; #[test] +;; fn sealed_op_execute() { +;; let val = SealedOp{}.execute(&mut vec![expr!(x y), expr!("="(y z))]); +;; assert!(crate::atom::matcher::atoms_are_equivalent(&val.unwrap()[0], &expr!("="(y z)))); +;; } + +;; Converted: +!(assertEqual (sealed ($x $y) (= ($y $z))) (= ($y $z))) + +;; Original: +;; #[test] +;; fn use_sealed_to_make_scoped_variable() { +;; assert_eq!(run_program("!(let $x (input $x) (output $x))"), Ok(vec![vec![expr!("output" ("input" x))]])); +;; assert_eq!(run_program("!(let (quote ($sv $st)) (sealed ($x) (quote ($x (output $x)))) +;; (let $sv (input $x) $st))"), Ok(vec![vec![expr!("output" ("input" x))]])); +;; } +;; Converted: +!(assertEqualToResult (let $x (input $x) (output $x)) (output (input x))) +!(assertEqualToResult (let (quote ($sv $st)) (sealed ($x) (quote ($x (output $x)))) (let $sv (input $x) $st)) (output (input x))) + + +;; #[derive(Clone, PartialEq, Debug)] +;; pub struct SomeGndAtom { } +;; +;; impl Display for SomeGndAtom { +;; fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +;; write!(f, "some-gnd-atom") +;; } +;; } +;; +;; impl Grounded for SomeGndAtom { +;; fn type_(&self) -> Atom { +;; Atom::expr([ARROW_SYMBOL, sym!("Arg1Type"), sym!("Arg2Type"), sym!("ReturnType")]) +;; } +;; } +;; Converted: +;; Define the grounded atom in MeTTa-compatible format. +;; This part would typically be defined in the system as an extension or plugin and referenced in the program as needed. +(: SomeGndAtom (-> Arg1Type Arg2Type ReturnType)) +;; Original: +;; #[test] +;; fn test_get_doc_func() { +;; let metta = Metta::new(Some(EnvBuilder::test_env())); +;; let parser = SExprParser::new(r#" +;; (: Arg1Type Type) +;; (: Arg2Type Type) +;; (: ReturnType Type) +;; (: some-func (-> Arg1Type Arg2Type ReturnType)) +;; (@doc some-func +;; (@desc "Test function") +;; (@params ( +;; (@param "First argument") +;; (@param "Second argument") +;; )) +;; (@return "Return value") +;; ) +;; +;; !(get-doc some-func) +;; "#); +;; +;; assert_eq_metta_results!(metta.run(parser), Ok(vec![ +;; vec![expr!("@doc-formal" +;; ("@item" "some-func") +;; ("@kind" "function") +;; ("@type" ("->" "Arg1Type" "Arg2Type" "ReturnType")) +;; ("@desc" {Str::from_str("Test function")}) +;; ("@params" ( +;; ("@param" ("@type" "Arg1Type") ("@desc" {Str::from_str("First argument")})) +;; ("@param" ("@type" "Arg2Type") ("@desc" {Str::from_str("Second argument")})) )) +;; ("@return" ("@type" "ReturnType") ("@desc" {Str::from_str("Return value")}) )], +;; ])); +;; } + +;; Converted: +(: Arg1Type Type) +(: Arg2Type Type) +(: ReturnType Type) +(: some-func (-> Arg1Type Arg2Type ReturnType)) +(@doc some-func + (@desc "Test function") + (@params ( + (@param (@type Arg1Type) (@desc "First argument")) + (@param (@type Arg2Type) (@desc "Second argument")) )) + (@return (@type ReturnType) (@desc "Return value"))) +!(assertEqual (get-doc some-func) (@doc-formal + (@item "some-func") + (@kind "function") + (@type (-> Arg1Type Arg2Type ReturnType)) + (@desc Test function) + (@params ( + (@param (@type Arg1Type) (@desc "First argument")) + (@param (@type Arg2Type) (@desc "Second argument")) )) + (@return (@type ReturnType) (@desc "Return value")))) + +;; Original: +;; #[test] +;; fn test_get_doc_atom() { +;; let metta = Metta::new(Some(EnvBuilder::test_env())); +;; let parser = SExprParser::new(r#" +;; (: SomeAtom SomeType) +;; (@doc SomeAtom (@desc "Test symbol atom having specific type")) +;; +;; !(get-doc SomeAtom) +;; "#); +;; +;; assert_eq_metta_results!(metta.run(parser), Ok(vec![ +;; vec![expr!("@doc-formal" +;; ("@item" "SomeAtom") +;; ("@kind" "atom") +;; ("@type" "SomeType") +;; ("@desc" {Str::from_str("Test symbol atom having specific type")}) )], +;; ])); +;; } - #[derive(Clone, PartialEq, Debug)] - pub struct SomeGndAtom { } - - impl Display for SomeGndAtom { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "some-gnd-atom") - } - } - - impl Grounded for SomeGndAtom { - fn type_(&self) -> Atom { - Atom::expr([ARROW_SYMBOL, sym!("Arg1Type"), sym!("Arg2Type"), sym!("RetType")]) - } - } - - #[test] - fn test_get_doc_func() { - let metta = Metta::new(Some(EnvBuilder::test_env())); - let parser = SExprParser::new(r#" - (: Arg1Type Type) - (: Arg2Type Type) - (: RetType Type) - (: some-func (-> Arg1Type Arg2Type RetType)) - (@doc some-func - (@desc "Test function") - (@params ( - (@param "First argument") - (@param "Second argument") - )) - (@return "Return value") - ) - - !(get-doc some-func) - "#); - - assert_eq_metta_results!(metta.run(parser), Ok(vec![ - vec![expr!("@doc-formal" - ("@item" "some-func") - ("@kind" "function") - ("@type" ("->" "Arg1Type" "Arg2Type" "RetType")) - ("@desc" {Str::from_str("Test function")}) - ("@params" ( - ("@param" ("@type" "Arg1Type") ("@desc" {Str::from_str("First argument")})) - ("@param" ("@type" "Arg2Type") ("@desc" {Str::from_str("Second argument")})) )) - ("@return" ("@type" "RetType") ("@desc" {Str::from_str("Return value")})) )], - ])); - } - - #[test] - fn test_get_doc_atom() { - let metta = Metta::new(Some(EnvBuilder::test_env())); - let parser = SExprParser::new(r#" - (: SomeAtom SomeType) - (@doc SomeAtom (@desc "Test symbol atom having specific type")) - - !(get-doc SomeAtom) - "#); - - assert_eq_metta_results!(metta.run(parser), Ok(vec![ - vec![expr!("@doc-formal" - ("@item" "SomeAtom") - ("@kind" "atom") - ("@type" "SomeType") - ("@desc" {Str::from_str("Test symbol atom having specific type")}) )], - ])); - } - - #[test] - fn test_get_doc_gnd_func() { - let metta = Metta::new(Some(EnvBuilder::test_env())); - metta.tokenizer().borrow_mut() - .register_token(regex::Regex::new(r"some-gnd-atom").unwrap(), |_| Atom::gnd(SomeGndAtom{})); - let parser = SExprParser::new(r#" - (@doc some-gnd-atom - (@desc "Test function") - (@params ( - (@param "First argument") - (@param "Second argument") - )) - (@return "Return value") - ) - !(get-doc some-gnd-atom) - "#); - - assert_eq_metta_results!(metta.run(parser), Ok(vec![ - vec![expr!("@doc-formal" - ("@item" {SomeGndAtom{}}) - ("@kind" "function") - ("@type" ("->" "Arg1Type" "Arg2Type" "RetType")) - ("@desc" {Str::from_str("Test function")}) - ("@params" ( - ("@param" ("@type" "Arg1Type") ("@desc" {Str::from_str("First argument")})) - ("@param" ("@type" "Arg2Type") ("@desc" {Str::from_str("Second argument")})) )) - ("@return" ("@type" "RetType") ("@desc" {Str::from_str("Return value")})) )], - ])); - } - - #[test] - fn test_get_doc_no_doc() { - let metta = Metta::new(Some(EnvBuilder::test_env())); - let parser = SExprParser::new(r#" - !(get-doc NoSuchAtom) - "#); - - assert_eq_metta_results!(metta.run(parser), Ok(vec![ - vec![expr!("@doc-formal" - ("@item" "NoSuchAtom") - ("@kind" "atom") - ("@type" "%Undefined%") - ("@desc" {Str::from_str("No documentation")}) )], - ])); - } - - #[test] - fn test_get_doc_function_call() { - let metta = Metta::new(Some(EnvBuilder::test_env())); - let parser = SExprParser::new(r#" - (: Arg1Type Type) - (: Arg2Type Type) - (: RetType Type) - (: some-func (-> Arg1Type Arg2Type RetType)) - (@doc some-func - (@desc "Test function") - (@params ( - (@param "First argument") - (@param "Second argument") - )) - (@return "Return value") - ) - - !(get-doc (some-func arg1 arg2)) - "#); - - assert_eq_metta_results!(metta.run(parser), Ok(vec![ - vec![expr!("@doc-formal" - ("@item" ("some-func" "arg1" "arg2")) - ("@kind" "atom") - ("@type" "RetType") - ("@desc" {Str::from_str("No documentation")}) )], - ])); - } - - #[test] - fn test_get_doc_no_type() { - let metta = Metta::new(Some(EnvBuilder::test_env())); - let parser = SExprParser::new(r#" - (@doc some-func-no-type - (@desc "Test function") - (@params ( - (@param "First argument") - (@param "Second argument") - )) - (@return "Return value") - ) - - !(get-doc some-func-no-type) - "#); - - assert_eq_metta_results!(metta.run(parser), Ok(vec![ - vec![expr!("@doc-formal" - ("@item" "some-func-no-type") - ("@kind" "function") - ("@type" "%Undefined%") - ("@desc" {Str::from_str("Test function")}) - ("@params" ( - ("@param" ("@type" "%Undefined%") ("@desc" {Str::from_str("First argument")})) - ("@param" ("@type" "%Undefined%") ("@desc" {Str::from_str("Second argument")})) )) - ("@return" ("@type" "%Undefined%") ("@desc" {Str::from_str("Return value")})) )], - ])); - } - - #[test] - fn test_error_is_used_as_an_argument() { - let metta = Metta::new(Some(EnvBuilder::test_env())); - let parser = SExprParser::new(r#" - !(get-type Error) - !(get-metatype Error) - !(get-type (Error Foo Boo)) - !(Error (+ 1 2) (+ 1 +)) - "#); - - assert_eq_metta_results!(metta.run(parser), Ok(vec![ - vec![expr!("->" "Atom" "Atom" "ErrorType")], - vec![expr!("Symbol")], - vec![expr!("ErrorType")], - vec![expr!("Error" ({SumOp{}} {Number::Integer(1)} {Number::Integer(2)}) ({SumOp{}} {Number::Integer(1)} {SumOp{}}))], - ])); - } +;; Converted: +(: SomeAtom SomeType) +(@doc SomeAtom (@desc "Test symbol atom having specific type")) +!(assertEqual (get-doc SomeAtom) (@doc-formal + (@item SomeAtom) + (@kind atom) + (@type SomeType) + (@desc Test symbol atom having specific type))) + +;; Original: +;; #[test] +;; fn test_get_doc_gnd_func() { +;; let metta = Metta::new(Some(EnvBuilder::test_env())); +;; metta.tokenizer().borrow_mut() +;; .register_token(regex::Regex::new(r"some-gnd-atom").unwrap(), |_| Atom::gnd(SomeGndAtom{})); +;; let parser = SExprParser::new(r#" +;; (@doc some-gnd-atom +;; (@desc "Test function") +;; (@params ( +;; (@param "First argument") +;; (@param "Second argument") +;; )) +;; (@return "Return value") +;; ) +;; !(get-doc some-gnd-atom) +;; "#); +;; +;; assert_eq_metta_results!(metta.run(parser), Ok(vec![ +;; vec![expr!("@doc-formal" +;; ("@item" {SomeGndAtom{}}) +;; ("@kind" "function") +;; ("@type" ("->" "Arg1Type" "Arg2Type" "ReturnType")) +;; ("@desc" {Str::from_str("Test function")}) +;; ("@params" ( +;; ("@param" ("@type" "Arg1Type") ("@desc" {Str::from_str("First argument")})) +;; ("@param" ("@type" "Arg2Type") ("@desc" {Str::from_str("Second argument")})) )) +;; ("@return" ("@type" "ReturnType") ("@desc" {Str::from_str("Return value")}) )], +;; ])); +;; } + +;; Converted: +(@doc some-gnd-atom + (@desc "Test function") + (@params ( + (@param (@type Arg1Type) (@desc "First argument")) + (@param (@type Arg2Type) (@desc "Second argument")) )) + (@return (@type ReturnType) (@desc "Return value"))) +!(assertEqual (get-doc some-gnd-atom) (@doc-formal + (@item some-gnd-atom) + (@kind function) + (@type (-> Arg1Type Arg2Type ReturnType)) + (@desc Test function) + (@params ( + (@param (@type Arg1Type) (@desc "First argument")) + (@param (@type Arg2Type) (@desc "Second argument")) )) + (@return (@type ReturnType) (@desc "Return value")))) + +;; Original: +;; #[test] +;; fn test_get_doc_no_doc() { +;; let metta = Metta::new(Some(EnvBuilder::test_env())); +;; let parser = SExprParser::new(r#" +;; !(get-doc NoSuchAtom) +;; "#); +;; +;; assert_eq_metta_results!(metta.run(parser), Ok(vec![ +;; vec![expr!("@doc-formal" +;; ("@item" "NoSuchAtom") +;; ("@kind" "atom") +;; ("@type" "%Undefined%") +;; ("@desc" {Str::from_str("No documentation")}) )], +;; ])); +;; } + +;; Converted: +!(assertEqual (get-doc NoSuchAtom) (@doc-formal + (@item NoSuchAtom) + (@kind atom) + (@type %Undefined%) + (@desc No documentation))) + +;; Original: +;; #[test] +;; fn test_get_doc_function_call() { +;; let metta = Metta::new(Some(EnvBuilder::test_env())); +;; let parser = SExprParser::new(r#" +;; (: Arg1Type Type) +;; (: Arg2Type Type) +;; (: ReturnType Type) +;; (: some-func (-> Arg1Type Arg2Type ReturnType)) +;; (@doc some-func +;; (@desc "Test function") +;; (@params ( +;; (@param "First argument") +;; (@param "Second argument") +;; )) +;; (@return "Return value") +;; ) +;; +;; !(get-doc (some-func arg1 arg2)) +;; "#); +;; +;; assert_eq_metta_results!(metta.run(parser), Ok(vec![ +;; vec![expr!("@doc-formal" +;; ("@item" ("some-func" "arg1" "arg2")) +;; ("@kind" "atom") +;; ("@type" "ReturnType") +;; ("@desc" {Str::from_str("No documentation")}) )], +;; ])); +;; } + +;; Converted: +(: Arg1Type Type) +(: Arg2Type Type) +(: ReturnType Type) +(: some-func (-> Arg1Type Arg2Type ReturnType)) +(@doc some-func + (@desc "Test function") + (@params ( + (@param (@type Arg1Type) (@desc "First argument")) + (@param (@type Arg2Type) (@desc "Second argument")) )) + (@return (@type ReturnType) (@desc "Return value"))) +!(assertEqual (get-doc (some-func arg1 arg2)) (@doc-formal + (@item (some-func arg1 arg2)) + (@kind atom) + (@type ReturnType) + (@desc No documentation))) + +;; Original: +;; #[test] +;; fn test_get_doc_no_type() { +;; let metta = Metta::new(Some(EnvBuilder::test_env())); +;; let parser = SExprParser::new(r#" +;; (@doc some-func-no-type +;; (@desc "Test function") +;; (@params ( +;; (@param "First argument") +;; (@param "Second argument") +;; )) +;; (@return "Return value") +;; ) +;; +;; !(get-doc some-func-no-type) +;; "#); +;; +;; assert_eq_metta_results!(metta.run(parser), Ok(vec![ +;; vec![expr!("@doc-formal" +;; ("@item" "some-func-no-type") +;; ("@kind" "function") +;; ("@type" "%Undefined%") +;; ("@desc" {Str::from_str("Test function")}) +;; ("@params" ( +;; ("@param" ("@type" "%Undefined%") ("@desc" {Str::from_str("First argument")})) +;; ("@param" ("@type" "%Undefined%") ("@desc" {Str::from_str("Second argument")})) )) +;; ("@return" ("@type" "%Undefined%") ("@desc" {Str::from_str("Return value")}) )], +;; ])); +;; } + +;; Converted: +(@doc some-func-no-type + (@desc "Test function") + (@params ( + (@param (@type %Undefined%) (@desc "First argument")) + (@param (@type %Undefined%) (@desc "Second argument")) )) + (@return (@type %Undefined%) (@desc "Return value"))) +!(assertEqual (get-doc some-func-no-type) (@doc-formal + (@item some-func-no-type) + (@kind function) + (@type %Undefined%) + (@desc Test function) + (@params ( + (@param (@type %Undefined%) (@desc "First argument")) + (@param (@type %Undefined%) (@desc "Second argument")) )) + (@return (@type %Undefined%) (@desc "Return value")))) + +;; Original: +;; #[test] +;; fn test_error_is_used_as_an_argument() { +;; let metta = Metta::new(Some(EnvBuilder::test_env())); +;; let parser = SExprParser::new(r#" +;; !(get-type Error) +;; !(get-metatype Error) +;; !(get-type (Error Foo Boo)) +;; !(Error (+ 1 2) (+ 1 +)) +;; "#); +;; +;; assert_eq_metta_results!(metta.run(parser), Ok(vec![ +;; vec![expr!("->" "Atom" "Atom" "ErrorType")], +;; vec![expr!("Symbol")], +;; vec![expr!("ErrorType")], +;; vec![expr!("Error" ({SumOp{}} {Number::Integer(1)} {Number::Integer(2)}) ({SumOp{}} {Number::Integer(1)} {SumOp{}}))], +;; ])); +;; } +;; Converted: +!(assertEqual (get-type Error) (-> Atom Atom ErrorType)) +!(assertEqual (get-metatype Error) Symbol) +!(assertEqual (get-type (Error Foo Boo)) ErrorType) +!(assertEqual (Error (+ 1 2) (+ 1 +)) (Error (+ 1 2) (+ 1 +))) diff --git a/tests/more-anti-regression/minimal-metta/stdlib_minimal_test.metta.answers b/tests/more-anti-regression/minimal-metta/stdlib_minimal_test.metta.answers deleted file mode 100644 index c571105d5fa..00000000000 --- a/tests/more-anti-regression/minimal-metta/stdlib_minimal_test.metta.answers +++ /dev/null @@ -1,12 +0,0 @@ -[(include! &corelib stdlib_minimal)] -[(assertEqualNoOrder (Error (get-type A space) match expects a space as the first argument) (B C))] -[(assertEqualNoOrder (Error (get-type (f 42) space) match expects a space as the first argument) (String))] -[] -[()] -[()] -[(Error (assertEqual (eval (switch (A $b) (((B C) (C B)) ((D E) (E B))))) ()) -Expected: [()] -Got: [] -Missed result: ())] -0.01user 0.00system 0:00.03elapsed 90%CPU (0avgtext+0avgdata 25044maxresident)k -0inputs+0outputs (0major+3023minor)pagefaults 0swaps diff --git a/tests/more-anti-regression/stdlib-mettalog/stdlib_mettalog_test.metta b/tests/more-anti-regression/stdlib-mettalog/stdlib_mettalog_test.metta old mode 100755 new mode 100644 index cc97bbd531d..d433d1cea36 --- a/tests/more-anti-regression/stdlib-mettalog/stdlib_mettalog_test.metta +++ b/tests/more-anti-regression/stdlib-mettalog/stdlib_mettalog_test.metta @@ -1,3 +1,6 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Converted Rust Tests with Original Source +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; !(include! &corelib stdlib_mettalog) ; !(import! &self stdlib_mettalog) @@ -123,38 +126,64 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +;;#[test] +;;fn mod_space_op() { +;; let program = r#" +;; !(bind! &new_space (new-space)) +;; !(add-atom &new_space (mod-space! stdlib)) +;; !(get-atoms &new_space) +;; "#; +;; let runner = Metta::new(Some(runner::environment::EnvBuilder::test_env())); +;; let result = runner.run(SExprParser::new(program)).unwrap(); +;; +;; let stdlib_space = runner.module_space(runner.get_module_by_name("stdlib").unwrap()); +;; assert_eq!(result[2], vec![Atom::gnd(stdlib_space)]); +;;} +;; Converted: +!(bind! &new_space (new-space)) +!(add-atom &new_space (mod-space! stdlib)) +!(assertEqualToResult (get-atoms &new_space) (&stdlib)) + + +;; #[test] +;; fn match_op() { +;; let space = DynSpace::new(metta_space("(A B)")); +;; let match_op = MatchOp{}; +;; assert_eq!(match_op.execute(&mut vec![expr!({space}), expr!("A" "B"), expr!("B" "A")]), +;; Ok(vec![expr!("B" "A")])); +;; } +;; Converted: +(let space (A B)) +!(assertEqual (match! space (A B) (B A)) (B A)) + + +;; #[test] +;; fn match_op_issue_530() { +;; let space = DynSpace::new(metta_space("(A $a $a)")); +;; let match_op = MatchOp{}; +;; let result = match_op.execute(&mut vec![expr!({space}), expr!("A" x y), expr!("A" x y)]).unwrap(); +;; assert_eq!(result.len(), 1); +;; assert!(atoms_are_equivalent(&result[0], &expr!("A" x x)), +;; "atoms are not equivalent: expected: {}, actual: {}", expr!("A" x x), result[0]); +;; } +;; Converted: +(let space (A $a $a)) +(let result (match! space (A x y) (A x y))) +!(assertEqual (length result) 1) +!(assertEqual (atoms_are_equivalent (first result) (A x x)) true) + + +;; #[test] +;; fn new_space_op() { +;; let res = NewSpaceOp{}.execute(&mut vec![]).expect("No result returned"); +;; let space = res.get(0).expect("Result is empty"); +;; let space = space.as_gnd::().expect("Result is not space"); +;; let space_atoms: Vec = space.borrow().as_space().atom_iter().unwrap().cloned().collect(); +;; assert_eq_no_order!(space_atoms, Vec::::new()); +;; } +;; Converted: +!(bind! &space (new-space)) +!(assertEqualNoOrder (get-atoms &space) ()) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Converted Rust Tests with Original Source @@ -178,10 +207,10 @@ ;; ])); ;; } ;; Converted: -!(assertEqualToResults (get-type Error) (-> Atom Atom ErrorType)) -!(assertEqualToResults (get-metatype Error) (Symbol)) -!(assertEqualToResults (get-type (Error Foo Boo)) (ErrorType)) -!(assertEqualToResults (Error (+ 1 2) (+ 1 +)) (Error ({SumOp{}} {Number::Integer(1)} {Number::Integer(2)}) ({SumOp{}} {Number::Integer(1)} {SumOp{}}))) +!(assertEqualToResult (get-type Error) (-> Atom Atom ErrorType)) +!(assertEqualToResult (get-metatype Error) (Symbol)) +!(assertEqualToResult (get-type (Error Foo Boo)) (ErrorType)) +!(assertEqualToResult (Error (+ 1 2) (+ 1 +)) (Error ({SumOp{}} {Number::Integer(1)} {Number::Integer(2)}) ({SumOp{}} {Number::Integer(1)} {SumOp{}}))) @@ -227,28 +256,54 @@ ;; #[test] ;; fn get_type_op() { ;; let space = DynSpace::new(metta_space(" -(: B Type) -(: C Type) -(: A B) -(: A C) +;; (: B Type) +;; (: C Type) +;; (: A B) +;; (: A C) ;; ")); ;; ;; let get_type_op = GetTypeOp::new(space.clone()); ;; assert_eq_no_order!(get_type_op.execute(&mut vec![sym!("A"), expr!({space.clone()})]).unwrap(), ;; vec![sym!("B"), sym!("C")]); ;; } +;; Converted: +(let space (new-space)) +(: B Type) +(: C Type) +(: A B) +(: A C) ;; Defines a type space and checks if A belongs to types B and C using GetTypeOp. !(assertEqualToResult (eval (get-type A &self)) (B C)) + + + + + + + + + + + + + + + + + + ;;;;;;;;;;;;;;;;;;;;;; ; Metta GetTypeOp Non-Valid Atom ;;;;;;;;;;;;;;;;;;;;;; + +;; Original: ;; #[test] ;; fn get_type_op_non_valid_atom() { ;; let space = DynSpace::new(metta_space(" -(: f (-> Number String)) -(: 42 Number) -(: "test" String) +;; (: f (-> Number String)) +;; (: 42 Number) +;; (: \"test\" String) ;; ")); ;; ;; let get_type_op = GetTypeOp::new(space.clone()); @@ -257,6 +312,11 @@ ;; assert_eq_no_order!(get_type_op.execute(&mut vec![expr!("f" "\"test\""), expr!({space.clone()})]).unwrap(), ;; vec![EMPTY_SYMBOL]); ;; } +;; Converted: +(let space (new-space)) +(: f (-> Number String)) +(: 42 Number) +(: "test" String) !(assertEqualToResult (eval (get-type (f 42) &self)) (String)) !(assertEqual (eval (get-type (f "test") &self)) (empty)) @@ -344,6 +404,28 @@ !(assertEqual (eval (case (unify (B C) (C B) ok Empty) ((ok ok) (%void% nok)))) nok) +;;;;;;;;;;;;;;;;;;;;;; +; Metta Case Empty +;;;;;;;;;;;;;;;;;;;;;; +;; #[test] +;; fn metta_case_empty() { +;; let result = run_program("!(case Empty ( (ok ok) (Empty nok) ))"); +;; assert_eq!(result, Ok(vec![vec![expr!("nok")]])); +;; let result = run_program("!(case (unify (C B) (C B) ok Empty) ( (ok ok) (Empty nok) ))"); +;; assert_eq!(result, Ok(vec![vec![expr!("ok")]])); +;; let result = run_program("!(case (unify (B C) (C B) ok nok) ( (ok ok) (nok nok) ))"); +;; assert_eq!(result, Ok(vec![vec![expr!("nok")]])); +;; let result = run_program("!(case (unify (B C) (C B) ok Empty) ( (ok ok) (Empty nok) ))"); +;; assert_eq!(result, Ok(vec![vec![expr!("nok")]])); +;; } +;; Converted: +!(assertEqual (case Empty ( (ok ok) (Empty nok) )) (nok)) +!(assertEqual (case (unify (C B) (C B) ok Empty) ( (ok ok) (Empty nok) )) (ok)) +!(assertEqual (case (unify (B C) (C B) ok nok) ( (ok ok) (nok nok) )) (nok)) +!(assertEqual (case (unify (B C) (C B) ok Empty) ( (ok ok) (Empty nok) )) (nok)) + + + ;;;;;;;;;;;;;;;;;;;;;; ; Metta Is-Function ;;;;;;;;;;;;;;;;;;;;;; @@ -412,6 +494,8 @@ ;; assert_eq!(run_program("!(eval (filter-atom (a (b) $c) $x (eval (if-error $x False True))))"), Ok(vec![vec![expr!("a" ("b") c)]])); ;; assert_eq!(run_program("!(eval (filter-atom (a (Error (b) \"Test error\") $c) $x (eval (if-error $x False True))))"), Ok(vec![vec![expr!("a" c)]])); ;; } + +;; Converted: !(assertEqual (eval (filter-atom () $x (eval (if-error $x False True)))) ()) !(assertEqual (eval (filter-atom (a (b) $c) $x (eval (if-error $x False True)))) (a (b) c)) !(assertEqual (eval (filter-atom (a (Error (b) "Test error") $c) $x (eval (if-error $x False True)))) (a c)) @@ -470,14 +554,64 @@ ;;;;;;;;;;;;;;;;;;;;;; ; Metta Interpret Symbol or Grounded Value As Type ;;;;;;;;;;;;;;;;;;;;;; +;; Original: +;; #[test] +;; fn metta_map_atom() { +;; assert_eq!(run_program("!(eval (map-atom () $x ($x mapped)))"), Ok(vec![vec![expr!()]])); +;; assert_eq!(run_program("!(eval (map-atom (a (b) $c) $x (mapped $x)))"), Ok(vec![vec![expr!(("mapped" "a") ("mapped" ("b")) ("mapped" c))]])); +;; } + +;; Converted: +!(assertEqual (eval (map-atom () $x ($x mapped))) ()) +!(assertEqual (eval (map-atom (a (b) $c) $x (mapped $x))) ((mapped a) (mapped (b)) (mapped c))) + +;; Original: +;; #[test] +;; fn metta_foldl_atom() { +;; assert_eq!(run_program("!(eval (foldl-atom () 1 $a $b (eval (+ $a $b))))"), Ok(vec![vec![expr!({Number::Integer(1)})]])); +;; assert_eq!(run_program("!(eval (foldl-atom (1 2 3) 0 $a $b (eval (+ $a $b))))"), Ok(vec![vec![expr!({Number::Integer(6)})]])); +;; } + +;; Converted: +!(assertEqual (eval (foldl-atom () 1 $a $b (eval (+ $a $b)))) {Number::Integer(1)}) +!(assertEqual (eval (foldl-atom (1 2 3) 0 $a $b (eval (+ $a $b)))) {Number::Integer(6)}) + +;; Original: +;; #[test] +;; fn metta_interpret_single_atom_as_atom() { +;; let result = run_program("!(metta A Atom &self)"); +;; assert_eq!(result, Ok(vec![vec![expr!("A")]])); +;; } + +;; Converted: +!(assertEqual (metta A Atom &self) A) + +;; Original: +;; #[test] +;; fn metta_interpret_single_atom_as_meta_type() { +;; assert_eq!(run_program("!(metta A Symbol &self)"), Ok(vec![vec![expr!("A")]])); +;; assert_eq!(run_program("!(metta $x Variable &self)"), Ok(vec![vec![expr!(x)]])); +;; assert_eq!(run_program("!(metta (A B) Expression &self)"), Ok(vec![vec![expr!("A" "B")]])); +;; assert_eq!(run_program("!(metta 42 Grounded &self)"), Ok(vec![vec![expr!({Number::Integer(42)})]])); +;; } + +;; Converted: +!(assertEqual (metta A Symbol &self) A) +!(assertEqual (metta $x Variable &self) x) +!(assertEqual (metta (A B) Expression &self) (A B)) +!(assertEqual (metta 42 Grounded &self) {Number::Integer(42)}) + +;; Original: ;; #[test] ;; fn metta_interpret_symbol_or_grounded_value_as_type() { -;; assert_eq!(run_program("(: a A) !(eval (interpret a A &self))"), Ok(vec![vec![expr!("a")]])); -;; assert_eq!(run_program("(: a A) !(eval (interpret a B &self))"), Ok(vec![vec![expr!("Error" "a" "BadType")]])); -;; assert_eq!(run_program("!(eval (interpret 42 Number &self))"), Ok(vec![vec![expr!({(42)})]])); +;; assert_eq!(run_program("(: a A) !(metta a A &self)"), Ok(vec![vec![expr!("a")]])); +;; assert_eq!(run_program("(: a A) !(metta a B &self)"), Ok(vec![vec![expr!("Error" "a" "BadType")]])); +;; assert_eq!(run_program("!(metta 42 Number &self)"), Ok(vec![vec![expr!({Number::Integer(42)})]])); ;; } ;; Interpreting symbols or grounded values as specified types. +;; Converted: (: a A) +!(assertEqual (metta a A &self) a) !(assertEqual (eval (interpret a A &self)) a) !(assertEqual (eval (interpret a B &self)) (Error "a" "BadType")) !(assertEqual (eval (interpret 42 Number &self)) 42) @@ -525,6 +659,31 @@ ;; #[test] ;; fn metta_interpret_func() { ;; let result = run_program(" +;; (: a T) +;; (: foo (-> T T)) +;; (= (foo $x) $x) +;; (= (bar $x) $x) +;; !(metta (foo (bar a)) %Undefined% &self) +;; "); +;; assert_eq!(result, Ok(vec![vec![expr!("a")]])); +;; let result = run_program(" +;; (: b B) +;; (: foo (-> T T)) +;; (= (foo $x) $x) +;; !(metta (foo b) %Undefined% &self) +;; "); +;; assert_eq!(result, Ok(vec![vec![expr!("Error" "b" "BadType")]])); +;; let result = run_program(" +;; (: Nil (List $t)) +;; (: Z Nat) +;; (: S (-> Nat Nat)) +;; (: Cons (-> $t (List $t) (List $t))) +;; !(metta (Cons S (Cons Z Nil)) %Undefined% &self) +;; "); +;; assert_eq!(result, Ok(vec![vec![expr!("Error" ("Cons" "Z" "Nil") "BadType")]])); +;; } + +;; Converted: (: a T) (: foo (-> T T)) (= (foo $x) $x) @@ -612,8 +771,8 @@ ;; let metta = Metta::new(Some(EnvBuilder::test_env())); ;; let assert = AssertEqualOp::new(metta.space().clone()); ;; let program = " -(= (foo $x) $x) -(= (bar $x) $x) +;; (= (foo $x) $x) +;; (= (bar $x) $x) ;; "; ;; assert_eq!(metta.run(SExprParser::new(program)), Ok(vec![])); ;; assert_eq!(metta.run(SExprParser::new("!(assertEqual (foo A) (bar A))")), Ok(vec![ @@ -626,6 +785,10 @@ ;; vec![expr!("Error" ({assert.clone()} ("foo" "A") "Empty") "\nExpected: []\nGot: [A]\nExcessive result: A")] ;; ])); ;; } + +;; Converted: +(= (foo $x) $x) +(= (bar $x) $x) !(assertEqual (eval (assertEqual (foo A) (bar A))) ()) !(assertEqual (eval (assertEqual (foo A) (bar B))) (Error "Expected: [B] Got: [A] Missed result: B")) !(assertEqual (eval (assertEqual (foo A) Empty)) (Error "Expected: [] Got: [A] Excessive result: A")) @@ -638,11 +801,11 @@ ;; let metta = Metta::new(Some(EnvBuilder::test_env())); ;; let assert = AssertEqualToResultOp::new(metta.space().clone()); ;; let program = " -(= (foo) A) -(= (foo) B) -(= (bar) C) -(= (baz) D) -(= (baz) D) +;; (= (foo) A) +;; (= (foo) B) +;; (= (bar) C) +;; (= (baz) D) +;; (= (baz) D) ;; "; ;; assert_eq!(metta.run(SExprParser::new(program)), Ok(vec![])); ;; assert_eq!(metta.run(SExprParser::new("!(assertEqualToResult (foo) (A B))")), Ok(vec![ @@ -655,14 +818,174 @@ ;; vec![expr!("Error" ({assert.clone()} ("baz") ("D")) "\nExpected: [D]\nGot: [D, D]\nExcessive result: D")] ;; ])); ;; } -;; More granular assertion comparing operation results to expected outcomes. -!(assertEqualToResult (foo) (A B) (())) -!(assertEqualToResult (bar) (A) (Error "Expected: [A] Got: [C] Missed result: A")) -!(assertEqualToResult (baz) (D) (Error "Expected: [D] Got: [D, D] Excessive result: D")) +;; Converted: +(= (foo) A) +(= (foo) B) +(= (bar) C) +(= (baz) D) +(= (baz) D) +!(assertEqualToResult (foo) (A B)) +!(assertEqualToResult (bar) ("Error" ("bar") ("A") "\nExpected: [A]\nGot: [C]\nMissed result: A")) +!(assertEqualToResult (baz) ("Error" ("baz") ("D") "\nExpected: [D]\nGot: [D, D]\nExcessive result: D")) + +;; Original: +;; #[test] +;; fn metta_superpose() { +;; assert_eq_metta_results!(run_program("!(superpose (red yellow green))"), +;; Ok(vec![vec![expr!("red"), expr!("yellow"), expr!("green")]])); +;; let program = " +;; (= (foo) FOO) +;; (= (bar) BAR) +;; !(superpose ((foo) (bar) BAZ)) +;; "; +;; assert_eq_metta_results!(run_program(program), +;; Ok(vec![vec![expr!("FOO"), expr!("BAR"), expr!("BAZ")]])); +;; } + +;; Converted: +!(assertEqual (superpose (red yellow green)) (red yellow green)) +(= (foo) FOO) +(= (bar) BAR) +!(assertEqual (superpose ((foo) (bar) BAZ)) (FOO BAR BAZ)) + +;; Original: +;; #[test] +;; fn metta_collapse() { +;; let program = " +;; (= (color) red) +;; (= (color) green) +;; (= (color) blue) +;; !(collapse (color)) +;; "; +;; let result = run_program(program).expect("Successful result is expected"); +;; assert_eq!(result.len(), 1); +;; let result = result.get(0).unwrap(); +;; assert_eq!(result.len(), 1); +;; let result = result.get(0).unwrap(); +;; let actual = <&ExpressionAtom>::try_from(result) +;; .expect("Expression atom is expected").children(); +;; assert_eq_no_order!(actual, vec![expr!("red"), expr!("green"), expr!("blue")]); +;; } + +;; Converted: +(= (color) red) +(= (color) green) +(= (color) blue) +!(assertEqualNoOrder (collapse (color)) (red green blue)) + +;; Original: +;; #[test] +;; fn metta_let_novar() { +;; let result = run_program("!(let (P A $b) (P $a B) (P $b $a))"); +;; assert_eq!(result, Ok(vec![vec![expr!("P" "B" "A")]])); +;; let result = run_program(" +;; (= (foo) (P A B)) +;; !(let (P A $b) (foo) (P $b A)) +;; "); +;; assert_eq!(result, Ok(vec![vec![expr!("P" "B" "A")]])); +;; let result = run_program(" +;; (= (foo) (P A B)) +;; !(let (foo) (P A $b) (P $b A)) +;; "); +;; assert_eq!(result, Ok(vec![vec![]])); +;; let result = run_program("!(let (P A $b) (P B C) (P C B))"); +;; assert_eq!(result, Ok(vec![vec![]])); +;; } + +;; Converted: +!(assertEqual (let (P A $b) (P $a B) (P $b $a)) (P B A)) +(= (foo) (P A B)) +!(assertEqual (let (P A $b) (foo) (P $b A)) (P B A)) +(= (foo) (P A B)) +!(assertEqual (let (foo) (P A $b) (P $b A)) ()) +!(assertEqual (let (P A $b) (P B C) (P C B)) ()) + +;; Original: +;; #[test] +;; fn metta_let_var() { +;; let result = run_program("!(let* () result)"); +;; assert_eq!(result, Ok(vec![vec![expr!("result")]])); +;; let result = run_program("!(let* ( ((P A $b) (P $a B)) ) (P $b $a))"); +;; assert_eq!(result, Ok(vec![vec![expr!("P" "B" "A")]])); +;; let result = run_program("!(let* ( ((P $a) (P A)) ((P B) (P $b)) ) (P $b $a))"); +;; assert_eq!(result, Ok(vec![vec![expr!("P" "B" "A")]])); +;; let result = run_program("!(let* ( ((P $a) (P A)) ((P B) (P C)) ) (P $b $a))"); +;; assert_eq!(result, Ok(vec![vec![]])); +;; } + +;; Converted: +!(assertEqual (let* () result) result) +!(assertEqual (let* (((P A $b) (P $a B))) (P $b $a)) (P B A)) +!(assertEqual (let* (((P $a) (P A)) ((P B) (P $b))) (P $b $a)) (P B A)) +!(assertEqual (let* (((P $a) (P A)) ((P B) (P C))) (P $b $a)) ()) + +;; Original: +;; #[test] +;; fn metta_quote_unquote() { +;; let header = " +;; (= (foo) A) +;; (= (bar $x) $x) +;; "; +;; assert_eq!(run_program(&format!("{header} !(bar (foo))")), Ok(vec![vec![sym!("A")]]), "sanity check"); +;; assert_eq!(run_program(&format!("{header} !(bar (quote (foo)))")), Ok(vec![vec![expr!("quote" ("foo"))]]), "quote"); +;; assert_eq!(run_program(&format!("{header} !(bar (unquote (quote (foo))))")), Ok(vec![vec![expr!("A")]]), "unquote before call"); +;; assert_eq!(run_program(&format!("{header} !(unquote (bar (quote (foo))))")), Ok(vec![vec![expr!("A")]]), "unquote after call"); +;; } + +;; Converted: +(= (foo) A) +(= (bar $x) $x) +!(assertEqual (bar (foo)) A) ;; Sanity check +!(assertEqual (bar (quote (foo))) ("quote" ("foo"))) ;; Quote +!(assertEqual (bar (unquote (quote (foo)))) A) ;; Unquote before call +!(assertEqual (unquote (bar (quote (foo)))) A) ;; Unquote after call +;; Original: +;; #[test] +;; fn test_frog_reasoning() { +;; let program = " +;; (= (is Fritz croaks) True) +;; (= (is Fritz eats-flies) True) +;; +;; (= (is Tweety chirps) True) +;; (= (is Tweety yellow) True) +;; (= (is Tweety eats-flies) True) +;; +;; !(metta (if (and (is $x croaks) (is $x eats-flies)) (= (is $x frog) True) Empty) %Undefined% &self) +;; "; +;; +;; assert_eq!(run_program(program), +;; Ok(vec![vec![expr!("=" ("is" "Fritz" "frog") {Bool(true)})]])); +;; } +;; Converted: +(= (is Fritz croaks) True) +(= (is Fritz eats-flies) True) +(= (is Tweety chirps) True) +(= (is Tweety yellow) True) +(= (is Tweety eats-flies) True) +!(assertEqual (metta (if (and (is $x croaks) (is $x eats-flies)) (= (is $x frog) True) Empty) %Undefined% &self) ("=" ("is" "Fritz" "frog") True)) +;; Original: +;; #[test] +;; fn test_match_all() { +;; let program = " +;; (= (color) blue) +;; (= (color) red) +;; (= (color) green) +;; +;; !(metta (color) %Undefined% &self) +;; "; +;; +;; assert_eq_metta_results!(run_program(program), +;; Ok(vec![vec![expr!("blue"), expr!("red"), expr!("green")]])); +;; } +;; Converted: +(= (color) blue) +(= (color) red) +(= (color) green) +!(assertEqual (metta (color) %Undefined% &self) (blue red green)) ;; Original: ;; #[test] @@ -675,6 +998,7 @@ ;; !(metta (eq (plus Z $n) $n) %Undefined% &self) ;; !(metta (eq (plus (S Z) $n) $n) %Undefined% &self) ;; "; +;; ;; assert_eq_metta_results!(run_program(program), ;; Ok(vec![vec![expr!({Bool(true)})], vec![expr!("eq" ("S" n) n)]])); ;; } @@ -684,7 +1008,7 @@ (= (plus Z $y) $y) (= (plus (S $k) $y) (S (plus $k $y))) !(assertEqual (metta (eq (plus Z $n) $n) %Undefined% &self) (True)) -!(assertEqual (metta (eq (plus (S Z) $n) $n) %Undefined% &self) ("eq" ("S" n) n)) +!(assertEqual (metta (eq (plus (S Z) $n) $n) %Undefined% &self) (eq (S $n) $n)) ;; Original: ;; #[test] @@ -697,6 +1021,7 @@ ;; ;; !(metta (myif (a $x) $x) %Undefined% &self) ;; "; +;; ;; assert_eq_metta_results!(run_program(program), ;; Ok(vec![vec![expr!("d")]])); ;; } @@ -716,6 +1041,7 @@ ;; ;; !(metta (a $W) %Undefined% &self) ;; "; +;; ;; assert_eq_metta_results!(run_program(program), ;; Ok(vec![vec![expr!({Bool(true)})]])); ;; } @@ -732,6 +1058,7 @@ ;; ;; !(metta (a (b $a) $x $y) %Undefined% &self) ;; "; +;; ;; let result = run_program(program); ;; assert!(result.is_ok_and(|res| res.len() == 1 && res[0].len() == 1 && ;; atoms_are_equivalent(&res[0][0], &expr!("a" ("c" a b) c d)))); @@ -752,6 +1079,7 @@ ;; ;; !(metta ((foo) a) %Undefined% &self) ;; "; +;; ;; assert_eq_metta_results!(run_program(program), Ok(vec![vec![expr!("a")]])); ;; } @@ -786,14 +1114,18 @@ ;; ;; !(metta (id_a myAtom) %Undefined% &self) ;; "; +;; ;; let metta = Metta::new(Some(EnvBuilder::test_env())); ;; metta.tokenizer().borrow_mut().register_token(Regex::new("id_num").unwrap(), ;; |_| Atom::gnd(ID_NUM)); +;; ;; assert_eq!(metta.run(SExprParser::new(program1)), ;; Ok(vec![vec![expr!("Error" "myAtom" "BadType")]])); +;; ;; let program2 = " ;; !(metta (id_num myAtom) %Undefined% &self) ;; "; +;; ;; assert_eq!(metta.run(SExprParser::new(program2)), ;; Ok(vec![vec![expr!("Error" "myAtom" "BadType")]])); ;; } @@ -817,19 +1149,21 @@ ;; ;; !(metta (foo a b) %Undefined% &self) ;; "; +;; ;; let metta = Metta::new(Some(EnvBuilder::test_env())); ;; metta.tokenizer().borrow_mut().register_token(Regex::new("id_num").unwrap(), ;; |_| Atom::gnd(ID_NUM)); +;; ;; assert_eq!(metta.run(SExprParser::new(program1)), ;; Ok(vec![vec![expr!("c")]])); - +;; ;; let program2 = "!(metta (foo a) %Undefined% &self)"; - +;; ;; assert_eq!(metta.run(SExprParser::new(program2)), ;; Ok(vec![vec![expr!("Error" ("foo" "a") "IncorrectNumberOfArguments")]])); - +;; ;; let program3 = "!(metta (foo a b c) %Undefined% &self)"; - +;; ;; assert_eq!(metta.run(SExprParser::new(program3)), ;; Ok(vec![vec![expr!("Error" ("foo" "a" "b" "c") "IncorrectNumberOfArguments")]])); ;; } @@ -854,31 +1188,50 @@ ;; Converted: !(assertEqual (let $x (input $x) (output $x)) ()) -!(assertEqual (let (quote ($sv $st)) (sealed ($x) (quote ($x (output $x)))) (let $sv (input $x) $st)) ("output" ("input" x))) +!(assertEqual (let (quote ($sv $st)) (sealed ($x) (quote ($x (output $x)))) (let $sv (input $x) $st)) (output (input $x))) ;;;;;;;;;;;;;;;;;;;;;; ; Test Pragma Interpreter Bare Minimal ;;;;;;;;;;;;;;;;;;;;;; + +;; Original: ;; #[test] ;; fn test_pragma_interpreter_bare_minimal() { ;; let program = " -(= (bar) baz) -(= (foo) (bar)) -;; !(eval (foo)) +;; (= (bar) baz) +;; (= (foo) (bar)) +;; !(foo) ;; !(pragma! interpreter bare-minimal) +;; !(foo) ;; !(eval (foo)) ;; "; -;; assert_eq!(metta_results!(run_program(program)), +;; +;; assert_eq_metta_results!(run_program(program), ;; Ok(vec![ ;; vec![expr!("baz")], ;; vec![UNIT_ATOM()], +;; vec![expr!(("foo"))], ;; vec![expr!(("bar"))], ;; ])); ;; } -!(assertEqual (eval (foo)) baz) +(= (bar) baz) +(= (foo) (bar)) +!(assertEqual (foo) baz) !(assertEqual (pragma! interpreter bare-minimal) ()) -!(assertEqual (eval (foo)) bar) +!(assertEqual (foo) (foo)) +!(assertEqual (eval (foo)) (bar)) + + + + + + + + + + + ;;;; tref.register_token(regex(r"if-equal"), move |_| { is_equivalent.clone() }); ;;;; tref.register_token(regex(r"register-module!"), move |_| { register_module_op.clone() }); @@ -889,275 +1242,561 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Original: -;; #[test] -;; fn println_op() { -;; assert_eq!(PrintlnOp{}.execute(&mut vec![sym!("A")]), unit_result()); -;; } +;; #[test] +;; fn println_op() { +;; assert_eq!(PrintlnOp{}.execute(&mut vec![sym!("A")]), unit_result()); +;; } ;; Converted: !(assertEqual (println! "A") ()) ;; Original: -;; #[test] -;; fn trace_op() { -;; assert_eq!(TraceOp{}.execute(&mut vec![sym!("\"Here?\""), sym!("42")]), -;; Ok(vec![sym!("42")])); -;; } +;; #[test] +;; fn trace_op() { +;; assert_eq!(TraceOp{}.execute(&mut vec![sym!("\"Here?\""), sym!("42")]), +;; Ok(vec![sym!("42")])); +;; } ;; Converted: !(assertEqual (trace! "Here?" 42) 42) ;; Original: -;; #[test] -;; fn nop_op() { -;; assert_eq!(NopOp{}.execute(&mut vec![]), unit_result()); -;; } +;; #[test] +;; fn nop_op() { +;; assert_eq!(NopOp{}.execute(&mut vec![]), unit_result()); +;; } ;; Converted: !(assertEqual (nop) ()) ;; Original: -;; #[test] -;; fn let_op() { -;; assert_eq!(LetOp{}.execute(&mut vec![expr!(a b), expr!("A" "B"), expr!(b a)]), -;; Ok(vec![expr!("B" "A")])); -;; } +;; #[test] +;; fn let_op() { +;; assert_eq!(LetOp{}.execute(&mut vec![expr!(a b), expr!("A" "B"), expr!(b a)]), +;; Ok(vec![expr!("B" "A")])); +;; } ;; Converted: -!(assertEqual (($a $b) (A B) ($b $a)) (B A)) +!(assertEqual (let ($a $b) (A B) ($b $a)) (B A)) ;; Original: -;; #[test] -;; fn let_op_external_vars_at_right_are_kept_untouched() { -;; assert_eq!(LetOp{}.execute(&mut vec![expr!(t), expr!(ext), expr!(t)]), -;; Ok(vec![expr!(ext)])); -;; assert_eq!(LetOp{}.execute(&mut vec![expr!(t), expr!(ext "A"), expr!(t)]), -;; Ok(vec![expr!(ext "A")])); -;; } +;; #[test] +;; fn let_op_external_vars_at_right_are_kept_untouched() { +;; assert_eq!(LetOp{}.execute(&mut vec![expr!(t), expr!(ext), expr!(t)]), +;; Ok(vec![expr!(ext)])); +;; assert_eq!(LetOp{}.execute(&mut vec![expr!(t), expr!(ext "A"), expr!(t)]), +;; Ok(vec![expr!(ext "A")])); +;; } ;; Converted: -!(assertEqual ($t $ext $t) $ext) -!(assertEqual ($t ("ext" "A") $t) ("ext" "A")) +!(assertEqual (let $t $ext $t) $ext) +!(assertEqual (let $t ("ext" "A") $t) ("ext" "A")) ;; Original: -;; #[test] -;; fn let_op_internal_variables_has_priority_in_template() { -;; assert_eq!(LetOp{}.execute(&mut vec![expr!(x), expr!(x "A"), expr!(x)]), -;; Ok(vec![expr!(x "A")])); -;; } +;; #[test] +;; fn let_op_internal_variables_has_priority_in_template() { +;; assert_eq!(LetOp{}.execute(&mut vec![expr!(x), expr!(x "A"), expr!(x)]), +;; Ok(vec![expr!(x "A")])); +;; } ;; Converted: -!(assertEqual ($x ($x A) $x) ($x A)) +!(assertEqual (let $x ($x A) $x) ($x A)) ;; Original: -;; #[test] -;; fn let_op_keep_variables_equalities_issue290() { -;; assert_eq_metta_results!(run_program("!(let* (($f f) ($f $x)) $x)"), Ok(vec![vec![expr!("f")]])); -;; assert_eq_metta_results!(run_program("!(let* (($f $x) ($f f)) $x)"), Ok(vec![vec![expr!("f")]])); -;; assert_eq_metta_results!(run_program("!(let (quote ($x $x)) (quote ($z $y)) (let $y A ($z $y)))"), Ok(vec![vec![expr!("A" "A")]])); -;; assert_eq_metta_results!(run_program("!(let (quote ($x $x)) (quote ($z $y)) (let $z A ($z $y)))"), Ok(vec![vec![expr!("A" "A")]])); -;; } +;; #[test] +;; fn let_op_keep_variables_equalities_issue290() { +;; assert_eq_metta_results!(run_program("!(let* (($f f) ($f $x)) $x)"), Ok(vec![vec![expr!("f")]])); +;; assert_eq_metta_results!(run_program("!(let* (($f $x) ($f f)) $x)"), Ok(vec![vec![expr!("f")]])); +;; assert_eq_metta_results!(run_program("!(let (quote ($x $x)) (quote ($z $y)) (let $y A ($z $y)))"), Ok(vec![vec![expr!("A" "A")]])); +;; assert_eq_metta_results!(run_program("!(let (quote ($x $x)) (quote ($z $y)) (let $z A ($z $y)))"), Ok(vec![vec![expr!("A" "A")]])); +;; } ;; Converted: -!(assertEqualToResults (let* (($f f) ($f $x)) $x) (f)) -!(assertEqualToResults (let* (($f $x) ($f f)) $x) (f)) -!(assertEqualToResults (let ((quote ($x $x))) ((quote ($z $y))) (let $y A ($z $y))) (A A)) -!(assertEqualToResults (let ((quote ($x $x))) ((quote ($z $y))) (let $z A ($z $y))) (A A)) +!(assertEqualToResult (let* (($f f) ($f $x)) $x) (f)) +!(assertEqualToResult (let* (($f $x) ($f f)) $x) (f)) +!(assertEqualToResult (let (quote ($x $x)) (quote ($z $y)) (let $y A ($z $y))) (A A)) +!(assertEqualToResult (let (quote ($x $x)) (quote ($z $y)) (let $z A ($z $y))) (A A)) + ;; Original: -;; #[test] -;; fn let_op_variables_visibility_pr262() { -;; let program = " -;; ;; Knowledge -;; (? P Q) -;; (? Q R) +;; #[test] +;; fn let_op_variables_visibility_pr262() { +;; let program = " +;; ;; Knowledge +;; (→ P Q) +;; (→ Q R) ;; -;; ;; Rule -;; (= (rule (? $p $q) (? $q $r)) (? $p $r)) +;; ;; Rule +;; (= (rule (→ $p $q) (→ $q $r)) (→ $p $r)) ;; -;; ;; Query (does not work as expected) -;; (= (query $kb) -;; (let* (($pq (? $p $q)) -;; ($qr (? $q $r))) -;; (match $kb -;; ;; Premises -;; (, $pq $qr) -;; ;; Conclusion -;; (rule $pq $qr)))) +;; ;; Query (does not work as expected) +;; (= (query $kb) +;; (let* (($pq (→ $p $q)) +;; ($qr (→ $q $r))) +;; (match $kb +;; ;; Premises +;; (, $pq $qr) +;; ;; Conclusion +;; (rule $pq $qr)))) ;; -;; ;; Call -;; !(query &self) -;; ;; [(? P R)] -;; "; -;; assert_eq_metta_results!(run_program(program), Ok(vec![vec![expr!("?" "P" "R")]])); -;; } +;; ;; Call +;; !(query &self) +;; ;; [(→ P R)] +;; "; +;; assert_eq_metta_results!(run_program(program), Ok(vec![vec![expr!("→" "P" "R")]])); +;; } ;; Converted: -(let* (($pq (? $p $q)) ($qr (? $q $r))) - (match $kb - (, $pq $qr) - (rule $pq $qr))) -!(assertEqualToResults (run_program program) (? P R)) +(→ P Q) +(→ Q R) +(= (rule (→ $p $q) (→ $q $r)) (→ $p $r)) +!(assertEqualToResult (query (let* (($pq (→ $p $q)) ($qr (→ $q $r))) (match $kb (, $pq $qr) (rule $pq $qr)))) (→ P R)) + ;; Original: -;; #[test] -;; fn let_var_op() { -;; assert_eq!(LetVarOp{}.execute(&mut vec![expr!(), sym!("B")]), -;; Ok(vec![sym!("B")])); -;; assert_eq!(LetVarOp{}.execute(&mut vec![expr!(((a "A"))), expr!(a)]), -;; Ok(vec![expr!({LetOp{}} a "A" a)])); -;; assert_eq!(LetVarOp{}.execute(&mut vec![expr!((a "A") (b "B")), expr!(b a)]), -;; Ok(vec![expr!({LetOp{}} a "A" ({LetVarOp{}} ((b "B")) (b a)))])); -;; } +;; #[test] +;; fn let_var_op() { +;; assert_eq!(LetVarOp{}.execute(&mut vec![expr!(), sym!("B")]), +;; Ok(vec![sym!("B")])); +;; assert_eq!(LetVarOp{}.execute(&mut vec![expr!(((a "A"))), expr!(a)]), +;; Ok(vec![expr!({LetOp{}} a "A" a)])); +;; assert_eq!(LetVarOp{}.execute(&mut vec![expr!((a "A") (b "B")), expr!(b a)]), +;; Ok(vec![expr!({LetOp{}} a "A" ({LetVarOp{}} ((b "B")) (b a)))])); +;; } ;; Converted: !(assertEqual (let* () B) B) !(assertEqual (let* (($a A)) $a) (let $a A $a)) !(assertEqual (let* (($a A) ($b B)) ($b $a)) (let $a A (let* (($b B)) ($b $a)))) ;; Original: -;; #[test] -;; fn state_ops() { -;; let result = NewStateOp{}.execute(&mut vec![expr!("A" "B")]).unwrap(); -;; let old_state = result.get(0).ok_or("error").unwrap(); -;; assert_eq!(old_state, &Atom::gnd(StateAtom::new(expr!("A" "B")))); -;; let result = ChangeStateOp{}.execute(&mut vec!(old_state.clone(), expr!("C" "D"))).unwrap(); -;; let new_state = result.get(0).ok_or("error").unwrap(); -;; assert_eq!(old_state, new_state); -;; assert_eq!(new_state, &Atom::gnd(StateAtom::new(expr!("C" "D")))); -;; let result = GetStateOp{}.execute(&mut vec![new_state.clone()]); -;; assert_eq!(result, Ok(vec![expr!("C" "D")])) -;; } +;; #[test] +;; fn state_ops() { +;; let result = NewStateOp{}.execute(&mut vec![expr!("A" "B")]).unwrap(); +;; let old_state = result.get(0).ok_or("error").unwrap(); +;; assert_eq!(old_state, &Atom::gnd(StateAtom::new(expr!("A" "B")))); +;; let result = ChangeStateOp{}.execute(&mut vec!(old_state.clone(), expr!("C" "D"))).unwrap(); +;; let new_state = result.get(0).ok_or("error").unwrap(); +;; assert_eq!(old_state, new_state); +;; assert_eq!(new_state, &Atom::gnd(StateAtom::new(expr!("C" "D")))); +;; let result = GetStateOp{}.execute(&mut vec![new_state.clone()]); +;; assert_eq!(result, Ok(vec![expr!("C" "D")])) +;; } ;; Converted: -!(assertEqual (new_state! "A" "B") (state! "A" "B")) -!(assertEqual (change_state! (state! "A" "B") ("C" "D")) (state! "C" "D")) -!(assertEqual (get_state! (state! "C" "D")) ("C" "D")) +!(bind! result (new-state! (A B))) +!(bind! old-state (first result)) +!(bind! result (change-state! old-state (C D))) +!(bind! new-state (first result)) +!(assertEqual old-state new-state) +!(assertEqual (get-state! new-state) ((C D))) + ;; Original: -;; #[test] -;; fn test_stdlib_uses_rust_grounded_tokens() { -;; assert_eq!(run_program("!(if True ok nok)"), Ok(vec![vec![Atom::sym("ok")]])); -;; } +;; #[test] +;; fn test_stdlib_uses_rust_grounded_tokens() { +;; assert_eq!(run_program("!(if True ok nok)"), Ok(vec![vec![Atom::sym("ok")]])); +;; } ;; Converted: -!(assertEqualToResults (if True ok nok) (ok)) +!(assertEqualToResult (if True ok nok) (ok)) ;; Original: -;; #[test] -;; 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_let_op_inside_other_operation() { +;; assert_eq!(run_program("!(and True (let $x False $x))"), Ok(vec![vec![expr!({Bool(false)})]])); +;; } ;; Converted: -!(assertEqualToResults (and True (let $x False $x)) (Bool(false))) +!(assertEqualToResult (and True (let $x False $x)) (False)) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Converted Rust Tests with Original Source ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Original: -;; #[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_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"))], +;; ])); +;; } ;; Converted: (= (foo) a) (= (foo) b) -!(assertEqualToResults (foo) (a b)) -!(assertEqualToResults (quote (foo)) (quote (foo))) +!(assertEqualToResult (foo) (a b)) +!(assertEqualToResult (quote (foo)) (quote (foo))) + +;; Original: +;; #[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) +;; !(unify ($x a) (b $x) 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")], +;; vec![expr!("nok")] +;; ])); +;; } +;; Converted: +!(assertEqualToResult (unify (a $b 1 (d)) (a $a 1 (d)) ok nok) (ok)) +!(assertEqualToResult (unify (a $b c) (a b $c) (ok $b $c) nok) (ok b c)) +!(assertEqualToResult (unify $a (a b c) (ok $a) nok) (ok (a b c))) +!(assertEqualToResult (unify (a b c) $a (ok $a) nok) (ok (a b c))) +!(assertEqualToResult (unify (a b c) (a b d) ok nok) (nok)) +!(assertEqualToResult (unify ($x a) (b $x) ok nok) (nok)) + +;; Original: +;; #[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![]])); +;; } +;; Converted: +!(assertEqualToResult (empty) ()) +!(assertNotEqual (empty) ()) + +;; Original: +;; #[test] +;; fn sealed_op_runner() { +;; let nested = run_program("!(sealed ($x) (sealed ($a $b) (quote (= ($a $x $c) ($b)))))"); +;; let simple_replace = run_program("!(sealed ($x $y) (quote (= ($y $z))))"); +;; +;; assert!(crate::atom::matcher::atoms_are_equivalent(&nested.unwrap()[0][0], &expr!("quote" ("=" (a b c) (z))))); +;; assert!(crate::atom::matcher::atoms_are_equivalent(&simple_replace.unwrap()[0][0], &expr!("quote" ("=" (y z))))); +;; } +;; Converted: +!(assertEqual (sealed ($x) (sealed ($a $b) (quote (= ($a $x $c) ($b))))) (quote (= (a b c) (z)))) +!(assertEqual (sealed ($x $y) (quote (= ($y $z)))) (quote (= (y z)))) + +;; Original: +;; #[test] +;; fn sealed_op_execute() { +;; let val = SealedOp{}.execute(&mut vec![expr!(x y), expr!("="(y z))]); +;; assert!(crate::atom::matcher::atoms_are_equivalent(&val.unwrap()[0], &expr!("="(y z)))); +;; } + +;; Converted: +!(assertEqual (sealed ($x $y) (= ($y $z))) (= ($y $z))) + +;; Original: +;; #[test] +;; fn use_sealed_to_make_scoped_variable() { +;; assert_eq!(run_program("!(let $x (input $x) (output $x))"), Ok(vec![vec![expr!("output" ("input" x))]])); +;; assert_eq!(run_program("!(let (quote ($sv $st)) (sealed ($x) (quote ($x (output $x)))) +;; (let $sv (input $x) $st))"), Ok(vec![vec![expr!("output" ("input" x))]])); +;; } +;; Converted: +!(assertEqualToResult (let $x (input $x) (output $x)) (output (input x))) +!(assertEqualToResult (let (quote ($sv $st)) (sealed ($x) (quote ($x (output $x)))) (let $sv (input $x) $st)) (output (input x))) + + +;; #[derive(Clone, PartialEq, Debug)] +;; pub struct SomeGndAtom { } +;; +;; impl Display for SomeGndAtom { +;; fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +;; write!(f, "some-gnd-atom") +;; } +;; } +;; +;; impl Grounded for SomeGndAtom { +;; fn type_(&self) -> Atom { +;; Atom::expr([ARROW_SYMBOL, sym!("Arg1Type"), sym!("Arg2Type"), sym!("ReturnType")]) +;; } +;; } +;; Converted: +;; Define the grounded atom in MeTTa-compatible format. +;; This part would typically be defined in the system as an extension or plugin and referenced in the program as needed. + +(: SomeGndAtom (-> Arg1Type Arg2Type ReturnType)) ;; Original: ;; #[test] -;; fn test_unify() { +;; fn test_get_doc_func() { ;; 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) -;; !(unify ($x a) (b $x) ok nok) -;; "); +;; let parser = SExprParser::new(r#" +;; (: Arg1Type Type) +;; (: Arg2Type Type) +;; (: ReturnType Type) +;; (: some-func (-> Arg1Type Arg2Type ReturnType)) +;; (@doc some-func +;; (@desc "Test function") +;; (@params ( +;; (@param "First argument") +;; (@param "Second argument") +;; )) +;; (@return "Return value") +;; ) +;; +;; !(get-doc some-func) +;; "#); ;; -;; 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")], -;; vec![expr!("nok")] -;; ])); +;; assert_eq_metta_results!(metta.run(parser), Ok(vec![ +;; vec![expr!("@doc-formal" +;; ("@item" "some-func") +;; ("@kind" "function") +;; ("@type" ("->" "Arg1Type" "Arg2Type" "ReturnType")) +;; ("@desc" {Str::from_str("Test function")}) +;; ("@params" ( +;; ("@param" ("@type" "Arg1Type") ("@desc" {Str::from_str("First argument")})) +;; ("@param" ("@type" "Arg2Type") ("@desc" {Str::from_str("Second argument")})) )) +;; ("@return" ("@type" "ReturnType") ("@desc" {Str::from_str("Return value")}) )], +;; ])); ;; } + ;; Converted: -!(assertEqualToResults (unify (a $b 1 (d)) (a $a 1 (d)) ok nok) (ok)) -!(assertEqualToResults (unify (a $b c) (a b $c) (ok $b $c) nok) (ok b c)) -!(assertEqualToResults (unify $a (a b c) (ok $a) nok) (ok (a b c))) -!(assertEqualToResults (unify (a b c) $a (ok $a) nok) (ok (a b c))) -!(assertEqualToResults (unify (a b c) (a b d) ok nok) (nok)) -!(assertEqualToResults (unify ($x a) (b $x) ok nok) (nok)) +(: Arg1Type Type) +(: Arg2Type Type) +(: ReturnType Type) +(: some-func (-> Arg1Type Arg2Type ReturnType)) +(@doc some-func + (@desc "Test function") + (@params ( + (@param (@type Arg1Type) (@desc "First argument")) + (@param (@type Arg2Type) (@desc "Second argument")) )) + (@return (@type ReturnType) (@desc "Return value"))) +!(assertEqual (get-doc some-func) (@doc-formal + (@item "some-func") + (@kind "function") + (@type (-> Arg1Type Arg2Type ReturnType)) + (@desc Test function) + (@params ( + (@param (@type Arg1Type) (@desc "First argument")) + (@param (@type Arg2Type) (@desc "Second argument")) )) + (@return (@type ReturnType) (@desc "Return value")))) ;; Original: ;; #[test] -;; fn test_empty() { +;; fn test_get_doc_atom() { ;; let metta = Metta::new(Some(EnvBuilder::test_env())); -;; let parser = SExprParser::new(" -;; !(empty) -;; "); +;; let parser = SExprParser::new(r#" +;; (: SomeAtom SomeType) +;; (@doc SomeAtom (@desc "Test symbol atom having specific type")) +;; +;; !(get-doc SomeAtom) +;; "#); ;; -;; assert_eq_metta_results!(metta.run(parser), -;; Ok(vec![vec![]])); +;; assert_eq_metta_results!(metta.run(parser), Ok(vec![ +;; vec![expr!("@doc-formal" +;; ("@item" "SomeAtom") +;; ("@kind" "atom") +;; ("@type" "SomeType") +;; ("@desc" {Str::from_str("Test symbol atom having specific type")}) )], +;; ])); ;; } ;; Converted: -!(assertEqual (empty) ()) +(: SomeAtom SomeType) +(@doc SomeAtom (@desc "Test symbol atom having specific type")) +!(assertEqual (get-doc SomeAtom) (@doc-formal + (@item SomeAtom) + (@kind atom) + (@type SomeType) + (@desc Test symbol atom having specific type))) ;; Original: ;; #[test] -;; fn sealed_op_runner() { -;; let nested = run_program("!(sealed ($x) (sealed ($a $b) (quote (= ($a $x $c) ($b)))))"); -;; let simple_replace = run_program("!(sealed ($x $y) (quote (= ($y $z))))"); +;; fn test_get_doc_gnd_func() { +;; let metta = Metta::new(Some(EnvBuilder::test_env())); +;; metta.tokenizer().borrow_mut() +;; .register_token(regex::Regex::new(r"some-gnd-atom").unwrap(), |_| Atom::gnd(SomeGndAtom{})); +;; let parser = SExprParser::new(r#" +;; (@doc some-gnd-atom +;; (@desc "Test function") +;; (@params ( +;; (@param "First argument") +;; (@param "Second argument") +;; )) +;; (@return "Return value") +;; ) +;; !(get-doc some-gnd-atom) +;; "#); ;; -;; assert!(crate::atom::matcher::atoms_are_equivalent(&nested.unwrap()[0][0], &expr!("quote" ("=" (a b c) (z))))); -;; assert!(crate::atom::matcher::atoms_are_equivalent(&simple_replace.unwrap()[0][0], &expr!("quote" ("=" (y z))))); +;; assert_eq_metta_results!(metta.run(parser), Ok(vec![ +;; vec![expr!("@doc-formal" +;; ("@item" {SomeGndAtom{}}) +;; ("@kind" "function") +;; ("@type" ("->" "Arg1Type" "Arg2Type" "ReturnType")) +;; ("@desc" {Str::from_str("Test function")}) +;; ("@params" ( +;; ("@param" ("@type" "Arg1Type") ("@desc" {Str::from_str("First argument")})) +;; ("@param" ("@type" "Arg2Type") ("@desc" {Str::from_str("Second argument")})) )) +;; ("@return" ("@type" "ReturnType") ("@desc" {Str::from_str("Return value")}) )], +;; ])); ;; } ;; Converted: -!(assertEqual (sealed ($x) (sealed ($a $b) (quote (= ($a $x $c) ($b))))) (quote (= (a b c) (z)))) -!(assertEqual (sealed ($x $y) (quote (= ($y $z)))) (quote (= (y z)))) +(@doc some-gnd-atom + (@desc "Test function") + (@params ( + (@param (@type Arg1Type) (@desc "First argument")) + (@param (@type Arg2Type) (@desc "Second argument")) )) + (@return (@type ReturnType) (@desc "Return value"))) +!(assertEqual (get-doc some-gnd-atom) (@doc-formal + (@item some-gnd-atom) + (@kind function) + (@type (-> Arg1Type Arg2Type ReturnType)) + (@desc Test function) + (@params ( + (@param (@type Arg1Type) (@desc "First argument")) + (@param (@type Arg2Type) (@desc "Second argument")) )) + (@return (@type ReturnType) (@desc "Return value")))) ;; Original: ;; #[test] -;; fn sealed_op_execute() { -;; let val = SealedOp{}.execute(&mut vec![expr!(x y), expr!("="(y z))]); -;; assert!(crate::atom::matcher::atoms_are_equivalent(&val.unwrap()[0], &expr!("="(y z)))); +;; fn test_get_doc_no_doc() { +;; let metta = Metta::new(Some(EnvBuilder::test_env())); +;; let parser = SExprParser::new(r#" +;; !(get-doc NoSuchAtom) +;; "#); +;; +;; assert_eq_metta_results!(metta.run(parser), Ok(vec![ +;; vec![expr!("@doc-formal" +;; ("@item" "NoSuchAtom") +;; ("@kind" "atom") +;; ("@type" "%Undefined%") +;; ("@desc" {Str::from_str("No documentation")}) )], +;; ])); ;; } ;; Converted: -!(assertEqual (sealedOpExecute (x y) (= (y z))) (= (y z))) +!(assertEqual (get-doc NoSuchAtom) (@doc-formal + (@item NoSuchAtom) + (@kind atom) + (@type %Undefined%) + (@desc No documentation))) ;; Original: ;; #[test] -;; fn use_sealed_to_make_scoped_variable() { -;; assert_eq!(run_program("!(let $x (input $x) (output $x))"), Ok(vec![vec![expr!("output" ("input" x))]])); -;; assert_eq!(run_program("!(let (quote ($sv $st)) (sealed ($x) (quote ($x (output $x)))) -;; (let $sv (input $x) $st))"), Ok(vec![vec![expr!("output" ("input" x))]])); +;; fn test_get_doc_function_call() { +;; let metta = Metta::new(Some(EnvBuilder::test_env())); +;; let parser = SExprParser::new(r#" +;; (: Arg1Type Type) +;; (: Arg2Type Type) +;; (: ReturnType Type) +;; (: some-func (-> Arg1Type Arg2Type ReturnType)) +;; (@doc some-func +;; (@desc "Test function") +;; (@params ( +;; (@param "First argument") +;; (@param "Second argument") +;; )) +;; (@return "Return value") +;; ) +;; +;; !(get-doc (some-func arg1 arg2)) +;; "#); +;; +;; assert_eq_metta_results!(metta.run(parser), Ok(vec![ +;; vec![expr!("@doc-formal" +;; ("@item" ("some-func" "arg1" "arg2")) +;; ("@kind" "atom") +;; ("@type" "ReturnType") +;; ("@desc" {Str::from_str("No documentation")}) )], +;; ])); ;; } ;; Converted: -!(assertEqual (let $x (input $x) (output $x)) ("output" ("input" x))) -!(assertEqual (let (quote ($sv $st)) (sealed ($x) (quote ($x (output $x)))) (let $sv (input $x) $st)) ("output" ("input" x))) - -;; #[derive(Clone, PartialEq, Debug)] -;; pub struct SomeGndAtom { } +(: Arg1Type Type) +(: Arg2Type Type) +(: ReturnType Type) +(: some-func (-> Arg1Type Arg2Type ReturnType)) +(@doc some-func + (@desc "Test function") + (@params ( + (@param (@type Arg1Type) (@desc "First argument")) + (@param (@type Arg2Type) (@desc "Second argument")) )) + (@return (@type ReturnType) (@desc "Return value"))) +!(assertEqual (get-doc (some-func arg1 arg2)) (@doc-formal + (@item (some-func arg1 arg2)) + (@kind atom) + (@type ReturnType) + (@desc No documentation))) -;; impl Display for SomeGndAtom { -;; fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { -;; write!(f, "some-gnd-atom") -;; } +;; Original: +;; #[test] +;; fn test_get_doc_no_type() { +;; let metta = Metta::new(Some(EnvBuilder::test_env())); +;; let parser = SExprParser::new(r#" +;; (@doc some-func-no-type +;; (@desc "Test function") +;; (@params ( +;; (@param "First argument") +;; (@param "Second argument") +;; )) +;; (@return "Return value") +;; ) +;; +;; !(get-doc some-func-no-type) +;; "#); +;; +;; assert_eq_metta_results!(metta.run(parser), Ok(vec![ +;; vec![expr!("@doc-formal" +;; ("@item" "some-func-no-type") +;; ("@kind" "function") +;; ("@type" "%Undefined%") +;; ("@desc" {Str::from_str("Test function")}) +;; ("@params" ( +;; ("@param" ("@type" "%Undefined%") ("@desc" {Str::from_str("First argument")})) +;; ("@param" ("@type" "%Undefined%") ("@desc" {Str::from_str("Second argument")})) )) +;; ("@return" ("@type" "%Undefined%") ("@desc" {Str::from_str("Return value")}) )], +;; ])); ;; } -;; impl Grounded for SomeGndAtom { -;; fn type_(&self) -> Atom { -;; Atom::expr([ARROW_SYMBOL, sym!("Arg1Type"), sym!("Arg2Type"), sym!("ReturnType")]) -;; } +;; Converted: +(@doc some-func-no-type + (@desc "Test function") + (@params ( + (@param (@type %Undefined%) (@desc "First argument")) + (@param (@type %Undefined%) (@desc "Second argument")) )) + (@return (@type %Undefined%) (@desc "Return value"))) +!(assertEqual (get-doc some-func-no-type) (@doc-formal + (@item some-func-no-type) + (@kind function) + (@type %Undefined%) + (@desc Test function) + (@params ( + (@param (@type %Undefined%) (@desc "First argument")) + (@param (@type %Undefined%) (@desc "Second argument")) )) + (@return (@type %Undefined%) (@desc "Return value")))) + +;; Original: +;; #[test] +;; fn test_error_is_used_as_an_argument() { +;; let metta = Metta::new(Some(EnvBuilder::test_env())); +;; let parser = SExprParser::new(r#" +;; !(get-type Error) +;; !(get-metatype Error) +;; !(get-type (Error Foo Boo)) +;; !(Error (+ 1 2) (+ 1 +)) +;; "#); +;; +;; assert_eq_metta_results!(metta.run(parser), Ok(vec![ +;; vec![expr!("->" "Atom" "Atom" "ErrorType")], +;; vec![expr!("Symbol")], +;; vec![expr!("ErrorType")], +;; vec![expr!("Error" ({SumOp{}} {Number::Integer(1)} {Number::Integer(2)}) ({SumOp{}} {Number::Integer(1)} {SumOp{}}))], +;; ])); ;; } + +;; Converted: +!(assertEqual (get-type Error) (-> Atom Atom ErrorType)) +!(assertEqual (get-metatype Error) Symbol) +!(assertEqual (get-type (Error Foo Boo)) ErrorType) +!(assertEqual (Error (+ 1 2) (+ 1 +)) (Error (+ 1 2) (+ 1 +))) diff --git a/tests/more-anti-regression/stdlib-mettalog/stdlib_mettalog_test_pt2.metta b/tests/more-anti-regression/stdlib-mettalog/stdlib_mettalog_test_pt2.metta new file mode 100644 index 00000000000..969218e1c8e --- /dev/null +++ b/tests/more-anti-regression/stdlib-mettalog/stdlib_mettalog_test_pt2.metta @@ -0,0 +1,1245 @@ + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Converted Rust Tests with Original Source +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; Original: +;; #[test] +;; fn interpret_atom_evaluate_incorrect_args() { +;; assert_eq!(call_interpret(&space(""), &metta_atom("(eval)")), +;; vec![expr!("Error" ("eval") "expected: (eval ), found: (eval)")]); +;; assert_eq!(call_interpret(&space(""), &metta_atom("(eval a b)")), +;; vec![expr!("Error" ("eval" "a" "b") "expected: (eval ), found: (eval a b)")]); +;; } + +;; Converted: +!(assertEqual (eval) ("Error" (eval) "expected: (eval ), found: (eval)")) +!(assertEqual (eval a b) ("Error" (eval a b) "expected: (eval ), found: (eval a b)")) + +;; Original: +;; #[test] +;; fn interpret_atom_evaluate_atom() { +;; let result = call_interpret(&space("(= a b)"), &metta_atom("(eval a)")); +;; assert_eq!(result, vec![metta_atom("b")]); +;; } + +;; Converted: +(= a b) +!(assertEqual (eval a) b) + +;; Original: +;; #[test] +;; fn interpret_atom_evaluate_atom_no_definition() { +;; let result = call_interpret(&space(""), &metta_atom("(eval a)")); +;; assert_eq!(result, vec![metta_atom("NotReducible")]); +;; } + +;; Converted: +!(assertEqual (eval a) NotReducible) + +;; Original: +;; #[test] +;; fn interpret_atom_evaluate_empty_expression() { +;; let result = call_interpret(&space(""), &metta_atom("(eval ())")); +;; assert_eq!(result, vec![metta_atom("NotReducible")]); +;; } + +;; Converted: +!(assertEqual (eval ()) NotReducible) + +;; Original: +;; #[test] +;; fn interpret_atom_evaluate_grounded_value() { +;; let result = call_interpret(&space(""), &expr!("eval" {6})); +;; assert_eq!(result, vec![metta_atom("NotReducible")]); +;; } + +;; Converted: +!(assertEqual (eval {6}) NotReducible) + +;; Original: +;; #[test] +;; fn interpret_atom_evaluate_pure_expression() { +;; let space = space("(= (foo $a B) $a)"); +;; let result = call_interpret(&space, &metta_atom("(eval (foo A $b))")); +;; assert_eq!(result, vec![metta_atom("A")]); +;; } + +;; Converted: +(= (foo $a B) $a) +!(assertEqual (eval (foo A $b)) A) + +;; Original: +;; #[test] +;; fn interpret_atom_evaluate_pure_expression_non_determinism() { +;; let space = space(" +;; (= color red) +;; (= color green) +;; (= color blue) +;; "); +;; let result = call_interpret(&space, &metta_atom("(eval color)")); +;; assert_eq_no_order!(result, vec![ +;; metta_atom("red"), +;; metta_atom("green"), +;; metta_atom("blue"), +;; ]); +;; } + +;; Converted: +(= color red) +(= color green) +(= color blue) +!(assertEqualNoOrder (eval color) (red green blue)) + +;; Original: +;; #[test] +;; fn interpret_atom_evaluate_pure_expression_no_definition() { +;; let result = call_interpret(&space(""), &metta_atom("(eval (foo A))")); +;; assert_eq!(result, vec![metta_atom("NotReducible")]); +;; } + +;; Converted: +!(assertEqual (eval (foo A)) NotReducible) + +;; Original: +;; #[test] +;; fn interpret_atom_evaluate_pure_expression_variable_in_space() { +;; let space = space("$t (= (foo $a B) $a)"); +;; let result = call_interpret(&space, &metta_atom("(eval (foo A $b))")); +;; assert_eq!(result, vec![metta_atom("A")]); +;; } + +;; Converted: +$t +(= (foo $a B) $a) +!(assertEqual (eval (foo A $b)) A) + +;; Original: +;; #[test] +;; fn interpret_atom_evaluate_pure_expression_variable_name_conflict() { +;; let space = space("(= (foo ($W)) True)"); +;; let result = call_interpret(&space, &metta_atom("(eval (foo $W))")); +;; assert_eq!(result[0], sym!("True")); +;; } + +;; Converted: +(= (foo ($W)) True) +!(assertEqual (eval (foo $W)) True) + +;; Original: +;; #[test] +;; fn interpret_atom_evaluate_grounded_expression() { +;; let result = call_interpret(&space(""), &expr!("eval" ({MulXUndefinedType(7)} {6}))); +;; assert_eq!(result, vec![expr!({42})]); +;; } + +;; Converted: +!(assertEqual (eval (MulXUndefinedType 7) 6) 42) + +;; Original: +;; #[test] +;; fn interpret_atom_evaluate_grounded_expression_empty() { +;; let result = call_interpret(&space(""), &expr!("eval" ({ReturnNothing()} {6}))); +;; assert_eq!(result, vec![]); +;; } + +;; Converted: +!(assertEqual (eval (ReturnNothing 6)) ()) + +;; Original: +;; #[test] +;; fn interpret_atom_evaluate_grounded_expression_noreduce() { +;; let result = call_interpret(&space(""), &expr!("eval" ({NonReducible()} {6}))); +;; assert_eq!(result, vec![expr!("NotReducible")]); +;; } + +;; Converted: +!(assertEqual (eval (NonReducible 6)) NotReducible) + +;; Original: +;; #[test] +;; fn interpret_atom_evaluate_grounded_expression_error() { +;; let result = call_interpret(&space(""), &expr!("eval" ({ThrowError()} {"Test error"}))); +;; assert_eq!(result, vec![expr!("Error" ({ThrowError()} {"Test error"}) "Test error")]); +;; } + +;; Converted: +!(assertEqual (eval (Error ThrowError "Test error")) (Error (Error ThrowError "Test error") "Test error")) + +;; Original: +;; #[test] +;; fn interpret_atom_evaluate_variable_operation() { +;; let space = space("(= (foo $a B) $a)"); +;; let result = call_interpret(&space, &metta_atom("(eval ($a A $b))")); +;; #[cfg(feature = "variable_operation")] +;; assert_eq!(result, vec![metta_atom("A")]); +;; #[cfg(not(feature = "variable_operation"))] +;; assert_eq!(result, vec![NOT_REDUCIBLE_SYMBOL]); +;; } + +;; Converted: +(= (foo $a B) $a) +!(assertEqual (eval ($a A $b)) A) + +;; Original: +;; #[test] +;; fn interpret_atom_evaluate_variable_via_call_direct_equality() { +;; let space = space(" +;; (= (bar) (function (return ()))) +;; (= (foo $b) (function +;; (chain (eval (bar)) $_ +;; (unify $b value +;; (return ()) +;; (return (Error () \"Unexpected error\")) ))))"); +;; let result = call_interpret(&space, +;; &metta_atom("(chain (eval (foo $a)) $_ $a)")); +;; assert_eq!(result[0], sym!("value")); +;; } + +;; Converted: +(= (bar) (function (return ()))) +(= (foo $b) (function + (chain (eval (bar)) $_ + (unify $b value + (return ()) + (return (Error () "Unexpected error")))))) +!(assertEqual (chain (eval (foo $a)) $_ $a) value) + +;; Original: +;; #[test] +;; fn interpret_atom_evaluate_variable_via_call_struct_equality() { +;; let formal_arg_struct = space(" +;; (= (bar) (function (return ()))) +;; (= (foo ($b)) (function +;; (chain (eval (bar)) $_ +;; (unify $b value +;; (return ()) +;; (return (Error () \"Unexpected error\")) ))))"); +;; let result = call_interpret(&formal_arg_struct, +;; &metta_atom("(chain (eval (foo $a)) $_ $a)")); +;; assert_eq!(result[0], expr!(("value"))); +;; +;; let actual_arg_struct = space(" +;; (= (bar) (function (return ()))) +;; (= (foo $b) (function +;; (chain (eval (bar)) $_ +;; (unify $b (value) +;; (return ()) +;; (return (Error () \"Unexpected error\")) ))))"); +;; let result = call_interpret(&actual_arg_struct, +;; &metta_atom("(chain (eval (foo ($a))) $_ $a)")); +;; assert_eq!(result[0], sym!("value")); +;; } + +;; Converted: +(= (bar) (function (return ()))) +(= (foo ($b)) (function + (chain (eval (bar)) $_ + (unify $b value + (return ()) + (return (Error () "Unexpected error")))))) +!(assertEqual (chain (eval (foo $a)) $_ $a) ("value")) + +(= (bar) (function (return ()))) +(= (foo $b) (function + (chain (eval (bar)) $_ + (unify $b (value) + (return ()) + (return (Error () "Unexpected error")))))) +!(assertEqual (chain (eval (foo ($a))) $_ $a) value) + +;; Original: +;; #[test] +;; fn interpret_atom_evaluate_variable_operation_nested() { +;; let space = space("(= ((baz $a) $b) ($a $b))"); +;; let result = call_interpret(&space, &metta_atom("(eval (($a A) B))")); +;; #[cfg(feature = "variable_operation")] +;; assert_eq!(result, vec![metta_atom("(A B)")]); +;; #[cfg(not(feature = "variable_operation"))] +;; assert_eq!(result, vec![NOT_REDUCIBLE_SYMBOL]); +;; } + +;; Converted: +(= ((baz $a) $b) ($a $b)) +!(assertEqual (eval (($a A) B)) (A B)) + +;; Original: +;; #[test] +;; fn interpret_atom_chain_incorrect_args() { +;; assert_eq!(call_interpret(&space(""), &metta_atom("(chain n $v t o)")), +;; vec![expr!("Error" ("chain" "n" v "t" "o") "expected: (chain (: Variable) ), found: (chain n $v t o)")]); +;; assert_eq!(call_interpret(&space(""), &metta_atom("(chain n v t)")), +;; vec![expr!("Error" ("chain" "n" "v" "t") "expected: (chain (: Variable) ), found: (chain n v t)")]); +;; assert_eq!(call_interpret(&space(""), &metta_atom("(chain n $v)")), +;; vec![expr!("Error" ("chain" "n" v) "expected: (chain (: Variable) ), found: (chain n $v)")]); +;; } + +;; Converted: +!(assertEqual (chain n $v t o) ("Error" (chain n v t o) "expected: (chain (: Variable) ), found: (chain n $v t o)")) +!(assertEqual (chain n v t) ("Error" (chain n v t) "expected: (chain (: Variable) ), found: (chain n v t)")) +!(assertEqual (chain n $v) ("Error" (chain n v) "expected: (chain (: Variable) ), found: (chain n $v)")) + +;; Original: +;; #[test] +;; fn interpret_atom_chain_atom() { +;; let result = call_interpret(&space(""), &expr!("chain" ("A" () {6} y) x ("bar" x))); +;; assert_eq!(result, vec![expr!("bar" ("A" () {6} y))]); +;; } + +;; Converted: +!(assertEqual (chain (A () {6} y) x (bar x)) (bar (A () {6} y))) + +;; Original: +;; #[test] +;; fn interpret_atom_chain_evaluation() { +;; let space = space("(= (foo $a B) $a)"); +;; let result = call_interpret(&space, &metta_atom("(chain (eval (foo A $b)) $x (bar $x))")); +;; assert_eq!(result, vec![metta_atom("(bar A)")]); +;; } + +;; Converted: +(= (foo $a B) $a) +!(assertEqual (chain (eval (foo A $b)) $x (bar $x)) (bar A)) + +;; Original: +;; #[test] +;; fn interpret_atom_chain_nested_evaluation() { +;; let space = space("(= (foo $a B) $a)"); +;; let result = call_interpret(&space, &metta_atom("(chain (chain (eval (foo A $b)) $x (bar $x)) $y (baz $y))")); +;; assert_eq!(result, vec![metta_atom("(baz (bar A))")]); +;; } + +;; Converted: +(= (foo $a B) $a) +!(assertEqual (chain (chain (eval (foo A $b)) $x (bar $x)) $y (baz $y)) (baz (bar A))) + +;; Original: +;; #[test] +;; fn interpret_atom_chain_nested_value() { +;; let result = call_interpret(&space(""), &metta_atom("(chain (chain A $x (bar $x)) $y (baz $y))")); +;; assert_eq!(result, vec![metta_atom("(baz (bar A))")]); +;; } + +;; Converted: +!(assertEqual (chain (chain A $x (bar $x)) $y (baz $y)) (baz (bar A))) + +;; Original: +;; #[test] +;; fn interpret_atom_chain_expression_non_determinism() { +;; let space = space(" +;; (= (color) red) +;; (= (color) green) +;; (= (color) blue) +;; "); +;; let result = call_interpret(&space, &metta_atom("(chain (eval (color)) $x (bar $x))")); +;; assert_eq_no_order!(result, vec![ +;; metta_atom("(bar red)"), +;; metta_atom("(bar green)"), +;; metta_atom("(bar blue))"), +;; ]); +;; } + +;; Converted: +(= (color) red) +(= (color) green) +(= (color) blue) +!(assertEqualNoOrder (chain (eval (color)) $x (bar $x)) ((bar red) (bar green) (bar blue))) + +;; Original: +;; #[test] +;; fn interpret_atom_chain_return() { +;; let result = call_interpret(&space(""), &metta_atom("(chain Empty $x (bar $x))")); +;; assert_eq!(result, vec![metta_atom("(bar Empty)")]); +;; } + +;; Converted: +!(assertEqual (chain Empty $x (bar $x)) (bar Empty)) + +;; Original: +;; #[test] +;; fn interpret_atom_chain_keep_var_from_evaluated_part() { +;; let result = call_interpret(&space("(= (even 4) True)"), &metta_atom("(chain (eval (even $x)) $res (= (is-even $x) $res))")); +;; assert_eq!(result, vec![metta_atom("(= (is-even 4) True)")]); +;; } + +;; Converted: +(= (even 4) True) +!(assertEqual (chain (eval (even $x)) $res (= (is-even $x) $res)) (= (is-even 4) True)) + +;; Original: +;; #[test] +;; fn interpret_atom_unify_incorrect_args() { +;; assert_eq!(call_interpret(&space(""), &metta_atom("(unify a p t e o)")), +;; vec![expr!("Error" ("unify" "a" "p" "t" "e" "o") "expected: (unify ), found: (unify a p t e o)")]); +;; assert_eq!(call_interpret(&space(""), &metta_atom("(unify a p t)")), +;; vec![expr!("Error" ("unify" "a" "p" "t") "expected: (unify ), found: (unify a p t)")]); +;; } + +;; Converted: +!(assertEqual (unify a p t e o) ("Error" (unify a p t e o) "expected: (unify ), found: (unify a p t e o)")) +!(assertEqual (unify a p t) ("Error" (unify a p t) "expected: (unify ), found: (unify a p t)")) + +;; Original: +;; #[test] +;; fn interpret_atom_unify_then() { +;; let result = call_interpret(&space(""), &metta_atom("(unify (A $b) ($a B) ($a $b) Empty)")); +;; assert_eq!(result, vec![metta_atom("(A B)")]); +;; } + +;; Converted: +!(assertEqual (unify (A $b) ($a B) ($a $b) Empty) (A B)) + +;; Original: +;; #[test] +;; fn interpret_atom_unify_else() { +;; let result = call_interpret(&space(""), &metta_atom("(unify (A $b C) ($a B D) ($a $b) Empty)")); +;; assert_eq!(result, vec![]); +;; } + +;; Converted: +!(assertEqual (unify (A $b C) ($a B D) ($a $b) Empty) ()) + +;; Original: +;; #[test] +;; fn interpret_atom_decons_atom_incorrect_args() { +;; assert_eq!(call_interpret(&space(""), &metta_atom("(decons-atom a)")), +;; vec![expr!("Error" ("decons-atom" "a") "expected: (decons-atom (: Expression)), found: (decons-atom a)")]); +;; assert_eq!(call_interpret(&space(""), &metta_atom("(decons-atom (a) (b))")), +;; vec![expr!("Error" ("decons-atom" ("a") ("b")) "expected: (decons-atom (: Expression)), found: (decons-atom (a) (b))")]); +;; assert_eq!(call_interpret(&space(""), &metta_atom("(decons-atom)")), +;; vec![expr!("Error" ("decons-atom") "expected: (decons-atom (: Expression)), found: (decons-atom)")]); +;; } + +;; Converted: +!(assertEqual (decons-atom a) ("Error" (decons-atom a) "expected: (decons-atom (: Expression)), found: (decons-atom a)")) +!(assertEqual (decons-atom (a) (b)) ("Error" (decons-atom (a) (b)) "expected: (decons-atom (: Expression)), found: (decons-atom (a) (b))")) +!(assertEqual (decons-atom) ("Error" (decons-atom) "expected: (decons-atom (: Expression)), found: (decons-atom)")) + +;; Original: +;; #[test] +;; fn interpret_atom_decons_atom_empty() { +;; let result = call_interpret(&space(""), &metta_atom("(decons-atom ())")); +;; assert_eq!(result, vec![expr!("Error" ("decons-atom" ()) "expected: (decons-atom (: Expression)), found: (decons-atom ())")]); +;; } + +;; Converted: +!(assertEqual (decons-atom ()) ("Error" (decons-atom ()) "expected: (decons-atom (: Expression)), found: (decons-atom ())")) + +;; Original: +;; #[test] +;; fn interpret_atom_decons_atom_single() { +;; let result = call_interpret(&space(""), &metta_atom("(decons-atom (a))")); +;; assert_eq!(result, vec![metta_atom("(a ())")]); +;; } + +;; Converted: +!(assertEqual (decons-atom (a)) (a ())) + +;; Original: +;; #[test] +;; fn interpret_atom_decons_atom_list() { +;; let result = call_interpret(&space(""), &metta_atom("(decons-atom (a b c))")); +;; assert_eq!(result, vec![metta_atom("(a (b c))")]); +;; } + +;; Converted: +!(assertEqual (decons-atom (a b c)) (a (b c))) + +;; Original: +;; #[test] +;; fn interpret_atom_cons_atom_incorrect_args() { +;; assert_eq!(call_interpret(&space(""), &metta_atom("(cons-atom a (e) o)")), +;; vec![expr!("Error" ("cons-atom" "a" ("e") "o") "expected: (cons-atom (: Expression)), found: (cons-atom a (e) o)")]); +;; assert_eq!(call_interpret(&space(""), &metta_atom("(cons-atom a e)")), +;; vec![expr!("Error" ("cons-atom" "a" "e") "expected: (cons-atom (: Expression)), found: (cons-atom a e)")]); +;; assert_eq!(call_interpret(&space(""), &metta_atom("(cons-atom a)")), +;; vec![expr!("Error" ("cons-atom" "a") "expected: (cons-atom (: Expression)), found: (cons-atom a)")]); +;; } + +;; Converted: +!(assertEqual (cons-atom a (e) o) ("Error" (cons-atom a (e) o) "expected: (cons-atom (: Expression)), found: (cons-atom a (e) o)")) +!(assertEqual (cons-atom a e) ("Error" (cons-atom a e) "expected: (cons-atom (: Expression)), found: (cons-atom a e)")) +!(assertEqual (cons-atom a) ("Error" (cons-atom a) "expected: (cons-atom (: Expression)), found: (cons-atom a)")) + +;; Original: +;; #[test] +;; fn interpret_atom_cons_atom_empty() { +;; let result = call_interpret(&space(""), &metta_atom("(cons-atom a ())")); +;; assert_eq!(result, vec![metta_atom("(a)")]); +;; } + +;; Converted: +!(assertEqual (cons-atom a ()) (a)) + +;; Original: +;; #[test] +;; fn interpret_atom_cons_atom_single() { +;; let result = call_interpret(&space(""), &metta_atom("(cons-atom a (b))")); +;; assert_eq!(result, vec![metta_atom("(a b)")]); +;; } + +;; Converted: +!(assertEqual (cons-atom a (b)) (a b)) + +;; Original: +;; #[test] +;; fn interpret_atom_cons_atom_list() { +;; let result = call_interpret(&space(""), &metta_atom("(cons-atom a (b c))")); +;; assert_eq!(result, vec![metta_atom("(a b c)")]); +;; } + +;; Converted: +!(assertEqual (cons-atom a (b c)) (a b c)) + +;; Original: +;; #[test] +;; fn test_superpose_bind() { +;; let vars: Variables = [ "a", "b", "c" ].into_iter().map(VariableAtom::new).collect(); +;; let atom = Atom::expr([Atom::sym("superpose-bind"), +;; Atom::expr([atom_bindings_into_atom(expr!("foo" a b), bind!{ a: expr!("A"), c: expr!("C") })])]); +;; let stack = Stack{ prev: None, atom, ret: no_handler, finished: false, vars: vars.clone() }; +;; +;; let result = superpose_bind(stack, bind!{ b: expr!("B"), d: expr!("D") }); +;; +;; assert_eq!(result, vec![InterpretedAtom( +;; Stack{ prev: None, atom: expr!("foo" a b), ret: no_handler, finished: true, vars: Variables::new() }, +;; bind!{ a: expr!("A"), b: expr!("B"), c: expr!("C"), d: expr!("D") } +;; )]); +;; } + +;; Converted: +!(assertEqual (superpose-bind (foo A B) (bind b: B d: D)) (InterpretedAtom (foo A B) (bind a: A b: B c: C d: D))) + +;; Original: +;; #[test] +;; fn metta_turing_machine() { +;; let space = space(" +;; (= (tm $rule $state $tape) +;; (function (eval (tm-body $rule $state $tape))) ) +;; +;; (= (tm-body $rule $state $tape) +;; (unify $state HALT +;; (return $tape) +;; (chain (eval (read $tape)) $char +;; (chain (eval ($rule $state $char)) $res +;; (unify $res ($next-state $next-char $dir) +;; (chain (eval (move $tape $next-char $dir)) $next-tape +;; (eval (tm-body $rule $next-state $next-tape)) ) +;; (return (Error (tm-body $rule $state $tape) \"Incorrect state\")) ))))) +;; +;; (= (read ($head $hole $tail)) $hole) +;; +;; (= (move ($head $hole $tail) $char N) ($head $char $tail)) +;; (= (move ($head $hole $tail) $char L) (function +;; (chain (cons-atom $char $head) $next-head +;; (chain (decons-atom $tail) $list +;; (unify $list ($next-hole $next-tail) +;; (return ($next-head $next-hole $next-tail)) +;; (return ($next-head 0 ())) ))))) +;; (= (move ($head $hole $tail) $char R) (function +;; (chain (cons-atom $char $tail) $next-tail +;; (chain (decons-atom $head) $list +;; (unify $list ($next-hole $next-head) +;; (return ($next-head $next-hole $next-tail)) +;; (return (() 0 $next-tail)) ))))) +;; +;; (= (busy-beaver A 0) (B 1 R)) +;; (= (busy-beaver A 1) (C 1 L)) +;; +;; (= (busy-beaver B 0) (A 1 L)) +;; (= (busy-beaver B 1) (B 1 R)) +;; +;; (= (busy-beaver C 0) (B 1 L)) +;; (= (busy-beaver C 1) (HALT 1 N)) +;; +;; "); +;; let result = interpret(space, &metta_atom("(eval (tm busy-beaver A (() 0 ())))")); +;; assert_eq!(result, Ok(vec![metta_atom("((1 1) 1 (1 1 1))")])); +;; } + +;; Converted: +(= (tm $rule $state $tape) + (function (eval (tm-body $rule $state $tape)))) +(= (tm-body $rule $state $tape) + (unify $state HALT + (return $tape) + (chain (eval (read $tape)) $char + (chain (eval ($rule $state $char)) $res + (unify $res ($next-state $next-char $dir) + (chain (eval (move $tape $next-char $dir)) $next-tape + (eval (tm-body $rule $next-state $next-tape))) + (return (Error (tm-body $rule $state $tape) "Incorrect state"))))))) +(= (read ($head $hole $tail)) $hole) +(= (move ($head $hole $tail) $char N) ($head $char $tail)) +(= (move ($head $hole $tail) $char L) + (function + (chain (cons-atom $char $head) $next-head + (chain (decons-atom $tail) $list + (unify $list ($next-hole $next-tail) + (return ($next-head $next-hole $next-tail)) + (return ($next-head 0 ()))))))) +(= (move ($head $hole $tail) $char R) + (function + (chain (cons-atom $char $tail) $next-tail + (chain (decons-atom $head) $list + (unify $list ($next-hole $next-head) + (return ($next-head $next-hole $next-tail)) + (return (() 0 $next-tail))))))) +(= (busy-beaver A 0) (B 1 R)) +(= (busy-beaver A 1) (C 1 L)) +(= (busy-beaver B 0) (A 1 L)) +(= (busy-beaver B 1) (B 1 R)) +(= (busy-beaver C 0) (B 1 L)) +(= (busy-beaver C 1) (HALT 1 N)) +!(assertEqual (eval (tm busy-beaver A (() 0 ()))) ((1 1) 1 (1 1 1))) + +;; Original: +;; #[test] +;; fn interpret_minimal_metta_smoketest() { +;; let space = space(" +;; (= (foo $a B) $a) +;; (= (fu $x) (function (chain (eval (foo $x B)) $r (return $r)))) +;; (= (color) red) +;; (= (color) green) +;; (= (color) blue) +;; "); +;; let result = interpret(&space, &metta_atom("(chain (chain A $x $x) $y $y)")); +;; assert_eq!(result, Ok(vec![metta_atom("A")])); +;; let result = interpret(&space, &metta_atom("(chain (chain (eval (foo A $b)) $x (bar $x)) $y (baz $y))")); +;; assert_eq!(result, Ok(vec![metta_atom("(baz (bar A))")])); +;; let result = interpret(&space, &metta_atom("(chain (chain (eval (fu A)) $x (bar $x)) $y (baz $y))")); +;; assert_eq!(result, Ok(vec![metta_atom("(baz (bar A))")])); +;; let result = interpret(&space, &metta_atom("(unify (A $b) ($a B) ($a $b) Empty)")); +;; assert_eq!(result, Ok(vec![metta_atom("(A B)")])); +;; let result = interpret(&space, &metta_atom("(decons-atom (a b c))")); +;; assert_eq!(result, Ok(vec![metta_atom("(a (b c))")])); +;; let result = interpret(&space, &metta_atom("(cons-atom a (b c))")); +;; assert_eq!(result, Ok(vec![metta_atom("(a b c)")])); +;; let result = interpret(&space, &metta_atom("(chain (collapse-bind (eval (color))) $collapsed (superpose-bind $collapsed))")).unwrap(); +;; assert_eq_no_order!(result, vec![metta_atom("red"), metta_atom("green"), metta_atom("blue")]); +;; let result = interpret(&space, &metta_atom("((P $a B) $a)")); +;; assert_eq!(result, Ok(vec![metta_atom("((P $a B) $a)")])); +;; let result = interpret(&space, &metta_atom("(collapse-bind (eval (color)))")).unwrap(); +;; assert_eq!(result.len(), 1); +;; assert_eq_no_order!(atom_as_slice(&result[0]).unwrap(), [ +;; atom_bindings_into_atom(expr!("red"), bind!{}), +;; atom_bindings_into_atom(expr!("green"), bind!{}), +;; atom_bindings_into_atom(expr!("blue"), bind!{}) +;; ]); +;; } + +;; Converted: +(= (foo $a B) $a) +(= (fu $x) (function (chain (eval (foo $x B)) $r (return $r)))) +(= (color) red) +(= (color) green) +(= (color) blue) +!(assertEqual (chain (chain A $x $x) $y $y) A) +!(assertEqual (chain (chain (eval (foo A $b)) $x (bar $x)) $y (baz $y)) (baz (bar A))) +!(assertEqual (chain (chain (eval (fu A)) $x (bar $x)) $y (baz $y)) (baz (bar A))) +!(assertEqual (unify (A $b) ($a B) ($a $b) Empty) (A B)) +!(assertEqual (decons-atom (a b c)) (a (b c))) +!(assertEqual (cons-atom a (b c)) (a b c)) +!(assertEqualNoOrder (chain (collapse-bind (eval (color))) $collapsed (superpose-bind $collapsed)) (red green blue)) +!(assertEqual ((P $a B) $a) ((P $a B) $a)) +!(assertEqualNoOrder (collapse-bind (eval (color))) (red green blue)) + + +;; Original: +;; #[test] +;; fn interpret_duplicated_types() { +;; let space = DynSpace::new(space(" +;; (: foo (-> A A)) +;; (: foo (-> A A)) +;; (: foo (-> Atom A)) +;; (: a A) +;; (= (foo $x) a) +;; ")); +;; let result = interpret(&space, &Atom::expr([METTA_SYMBOL, expr!("foo" "a"), ATOM_TYPE_UNDEFINED, Atom::gnd(space.clone())])); +;; assert_eq!(result, Ok(vec![metta_atom("a")])); +;; } + +;; Converted: +(: foo (-> A A)) +(: foo (-> A A)) +(: foo (-> Atom A)) +(: a A) +(= (foo $x) a) +!(assertEqual (eval (foo a) %Undefined% &self) a) + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Converted Rust Tests with Original Source +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + + +;; #[test] +;; fn case_op_internal_variables_has_priority_in_template() { +;; let space = DynSpace::new(GroundingSpace::new()); +;; let case_op = CaseOp::new(space.clone()); +;; +;; assert_eq!(case_op.execute(&mut vec![expr!(x "A"), expr!(((x x)))]), +;; Ok(vec![expr!(x "A")])); +;; } +;; Converted: +(let space (new-space)) +!(assertEqual (case! space (x "A") (((x x)))) (x "A")) + + +;; fn assert_runtime_error(actual: Result, ExecError>, expected: Regex) { +;; match actual { +;; Err(ExecError::Runtime(msg)) => assert!(expected.is_match(msg.as_str()), +;; "Incorrect error message:\nexpected: {:?}\n actual: {:?}", expected.to_string(), msg), +;; _ => assert!(false, "Error is expected as result, {:?} returned", actual), +;; } +;; } +;; Converted: +(let assert-runtime-error (actual expected) + (match actual + (Err (ExecError::Runtime msg)) (assert (expected.is_match msg)) + _ (assert false))) + + +;; #[test] +;; fn assert_equal_op() { +;; let space = DynSpace::new(metta_space(" +;; (= (foo) (A B)) +;; (= (foo) (B C)) +;; (= (bar) (B C)) +;; (= (bar) (A B)) +;; (= (err) (A B)) +;; ")); +;; +;; let assert_equal_op = AssertEqualOp::new(space); +;; +;; assert_eq!(assert_equal_op.execute(&mut vec![expr!(("foo")), expr!(("bar"))]), unit_result()); +;; +;; let actual = assert_equal_op.execute(&mut vec![expr!(("foo")), expr!(("err"))]); +;; let expected = Regex::new("\nExpected: \\[(A B)\\]\nGot: \\[\\((B C)|, |(A B)\\){3}\\]\nExcessive result: (B C)").unwrap(); +;; assert_runtime_error(actual, expected); +;; +;; let actual = assert_equal_op.execute(&mut vec![expr!(("err")), expr!(("foo"))]); +;; let expected = Regex::new("\nExpected: \\[\\((B C)|, |(A B)\\){3}\\]\nGot: \\[(A B)\\]\nMissed result: (B C)").unwrap(); +;; assert_runtime_error(actual, expected); +;; } +;; Converted: +(let space (new-space)) +(= (foo) (A B)) +(= (foo) (B C)) +(= (bar) (B C)) +(= (bar) (A B)) +(= (err) (A B)) +!(assertEqual (assert-equal! space ("foo") ("bar")) (unit-result)) +(let actual (assert-equal! space ("foo") ("err"))) +(let expected (Regex::new "\nExpected: \\[(A B)\\]\nGot: \\[\\((B C)|, |(A B)\\){3}\\]\nExcessive result: (B C)")) +!(assert-runtime-error actual expected) +(let actual (assert-equal! space ("err") ("foo"))) +(let expected (Regex::new "\nExpected: \\[\\((B C)|, |(A B)\\){3}\\]\nGot: \\[(A B)\\]\nMissed result: (B C)")) +!(assert-runtime-error actual expected) + + +;; #[test] +;; fn assert_equal_to_result_op() { +;; let space = DynSpace::new(metta_space(" +;; (= (foo) (A B)) +;; (= (foo) (B C)) +;; ")); +;; let assert_equal_to_result_op = AssertEqualToResultOp::new(space); +;; +;; assert_eq!(assert_equal_to_result_op.execute(&mut vec![ +;; expr!(("foo")), expr!(("B" "C") ("A" "B"))]), +;; unit_result()); +;; } +;; Converted: +(let space (new-space)) +(= (foo) (A B)) +(= (foo) (B C)) +!(assertEqual (assert-equal-to-result! space ("foo") (("B" "C") ("A" "B"))) (unit-result)) + + +;; #[test] +;; fn collapse_op() { +;; let space = DynSpace::new(metta_space(" +;; (= (foo) (A B)) +;; (= (foo) (B C)) +;; ")); +;; let collapse_op = CollapseOp::new(space); +;; +;; let actual = collapse_op.execute(&mut vec![expr!(("foo"))]).unwrap(); +;; assert_eq!(actual.len(), 1); +;; assert_eq_no_order!( +;; *atom_as_expr(&actual[0]).unwrap().children(), +;; vec![expr!("B" "C"), expr!("A" "B")]); +;; } +;; Converted: +(let space (new-space)) +(= (foo) (A B)) +(= (foo) (B C)) +(let actual (collapse! space ("foo"))) +!(assertEqual (length actual) 1) +!(assertEqualNoOrder (children (first actual)) ((B C) (A B))) + + +;; #[test] +;; fn superpose_op() { +;; let space = DynSpace::new(GroundingSpace::new()); +;; let superpose_op = SuperposeOp::new(space); +;; assert_eq!(superpose_op.execute(&mut vec![expr!("A" ("B" "C"))]), +;; Ok(vec![sym!("A"), expr!("B" "C")])); +;; } +;; Converted: +(let space (new-space)) +!(assertEqual (superpose! space ("A" ("B" "C"))) (("A") ("B" "C"))) + + +;; #[test] +;; fn unique_op() { +;; let space = DynSpace::new(metta_space(" +;; (= (foo) (A (B C))) +;; (= (foo) (A (B C))) +;; (= (foo) (f g)) +;; (= (foo) (f g)) +;; (= (foo) (f g)) +;; (= (foo) Z) +;; ")); +;; let unique_op = UniqueOp::new(space); +;; let actual = unique_op.execute(&mut vec![expr!(("foo"))]).unwrap(); +;; assert_eq_no_order!(actual, +;; vec![expr!("A" ("B" "C")), expr!("f" "g"), expr!("Z")]); +;; } +;; Converted: +(let space (new-space)) +(= (foo) (A (B C))) +(= (foo) (A (B C))) +(= (foo) (f g)) +(= (foo) (f g)) +(= (foo) (f g)) +(= (foo) Z) +(let actual (unique! space ("foo"))) +!(assertEqualNoOrder actual ((A (B C)) (f g) (Z))) + + +;; #[test] +;; fn union_op() { +;; let space = DynSpace::new(metta_space(" +;; (= (foo) (A (B C))) +;; (= (foo) (A (B C))) +;; (= (foo) (f g)) +;; (= (foo) (f g)) +;; (= (foo) (f g)) +;; (= (foo) Z) +;; (= (bar) (A (B C))) +;; (= (bar) p) +;; (= (bar) p) +;; (= (bar) (Q a)) +;; ")); +;; let union_op = UnionOp::new(space); +;; let actual = union_op.execute(&mut vec![expr!(("foo")), expr!(("bar"))]).unwrap(); +;; assert_eq_no_order!(actual, +;; vec![expr!("A" ("B" "C")), expr!("A" ("B" "C")), expr!("f" "g"), expr!("f" "g"), expr!("f" "g"), expr!("Z"), +;; expr!("A" ("B" "C")), expr!("p"), expr!("p"), expr!("Q" "a")]); +;; } +;; Converted: +(let space (new-space)) +(= (foo) (A (B C))) +(= (foo) (A (B C))) +(= (foo) (f g)) +(= (foo) (f g)) +(= (foo) (f g)) +(= (foo) Z) +(= (bar) (A (B C))) +(= (bar) p) +(= (bar) p) +(= (bar) (Q a)) +(let actual (union! space ("foo") ("bar"))) +!(assertEqualNoOrder actual ((A (B C)) (A (B C)) (f g) (f g) (f g) (Z) (A (B C)) (p) (p) (Q a))) + + +;; #[test] +;; fn intersection_op() { +;; let space = DynSpace::new(metta_space(" +;; (= (foo) Z) +;; (= (foo) (A (B C))) +;; (= (foo) (A (B C))) +;; (= (foo) (f g)) +;; (= (foo) (f g)) +;; (= (foo) (f g)) +;; (= (foo) (P b)) +;; (= (bar) (f g)) +;; (= (bar) (f g)) +;; (= (bar) (A (B C))) +;; (= (bar) p) +;; (= (bar) p) +;; (= (bar) (Q a)) +;; (= (bar) Z) +;; +;; (= (nsl) 5) +;; (= (nsl) 4) +;; (= (nsl) 3) +;; (= (nsl) 2) +;; (= (nsr) 5) +;; (= (nsr) 3) +;; ")); +;; let intersection_op = IntersectionOp::new(space); +;; let actual = intersection_op.execute(&mut vec![expr!(("foo")), expr!(("bar"))]).unwrap(); +;; assert_eq_no_order!(actual, +;; vec![expr!("A" ("B" "C")), expr!("f" "g"), expr!("f" "g"), expr!("Z")]); +;; +;; assert_eq_no_order!(intersection_op.execute(&mut vec![expr!(("nsl")), expr!(("nsr"))]).unwrap(), +;; vec![expr!("5"), expr!("3")]); +;; } +;; Converted: +(let space (new-space)) +(= (foo) Z) +(= (foo) (A (B C))) +(= (foo) (A (B C))) +(= (foo) (f g)) +(= (foo) (f g)) +(= (foo) (f g)) +(= (foo) (P b)) +(= (bar) (f g)) +(= (bar) (f g)) +(= (bar) (A (B C))) +(= (bar) p) +(= (bar) p) +(= (bar) (Q a)) +(= (bar) Z) +(= (nsl) 5) +(= (nsl) 4) +(= (nsl) 3) +(= (nsl) 2) +(= (nsr) 5) +(= (nsr) 3) +(let actual (intersection! space ("foo") ("bar"))) +!(assertEqualNoOrder actual ((A (B C)) (f g) (f g) (Z))) +!(assertEqualNoOrder (intersection! space ("nsl") ("nsr")) (5 3)) + + +;; #[test] +;; fn subtraction_op() { +;; let space = DynSpace::new(metta_space(" +;; (= (foo) Z) +;; (= (foo) S) +;; (= (foo) S) +;; (= (foo) (A (B C))) +;; (= (foo) (A (B C))) +;; (= (foo) (f g)) +;; (= (foo) (f g)) +;; (= (foo) (f g)) +;; (= (foo) (P b)) +;; (= (bar) (f g)) +;; (= (bar) (A (B C))) +;; (= (bar) p) +;; (= (bar) p) +;; (= (bar) (Q a)) +;; (= (bar) Z) +;; (= (bar) S) +;; (= (bar) S) +;; (= (bar) S) +;; ")); +;; let subtraction_op = SubtractionOp::new(space); +;; let actual = subtraction_op.execute(&mut vec![expr!(("foo")), expr!(("bar"))]).unwrap(); +;; assert_eq_no_order!(actual, +;; vec![expr!("A" ("B" "C")), expr!("f" "g"), expr!("f" "g"), expr!("P" "b")]); +;; } +;; Converted: +(let space (new-space)) +(= (foo) Z) +(= (foo) S) +(= (foo) S) +(= (foo) (A (B C))) +(= (foo) (A (B C))) +(= (foo) (f g)) +(= (foo) (f g)) +(= (foo) (f g)) +(= (foo) (P b)) +(= (bar) (f g)) +(= (bar) (A (B C))) +(= (bar) p) +(= (bar) p) +(= (bar) (Q a)) +(= (bar) Z) +(= (bar) S) +(= (bar) S) +(= (bar) S) +(let actual (subtraction! space ("foo") ("bar"))) +!(assertEqualNoOrder actual ((A (B C)) (f g) (f g) (P b))) + + +;; #[test] +;; fn superpose_op_type() { +;; let space = DynSpace::new(GroundingSpace::new()); +;; assert!(validate_atom(space.borrow().as_space(), &expr!({SumOp{}} +;; ({SuperposeOp::new(space.clone())} ({Number::Integer(1)} {Number::Integer(2)} {Number::Integer(3)})) +;; {Number::Integer(1)}))); +;; } +;; Converted: +(let space (new-space)) +!(assert (validate-atom space (sum! (superpose! space (1 2 3)) 1))) + + +;; #[test] +;; fn superpose_op_multiple_interpretations() { +;; let metta = Metta::new(Some(EnvBuilder::test_env())); +;; let parser = SExprParser::new(" +;; (= (f) A) +;; (= (f) B) +;; (= (g) C) +;; (= (g) D) +;; +;; !(superpose ((f) (g))) +;; "); +;; +;; assert_eq_metta_results!(metta.run(parser), +;; Ok(vec![vec![expr!("A"), expr!("B"), expr!("C"), expr!("D")]])); +;; } +;; Converted: +(= (f) A) +(= (f) B) +(= (g) C) +(= (g) D) +!(assertEqualToResult (superpose ((f) (g))) (A B C D)) + + +;; #[test] +;; fn superpose_op_superposed_with_collapse() { +;; let metta = Metta::new(Some(EnvBuilder::test_env())); +;; let parser = SExprParser::new(" +;; (= (f) A) +;; (= (f) B) +;; +;; !(let $x (collapse (f)) (superpose $x)) +;; "); +;; +;; assert_eq_metta_results!(metta.run(parser), +;; Ok(vec![vec![expr!("A"), expr!("B")]])); +;; } +;; Converted: +(= (f) A) +(= (f) B) +!(assertEqualToResult (let $x (collapse (f)) (superpose $x)) (A B)) + + +;; #[test] +;; fn superpose_op_consumes_interpreter_errors() { +;; let metta = Metta::new(Some(EnvBuilder::test_env())); +;; let parser = SExprParser::new(" +;; (: f (-> A B)) +;; (= (f $x) $x) +;; +;; (: a A) +;; (: b B) +;; +;; !(superpose ((f (superpose ())) (f a) (f b))) +;; "); +;; +;; assert_eq!(metta.run(parser), Ok(vec![vec![ +;; expr!("Error" ("f" ({SuperposeOp{space:metta.space().clone()}} ())) "NoValidAlternatives"), +;; expr!("a"), expr!("Error" "b" "BadType")]])); +;; } +;; Converted: +(: f (-> A B)) +(= (f $x) $x) +(: a A) +(: b B) +!(assertEqual (superpose ((f (superpose ())) (f a) (f b))) (Error (f (superpose ())) "NoValidAlternatives") (a) (Error b "BadType")) + + +;; #[test] +;; fn get_type_op() { +;; let space = DynSpace::new(metta_space(" +;; (: B Type) +;; (: C Type) +;; (: A B) +;; (: A C) +;; ")); +;; +;; let get_type_op = GetTypeOp::new(space); +;; assert_eq_no_order!(get_type_op.execute(&mut vec![sym!("A")]).unwrap(), +;; vec![sym!("B"), sym!("C")]); +;; } +;; Converted: +(let space (new-space)) +(: B Type) +(: C Type) +(: A B) +(: A C) +!(assertEqualNoOrder (get-type! space A) (B C)) + + + +;; #[test] +;; fn get_type_op_non_valid_atom() { +;; let space = DynSpace::new(metta_space(" +;; (: f (-> Number String)) +;; (: 42 Number) +;; (: \"test\" String) +;; ")); +;; +;; let get_type_op = GetTypeOp::new(space); +;; assert_eq_no_order!(get_type_op.execute(&mut vec![expr!("f" "42")]).unwrap(), +;; vec![sym!("String")]); +;; assert_eq_no_order!(get_type_op.execute(&mut vec![expr!("f" "\"test\"")]).unwrap(), +;; Vec::::new()); +;; } +;; Converted: +(let space (new-space)) +(: f (-> Number String)) +(: 42 Number) +(: "test" String) +!(assertEqualNoOrder (get-type! space ("f" 42)) ("String")) +!(assertEqualNoOrder (get-type! space ("f" "test")) ()) + + +;; #[test] +;; fn add_atom_op() { +;; 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()]); +;; let space_atoms: Vec = space.borrow().as_space().atom_iter().unwrap().cloned().collect(); +;; assert_eq_no_order!(space_atoms, vec![expr!(("foo" "bar"))]); +;; } +;; Converted: +(let space (new-space)) +(add-atom space (foo bar)) +!(assertEqualNoOrder (get-atoms space) ((foo bar))) + + +;; #[test] +;; fn remove_atom_op() { +;; let space = DynSpace::new(metta_space(" +;; (foo bar) +;; (bar foo) +;; ")); +;; 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()]); +;; let space_atoms: Vec = space.borrow().as_space().atom_iter().unwrap().cloned().collect(); +;; assert_eq_no_order!(space_atoms, vec![expr!(("bar" "foo"))]); +;; } +;; Converted: +(let space (new-space)) +(add-atom space (foo bar)) +(add-atom space (bar foo)) +(remove-atom space (foo bar)) +!(assertEqualNoOrder (get-atoms space) ((bar foo))) + + +;; #[test] +;; fn get_atoms_op() { +;; let space = DynSpace::new(metta_space(" +;; (foo bar) +;; (bar foo) +;; ")); +;; let satom = Atom::gnd(space.clone()); +;; let res = GetAtomsOp{}.execute(&mut vec![satom]).expect("No result returned"); +;; let space_atoms: Vec = space.borrow().as_space().atom_iter().unwrap().cloned().collect(); +;; assert_eq_no_order!(res, space_atoms); +;; assert_eq_no_order!(res, vec![expr!(("foo" "bar")), expr!(("bar" "foo"))]); +;; } +;; Converted: +(let space (new-space)) +(add-atom space (foo bar)) +(add-atom space (bar foo)) +!(assertEqualNoOrder (get-atoms space) ((foo bar) (bar foo))) + + +;; #[test] +;; fn car_atom_op() { +;; let res = CarAtomOp{}.execute(&mut vec![expr!(("A" "C") "B")]).expect("No result returned"); +;; assert_eq!(res, vec![expr!("A" "C")]); +;; } +;; Converted: +!(assertEqual (car-atom (("A" "C") "B")) ("A" "C")) + + +;; #[test] +;; fn cdr_atom_op() { +;; let res = CdrAtomOp{}.execute(&mut vec![expr!(("A"))]).expect("No result returned"); +;; assert_eq!(res, vec![expr!()]); +;; let res = CdrAtomOp{}.execute(&mut vec![expr!(("A" "C") ("D" "E") "B")]).expect("No result returned"); +;; assert_eq!(res, vec![expr!(("D" "E") "B")]); +;; let res = CdrAtomOp{}.execute(&mut vec![]); +;; assert_eq!(res, Err(ExecError::Runtime("cdr-atom expects non-empty expression".into()))); +;; } +;; Converted: +!(assertEqual (cdr-atom (("A"))) ()) +!(assertEqual (cdr-atom (("A" "C") ("D" "E") "B")) (("D" "E") "B")) +!(assertEqual (cdr-atom ()) (error "cdr-atom expects non-empty expression")) + + +;; #[test] +;; fn cons_atom_op() { +;; let res = ConsAtomOp{}.execute(&mut vec![expr!("A"), expr!()]).expect("No result returned"); +;; assert_eq!(res, vec![expr!(("A"))]); +;; let res = ConsAtomOp{}.execute(&mut vec![expr!("A" "F"), expr!(("B" "C") "D")]).expect("No result returned"); +;; assert_eq!(res, vec![expr!(("A" "F") ("B" "C") "D")]); +;; } +;; Converted: +!(assertEqual (cons-atom ("A") ()) (("A"))) +!(assertEqual (cons-atom ("A" "F") (("B" "C") "D")) (("A" "F") ("B" "C") "D")) + + +;; #[test] +;; fn bind_new_space_op() { +;; let tokenizer = Shared::new(Tokenizer::new()); +;; +;; let bind_op = BindOp::new(tokenizer.clone()); +;; +;; assert_eq!(bind_op.execute(&mut vec![sym!("&my"), sym!("definition")]), unit_result()); +;; let borrowed = tokenizer.borrow(); +;; let constr = borrowed.find_token("&my"); +;; assert!(constr.is_some()); +;; assert_eq!(constr.unwrap()("&my"), Ok(sym!("definition"))); +;; } +;; Converted: +(let &my definition) +!(assertEqual (&my) definition) + + +;; #[test] +;; fn case_op() { +;; let space = DynSpace::new(metta_space(" +;; (= (foo) (A B)) +;; ")); +;; +;; let case_op = CaseOp::new(space.clone()); +;; +;; assert_eq!(case_op.execute(&mut vec![expr!(("foo")), +;; expr!(((n "B") n) ("Empty" "D"))]), +;; Ok(vec![Atom::sym("A")])); +;; assert_eq!(case_op.execute(&mut vec![expr!({MatchOp{}} {space} ("B" "C") ("C" "B")), +;; expr!(((n "C") n) ("Empty" "D"))]), +;; Ok(vec![Atom::sym("D")])); +;; } +;; Converted: +(let space (new-space)) +(= (foo) (A B)) +!(assertEqual (case! space ("foo") (((n "B") n) ("Empty" "D"))) "A") +!(assertEqual (case! space (match! space ("B" "C") ("C" "B")) (((n "C") n) ("Empty" "D"))) "D") + + +;; #[test] +;; fn case_op_external_vars_at_right_are_kept_untouched() { +;; let space = DynSpace::new(GroundingSpace::new()); +;; let case_op = CaseOp::new(space.clone()); +;; +;; assert_eq!(case_op.execute(&mut vec![expr!(ext), expr!(((t t)))]), +;; Ok(vec![expr!(ext)])); +;; assert_eq!(case_op.execute(&mut vec![expr!(ext "A"), expr!(((t t)))]), +;; Ok(vec![expr!(ext "A")])); +;; } +;; Converted: +(let space (new-space)) +!(assertEqual (case! space ext (((t t)))) ext) +!(assertEqual (case! space (ext "A") (((t t)))) (ext "A")) +