-- | -- Module : Math.Diophantine.Parser -- Copyright : Joe Jevnik 2013 -- -- License : GPL-2 -- Maintainer : joejev@gmail.org -- Stability : stable -- Portability : GHC -- -- A module for parsing 'Equation's. module Math.Diophantine.Parser ( ParseError(..) -- instances: Show , readEquation -- :: String -> Either ParseError Equation , readMaybeEquation -- :: String -> Maybe Equation ) where import Math.Diophantine.Internal (Equation(..), Z(..)) import Math.Diophantine.Grammar ( EqParser(..) , ParseError(..) , parseRawEquation , Equals(..) , Expr(..) , Term(..) , VarTerm(..) ) -- | Reads an equation from a string returning an 'Equation' or 'ParseError'. readEquation :: String -> Either ParseError Equation readEquation cs = case parseRawEquation cs of Invalid pe -> Left pe Valid eq -> Right $ fromRawEq eq -- | like 'readEquation' but discards the ParseError's data and only returns -- a valid 'Equation' or 'Nothing'. readMaybeEquation :: String -> Maybe Equation readMaybeEquation cs = case readEquation cs of Left _ -> Nothing Right e -> Just e -- | Moves all the expressions to the lhs of the eq and simplifies. fromRawEq :: Equals -> Equation fromRawEq (Equals lhs rhs) = let lx = findXCoef lhs 0 ly = findYCoef lhs 0 lx2 = findX2Coef lhs 0 ly2 = findY2Coef lhs 0 lxy = findXYCoef lhs 0 lc = findConstant lhs 0 rx = findXCoef rhs 0 ry = findYCoef rhs 0 rx2 = findX2Coef rhs 0 ry2 = findY2Coef rhs 0 rxy = findXYCoef rhs 0 rc = findConstant rhs 0 in GeneralEquation (lx2 - rx2) (lxy - rxy) (ly2 - ry2) (lx - rx) (ly - ry) (lc - rc) -- -------------------------------------------------------------------------- -- -- Find the coefficients for the different terms -- TODO: Make this in template haskell ;_; findXCoef :: Expr -> Z -> Z findXCoef (Plus expr (Variable n XTerm 1)) m = findXCoef expr (n + m) findXCoef (Plus expr _) m = findXCoef expr m findXCoef (Minus expr (Variable n XTerm 1)) m = findXCoef expr (m - n) findXCoef (Minus expr _) m = findXCoef expr m findXCoef (ETerm (Variable n XTerm 1)) m = n + m findXCoef (ETerm _) m = m findX2Coef :: Expr -> Z -> Z findX2Coef (Plus expr (Variable n XTerm 2)) m = findX2Coef expr (n + m) findX2Coef (Plus expr _) m = findX2Coef expr m findX2Coef (Minus expr (Variable n XTerm 2)) m = findX2Coef expr (m - n) findX2Coef (Minus expr _) m = findX2Coef expr m findX2Coef (ETerm (Variable n XTerm 2)) m = n + m findX2Coef (ETerm _) m = m findYCoef :: Expr -> Z -> Z findYCoef (Plus expr (Variable n YTerm 1)) m = findYCoef expr (n + m) findYCoef (Plus expr _) m = findYCoef expr m findYCoef (Minus expr (Variable n YTerm 1)) m = findYCoef expr (m - n) findYCoef (Minus expr _) m = findYCoef expr m findYCoef (ETerm (Variable n YTerm 1)) m = n + m findYCoef (ETerm _) m = m findY2Coef :: Expr -> Z -> Z findY2Coef (Plus expr (Variable n YTerm 2)) m = findY2Coef expr (n + m) findY2Coef (Plus expr _) m = findY2Coef expr m findY2Coef (Minus expr (Variable n YTerm 2)) m = findY2Coef expr (m - n) findY2Coef (Minus expr _) m = findY2Coef expr m findY2Coef (ETerm (Variable n YTerm 2)) m = n + m findY2Coef (ETerm _) m = m findXYCoef :: Expr -> Z -> Z findXYCoef (Plus expr (Variable n XYTerm 1)) m = findXYCoef expr (n + m) findXYCoef (Plus expr _) m = findXYCoef expr m findXYCoef (Minus expr (Variable n XYTerm 1)) m = findXYCoef expr (m - n) findXYCoef (Minus expr _) m = findXYCoef expr m findXYCoef (ETerm (Variable n XYTerm 1)) m = n + m findXYCoef (ETerm _) m = m findConstant :: Expr -> Z -> Z findConstant (Plus expr (Constant n)) m = findConstant expr (n + m) findConstant (Plus expr _) m = findConstant expr m findConstant (Minus expr (Constant n)) m = findConstant expr (m - n) findConstant (Minus expr _) m = findConstant expr m findConstant (ETerm (Constant n)) m = n + m findConstant (ETerm _) m = m