Skip to content

Instantly share code, notes, and snippets.

@kana-sama
Last active November 20, 2020 19:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kana-sama/3212599df760b06676d888f8c8143dfa to your computer and use it in GitHub Desktop.
Save kana-sama/3212599df760b06676d888f8c8143dfa to your computer and use it in GitHub Desktop.
import Data.Function (on)
import Data.List (groupBy, sortOn)
import Data.Maybe (mapMaybe)
data Expr
= Var String
| Const Integer
| Add Expr Expr
| Mul Expr Expr
deriving (Show)
type NormExpr = [(Integer, [String])]
normalize :: Expr -> NormExpr
normalize (Var v) = [(1, [v])]
normalize (Const x) = [(x, [])]
normalize (Add a b) = normalize a <> normalize b
normalize (Mul a b) = [(a_k * b_k, a_vars <> b_vars) | (a_k, a_vars) <- normalize a, (b_k, b_vars) <- normalize b]
simplifyNorm :: NormExpr -> NormExpr
simplifyNorm = fmap (\terms -> (sum (fmap fst terms), snd (head terms))) . groupBy ((==) `on` snd) . sortOn snd
toExpr :: NormExpr -> Expr
toExpr = foldr1 Add . mapMaybe f
where
f (0, _) = Nothing
f (1, []) = Just $ Const 1
f (1, vars) = Just $ foldl1 Mul (Var <$> vars)
f (k, vars) = Just $ foldl Mul (Const k) (Var <$> vars)
simplify :: Expr -> Expr
simplify = toExpr . simplifyNorm . normalize
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment