summaryrefslogtreecommitdiff
path: root/assignment-11/sets.icl
diff options
context:
space:
mode:
Diffstat (limited to 'assignment-11/sets.icl')
-rw-r--r--assignment-11/sets.icl255
1 files changed, 255 insertions, 0 deletions
diff --git a/assignment-11/sets.icl b/assignment-11/sets.icl
new file mode 100644
index 0000000..00798d8
--- /dev/null
+++ b/assignment-11/sets.icl
@@ -0,0 +1,255 @@
+module sets
+
+import StdBool
+import StdEnum
+from StdFunc import const, id, o
+import StdInt
+import StdList
+import StdOverloaded
+import StdString
+
+import Data.Error
+from Data.Functor import class Functor(fmap)
+import Data.List
+import qualified Data.Map as M
+import Data.Maybe
+import Data.Tuple
+from Text import class Text(concat), instance Text String
+
+:: Ident :== String
+
+:: Expr = Expr
+:: Upd = Upd
+:: Stmt = Stmt
+
+:: In a b = (In) infix 0 a b
+:: Do a b = (Do) infix 0 a b
+
+class isExpr a :: a -> Bool
+instance isExpr Expr where isExpr _ = True
+instance isExpr Upd where isExpr _ = True
+
+class Type t | toString, TC t
+where
+ type :: t -> String
+
+instance Type () where type _ = "()"
+instance Type Int where type _ = "Int"
+instance Type Char where type _ = "Char"
+instance Type Bool where type _ = "Bool"
+
+class DSL v | AExpr, BExpr, Compare, SetExpr, Var, Stmt v
+
+class AExpr v
+where
+ lit :: a -> v a Expr | Type a
+ (+.) infixl 6 :: (v t p) (v t q) -> v t Expr | Type, + t
+ (-.) infixl 6 :: (v t p) (v t q) -> v t Expr | Type, - t
+ (*.) infixl 7 :: (v t p) (v t q) -> v t Expr | Type, * t
+ (!~) :: (v t p) -> v t Expr | Type, ~ t
+
+class BExpr v
+where
+ (&&.) infixr 3 :: (v Bool p) (v Bool q) -> v Bool Expr
+ (||.) infixr 2 :: (v Bool p) (v Bool q) -> v Bool Expr
+
+class Compare v
+where
+ (==.) infix 4 :: (v t p) (v t q) -> v Bool Expr | Type, == t
+ (<.) infix 4 :: (v t p) (v t q) -> v Bool Expr | Type, < t
+
+class SetExpr v
+where
+ set :: [a] -> v [a] Expr | Type a
+ (:+) infix 5 :: (v t p) (v [t] q) -> v [t] Expr | Type, Eq t
+ (+:) infix 5 :: (v [t] p) (v t q) -> v [t] Expr | Type, Eq t
+ (-:) infix 5 :: (v [t] p) (v t q) -> v [t] Expr | Type, Eq t
+ (:+:) infixl 6 :: (v [t] p) (v [t] q) -> v [t] Expr | Type, Eq t
+ (:-:) infixl 6 :: (v [t] p) (v [t] q) -> v [t] Expr | Type, Eq t
+ (:*:) infixl 7 :: (v [t] p) (v [t] q) -> v [t] Expr | Type, Eq t
+
+class Var v
+where
+ var :: ((v t Upd) -> In t (v a p)) -> v a p | Type t
+ (=.) infixr 2 :: (v t Upd) (v t p) -> v t p | Type t & isExpr p
+
+class Stmt v
+where
+ If :: (v Bool p) (v t q) (v u r) -> v () Stmt
+ For :: ((v t Upd) -> Do (v [t] Expr) (v u a)) -> v () Stmt | Type t
+ (:.) infixl 1 :: (v t p) (v u q) -> v u Stmt
+
+:: Show t s = Show (ShowState -> ShowState)
+:: ShowState =
+ { output :: [String]
+ , fresh :: Int
+ }
+
+print :: (Show s t) -> String
+print (Show s) = concat (s {output=[], fresh=1}).output
+
+(<<) infixr 9 //:: (Show a p) (Show b q) -> Show c r
+(<<) (Show f) (Show g) :== Show (f o g)
+(-<) infixr 9; (-<) s f :== show s << f
+
+show :: a -> Show b c | toString a
+show x = Show \st -> {st & output=[toString x:st.output]}
+
+between :: a b (Show t u) -> Show p q | toString a & toString b
+between x y s = x -< s << show y
+
+par :: (Show a p) -> Show b q
+par s = between "(" ")" s
+
+brace :: (Show a p) -> Show b q
+brace s = between "{ " " }" s
+
+showsperse :: a [Show b p] -> Show c q | toString a
+showsperse _ [] = Show id
+showsperse _ [Show x] = Show x
+showsperse g [x:xs] = x << g -< showsperse g xs
+
+instance AExpr Show
+where
+ lit x = show x
+ (+.) x y = par (x << " +. " -< y)
+ (-.) x y = par (x << " -. " -< y)
+ (*.) x y = par (x << " *. " -< y)
+ (!~) x = "!~" -< par x
+
+instance BExpr Show
+where
+ (&&.) x y = par (x << " &&. " -< y)
+ (||.) x y = par (x << " ||. " -< y)
+
+instance Compare Show
+where
+ (==.) x y = par (x << " ==. " -< y)
+ (<.) x y = par (x << " <. " -< y)
+
+instance SetExpr Show
+where
+ set xs = between "[" "]" (showsperse "," (map show xs))
+ (:+) xs x = par (xs << " :+ " -< x)
+ (+:) x xs = par (x << " +: " -< xs)
+ (-:) xs x = par (xs << " -: " -< x)
+ (:+:) xs ys = par (xs << " :+: " -< ys)
+ (:-:) xs ys = par (xs << " :-: " -< ys)
+ (:*:) xs ys = par (xs << " :*: " -< ys)
+
+instance Var Show
+where
+ var x = Show \st -> let v = show ("v" +++ toString st.fresh) in case x v of
+ In x f -> case "var " -< v << " = " -< x -< " :.\n" -< f of
+ Show f -> f {st & fresh=st.fresh+1}
+ (=.) v x = v << " =. " -< x
+
+instance Stmt Show
+where
+ If b t e = "If " -< par b << " " -< brace t << " " -< brace e
+ For x = Show \st -> let v = show ("v" +++ toString st.fresh) in case x v of
+ Do s f -> case "For " -< v << " in " -< s << " do " -< brace f of
+ Show f -> f {st & fresh=st.fresh+1}
+ (:.) s t = s << " :.\n" -< t
+
+:: Eval t s = Eval ((RW t) EvalState -> MaybeError String (t, EvalState))
+:: RW t = R | W t
+:: EvalState =
+ { vars :: 'M'.Map Int Dynamic
+ , next :: Int
+ }
+
+eval :: (Eval t s) -> MaybeError String (t, EvalState)
+eval (Eval x) = x R {vars='M'.newMap, next=1}
+
+(<$>) infixl 4 // :: (a -> b) (v t a) -> v u b
+(<$>) f (Eval x) = Eval \_ st -> fmap (appFst f) (x R st)
+
+pure :: a -> Eval a t
+pure x = Eval \_ st -> Ok (x,st)
+
+liftA2 :: (a b -> c) (Eval a t) (Eval b u) -> Eval c v
+liftA2 f (Eval x) (Eval y) = Eval \_ st -> case x R st of
+ Ok (x0,st) -> case y R st of
+ Ok (y,st) -> Ok (f x0 y, st)
+ Error e -> Error e
+ Error e -> Error e
+
+instance AExpr Eval
+where
+ lit x = pure x
+ (+.) x y = liftA2 (+) x y
+ (-.) x y = liftA2 (-) x y
+ (*.) x y = liftA2 (*) x y
+ (!~) x = (~) <$> x
+
+instance BExpr Eval
+where
+ (&&.) x y = liftA2 (&&) x y
+ (||.) x y = liftA2 (||) x y
+
+instance Compare Eval
+where
+ (==.) x y = liftA2 (==) x y
+ (<.) x y = liftA2 (<) x y
+
+addElem :: a [a] -> [a] | Eq a; addElem x xs = if (isMember x xs) xs [x:xs]
+delElem :== removeMember
+
+instance SetExpr Eval
+where
+ set xs = pure xs
+ (:+) x xs = liftA2 addElem x xs
+ (+:) xs x = liftA2 addElem x xs
+ (-:) xs x = liftA2 delElem x xs
+ (:+:) xs ys = liftA2 union xs ys
+ (:*:) xs ys = liftA2 intersect xs ys
+ (:-:) xs ys = liftA2 difference xs ys
+
+rwvar :: Int (RW a) (EvalState) -> MaybeError String (a, EvalState) | TC a
+rwvar i R st = case 'M'.get i st.vars of
+ Just (v :: a^) -> Ok (v,st)
+ Just _ -> Error "Wrong type"
+ Nothing -> Error "Undefined variable"
+rwvar i (W x) st = Ok (x, {st & vars='M'.put i (dynamic x) st.vars})
+
+instance Var Eval
+where
+ (=.) (Eval v) (Eval e) = Eval \_ st -> case e R st of
+ Ok (e,st) -> v (W e) st
+ Error e -> Error e
+ var f = Eval \_ st -> let (x In (Eval r)) = f (Eval (rwvar st.next)) in
+ r R {st & next=st.next+1, vars='M'.put st.next (dynamic x) st.vars}
+
+instance Stmt Eval
+where
+ If (Eval b) (Eval t) (Eval e) = Eval \_ st -> case b R st of
+ Ok (True, st) -> fmap (appFst (const ())) (t R st)
+ Ok (False,st) -> fmap (appFst (const ())) (e R st)
+ Error e -> Error e
+ For f = Eval \_ st -> let (xs Do b) = f (Eval (rwvar st.next)) in
+ let (Eval e) = for st.next xs b in e R {st & next=st.next+1}
+ where
+ for :: Int (Eval [a] Expr) (Eval b t) -> Eval () Stmt | TC a
+ for i (Eval s) (Eval b) = Eval \_ st -> case s R st of
+ Ok (xs,st) -> loop xs st
+ Error e -> Error e
+ where
+ loop :: [a] EvalState -> MaybeError String ((), EvalState) | TC a
+ loop [] st = Ok ((), st)
+ loop [x:xs] st = case b R {st & vars='M'.put i (dynamic x) st.vars} of
+ Ok (_,st) -> loop xs st
+ Error e -> Error e
+ (:.) (Eval s) (Eval t) = Eval \_ st -> case s R st of
+ Ok (s,st) -> t R st
+ Error e -> Error e
+
+Start = (print stmt, '\n', eval stmt)
+where
+ stmt :: v Int Stmt | DSL v
+ stmt =
+ var \y = 1 In (
+ For \x . set [1..10] Do
+ y =. y *. x
+ ):.
+ y