-- |
-- Module: Symtegration.Polynomial.Solve
-- Description: Derive the roots of polynomials with rational coefficients.
-- Copyright: Copyright 2025 Yoo Chung
-- License: Apache-2.0
-- Maintainer: dev@chungyc.org
--
-- This module supports deriving exact solutions to polynomial equations.
-- It cannot derive solutions for all polynomials; it will only return those which it can.
module Symtegration.Polynomial.Solve (solve) where

import Data.List (nub)
import Symtegration.Polynomial
import Symtegration.Polynomial.Indexed
import Symtegration.Symbolic

-- $setup
-- >>> import Symtegration
-- >>> import Symtegration.Polynomial

-- | Derive the roots for the given polynomial.  Only real roots are returned.
--
-- >>> map (toHaskell . simplify) <$> solve (2 * power 1 - 6)
-- Just ["3"]
--
-- >>> map (toHaskell . simplify) <$> solve (power 2 - 4)
-- Just ["2","-2"]
--
-- Returns 'Nothing' if the function does not know how to derive the roots.
solve :: IndexedPolynomial -> Maybe [Expression]
solve :: IndexedPolynomial -> Maybe [Expression]
solve IndexedPolynomial
p
  | IndexedPolynomial -> Int
forall (p :: * -> * -> *) e c. Polynomial p e c => p e c -> e
degree IndexedPolynomial
p Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 = Rational -> Rational -> Maybe [Expression]
solveLinear (IndexedPolynomial -> Int -> Rational
forall (p :: * -> * -> *) e c. Polynomial p e c => p e c -> e -> c
coefficient IndexedPolynomial
p Int
1) (IndexedPolynomial -> Int -> Rational
forall (p :: * -> * -> *) e c. Polynomial p e c => p e c -> e -> c
coefficient IndexedPolynomial
p Int
0)
  | IndexedPolynomial -> Int
forall (p :: * -> * -> *) e c. Polynomial p e c => p e c -> e
degree IndexedPolynomial
p Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
2 = Rational -> Rational -> Rational -> Maybe [Expression]
solveQuadratic (IndexedPolynomial -> Int -> Rational
forall (p :: * -> * -> *) e c. Polynomial p e c => p e c -> e -> c
coefficient IndexedPolynomial
p Int
2) (IndexedPolynomial -> Int -> Rational
forall (p :: * -> * -> *) e c. Polynomial p e c => p e c -> e -> c
coefficient IndexedPolynomial
p Int
1) (IndexedPolynomial -> Int -> Rational
forall (p :: * -> * -> *) e c. Polynomial p e c => p e c -> e -> c
coefficient IndexedPolynomial
p Int
0)
  | IndexedPolynomial -> Int
forall (p :: * -> * -> *) e c. Polynomial p e c => p e c -> e
degree IndexedPolynomial
p Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
3 = Rational -> Rational -> Rational -> Rational -> Maybe [Expression]
solveCubic (IndexedPolynomial -> Int -> Rational
forall (p :: * -> * -> *) e c. Polynomial p e c => p e c -> e -> c
coefficient IndexedPolynomial
p Int
3) (IndexedPolynomial -> Int -> Rational
forall (p :: * -> * -> *) e c. Polynomial p e c => p e c -> e -> c
coefficient IndexedPolynomial
p Int
2) (IndexedPolynomial -> Int -> Rational
forall (p :: * -> * -> *) e c. Polynomial p e c => p e c -> e -> c
coefficient IndexedPolynomial
p Int
1) (IndexedPolynomial -> Int -> Rational
forall (p :: * -> * -> *) e c. Polynomial p e c => p e c -> e -> c
coefficient IndexedPolynomial
p Int
0)
  | IndexedPolynomial -> Int
