Skip to content

Exercises ​

A few exercises to practice the evaluation model. Each has a worked solution you can run in this engine (paste it into a .metta file and run metta run file.metta, or pass it to runProgram). Try them before peeking.

A reminder on the list encoding used below: the empty list is () and a cons cell is (:: head tail), so [A, B, C] is (:: A (:: B (:: C ()))).

1. Store facts, then query them ​

Store that Ada likes coffee and chocolate and Turing likes tea, then ask what Ada likes.

metta
(Likes Ada Coffee)
(Likes Ada Chocolate)
(Likes Turing Tea)

!(match &self (Likes Ada $thing) $thing)   ; Coffee and Chocolate

match searches the stored atoms (not sub-expressions) for the pattern and returns the template $thing for each match.

2. inc, dec, square ​

Define (inc $x), (dec $x), and (square $x) with grounded arithmetic.

metta
(= (inc $x) (+ $x 1))
(= (dec $x) (- $x 1))
(= (square $x) (* $x $x))

!(inc 41)      ; 42
!(dec 10)      ; 9
!(square 12)   ; 144

3. classify by sign ​

Define (classify $x) returning Positive, Negative, or Zero. Nested if does it:

metta
(= (classify $x)
   (if (> $x 0) Positive
       (if (< $x 0) Negative Zero)))

!(classify 7)    ; Positive
!(classify -3)   ; Negative
!(classify 0)    ; Zero

4. factorial ​

Grounded numbers cannot be deconstructed by pattern matching, so use if for the base case:

metta
(= (fact $n) (if (> $n 0) (* $n (fact (- $n 1))) 1))

!(fact 0)   ; 1
!(fact 5)   ; 120
!(fact 7)   ; 5040

5. length of a list ​

Two rules, a base case and a recursive case:

metta
(= (length ()) 0)
(= (length (:: $x $xs)) (+ 1 (length $xs)))

!(length (:: A (:: B (:: C ()))))   ; 3

Doing the same from TypeScript ​

Every exercise above can be written with the typed eDSL instead of source strings. Factorial, for example:

ts
import { 
mettaDB
,
names
,
vars
,
If
,
gt
,
mul
,
sub
} from "@mettascript/edsl";
const
db
=
mettaDB
();
const {
fact
} =
names
();
const {
x
} =
vars
();
db
.
rule
(
fact
(
x
),
If
(
gt
(
x
, 0),
mul
(
x
,
fact
(
sub
(
x
, 1))), 1));
db
.
evalJs
(
fact
(5)); // [120]

Released under the MIT License.