twee-2.0: src/Twee/Equation.hs
{-# LANGUAGE DeriveGeneric, TypeFamilies #-}
module Twee.Equation where
import Twee.Base
import GHC.Generics
import Data.Maybe
--------------------------------------------------------------------------------
-- Equations.
--------------------------------------------------------------------------------
data Equation f =
(:=:) {
eqn_lhs :: {-# UNPACK #-} !(Term f),
eqn_rhs :: {-# UNPACK #-} !(Term f) }
deriving (Eq, Ord, Show, Generic)
type EquationOf a = Equation (ConstantOf a)
instance Symbolic (Equation f) where
type ConstantOf (Equation f) = f
instance PrettyTerm f => Pretty (Equation f) where
pPrint (x :=: y) = pPrint x <+> text "=" <+> pPrint y
instance Sized f => Sized (Equation f) where
size (x :=: y) = size x + size y
-- Order an equation roughly left-to-right.
-- However, there is no guarantee that the result is oriented.
order :: Function f => Equation f -> Equation f
order (l :=: r)
| l == r = l :=: r
| otherwise =
case compare (size l) (size r) of
LT -> r :=: l
GT -> l :=: r
EQ -> if lessEq l r then r :=: l else l :=: r
-- Apply a function to both sides of an equation.
bothSides :: (Term f -> Term f') -> Equation f -> Equation f'
bothSides f (t :=: u) = f t :=: f u
-- Is an equation of the form t = t?
trivial :: Eq f => Equation f -> Bool
trivial (t :=: u) = t == u
simplerThan :: Function f => Equation f -> Equation f -> Bool
eq1 `simplerThan` eq2 =
t1 `lessEq` t2 &&
(isNothing (unify t1 t2) || (u1 `lessEq` u2))
where
t1 :=: u1 = skolemise eq1
t2 :=: u2 = skolemise eq2
skolemise = subst (con . skolem)