MeTTa has an `m` in it - trueagi-io/metta-wam GitHub Wiki
The m
function in MeTTa is the core logic execution engine, handling goal evaluation, rule expansion, backward chaining, backtracking, and unification. It operates in a default context (&self
), which can be overridden (ctx &them ...
) inside or outside of m
.
m
Key Features of - ✅ Expands functions and rules before execution.
- ✅ Backtracks and retries on failure.
- ✅ Unifies facts and rules like Prolog.
- ✅ Executes in a specific logical context (
ctx &self
orctx &them
). - ✅ Supports logical operators (
or
,not
,naf
,call
,eval
,ignore
,limit
,count-of
,unique
,at-least
). - ✅ Implicit
and
behavior—all statements insidem
must succeed. - ✅ Ensures all variable bindings are returned if
True
is placed at the end.
m
Works
How When m
is executed, it follows these steps:
1️⃣ Expands function calls into their definitions.
2️⃣ Expands rule heads into their bodies.
3️⃣ Performs fact queries against the knowledge base.
4️⃣ Executes in the default &self
context unless overridden.
5️⃣ Backtracks and retries on failure.
6️⃣ Returns variable bindings if successful, or the last computed value if applicable.
and
Behavior
Implicit Unlike Prolog, and
is implicit in m
—all statements inside m
must succeed for execution to continue.
and
in m
Example: Implicit (m
(rdf! $Gene ex:gene_name "BRCA2") ;; Must succeed
(rdf! $Gene ex:transcribed_to $Transcript) ;; Must succeed
(rdf! $Transcript ex:translates_to $Protein) ;; Must succeed
)
- If any statement fails,
m
backtracks and retries. - Unlike Prolog, you don’t need explicit
and
—each statement must succeed.
True
at the End of m
The Special Role of Placing True
at the end ensures that the final return value is always the full set of variable bindings.
- If the last statement normally returns a value, that value is discarded and all variable bindings are returned instead.
- If there is no
True
at the end,m
returns the value of the last executed statement instead.
True
Example Without (m
(rdf! "BRCA2" ex:gene_length $Length)
)
✅ Returns:
1005
(The direct value of $Length
is returned.)
True
Example With (m
(rdf! "BRCA2" ex:gene_length $Length)
True
)
✅ Returns:
(($Length "1005"))
(The variable binding is returned instead of just the value.)
m
Logical Operators in While and
is implicit, m
supports explicit logical operators:
or
– At least one condition must be true.not
– Logical negation (fails if the condition is true).naf
– Negation as failure (succeeds if the query fails).call
– Forces head/fact unification.eval
– Forces function call evaluation.ignore
– Allows failure without stopping execution.limit
– Cuts execution after a set number of answers.count-of
– Returns the number of matching solutions.unique
– Ensures unique results by filtering duplicates.at-least
– Ensures at leastn
answers are found.
Advanced Query Controls
limit
)
1️⃣ Limiting Execution (Use limit
to restrict the number of results.
Example: Limit to 2 Results
(m
(limit 2
(rdf! "BRCA2" ex:transcribed_to $Transcript)
(rdf! $Transcript ex:translates_to $Protein)
)
)
✅ Stops after 2 results, even if more exist.
count-of
)
2️⃣ Counting Results (Use count-of
to return the number of solutions.
Example: Count All Transcripts
(m
(count-of
(rdf! "BRCA2" ex:transcribed_to $Transcript)
)
)
✅ Returns: 3
(if three transcripts exist).
unique
)
3️⃣ Ensuring Unique Results (Use unique
to eliminate duplicate solutions.
Example: Ensure Unique Pathways
(m
(unique
(rdf! "BRCA2" ex:genes_pathways $Pathway)
)
)
✅ Ensures each pathway is listed only once.
at-least
)
4️⃣ Ensuring a Minimum Number of Results (Use at-least
to force m
to find a minimum number of answers.
Example: Require at Least 2 Solutions
(m
(at-least 2
(rdf! "BRCA2" ex:transcribed_to $Transcript)
)
)
✅ Fails if fewer than 2 transcripts are found.
ctx
)
Context Handling (By default, m
runs in context &self
, but can execute in any context:
(ctx &them (m (rdf! $Gene ex:gene_name "BRCA2")))
- This allows execution in a different logical space (
&them
). ctx
can be inside or outside ofm
.
Examples of Query Execution
1️⃣ Retrieving a Query by Name & Type
!(m (test-query brca2 sparql $query))
!(m (test-query igf2 prolog-rdf $query))
!(m (test-query brca2 metta-rdf $query))
2️⃣ Running a Local RDF Query
!(m (test-query brca2 prolog-rdf $query) (call-p $query))
3️⃣ Executing a SPARQL Query
!(m (test-query brca2 sparql $query) (call-fn sparql-internal ($query $Results)))
4️⃣ Evaluating a MeTTa Query
!(m (test-query brca2 metta-rdf $metta-code) (eval $metta-code))
!(m (test-query igf2 metta-rdf $metta-code) (eval $metta-code))
Conclusion
The m
function is the core logic execution engine in MeTTa, enabling:
- Implicit
and
for execution chaining. - Backward chaining for inference.
- Backtracking & retrying when queries fail.
- Execution in different contexts (
ctx
). - Logical operators (
or
,not
,naf
,call
,eval
,ignore
,limit
,count-of
,unique
,at-least
). - Returning variable bindings when
True
is specified at the end.