Host Interop - trueagi-io/metta-wam GitHub Wiki

MeTTaLog Host Call Primitives

This page documents the host interop primitives in MeTTaLog, which allow MeTTa programs to invoke logic predicates implemented in the host language (e.g., Prolog, Rust). These calls differ in purpose, determinism, and return behavior.


Summary Table

Primitive Behavior Return Value Example
call-p! Call Predicate True or False (call-p! member 2 [1 2 3])
call-fn! Call Function Final argument or Empty (call-fn! append [1 2] [3 4])
call-for! Call for Value Binds $var on each call (call-for! $x (member $x [a b c]))
call-unit! Call Side Effect () or Empty (call-unit! (debug_log "init"))


call-p!

Usage:

!(call-p! predicate arg1 arg2 ...)

Description: Calls a host predicate with the given arguments.

Return:

  • Returns True if the predicate succeeds.
  • Returns False if the predicate fails.

Example:

!(call-p! member 2 [1 2 3]) ; => True
!(call-p! member 5 [1 2 3]) ; => False

call-fn!

Usage:

!(call-fn! predicate arg1 arg2 ... result)

Description: Calls a host predicate, returning the value of the final argument.

Return:

  • Returns the final argument if the call succeeds.
  • Returns Empty if the call fails.

Examples:

!(call-fn! append [1 2] [3 4])         ; => (1 2 3 4)
!(call-fn! append [1 2] bad_input)     ; => Empty

call-unit!

Usage:

!(call-unit! (predicate arg1 arg2 ...))

Description: Calls a host predicate that performs a side effect and ignores the result.

Return:

  • Returns () (UnitAtom) if the call succeeds.
  • Returns Empty if the call fails.

Examples:

!(call-unit! (member e [a b c])) ; => ()
!(call-unit! fail)               ; => Empty
!(call-unit! true)               ; => ()

Cuts are Allowed: Host predicates used with call-unit! can include cuts, since only one solution is expected.

Example with cut:

!(call-unit! (member $x [a b c]) (cut!) (write $x)) ; => ()

will only write a


call-for!

Usage:

!(call-for! $x (member $x [a b c])) ; => a, b, c
!(call-for! $x (member $x [a b c]) (cut!)) ; => a

Description: Calls a nondeterministic host predicate, returning all answers by binding the first argument to $x.

Return:

  • Yields multiple results through $x via backtracking.

Note: Host predicates used with call-for! should not include cuts if you want all possible results.


Notes

  • All host predicates must be registered (e.g., via mc/mt in Prolog).
  • call-p! and call-fn! pass flat argument lists.
  • call-unit! and call-for! take a full (predicate ...) S-expression.
  • call-fn! and call-unit! may use ! (cut) to prevent backtracking.
  • call-for! should avoid cuts if all answers are needed.
  • Use $_ to ignore output variables if needed.
  • All forms are safe: failure returns False, Empty, or nothing.

Advanced Example: Cuts

This section demonstrates how cut! and cut-fn! influence clause-level vs. function-level backtracking.

; up-to-four has two clauses, each providing multiple answers
(= (up-to-four)
   (call-for! $x (member $x [1 2 3])))

(= (up-to-four)
   (call-for! $x (member $x [4 5 6]) (cut!)))

!(up-to-four) ; => 1, 2, 3, 4
  • The first clause yields 1, 2, 3.
  • The second clause starts with 4, but (cut!) prevents 5, 6.

; up-to-three uses cut-fn! in a single clause to limit the entire function
(= (up-to-three)
   (call-for! $x
     (cut-fn!)
     (member $x [1 2 3])))

(= (up-to-three)
   (call-for! $x (member $x [4 5 6]) (cut!)))

!(up-to-three) ; => 1, 2, 3
  • cut-fn! stops any subsequent clauses from being considered, even though another one exists.
  • So only [1 2 3] is used, and [4 5 6] is skipped entirely.