Working out (2 × 3) + (10 − 4), and showing every intermediate result.
expression-eval.pl · output · proof · check · try it in the playground
A formula like (2 × 3) + (10 − 4) is really a little tree: the + at the
top, a multiplication and a subtraction below it, and plain numbers at the
bottom. Spreadsheets and calculators work through such trees all the time.
What is the value of this formula? And can we see how each part was computed?
Every part of the formula gets a name, called a node:
literal(n2, 2).
literal(n3, 3).
literal(n10, 10).
literal(n4, 4).
expression(product, mul, n2, n3).
expression(difference, sub, n10, n4).
expression(total, add, product, difference).
root(example, total).
product multiplies n2 and n3; difference subtracts n4 from n10;
total adds those two. The formula called example starts at total.
value(Node, Value) :- literal(Node, Value).
value(Node, Value) :- expression(Node, Operation, Left, Right),
value(Left, L), value(Right, R), calculate(Operation, L, R, Value).
calculate(add, L, R, Value) :- Value is L+R.
calculate(sub, L, R, Value) :- Value is L-R.
calculate(mul, L, R, Value) :- Value is L*R.
result(Name, Value) :+ root(Name, Node), value(Node, Value).
A number’s value is itself. An expression’s value: evaluate both sides, then apply the operation. This is recursion: a rule that uses itself on smaller pieces until it reaches plain numbers.
result(example, 12).
(2 × 3) + (10 − 4) = 6 + 6 = 12.
The proof follows the tree from the top down, 22 steps in all:
total is 12, because product is 6, difference is 6, and 6 + 6 = 12.product is 6, because n2 is 2, n3 is 3, and 2 × 3 = 6.difference is 6, because n10 is 10, n4 is 4, and 10 − 4 = 6.literal fact.Every step names the program line it used and the values it filled in.
A separate checker read the proof against the program:
Verdict: checked. All 22 steps verified, nothing taken on trust.
node bin/eyedia.js examples/expression-eval.pl
node bin/eyedia.js --proof examples/expression-eval.pl
Or open it in the playground.
Change literal(n4, 4). to literal(n4, 1). and run again: the difference
becomes 9 and the answer result(example, 15).
Even simple arithmetic is a chain of small steps. When each one is written down and rechecked, a wrong input is easy to find, and a right answer is easy to trust.