--- /dev/null
+module LTA.Common
+ ( PrettyPrintable(..)
+ ) where
+
+import Text.PrettyPrint
+ (Doc, renderStyle, Style(..), Mode(..), double, float , integer, int)
+
+class PrettyPrintable a where
+ toDoc :: a -> Doc
+ prettyPrint :: a -> String
+ prettyPrint = renderStyle Style {mode = PageMode, lineLength=72, ribbonsPerLine=1.5 } . toDoc
+
+instance PrettyPrintable Double where
+ toDoc = double
+
+instance PrettyPrintable Float where
+ toDoc = float
+
+instance PrettyPrintable Integer where
+ toDoc = integer
+
+instance PrettyPrintable Int where
+ toDoc = int
--- /dev/null
+module LTA.Precedence
+ ( Assoc(..)
+ , PrecExpr(..)
+ , buildAtom
+ , buildFunction
+ , buildInfix
+ ) where
+
+import Control.Applicative ((<$>))
+import Text.PrettyPrint (Doc, comma, hcat, parens, punctuate, text)
+
+data Assoc
+ = AssocLeft
+ | AssocRight
+ | AssocNone
+ deriving Eq
+
+data PrecExpr
+ = PrecExpr Assoc Integer Doc
+
+precedence :: PrecExpr -> Integer
+precedence (PrecExpr _ p _) = p
+
+associativity :: PrecExpr -> Assoc
+associativity (PrecExpr a _ _) = a
+
+value :: PrecExpr -> Doc
+value (PrecExpr _ _ v) = v
+
+buildAtom :: Doc -> PrecExpr
+buildAtom = PrecExpr AssocNone 9
+
+buildFunction :: String -> [PrecExpr] -> PrecExpr
+buildFunction name params = PrecExpr AssocNone 9 call where
+ call = hcat [text name, parens flatParams]
+ flatParams = hcat . punctuate comma $ value <$> params
+
+buildInfix :: String -> Assoc -> Integer -> PrecExpr -> PrecExpr -> PrecExpr
+buildInfix name assoc prec left right = PrecExpr assoc prec val where
+ valueLeft = bracket bracketLeft $ value left
+ valueRight = bracket bracketRight $ value right
+ val = hcat [valueLeft, text " ", text name, text " ", valueRight]
+ bracketLeft =
+ prec > (precedence left) ||
+ (prec == precedence left && assoc /= associativity left)
+ bracketRight =
+ prec > (precedence right) ||
+ (prec == precedence right && assoc /= associativity right)
+
+bracket :: Bool -> Doc -> Doc
+bracket True = parens
+bracket False = id
import Data.List (foldl')
import Data.Map (Map)
import Data.Set (Set)
+import LTA.Common (PrettyPrintable(..))
+import LTA.Precedence (PrecExpr(..), buildAtom, buildFunction, buildInfix)
+import Text.PrettyPrint (text)
import qualified Data.Map as Map
import qualified Data.Set as Set
(~>) :: Expr -> Expr -> Cond
(~>) = Compare GreaterThan
+instance PrettyPrintable Expr where
+ toDoc expr = case buildPrecedence expr of
+ (PrecExpr _ _ doc) -> doc
+ where
+ buildPrecedence e = case e of
+ IntegerSymbol s -> buildAtom $ text s
+ FloatSymbol s -> buildAtom $ text s
+ Constant c -> buildAtom . text $ show c
+ Summation var low high summand -> buildFunction "sum" params where
+ params = buildPrecedence <$> [summand, IntegerSymbol var, low, high]
+ v -> error $ "Unimplemented: " ++ show v
+
instance ContainsSymbols Expr where
rename from to e = case e of
IntegerSymbol name -> if name == from
Not e -> findSymbols e
findUniqueSymbol :: (ContainsSymbols e) => String -> e -> String
-findUniqueSymbol prefix expr =
+findUniqueSymbol prefix expr =
head [n | n <- generateNames, Set.notMember n syms ] where
syms = findSymbols expr
generateNames = [prefix ++ "_" ++ show n | n <- [0::Integer ..]]
Library
Hs-Source-Dirs: .
GHC-Options: -Wall
- Build-Depends: base, containers
- Exposed-Modules: LTA.Symbolic
+ Build-Depends: base, containers, pretty
+ Exposed-Modules: LTA.Common
+ LTA.Precedence
+ LTA.Symbolic
Executable lta
Main-is: Main.hs
Hs-Source-Dirs: src
GHC-Options: -Wall
- Build-Depends: base, lta
+ Build-Depends: base, lta, pretty
module Main (main) where
import LTA.Symbolic
+import LTA.Common
+import Text.PrettyPrint (comma, hcat, parens, punctuate, text)
-data Matrix
+data Matrix
= Matrix Expr Expr Expr
deriving(Eq, Ord, Show)
+instance PrettyPrintable Matrix where
+ toDoc (Matrix rows cols expr) =
+ hcat $ [text "matrix", parens . hcat . punctuate comma $ params] where
+ params = [toDoc rows, toDoc cols, toDoc expr]
+
multiply :: Matrix -> Matrix -> Matrix
-multiply (Matrix aRows aCols aExpr) (Matrix bRows bCols bExpr) =
+multiply (Matrix aRows aCols aExpr) (Matrix bRows bCols bExpr) =
Matrix aRows bCols $ Summation sumVar 0 aCols (aExpr' * bExpr') where
sumVar = findUniqueSymbol "sum" (aExpr * bExpr)
aExpr' = rename "col" sumVar aExpr
bExpr' = rename "row" sumVar bExpr
main :: IO()
-main = putStrLn . show $ (pad size) `multiply` (dft size) where
+main = putStrLn . prettyPrint $ (pad size) `multiply` (dft size) where
size = IntegerSymbol "N"
row :: Expr
isEven n = (n `Mod` 2) ~== 0
pad :: Expr -> Matrix
-pad size =
+pad size =
Matrix (2*size) size $ Conditional (isEven size) (evenPad size) (oddPad size)
evenPad :: Expr -> Expr