@@ -1,7 +1,7 @@
11{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances,
22 PatternGuards #-}
33
4−module Core.Evaluate(normalise, normaliseC, specialise, hnf,
4+module Core.Evaluate(normalise, normaliseC, simplify, specialise, hnf,
55 Fun(..), Def(..), Context,
66 addToCtxt, addTyDecl, addDatatype, addCasedef, addOperator,
77 lookupTy, lookupP, lookupDef, lookupVal, lookupTyEnv,
@@ -16,7 +16,7 @@ import Core.CaseTree
1616type EvalState = ()
1717type Eval a = State EvalState a
1818
19−data EvalOpt = Spec | HNF
19+data EvalOpt = Spec | HNF | Simplify
2020 deriving (Show, Eq)
2121
2222-- VALUES (as HOAS) ---------------------------------------------------------
@@ -66,6 +66,14 @@ specialise ctxt statics t
6666 = evalState (do val <- eval ctxt statics [] (finalise t) [Spec]
6767 quote 0 val) ()
6868
69+-- Like normalise, but we only reduce functions that are marked as okay to
70+-- inline (and probably shouldn't reduce lets?)
71+
72+simplify :: Context -> Env -> TT Name -> TT Name
73+simplify ctxt env t
74+ = evalState (do val <- eval ctxt emptyContext (map finalEntry env) (finalise t) [Simplify]
75+ quote 0 val) ()
76+
6977hnf :: Context -> Env -> TT Name -> TT Name
7078hnf ctxt env t
7179 = evalState (do val <- eval ctxt emptyContext (map finalEntry env) (finalise t) [HNF]
@@ -92,17 +100,20 @@ unbindEnv (_:bs) (Bind n b sc) = unbindEnv bs sc
92100eval :: Context -> Ctxt [Bool] -> Env -> TT Name -> [EvalOpt] -> Eval Value
93101eval ctxt statics genv tm opts = ev True [] tm where
94102 spec = Spec `elem` opts
103+ simpl = Simplify `elem` opts
95104
96105 ev top env (P _ n ty)
97106 | Just (Let t v) <- lookup n genv = ev top env v
98107 ev top env (P Ref n ty) = case lookupDef n ctxt of
99108 Just (Function (Fun _ _ _ v)) -> return v
100109 Just (TyDecl nt ty hty) -> return $ VP nt n hty
101− Just (CaseOp _ _ [] tree) ->
102− do c <- evCase top env [] [] tree
103− case c of
104− (Nothing, _) -> liftM (VP Ref n) (ev top env ty)
105− (Just v, _) -> return v
110+ Just (CaseOp inl _ _ [] tree) ->
111+ if simpl && (not inl)
112+ then liftM (VP Ref n) (ev top env ty)
113+ else do c <- evCase top env [] [] tree
114+ case c of
115+ (Nothing, _) -> liftM (VP Ref n) (ev top env ty)
116+ (Just v, _) -> return v
106117 _ -> liftM (VP Ref n) (ev top env ty)
107118 ev top env (P nt n ty) = liftM (VP nt n) (ev top env ty)
108119 ev top env (V i) | i < length env = return $ env !! i
@@ -137,12 +148,13 @@ eval ctxt statics genv tm opts = ev True [] tm where
137148 apply False env f args
138149 | spec = return $ unload env f args
139150 apply top env (VP Ref n ty) args
140− | Just (CaseOp _ _ ns tree) <- lookupDef n ctxt
151+ | Just (CaseOp inl _ _ ns tree) <- lookupDef n ctxt
141152 = -- traceWhen (n == UN ["interp"]) (show (n, args)) $
142− do c <- evCase top env ns args tree
143− case c of
144− (Nothing, _) -> return $ unload env (VP Ref n ty) args
145− (Just v, rest) -> evApply top env rest v
153+ if simpl && (not inl) then return $ unload env (VP Ref n ty) args
154+ else do c <- evCase top env ns args tree
155+ case c of
156+ (Nothing, _) -> return $ unload env (VP Ref n ty) args
157+ (Just v, rest) -> evApply top env rest v
146158 | Just (Operator _ i op) <- lookupDef n ctxt
147159 = if (i <= length args)
148160 then case op (take i args) of
@@ -282,7 +294,7 @@ eval_hnf ctxt statics genv tm = ev [] tm where
282294 ev env (P Ref n ty) = case lookupDef n ctxt of
283295 Just (Function (Fun _ _ t _)) -> ev env t
284296 Just (TyDecl nt ty hty) -> return $ HP nt n ty
285− Just (CaseOp _ _ [] tree) ->
297+ Just (CaseOp inl _ _ [] tree) ->
286298 do c <- evCase env [] [] tree
287299 case c of
288300 (Nothing, _, _) -> return $ HP Ref n ty
@@ -312,7 +324,7 @@ eval_hnf ctxt statics genv tm = ev [] tm where
312324 app <- apply env sc' as
313325 wknH (-1) app
314326 apply env (HP Ref n ty) args
315− | Just (CaseOp _ _ ns tree) <- lookupDef n ctxt
327+ | Just (CaseOp _ _ _ ns tree) <- lookupDef n ctxt
316328 = do c <- evCase env ns args tree
317329 case c of
318330 (Nothing, _, env') -> return $ unload env' (HP Ref n ty) args
@@ -415,13 +427,14 @@ data Fun = Fun Type Value Term Value
415427data Def = Function Fun
416428 | TyDecl NameType Type Value
417429 | Operator Type Int ([Value] -> Maybe Value)
418− | CaseOp Type [(Term, Term)] [Name] SC
430+ | CaseOp Bool Type [(Term, Term)] [Name] SC -- Bool for inlineable
419431
420432instance Show Def where
421433 show (Function f) = "Function: " ++ show f
422434 show (TyDecl nt ty val) = "TyDecl: " ++ show nt ++ " " ++ show ty
423435 show (Operator ty _ _) = "Operator: " ++ show ty
424− show (CaseOp ty _ ns sc) = "Case: " ++ show ns ++ " " ++ show sc
436+ show (CaseOp _ ty ps ns sc) = "Case: " ++ show ps ++ "\n" ++
437+ show ns ++ " " ++ show sc
425438
426439-------
427440
@@ -448,10 +461,14 @@ addDatatype (Data n tag ty cons) ctxt
448461 addCons (tag+1) cons (addDef n
449462 (TyDecl (DCon tag (arity ty')) ty (veval ctxt [] ty)) ctxt)
450463
451−addCasedef :: Name -> Bool -> [(Term, Term)] -> Type -> Context -> Context
452−addCasedef n tcase ps ty ctxt
453− = case simpleCase tcase ps of
454− CaseDef args sc -> addDef n (CaseOp ty ps args sc) ctxt
464+addCasedef :: Name -> Bool -> Bool -> [(Term, Term)] -> Type -> Context -> Context
465+addCasedef n alwaysInline tcase ps ty ctxt
466+ = let ps' = simpl ps in
467+ case simpleCase tcase ps' of
468+ CaseDef args sc -> let inl = alwaysInline in
469+ addDef n (CaseOp inl ty ps args sc) ctxt
470+ where simpl [] = []
471+ simpl ((l,r) : xs) = (l, simplify ctxt [] r) : simpl xs
455472
456473addOperator :: Name -> Type -> Int -> ([Value] -> Maybe Value) -> Context -> Context
457474addOperator n ty a op ctxt
@@ -463,7 +480,7 @@ lookupTy n ctxt = do def <- lookupCtxt n ctxt
463480 (Function (Fun ty _ _ _)) -> return ty
464481 (TyDecl _ ty _) -> return ty
465482 (Operator ty _ _) -> return ty
466− (CaseOp ty _ _ _) -> return ty
483+ (CaseOp _ ty _ _ _) -> return ty
467484
468485lookupP :: Name -> Context -> Maybe Term
469486lookupP n ctxt
@@ -471,7 +488,7 @@ lookupP n ctxt
471488 case def of
472489 (Function (Fun ty _ tm _)) -> return (P Ref n ty)
473490 (TyDecl nt ty hty) -> return (P nt n ty)
474− (CaseOp ty _ _ _) -> return (P Ref n ty)
491+ (CaseOp _ ty _ _ _) -> return (P Ref n ty)
475492 (Operator ty _ _) -> return (P Ref n ty)
476493
477494lookupDef :: Name -> Context -> Maybe Def