R5 — Equations
Goal: solve equations, inequalities and systems — and understand the one thing solve does that will surprise you.
One equation, one unknown
> solve(2x + 6 = 0, x)
x := -3.0
Why does that look like an assignment?
Because it is one. Read the echo again — x := -3.0, the exact shape R3 taught. solve does not merely report the root, it stores it, so the next line that mentions x uses it:
> x + 1
-2.0
That is convenient when you want to carry a result forward into further work, and a trap when you do not: a second solve would substitute the first answer before doing anything at all. This is the stale-binding problem R3 warned about, arriving from a command you did not think of as an assignment.
Clear it between problems:
> unset x
x unset
> solve(x^2 - 4 = 0, x)
x_1 := -2.0
x_2 := 2.0
Two roots, and notice they bound as x_1 and x_2 rather than x — so x itself is untouched. Proof, rather than assertion:
> unset x
x is not set
Nothing to clear. The habit to build is simple: when a solve answer looks wrong, check env first.
Symbolic coefficients
> solve(a*x + b = 0, x)
x := ((-1.0 * b) / a)
> unset x
x unset
That is what makes this a computer algebra system rather than a numerical solver: it rearranged the equation without ever knowing what a and b are.
When there is no closed form
> solve(cos(z) = z, z)
z := 0.73909
> unset z
z unset
No formula exists for that root, so the answer is numeric — and which kind you got is visible in the answer itself rather than hidden behind a flag.
Naming an equation
An equation is an ordinary value, so you can store one and solve it later:
> eq := x^2 - 5x + 6 = 0
eq := (((x ^ 2.0) + (-1.0 * (5.0 * x))) + 6.0) = 0.0
> solve(eq, x)
x_1 := 2.0
x_2 := 3.0
> unset x_1
x_1 unset
> unset x_2
x_2 unset
Inequalities
The answer to an inequality is a region, and the language can say so:
> solve(2x + 6 > 0, x)
(x > -3.0)
> solve(x^2 - 4 > 0, x)
((x < -2.0) or (x > 2.0))
The second is a union, written with or — an ordinary connective here, not a special kind of object. A bounded region comes back as an and, and you can pose a combination directly:
> solve(x^2 - 4 < 0, x)
((x > -2.0) and (x < 2.0))
> solve(2x > 2 and x < 5, x)
((x > 1.0) and (x < 5.0))
Note there is no := in any of those: a region is not a value to assign, so nothing was stored. Only a definite answer binds.
Systems
solveSystem takes a row of equations, then the unknowns in order:
> solveSystem([[x + y = 3, x - y = 1]], x, y)
[[x = 2.0, y = 1.0]]
The [[...]] brackets are the matrix literal — one row — which is also the shape the answer comes back in. R6 is about those.
Equations are values too
An equation evaluates as soon as everything in it is known:
> 2 + 2 = 4
true
> sin(pi) = 0
true
The second is true because equality here is tolerance-based at the display precision. sin(pi) is not exactly zero in floating point — π is not exactly π — and answering false would be technically correct and practically useless. R8 is about getting the exact answer when you want it.
Try it yourself
A rectangle has perimeter 20 and area 24. Find its sides.
Answers
The obvious attempt is a system: ```text > solveSystem([[2w + 2h = 20, w * h = 24]], w, h) solveSystem([[((2.0 * w) + (2.0 * h)) = 20.0, (w * h) = 24.0]], w, h) ``` *[run this session](https://lycogrypho.github.io/Leonardo/app/#s=precision%205%0Acolors%20dark%0Apretty%20off%0Alatex%20off%0Anames%20off%0Alogic%20minmax%0Alogic%20symmetric%20off%0Aexact%20precision%2030%0Aexact%20off%0Aeq%20%3A%3D%20(((x%20%5E%202.0)%20%2B%20((-1.0)%20*%20(5.0%20*%20x)))%20%2B%206.0)%20%3D%200.0)* Declined — the unchanged-answer shape from [R4](/Leonardo/lessons/r4.html). **`solveSystem` is linear only**, and `w * h` is not, so it did not guess. Substitute by hand (`h = 10 - w`) and solve the quadratic that remains: ```text > solve(w * (10 - w) = 24, w) w_1 := 4.0 w_2 := 6.0 ``` *[run this session](https://lycogrypho.github.io/Leonardo/app/#s=precision%205%0Acolors%20dark%0Apretty%20off%0Alatex%20off%0Anames%20off%0Alogic%20minmax%0Alogic%20symmetric%20off%0Aexact%20precision%2030%0Aexact%20off%0Aw_1%20%3A%3D%204.0%0Aw_2%20%3A%3D%206.0%0Aeq%20%3A%3D%20(((x%20%5E%202.0)%20%2B%20((-1.0)%20*%20(5.0%20*%20x)))%20%2B%206.0)%20%3D%200.0)* Sides 4 and 6 — the two roots are the same rectangle, seen twice.What you learned
solvebinds its answer — one root as the variable, several asx_1,x_2, … Useunsetbetween problems, or the next solve starts from the last one.- It handles linear and quadratic exactly, symbolic coefficients included, and falls back to numeric roots when no formula exists.
- An inequality’s answer is a region, written with
and/orin the same language you asked in — and regions do not bind. solveSystem([[...]], x, y)is linear only, and declines rather than guessing.- Equality between numbers is tolerant, so
sin(pi) = 0istrue.
Previous: R4 — Calculus · Next: R6 — Matrices · All lessons