egison-5.0.0: sample/math/algebra/quartic-equation.egi
-- Quartic Formula (Ferrari's method)
declare symbol x, y
def quarticFormula : MathExpr -> MathExpr -> (MathExpr, MathExpr, MathExpr, MathExpr) := qtF
def qtF (f: MathExpr) (x: MathExpr) : (MathExpr, MathExpr, MathExpr, MathExpr) :=
match coefficients f x as list mathExpr with
| $a_0 :: $a_1 :: $a_2 :: $a_3 :: $a_4 :: [] -> qtF' a_4 a_3 a_2 a_1 a_0
def qtF' (a: MathExpr) (b: MathExpr) (c: MathExpr) (d: MathExpr) (e: MathExpr) : (MathExpr, MathExpr, MathExpr, MathExpr) :=
match (a, b, c, d, e) as
(mathExpr, mathExpr, mathExpr, mathExpr, mathExpr) with
| (#1, #0, $p, #0, $q) ->
let (s1, s2) := qF' 1 p q
(r1, r2) := qF' 1 0 (- s1)
(r3, r4) := qF' 1 0 (- s2)
in (r1, r2, r3, r4)
| (#1, #0, $p, $q, $r) ->
let u := (3)#$1
(withSymbols [u]
cF (u * (p + u) ^ 2 + (-4) * r * u + (- (q ^ 2))) u)
(r1, r2) := qF (y ^ 2 + (p + u) / 2 + sqrt u * (y - q / (2 * u))) y
(r3, r4) := qF
(y ^ 2 + (p + u) / 2 + (- sqrt u) * (y - q / (2 * u)))
y
in (r1, r2, r3, r4)
| (#1, _, _, _, _) ->
(4)#($1 - b / 4, $2 - b / 4, $3 - b / 4, $4 - b / 4)
(withSymbols [x, y]
qtF
(substitute
[(x, y - b / 4)]
(x ^ 4 + b * x ^ 3 + c * x ^ 2 + d * x + e))
y)
| (_, _, _, _, _) -> qtF' 1 (b / a) (c / a) (d / a) (e / a)
def w := ((-1) + i * sqrt 3) / 2
-- Verify: (x-1)(x-2)(x-3)(x-4) should give roots 1, 2, 3, 4
assertEqual "quartic (x-1)(x-2)(x-3)(x-4)"
(qtF ((x - 1) * (x - 2) * (x - 3) * (x - 4)) x)
(4, 1, 3, 2)