A tutorial on chess search
MeTTa is firstly a programming language. Perhaps you tried a bit of MeTTa coding, or heard about MeTTa on social media, at a conference, or from a colleague, and want to explore. You heard it is an innovative AI language that would benefit your projects.
You probably have some questions in mind such as:
Well, if you have variations of these questions, you are on the right tutorial.
The single most defining characteristic of MeTTa is this: it insists on giving you all possible results. Whether you like it or not!
Suppose you are creating a package delivery routing application. Given a starting point and a destination, let's say ten routes exist, each with many twists and turns, so your code has lots of constraints. MeTTa outputs all ten complete routes in one run, at once.
Now suppose you are creating a scheduling application. Given today's agenda, there are ninety-nine possible schedules given available rooms, equipment, personnel, tasks, etc. Again, MeTTa outputs all ninety-nine schedules in a single result.
If this sounds to you a bit like an SQL "return all rows" matching request, you'd be on the right track. In essence, MeTTa is a fusion of "return all rows" SQL type calls and basically ordinary code. Given some specific inputs, code written in MeTTa by default will return all possible output combinations that result from executing all possible paths in your code applicable to the input. You get everything.
This might immediately raise the worrying prospect of having to deal with an avalanche of results. Well, don't worry, because there are ways of corralling such an avalanche with MeTTa. In fact that's the point of it. And you basically only need about a dozen constructs to do everything you need in MeTTa.
Reality is incredibly complex. AI is a distinct discipline within computer science because worldly complex problems can't be handled by conventional programming in which all possible combinations are accounted for and pre-coded in advance. Techniques are developed to reach goals without requiring the specific pre-coding and foresight of all sequences of all possible combinations. AI evolved into a trick bag for handling such situations. AI, symbolic and neural, has to search for a path from start request to goal result without a predetermined route.
Historically it has been difficult to write conventional symbolic programs to handle problems characterized by real world complexity. The strategy MeTTa employs to meet the challenge of subduing combinatorial explosions is to add a small set of programming principles and constructs to enable conventional seeming programs to tame a massive number of combinations and "all possible results." (You can get similar results with languages such as Prolog, but Prolog is a very unusual language for beginning and potential users to learn.)
There are three defining programming constructs in MeTTa to manage combinatorial explosion, covered in detail later along with a few other supporting constructs:
Basically the combinatorial explosion happens as a result of the first two steps, but collapse sets an important boundary. If you forget to terminate this sequence with collapse, beware that MeTTa might insist on backing up later in your code and recomputing other variations you may not have thought of, much to your surprise and possible annoyance.
In order to avoid this potential "gotcha" (MeTTa unexpectedly backing up, retrying your match) all you need to do is use collapse. MeTTa will then proceed forward and not dwell on other possible cases. collapse is your primary tool for curtailing a combinatorial explosion, and can be used basically anywhere that you suspect MeTTa code blocks might generate multiple results.
The world is presently on fire with LLMs, so you might be wondering what the advantage of MeTTa, a symbolic language, might be for AI.
LLMs are, of course, incredible AI technology and a bona fide breakthrough. LLMs have a sort of common sense facility coupled with a regularly astonishing breadth of generality.
Yet their weaknesses are well known, and while improving, still present. Hallucinations remain a regular problem. Their ability to store memories and other data long term, reliably, is problematic. Dynamic learning is weak or non-existent.
MeTTa is reliable as long term memory. MeTTa is firstly a programming language, but can effectively double as a knowledge graph, allowing create, read, update, and delete (CRUD) processing. It can process problems dependably with significant combinatorial variations, such as chess. The type of intelligence MeTTa exemplifies is arguably deep, not necessarily wide in breadth like an LLM. However, MeTTa has no intrinsic approximation of a common sense facility comparable to an LLM and, as a symbolic engine, may be brittle. (Although it is possible to incorporate embeddings in MeTTa code.)
The question of whether or not, and to what extent, MeTTa can synergize with LLMs is an open and tantalizing one. MeTTa in a RAG type of role can potentially add a deep and reliable component to the broader, more common sense infused intelligence of an LLM. If you have an application with combinatorial complexity, the need to update memory reliably, and predictable inference, MeTTa can help.
Some background exposure to MeTTa, LISP, Prolog or similar languages is helpful. Absolute newbies might want to visit MeTTa Learn Docs for additional MeTTa background, however the tutorial covers most basics. Knowing some chess too, is helpful, but you can still gain knowledge of MeTTa techniques even without knowing how to play.
Chess has a high degree of combinatorial explosion. After a crash course in a few basic MeTTa constructs, we will study code for a chess game. You can then make a major modification to it.
Your code and data reside together in atomspace as MeTTa can be both a programming language and a data construct, a knowledge graph.
For this tutorial you can use the handy boxes appearing throughout to try out segments of code. You can display and reset your atomspace using the buttons above at any time.
In MeTTa, the "code" is essentially rewrite rules starting with "(=". Given some input pattern, the right side of the rewrite rule is executed. The input pattern below is "(What is MeTTa?)".
Your "data" is stored in atomspace enclosed in balanced parenthesis.
If you start your MeTTa statement with "!" you trigger an immediate execution of what follows the exclamation point.
When you click the "Run" button below MeTTa will add the "code" and "data" statements to atomspace. Then MeTTa executes the "!" statement which results in "(What is MeTTa?)" being matched with "(What is MeTTa?)" in the left side of the "(=" rewrite rule. The right side of the "(=" rewrite fires. It matches "(MeTTa is fun)" added in the second step. The result "fun" is returned by the rewrite rule, displayed as your output of the "!" statement, but not added to atomspace.
After running the code segment below click to display your updated atomspace.
; "code" rewrite rule atom
(= (What is MeTTa?) (match &self (MeTTa is $variable) $variable))
; "data," another type of atom
(MeTTa is fun)
; execute
!(What is MeTTa?)A red parenthesis in the code box is often a tip-off that you have unbalanced parenthesis somewhere in your expression.
It's possible to subdivide atomspace into different spaces. The default space inside atomspace is designated as &self. For this tutorial we will only use &self. MeTTa also has typing functionality and constructs, however we will omit typing from this tutorial as it is not strictly required for our application.