Skip to content

Adding a New Built‐in Function to the MettaLog Interpreter

Mike Archbold edited this page Sep 30, 2024 · 5 revisions

These are instructions for how to add a new built-in function to the MettaLog interpreter. The process includes updating several files within the codebase to ensure the function is properly defined, implemented, and documented.

Tasks

  1. Define the Function in stdlib_mettalog.metta:

    • Add the function definition to stdlib_mettalog.metta so that MettaLog recognizes it as a built-in function.
    • Example:
      ;; Public MeTTa
      (@doc stringToChars
          (@desc "Converts a String to an Expression of Chars")
          (@params (
              (@param "String to be expanded")))
          (@return "Expression with a list of Chars"))
      (: stringToChars (-> String Expresson))
      ;; Implemented from Interpreters
      
  2. Implement the Function in metta_eval.pl:

    • Add the implementation of the function to the eval_20 predicate in metta_eval.pl, see metta_eval wiki

    • Example:

      eval_20(Eq,RetType,Depth,Self,['stringToChars',String],Chars):- !,                          
           eval_args(Eq,RetType,Depth,Self,String,SS), 
           string_chars(SS,Chars0), 
           maplist(as_metta_char,Chars0,Chars).
  3. Add Test Cases in a new file of form 'NewFunction.metta':

    • Add within directory metta-wam/tests/baseline_compat/hyperon-mettalog_sanity/
    • Add relevant test cases to ensure the function behaves as expected.
    • Example test:
      
      !(assertEqual (stringToChars "xyzzy") ('x' 'y' 'z' 'z' 'y'))
      
      !(assertEqual (charsToString ('x' 'y' 'z' 'z' 'y')) "xyzzy")
      
      !(assertEqual (stringToChars "") ())
      
      !(assertEqual (charsToString ()) "")
      
      ;; this one works differently in metta and mettalog
      !(assertEqual (charsToString (stringToChars "xyzzy")) "xyzzy")
      
      !(assertEqual (stringToChars (charsToString ('x' 'y' 'z' 'z' 'y'))) ('x' 'y' 'z' 'z' 'y'))
      
      ;; metta gets all these wrong
      !(assertEqual (charsToString ('x' 'y' ' ' 'z' 'y')) "xy zy")
      
      !(assertEqual (stringToChars "xy zy") ('x' 'y' ' ' 'z' 'y'))
      
      !(assertEqual (charsToString (' ')) " ")
      
      !(assertEqual (stringToChars " ") (' '))
      
      !(assertEqual (stringToChars (superpose ("ab" "cd" "ef"))) (superpose (('a' 'b') ('c' 'd') ('e' 'f'))))
      
      ;; format-args
      
      !(assertEqual (format-args "" (1 2 3)) "")
      
      !(assertEqual (format-args " " (1 2 3)) " ")
      
      !(assertEqual (format-args "{}" (1 2 3)) "1")
      
      !(assertEqual (format-args "{}}" (1 2 3)) "{}")
      
      !(assertEqual (format-args "xyz zy" (1 2 3)) "xyz zy")
      
      !(assertEqual (format-args "Indexed {1} {} {0} {}" (1 2 3)) "Indexed 2 1 1 2")
      
      !(assertEqual (format-args "Different types {} {} {} {} {} {}" (1 "2" 'c' -0.5 atom (1 2 c -0.5 atom))) "Different types 1 2 c -0.5 
        atom (1 2 c -0.5 atom)")
      
      !(assertEqual (format-args "Two digit index={11}" (0 1 2 3 4 5 6 7 8 9 10 "eleven")) "Two digit index=eleven")
      
      ;; malformed examples
      !(assertEqual (format-args "Bad args list {1} {} {0} {}" x) (format-args "Bad args list {1} {} {0} {}" x))
      
      !(assertEqual (format-args "Malformed format}{{}{{{}{} {4} { } {-1} {x} {{{{{{}}}}}}{{{{{}}}}}" ("success1" "success2")) "Malformed 
            format}{}{success1success2 {4} { } {-1} {x} {{{}}}{{{}}}")
      

Acceptance Criteria

  • The new function is defined in stdlib_mettalog.metta, implemented in metta_eval.pl, and tested.
  • All tests pass successfully, demonstrating that the function behaves as expected.

Reference Documentation