forall (p :: * -> * -> *) e c. Polynomial p e c => p e c -> e
degree IndexedPolynomial
p Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
4 = Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Maybe [Expression]
solveQuartic (IndexedPolynomial -> Int -> Rational
forall (p :: * -> * -> *) e c. Polynomial p e c => p e c -> e -> c
coefficient IndexedPolynomial
p Int
4) (IndexedPolynomial -> Int -> Rational
forall (p :: * -> * -> *) e c. Polynomial p e c => p e c -> e -> c
coefficient IndexedPolynomial
p Int
3) (IndexedPolynomial -> Int -> Rational
forall (p :: * -> * -> *) e c. Polynomial p e c => p e c -> e -> c
coefficient IndexedPolynomial
p Int
2) (IndexedPolynomial -> Int -> Rational
forall (p :: * -> * -> *) e c. Polynomial p e c => p e c -> e -> c
coefficient IndexedPolynomial
p Int
1) (IndexedPolynomial -> Int -> Rational
forall (p :: * -> * -> *) e c. Polynomial p e c => p e c -> e -> c
coefficient IndexedPolynomial
p Int
0)
  | Bool
otherwise = Maybe [Expression]
forall a. Maybe a
Nothing

-- | Returns the real root for a polynomial of degree 1.
solveLinear :: Rational -> Rational -> Maybe [Expression]
solveLinear :: Rational -> Rational -> Maybe [Expression]
solveLinear Rational
a Rational
b = [Expression] -> Maybe [Expression]
forall a. a -> Maybe a
Just [Rational -> Expression
forall a. Fractional a => Rational -> a
fromRational ((-Rational
b) Rational -> Rational -> Rational
forall a. Fractional a => a -> a -> a
/ Rational
a)]

-- | Returns the real roots for a polynomial of degree 2.
solveQuadratic :: Rational -> Rational -> Rational -> Maybe [Expression]
solveQuadratic :: Rational -> Rational -> Rational -> Maybe [Expression]
solveQuadratic Rational
a Rational
b Rational
c
  | Rational
sq Rational -> Rational -> Bool
forall a. Eq a => a -> a -> Bool
== Rational
0 = [Expression] -> Maybe [Expression]
forall a. a -> Maybe a
Just [Rational -> Expression
forall a. Fractional a => Rational -> a
fromRational (Rational -> Expression) -> Rational -> Expression
forall a b. (a -> b) -> a -> b
$ (-Rational
b) Rational -> Rational -> Rational
forall a. Fractional a => a -> a -> a
/ (Rational
2 Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
a)]
  | Rational
sq Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
> Rational
0 =
      [Expression] -> Maybe [Expression]
