module Language.PTS.Specification (
Specification (..),
specificationDoc,
star_,
HasBox (..),
HasTriangle (..),
) where
import Prelude ()
import Prelude.Compat
import Data.Foldable (toList)
import Language.PTS.Pretty
class (Eq s, Show s, Enum s, PrettyPrec s) => Specification s where
typeSort :: s
typeSortSort :: s
axiom :: s -> Maybe s
rule :: s -> s -> Maybe s
specificationDoc :: Specification s => s -> PrettyM Doc
specificationDoc s =
pppText "𝓢:" <+> pppHsepPunctuated pppComma_
[ ppp0 x | x <- take 3 [ s.. ] ]
$$$
pppText "𝓐:" <+> pppHsepPunctuated pppComma_
[ ppp0 x <+> pppColon <+> ppp0 y
| x <- take 3 [ s.. ]
, y <- toList (axiom x)
]
$$$
pppText "𝓡:"
<+> pppSepPunctuated pppComma_ pppRules
<> (if more then pppText ", ..." else mempty)
where
pppRules =
[ pppParens True $ pppCatPunctuated pppComma_ $ map (ppp0) [x, y, z]
| (x, y, z) <- take 9 rules
]
rules =
[ (x,y,z)
| (y, x) <- fair [s ..] [s ..]
, z <- toList (rule x y)
]
more = not (null (drop 9 rules))
fair :: [a] -> [b] -> [(a, b)]
fair [] _ = []
fair _ [] = []
fair (x : xs) (y : ys) = (x,y) : inter3
(map (\x' -> (x',y)) xs)
(map (\y' -> (x,y')) ys)
(fair xs ys)
inter3 :: [c] -> [c] -> [c] -> [c]
inter3 [] ys zs = inter2 ys zs
inter3 xs [] zs = inter2 xs zs
inter3 xs ys [] = inter2 xs ys
inter3 (x:xs) (y:ys) (z:zs) = x : y : z : inter3 xs ys zs
inter2 :: [c] -> [c] -> [c]
inter2 [] ys = ys
inter2 xs [] = xs
inter2 (x:xs) (y:ys) = x : y : inter2 xs ys
star_ :: Specification s => s
star_ = typeSort
class Specification s => HasBox s where
box_ :: s
class HasBox s => HasTriangle s where
triangle_ :: s