MeTTaTAP - trueagi-io/metta-wam GitHub Wiki

Conversion of Programs to Predicates in Inference Engines

This guide outlines how to transform traditional function-based constructs into predicate-based logic, making them suitable for inference engines such as those used in logic programming environments (e.g., MeTTa). The transformation supports reasoning and nondeterministic evaluation, using hybrid parameters that serve dynamically as inputs or outputs.


๐Ÿ“˜ Overview

In imperative or functional programming, functions return values. But in logic programming, relations (predicates) model computation by stating facts or constraints between arguments.

The goal of this transformation is to:

  • Represent computations as logic relations.
  • Enable reasoning, backtracking, and unification.
  • Allow inference engines to execute or prove goals symbolically.

๐Ÿ” Conversion Process Using S-Expressions


๐Ÿงฎ Step 1: Function Representation (Imperative Style)

In traditional programming:

(let $Z (add $X $Y)
     (println! $Z))

This evaluates (add $X $Y), binds the result to $Z, and then prints $Z.


๐Ÿ”„ Step 2: Convert to Predicate Style

Convert to a relational form where the output is an explicit argument:

(progn
  (add $X $Y $Z)
  (println! $Z))

Here, add/3 expresses a relation between three terms: the two inputs and their sum.


๐Ÿ” Step 3: Handling Nested Functions

Original (Nested Function Call):

(let $B (multiply (add $X $Y) $A) ...)

Converted (Chained Predicates):

(shared
  (add $X $Y $Sum)
  (multiply $Sum $A $B))
  • $Sum is a bridging variable, representing the output of add and the input to multiply.
  • shared ensures the variable $Sum is available to both predicates.

๐Ÿงฌ Hybrid Parameters in Logic

Logic parameters are bidirectional: their role as input or output is determined by their use.

โž• Example: Addition as a Predicate

(add $X $Y $Z)
  • May be used to compute $Z from $X and $Y
  • Or, solve for $X or $Y given $Z

๐Ÿงช Full Example: Nested Arithmetic

Original Code (Function Composition):

(println! (* (+ 1 2) 3))

Transformed to Predicates:

(shared
  (add 1 2 $Sum)
  (multiply $Sum 3 $Result)
  (println! $Result))

This format supports:

  • Step-by-step tracing.
  • Partial evaluation.
  • Reasoning in reverse (e.g., finding inputs that produce a known result).

๐Ÿค Derived Relations Example

Relational logic allows expressing derived relationships in modular steps.

Original Expression:

(likes Joe (friendsOf Mary))

Converted with Intermediate Variable:

(shared
  (likes Joe $mf)
  (equals $mf (friendsOf Mary)))

Alternative Form (With Explicit Friend Relation):

(shared
  (likes Joe $mf)
  (friends Mary $mf))
  • $mf represents Maryโ€™s friends.
  • This version is better when friends/2 is a known predicate, but friendsOf is not explicitly implemented.

๐Ÿ” Summary Table

Original Expression Predicate-Based Equivalent
(let $Z (add $X $Y) ...) (add $X $Y $Z)
(* (+ 1 2) 3) (add 1 2 $Sum)(multiply $Sum 3 $Result)
(likes Joe (friendsOf Mary)) (likes Joe $mf)(equals $mf (friendsOf Mary))
(alternative) (likes Joe $mf)(friends Mary $mf)

๐Ÿง  Why This Matters

By converting functions to predicates:

  • You unlock symbolic reasoning over computations.
  • You enable nonlinear execution paths, such as reverse querying or constraint solving.
  • Your code becomes more declarative, extensible, and introspectable by inference engines.