forall a. a -> Maybe a
Just
        [ ((-Expression
b') Expression -> Expression -> Expression
forall a. Num a => a -> a -> a
+ Expression
sq' Expression -> Expression -> Expression
forall a. Floating a => a -> a -> a
** (Expression
1 Expression -> Expression -> Expression
forall a. Fractional a => a -> a -> a
/ Expression
2)) Expression -> Expression -> Expression
forall a. Fractional a => a -> a -> a
/ (Expression
2 Expression -> Expression -> Expression
forall a. Num a => a -> a -> a
* Expression
a'),
          ((-Expression
b') Expression -> Expression -> Expression
forall a. Num a => a -> a -> a
- Expression
sq' Expression -> Expression -> Expression
forall a. Floating a => a -> a -> a
** (Expression
1 Expression -> Expression -> Expression
forall a. Fractional a => a -> a -> a
/ Expression
2)) Expression -> Expression -> Expression
forall a. Fractional a => a -> a -> a
/ (Expression
2 Expression -> Expression -> Expression
forall a. Num a => a -> a -> a
* Expression
a')
        ]
  | Bool
otherwise = [Expression] -> Maybe [Expression]
forall a. a -> Maybe a
Just []
  where
    sq :: Rational
sq = Rational
b Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
b Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
- Rational
4 Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
a Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
c
    sq' :: Expression
sq' = Rational -> Expression
forall a. Fractional a => Rational -> a
fromRational Rational
sq
    a' :: Expression
a' = Rational -> Expression
forall a. Fractional a => Rational -> a
fromRational Rational
a
    b' :: Expression
b' = Rational -> Expression
forall a. Fractional a => Rational -> a
fromRational Rational
b

-- | Returns the real roots for a polynomial of degree 2.
solveCubic :: Rational -> Rational -> Rational -> Rational -> Maybe [Expression]
solveCubic :: Rational -> Rational -> Rational -> Rational -> Maybe [Expression]
solveCubic Rational
a Rational
b Rational
c Rational
d = (Expression -> Expression) -> [Expression] -> [Expression]
forall a b. (a -> b) -> [a] -> [b]
map Expression -> Expression
forall {a}. Fractional a => a -> a
restore ([Expression] -> [Expression])
-> Maybe [Expression] -> Maybe [Expression]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe [Expression]
depressedRoots
  where
    restore :: a -> a
restore a
x = a
x a -> a -> a
forall a. Num a => a -> a -> a
- Rational -> a
forall a. Fractional a => Rational -> a
fromRational Rational
b a -> a -> a
forall a. Fractional a => a -> a -> a
/ (a
3 a -> a -> a
forall a. Num a => a -> a -> a
* Rational -> a
forall a. Fractional a => Rational -> a
fromRational Rational
a)
    depressedRoots :: Maybe [Expression]
depressedRoots = Rational -> Rational -> Maybe [Expression]
solveDepressedCubic Rational
p Rational
q
    p :: Rational
p = (Rational
3 Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
a Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
c Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
- Rational
b Rational -> Int -> Rational
forall a b. (Num a, Integral b) => a -> b -> a
^ Int
two) Rational -> Rational -> Rational
forall a. Fractional a => a -> a -> a
/ (Rational
3 Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
a Rational -> Int -> Rational
forall a b. (Num a, Integral b) => a -> b -> a
^ Int
two)
    q :: Rational
q = (Rational
2 Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
b Rational -> Int -> Rational
forall a b. (Num a, Integral b) => a -> b -> a
^ Int
three Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
- Rational
9 Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
a Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
b Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
c Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
+ Rational
27 Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
a Rational -> Int -> Rational
forall a b. (Num a, Integral b) => a -> b -> a
^ Int
two Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
d) Rational -> Rational -> Rational
forall a. Fractional a => a -> a -> a
/ (Rational
27 Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
a Rational -> Int -> Rational
forall a b. (Num a, Integral b) => a -> b -> a
^ Int
three)
    two :: Int
two = Int
2 :: Int
    three :: Int
three = Int
3 :: Int

-- | Solve depressed cubic equations of the form \(x^3 + px + q = 0\).
-- Only returns real roots.
--
-- #### References
--
-- * [Wikipedia](https://en.wikipedia.org/wiki/Cubic_equation#Trigonometric_and_hyperbolic_solutions)
-- * [Wolfram MathWorld](https://mathworld.wolfram.com/CubicFormula.html)
solveDepressedCubic :: Rational -> Rational -> Maybe [Expression]
solveDepressedCubic :: Rational -> Rational -> Maybe [Expression]
solveDepressedCubic Rational
0 Rational
q
  | Rational
q Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
< Rational
0 = [Expression] -> Maybe [Expression]
forall a. a -> Maybe a
Just [Rational -> Expression
forall a. Fractional a => Rational -> a
fromRational (-Rational
q) Expression -> Expression -> Expression
forall a. Floating a => a -> a -> a
** (Expression
1 Expression -> Expression -> Expression
forall a. Fractional a => a -> a -> a
/ Expression
3)]
  | Bool
otherwise = [Expression] -> Maybe [Expression]
forall a. a -> Maybe a
Just [Expression -> Expression
forall a. Num a => a -> a
negate (Expression -> Expression) -> Expression -> Expression
forall a b. (a -> b) -> a -> b
$ Rational -> Expression
forall a. Fractional a => Rational -> a
fromRational Rational
q Expression -> Expression -> Expression
forall a. Floating a => a -> a -> a
** (Expression
1 Expression -> Expression -> Expression
forall a. Fractional a => a -> a -> a
/ Expression
3)]
solveDepressedCubic Rational
p Rational
q
  | Rational
s Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
< Rational
0 =
      let c :: Expression
c = Expression
2 Expression -> Expression -> Expression
forall a. Num a => a -> a -> a
* Expression -> Expression
forall a. Floating a => a -> a
sqrt (-(Expression
p' Expression -> Expression -> Expression
forall a. Fractional a => a -> a -> a
/ Expression
3))
          theta :: Expression
theta = Expression -> Expression
forall a. Floating a => a -> a
acos (Expression
3 Expression -> Expression -> Expression
forall a. Fractional a => a -> a -> a
/ Expression
2 Expression -> Expression -> Expression
forall a. Num a => a -> a -> a
* Expression
q' Expression -> Expression -> Expression
forall a. Fractional a => a -> a -> a
/ Expression
p' Expression -> Expression -> Expression
forall a. Num a => a -> a -> a
* Expression -> Expression
forall a. Floating a => a -> a
sqrt (-(Expression
3 Expression -> Expression -> Expression
forall a. Fractional a => a -> a -> a
/ Expression
p'))) Expression -> Expression -> Expression
forall a. Fractional a => a -> a -> a
/ Expression
3
       in [Expression] -> Maybe [Expression]
forall a. a -> Maybe a
Just [Expression
c Expression -> Expression -> Expression
forall a. Num a => a -> a -> a
* Expression -> Expression
forall a. Floating a => a -> a
cos Expression
theta, Expression
c Expression -> Expression -> Expression
forall a. Num a => a -> a -> a
* Expression -> Expression
forall a. Floating a => a -> a
cos (Expression
theta Expression -> Expression -> Expression
forall a. Num a => a -> a -> a
- Expression
2 Expression -> Expression -> Expression
forall a. Num a => a -> a -> a
* Expression
forall a. Floating a => a
pi Expression -> Expression -> Expression
forall a. Fractional a => a -> a -> a
/ Expression
3), Expression
c Expression -> Expression -> Expression
forall a. Num a => a -> a -> a
* Expression -> Expression
forall a. Floating a => a -> a
cos (Expression
theta Expression -> Expression -> Expression
forall a. Num a => a -> a -> a
- Expression
4 Expression -> Expression -> Expression
forall a. Num a => a -> a -> a
* Expression
forall a. Floating a => a
pi Expression -> Expression -> Expression
forall a. Fractional a => a -> a -> a
/ Expression
3)]
  | Rational
p Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
< Rational
0,
    Rational
s Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
> Rational
0 =
      [Expression] -> Maybe [Expression]
forall a. a -> Maybe a
Just [(-Expression
2) Expression -> Expression -> Expression
forall a. Num a => a -> a -> a
* Expression -> Expression
forall a. Num a => a -> a
signum Expression
q' Expression -> Expression -> Expression
forall a. Num a => a -> a -> a
* Expression -> Expression
forall a. Floating a => a -> a
sqrt (-(Expression
p' Expression -> Expression -> Expression
forall a. Fractional a => a -> a -> a
/ Expression
3)) Expression -> Expression -> Expression
forall a. Num a => a -> a -> a
* Expression -> Expression
forall a. Floating a => a -> a
cosh (Expression -> Expression
forall a. Floating a => a -> a
acosh ((-Expression
3) Expression -> Expression -> Expression
forall a. Fractional a => a -> a -> a
/ Expression
2 Expression -> Expression -> Expression
forall a. Num a => a -> a -> a
* Expression -> Expression
forall a. Num a => a -> a
abs Expression
q' Expression -> Expression -> Expression
forall a. Fractional a => a -> a -> a
/ Expression
p' Expression -> Expression -> Expression
forall a. Num a => a -> a -> a
* Expression -> Expression
forall a. Floating a => a -> a
sqrt (-(Expression
3 Expression -> Expression -> Expression
forall a. Fractional a => a -> a -> a
/ Expression
p'))) Expression -> Expression -> Expression
forall a. Fractional a => a -> a -> a
/ Expression
3)]
  | Rational
s Rational -> Rational -> Bool
forall a. Eq a => a -> a -> Bool
== Rational
0 = [Expression] -> Maybe [Expression]
forall a. a -> Maybe a
Just [Rational -> Expression
forall a. Fractional a => Rational -> a
fromRational (Rational
3 Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
q Rational -> Rational -> Rational
forall a. Fractional a => a -> a -> a
/ Rational
p), Rational -> Expression
forall a. Fractional a => Rational -> a
fromRational ((-Rational
3) Rational -> Rational -> Rational
forall a. Fractional a => a -> a -> a
/ Rational
2 Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
q Rational -> Rational -> Rational
forall a. Fractional a => a -> a -> a
/ Rational
p)]
  | Rational
p Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
> Rational
0 =
      [Expression] -> Maybe [Expression]
forall a. a -> Maybe a
Just [(-Expression
2) Expression -> Expression -> Expression
forall a. Num a => a -> a -> a
* Expression -> Expression
forall a. Floating a => a -> a
sqrt (Expression
p' Expression -> Expression -> Expression
forall a. Fractional a => a -> a -> a
/ Expression
3) Expression -> Expression -> Expression
forall a. Num a => a -> a -> a
* Expression -> Expression
forall a. Floating a => a -> a
sinh (Expression -> Expression
forall a. Floating a => a -> a
asinh (Expression
3 Expression -> Expression -> Expression
forall a. Fractional a => a -> a -> a
/ Expression
2 Expression -> Expression -> Expression
forall a. Num a => a -> a -> a
* Expression
q' Expression -> Expression -> Expression
forall a. Fractional a => a -> a -> a
/ Expression
p' Expression -> Expression -> Expression
forall a. Num a => a -> a -> a
* Expression -> Expression
forall a. Floating a => a -> a
sqrt (Expression
3 Expression -> Expression -> Expression
forall a. Fractional a => a -> a -> a
/ Expression
p')) Expression -> Expression -> Expression
forall a. Fractional a => a -> a -> a
/ Expression
3)]
  | Bool
otherwise = Maybe [Expression]
forall a. Maybe a
Nothing
  where
    s :: Rational
s = Rational
4 Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
p Rational -> Int -> Rational
forall a b. (Num a, Integral b) => a -> b -> a
^ (Int
3 :: Int) Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
+ Rational
27 Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
q Rational -> Int -> Rational
forall a b. (Num a, Integral b) => a -> b -> a
^ (Int
2 :: Int)
    p' :: Expression
p' = Rational -> Expression
forall a. Fractional a => Rational -> a
fromRational Rational
p
    q' :: Expression
q' = Rational -> Expression
forall a. Fractional a => Rational -> a
fromRational Rational
q

-- | Returns the real roots for a polynomial of degree 4.
solveQuartic :: Rational -> Rational -> Rational -> Rational -> Rational -> Maybe [Expression]
solveQuartic :: Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Maybe [Expression]
solveQuartic Rational
a Rational
b Rational
0 Rational
0 Rational
0
  | Rational
b Rational -> Rational -> Bool
forall a. Eq a => a -> a -> Bool
/= Rational
0 = [Expression] -> Maybe [Expression]
forall a. a -> Maybe a
Just [Expression
0, Rational -> Expression
forall a. Fractional a => Rational -> a
fromRational (Rational -> Expression) -> Rational -> Expression
forall a b. (a -> b) -> a -> b
$ -(Rational
b Rational -> Rational -> Rational
forall a. Fractional a => a -> a -> a
/ Rational
a)]
  | Bool
otherwise = [Expression] -> Maybe [Expression]
forall a. a -> Maybe a
Just [Expression
0]
solveQuartic Rational
a Rational
b Rational
c Rational
0 Rational
0
  | (Just [Expression]
xs) <- Rational -> Rational -> Rational -> Maybe [Expression]
solveQuadratic Rational
a Rational
b Rational
c = [Expression] -> Maybe [Expression]
forall a. a -> Maybe a
Just ([Expression] -> Maybe [Expression])
-> [Expression] -> Maybe [Expression]
forall a b. (a -> b) -> a -> b
$ [Expression] -> [Expression]
forall a. Eq a => [a] -> [a]
nub ([Expression] -> [Expression]) -> [Expression] -> [Expression]
forall a b. (a -> b) -> a -> b
$ Expression
0 Expression -> [Expression] -> [Expression]
forall a. a -> [a] -> [a]
: [Expression]
xs
  | Bool
otherwise = Maybe [Expression]
forall a. Maybe a
Nothing
solveQuartic Rational
a Rational
b Rational
c Rational
d Rational
0
  | (Just [Expression]
xs) <- Rational -> Rational -> Rational -> Rational -> Maybe [Expression]
solveCubic Rational
a Rational
b Rational
c Rational
d = [Expression] -> Maybe [Expression]
forall a. a -> Maybe a
Just ([Expression] -> Maybe [Expression])
-> [Expression] -> Maybe [Expression]
forall a b. (a -> b) -> a -> b
$ [Expression] -> [Expression]
forall a. Eq a => [a] -> [a]
nub ([Expression] -> [Expression]) -> [Expression] -> [Expression]
forall a b. (a -> b) -> a -> b
$ Expression
0 Expression -> [Expression] -> [Expression]
forall a. a -> [a] -> [a]
: [Expression]
xs
  | Bool
otherwise = Maybe [Expression]
forall a. Maybe a
Nothing
solveQuartic Rational
a Rational
0 Rational
0 Rational
0 Rational
b
  | Rational
a Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
> Rational
0, Rational
b Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
> Rational
0 = [Expression] -> Maybe [Expression]
forall a. a -> Maybe a
Just []
  | Rational
a Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
< Rational
0, Rational
b Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
< Rational
0 = [Expression] -> Maybe [Expression]
forall a. a -> Maybe a
Just []
  | Rational
b Rational -> Rational -> Bool
forall a. Eq a => a -> a -> Bool
== Rational
0 = [Expression] -> Maybe [Expression]
forall a. a -> Maybe a
Just [Expression
0]
  | Bool
otherwise = [Expression] -> Maybe [Expression]
forall a. a -> Maybe a
Just [Expression
x, -Expression
x]
  where
    x :: Expression
x = Rational -> Expression
forall a. Fractional a => Rational -> a
fromRational ((-Rational
b) Rational -> Rational -> Rational
forall a. Fractional a => a -> a -> a
/ Rational
a) Expression -> Expression -> Expression
forall a. Floating a => a -> a -> a
** (Expression
1 Expression -> Expression -> Expression
forall a. Fractional a => a -> a -> a
/ Expression
4)
solveQuartic Rational
a Rational
0 Rational
b Rational
0 Rational
c
  | Rational
sq Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
< Rational
0 = [Expression] -> Maybe [Expression]
forall a. a -> Maybe a
Just []
  | Rational
sq Rational -> Rational -> Bool
forall a. Eq a => a -> a -> Bool
== Rational
0, Rational
st Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
< Rational
0 = [Expression] -> Maybe [Expression]
forall a. a -> Maybe a
Just []
  | Rational
sq Rational -> Rational -> Bool
forall a. Eq a => a -> a -> Bool
== Rational
0 = [Expression] -> Maybe [Expression]
forall a. a -> Maybe a
Just [Expression -> Expression
forall a. Floating a => a -> a
sqrt Expression
st', -Expression -> Expression
forall a. Floating a => a -> a
sqrt Expression
st']
  | Rational
a Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
> Rational
0, Rational
sq Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
> Rational
0, Rational
b Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
> Rational
0, Rational
sq Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
> Rational
b Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
b = [Expression] -> Maybe [Expression]
forall a. a -> Maybe a
Just [Expression -> Expression
forall a. Floating a => a -> a
sqrt Expression
x1, -Expression -> Expression
forall a. Floating a => a -> a
sqrt Expression
x1]
  | Rational
a Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
< Rational
0, Rational
sq Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
> Rational
0, Rational
b Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
< Rational
0, Rational
sq Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
> Rational
b Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
b = [Expression] -> Maybe [Expression]
forall a. a -> Maybe a
Just [Expression -> Expression
forall a. Floating a => a -> a
sqrt Expression
x2, -Expression -> Expression
forall a. Floating a => a -> a
sqrt Expression
x2]
  | Rational
a Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
> Rational
0, Rational
sq Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
> Rational
0, Rational
b Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
< Rational
0, Rational
sq Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
< Rational
b Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
b = [Expression] -> Maybe [Expression]
forall a. a -> Maybe a
Just [Expression -> Expression
forall a. Floating a => a -> a
sqrt Expression
x1, -Expression -> Expression
forall a. Floating a => a -> a
sqrt Expression
x1, Expression -> Expression
forall a. Floating a => a -> a
sqrt Expression
x2, -Expression -> Expression
forall a. Floating a => a -> a
sqrt Expression
x2]
  | Rational
a Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
< Rational
0, Rational
sq Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
> Rational
0, Rational
b Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
> Rational
0, Rational
sq Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
< Rational
b Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
b = [Expression] -> Maybe [Expression]
forall a. a -> Maybe a
Just [Expression -> Expression
forall a. Floating a => a -> a
sqrt Expression
x1, -Expression -> Expression
forall a. Floating a => a -> a
sqrt Expression
x1, Expression -> Expression
forall a. Floating a => a -> a
sqrt Expression
x2, -Expression -> Expression
forall a. Floating a => a -> a
sqrt Expression
x2]
  | Bool
otherwise = Maybe [Expression]
forall a. Maybe a
Nothing
  where
    sq :: Rational
sq = Rational
b Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
b Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
- Rational
4 Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
a Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
c
    st :: Rational
st = (-Rational
b) Rational -> Rational -> Rational
forall a. Fractional a => a -> a -> a
/ (Rational
2 Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
a)
    sq' :: Expression
sq' = Rational -> Expression
forall a. Fractional a => Rational -> a
fromRational Rational
sq
    st' :: Expression
st' = Rational -> Expression
forall a. Fractional a => Rational -> a
fromRational Rational
st
    a' :: Expression
a' = Rational -> Expression
forall a. Fractional a => Rational -> a
fromRational Rational
a
    b' :: Expression
b' = Rational -> Expression
forall a. Fractional a => Rational -> a
fromRational Rational
b
    x1 :: Expression
x1 = ((-Expression
b') Expression -> Expression -> Expression
forall a. Num a => a -> a -> a
+ Expression -> Expression
forall a. Floating a => a -> a
sqrt Expression
sq') Expression -> Expression -> Expression
forall a. Fractional a => a -> a -> a
/ (Expression
2 Expression -> Expression -> Expression
forall a. Num a => a -> a -> a
* Expression
a')
    x2 :: Expression
x2 = ((-Expression
b') Expression -> Expression -> Expression
forall a. Num a => a -> a -> a
- Expression -> Expression
forall a. Floating a => a -> a
sqrt Expression
sq') Expression -> Expression -> Expression
forall a. Fractional a => a -> a -> a
/ (Expression
2 Expression -> Expression -> Expression
forall a. Num a => a -> a -> a
* Expression
a')
solveQuartic Rational
_ Rational
_ Rational
_ Rational
_ Rational
_ = Maybe [Expression]
forall a. Maybe a
Nothing