trueagi-io / metta-wam

A Hyperon MeTTa Interpreter/Transpilier that targets the Warren Abstract Machine
7 stars 9 forks source link

Implement the `unique` Function and Add Test Cases #53

Closed TeamSPoon closed 1 week ago

TeamSPoon commented 1 month ago

Implement the unique Function and Add Test Cases

This issue involves implementing the unique function in MeTTa, which should take non-deterministic results and return non-deterministic results with duplicates removed. The goal is to handle lists of various types, including numbers, symbols, nested structures, and mixed types, while ensuring correct behavior in all scenarios.

Task Description

  1. Implement the unique Function:

    • The unique function should accept non-deterministic input, process it to remove duplicates, and return a non-deterministic output. The function must preserve the order of the first occurrence of each unique element.
    • Example behavior:

      metta+> !(unique (superpose (1 2 2 3 1 4)))
      [1, 2, 3, 4]
      
      metta+> !(unique (superpose (foo bar foo baz)))
      [foo, bar, baz]
  2. Create the Test File:

    • A new file named unique_test.metta should be added to the tests/baseline_compat/hyperon-mettalog_sanity directory.
  3. Define and Test the list-to-set Function:

    • Add the following function definition:

      (: list-to-set (-> Expression Expression))
      (= (list-to-set $list)
        (collapse (unique (superpose $list))))
    • Include the Following Test Cases:

      ;; Test unique with simple duplicates
      ;; This test verifies that `unique` removes all duplicates from (a b b c c c d), resulting in [a, b, c, d].
      !(assertEqual
      (unique (superpose (a b b c c c d)))
      (superpose (a b c d))
      )
      
      ;; Test unique with no duplicates
      ;; This test ensures that `unique` leaves a list unchanged if it already contains only unique elements.
      !(assertEqual
      (unique (superpose (a b c d)))
      (superpose (a b c d))
      )
      
      ;; Test unique with a single element
      ;; This checks that `unique` works correctly for a single-element list, leaving it unchanged as [a].
      !(assertEqual
      (unique (superpose (a)))
      (superpose (a))
      )
      
      ;; Test unique with an empty list
      ;; This confirms that `unique` handles an empty list without errors, correctly returning an empty result.
      !(assertEqual
      (unique (superpose ()))
      (superpose ())
      )
      
      ;; Test unique with all elements being the same
      ;; This verifies that when all elements are the same (a a a a), `unique` reduces it to a single element [a].
      !(assertEqual
      (unique (superpose (a a a a)))
      (superpose (a))
      )
      
      ;; Test unique with nested lists
      ;; This ensures that unique identifies identical nested lists and reduces them to a single instance.
      !(assertEqual
      (unique (superpose ((1 2) (1 2) (3 4))))
      (superpose ((1 2) (3 4)))
      )
      
      ;; Test unique with mixed types
      ;; This test checks that `unique` handles different data types correctly and removes duplicates while preserving the order.
      !(assertEqual
      (unique (superpose (1 "hello" 1 "world" "hello" 3.14 3.14)))
      (superpose (1 "hello" "world" 3.14))
      )
      
      ;; Test list-to-set with simple duplicates
      ;; This test ensures that list-to-set correctly collapses duplicates into a unique set.
      !(assertEqual
      (list-to-set (a b b c c c d))
      (a b c d)
      )
      
      ;; Test list-to-set with nested lists
      ;; This test checks that list-to-set properly collapses duplicates within nested lists.
      !(assertEqual
      (list-to-set ((1 2) (1 2) (3 4)))
      ((1 2) (3 4))
      )
  4. Run and Verify:

    • Once the test cases are in place, ensure they run correctly within the MeTTa test suite.

Expected Outcome

The unique function should correctly handle non-deterministic input, returning non-deterministic results with duplicates removed. The function should work correctly with lists of varying types, including duplicates, single elements, nested lists, and mixed types. The list-to-set function should be tested to confirm that it correctly collapses duplicates into a unique set. The tests should confirm that the functions behave as expected across these scenarios, ensuring consistency with MeTTa's non-deterministic evaluation principles.

TeamSPoon commented 3 weeks ago

adding a handfull of other tests...

;; Test unique with variables
;; This test checks that unique handles variables correctly, ensuring that each unique instance is preserved.
!(assertEqual
  (unique (superpose ($x $y $x $z)))
  (superpose ($x $y $z))
)

;; Test unique with variables in nested lists
;; This test checks that unique correctly handles variables within nested lists, preserving each unique nested structure.
!(assertEqual
  (unique (superpose ((:: $x $y) (:: $x $z) (:: $x $y) (:: $a $b))))
  (superpose ((:: $x $y) (:: $x $z) (:: $a $b)))
)

;; Test unique with repeated variables in nested lists
;; This test ensures that unique treats identical nested lists with variables as duplicates, reducing them to a single instance.
!(assertEqual
  (unique (superpose ((:: $x $y) (:: $x $y) (:: $x $z) (:: $x $y))))
  (superpose ((:: $x $y) (:: $x $z)))
)

;; Test unique with mixed types and variables in nested lists
;; This test checks that unique handles a mix of nested structures with variables, symbols, and other data types correctly.
!(assertEqual
  (unique (superpose ((:: 1 $x) (:: $x "hello") (:: 1 $x) (:: $y $z) (:: $x "hello"))))
  (superpose ((:: 1 $x) (:: $x "hello") (:: $y $z)))
)

;; Test unique with complex nested structures including variables
;; This test verifies that unique handles more complex nested structures containing variables, preserving each unique structure.
!(assertEqual
  (unique (superpose ((:: $x (:: a b)) (:: $x (:: a b)) (:: (:: 1 $x) (:: 2 $y)) (:: (:: 1 $x) (:: 2 $y)))))
  (superpose ((:: $x (:: a b)) (:: (:: 1 $x) (:: 2 $y))))
)