@@ -1,7 +1,7 @@
1{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances,
1{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances,
2 PatternGuards #-}
2 PatternGuards #-}
4−module Core.Evaluate(normalise, normaliseC, specialise, hnf,
4+module Core.Evaluate(normalise, normaliseC, simplify, specialise, hnf,
5 Fun(..), Def(..), Context,
5 Fun(..), Def(..), Context,
6 addToCtxt, addTyDecl, addDatatype, addCasedef, addOperator,
6 addToCtxt, addTyDecl, addDatatype, addCasedef, addOperator,
7 lookupTy, lookupP, lookupDef, lookupVal, lookupTyEnv,
7 lookupTy, lookupP, lookupDef, lookupVal, lookupTyEnv,
@@ -16,7 +16,7 @@ import Core.CaseTree
16type EvalState = ()
16type EvalState = ()
17type Eval a = State EvalState a
17type Eval a = State EvalState a
19−data EvalOpt = Spec | HNF
19+data EvalOpt = Spec | HNF | Simplify
20 deriving (Show, Eq)
20 deriving (Show, Eq)
22-- VALUES (as HOAS) ---------------------------------------------------------
22-- VALUES (as HOAS) ---------------------------------------------------------
@@ -66,6 +66,14 @@ specialise ctxt statics t
66 = evalState (do val <- eval ctxt statics [] (finalise t) [Spec]
66 = evalState (do val <- eval ctxt statics [] (finalise t) [Spec]
67 quote 0 val) ()
67 quote 0 val) ()
69+-- Like normalise, but we only reduce functions that are marked as okay to
70+-- inline (and probably shouldn't reduce lets?)
72+simplify :: Context -> Env -> TT Name -> TT Name
74+ = evalState (do val <- eval ctxt emptyContext (map finalEntry env) (finalise t) [Simplify]
69hnf :: Context -> Env -> TT Name -> TT Name
77hnf :: Context -> Env -> TT Name -> TT Name
70hnf ctxt env t
78hnf ctxt env t
71 = evalState (do val <- eval ctxt emptyContext (map finalEntry env) (finalise t) [HNF]
79 = 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
92eval :: Context -> Ctxt [Bool] -> Env -> TT Name -> [EvalOpt] -> Eval Value
100eval :: Context -> Ctxt [Bool] -> Env -> TT Name -> [EvalOpt] -> Eval Value
93eval ctxt statics genv tm opts = ev True [] tm where
101eval ctxt statics genv tm opts = ev True [] tm where
94 spec = Spec `elem` opts
102 spec = Spec `elem` opts
103+ simpl = Simplify `elem` opts
96 ev top env (P _ n ty)
105 ev top env (P _ n ty)
97 | Just (Let t v) <- lookup n genv = ev top env v
106 | Just (Let t v) <- lookup n genv = ev top env v
98 ev top env (P Ref n ty) = case lookupDef n ctxt of
107 ev top env (P Ref n ty) = case lookupDef n ctxt of
99 Just (Function (Fun _ _ _ v)) -> return v
108 Just (Function (Fun _ _ _ v)) -> return v
100 Just (TyDecl nt ty hty) -> return $ VP nt n hty
109 Just (TyDecl nt ty hty) -> return $ VP nt n hty
101− Just (CaseOp _ _ [] tree) ->
110+ Just (CaseOp inl _ _ [] tree) ->
111+ if simpl && (not inl)
112+ then liftM (VP Ref n) (ev top env ty)
102− do c <- evCase top env [] [] tree
113+ else do c <- evCase top env [] [] tree
103− case c of
114+ case c of
104− (Nothing, _) -> liftM (VP Ref n) (ev top env ty)
115+ (Nothing, _) -> liftM (VP Ref n) (ev top env ty)
105− (Just v, _) -> return v
116+ (Just v, _) -> return v
106 _ -> liftM (VP Ref n) (ev top env ty)
117 _ -> liftM (VP Ref n) (ev top env ty)
107 ev top env (P nt n ty) = liftM (VP nt n) (ev top env ty)
118 ev top env (P nt n ty) = liftM (VP nt n) (ev top env ty)
108 ev top env (V i) | i < length env = return $ env !! i
119 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
137 apply False env f args
148 apply False env f args
138 | spec = return $ unload env f args
149 | spec = return $ unload env f args
139 apply top env (VP Ref n ty) args
150 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
141 = -- traceWhen (n == UN ["interp"]) (show (n, args)) $
152 = -- traceWhen (n == UN ["interp"]) (show (n, args)) $
153+ if simpl && (not inl) then return $ unload env (VP Ref n ty) args
142− do c <- evCase top env ns args tree
154+ else do c <- evCase top env ns args tree
143− case c of
155+ case c of
144− (Nothing, _) -> return $ unload env (VP Ref n ty) args
156+ (Nothing, _) -> return $ unload env (VP Ref n ty) args
145− (Just v, rest) -> evApply top env rest v
157+ (Just v, rest) -> evApply top env rest v
146 | Just (Operator _ i op) <- lookupDef n ctxt
158 | Just (Operator _ i op) <- lookupDef n ctxt
147 = if (i <= length args)
159 = if (i <= length args)
148 then case op (take i args) of
160 then case op (take i args) of
@@ -282,7 +294,7 @@ eval_hnf ctxt statics genv tm = ev [] tm where
282 ev env (P Ref n ty) = case lookupDef n ctxt of
294 ev env (P Ref n ty) = case lookupDef n ctxt of
283 Just (Function (Fun _ _ t _)) -> ev env t
295 Just (Function (Fun _ _ t _)) -> ev env t
284 Just (TyDecl nt ty hty) -> return $ HP nt n ty
296 Just (TyDecl nt ty hty) -> return $ HP nt n ty
285− Just (CaseOp _ _ [] tree) ->
297+ Just (CaseOp inl _ _ [] tree) ->
286 do c <- evCase env [] [] tree
298 do c <- evCase env [] [] tree
287 case c of
299 case c of
288 (Nothing, _, _) -> return $ HP Ref n ty
300 (Nothing, _, _) -> return $ HP Ref n ty
@@ -312,7 +324,7 @@ eval_hnf ctxt statics genv tm = ev [] tm where
312 app <- apply env sc' as
324 app <- apply env sc' as
313 wknH (-1) app
325 wknH (-1) app
314 apply env (HP Ref n ty) args
326 apply env (HP Ref n ty) args
315− | Just (CaseOp _ _ ns tree) <- lookupDef n ctxt
327+ | Just (CaseOp _ _ _ ns tree) <- lookupDef n ctxt
316 = do c <- evCase env ns args tree
328 = do c <- evCase env ns args tree
317 case c of
329 case c of
318 (Nothing, _, env') -> return $ unload env' (HP Ref n ty) args
330 (Nothing, _, env') -> return $ unload env' (HP Ref n ty) args
@@ -415,13 +427,14 @@ data Fun = Fun Type Value Term Value
415data Def = Function Fun
427data Def = Function Fun
416 | TyDecl NameType Type Value
428 | TyDecl NameType Type Value
417 | Operator Type Int ([Value] -> Maybe Value)
429 | Operator Type Int ([Value] -> Maybe Value)
418− | CaseOp Type [(Term, Term)] [Name] SC
430+ | CaseOp Bool Type [(Term, Term)] [Name] SC -- Bool for inlineable
420instance Show Def where
432instance Show Def where
421 show (Function f) = "Function: " ++ show f
433 show (Function f) = "Function: " ++ show f
422 show (TyDecl nt ty val) = "TyDecl: " ++ show nt ++ " " ++ show ty
434 show (TyDecl nt ty val) = "TyDecl: " ++ show nt ++ " " ++ show ty
423 show (Operator ty _ _) = "Operator: " ++ show ty
435 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
@@ -448,10 +461,14 @@ addDatatype (Data n tag ty cons) ctxt
448 addCons (tag+1) cons (addDef n
461 addCons (tag+1) cons (addDef n
449 (TyDecl (DCon tag (arity ty')) ty (veval ctxt [] ty)) ctxt)
462 (TyDecl (DCon tag (arity ty')) ty (veval ctxt [] ty)) ctxt)
451−addCasedef :: Name -> Bool -> [(Term, Term)] -> Type -> Context -> Context
464+addCasedef :: Name -> Bool -> Bool -> [(Term, Term)] -> Type -> Context -> Context
452−addCasedef n tcase ps ty ctxt
465+addCasedef n alwaysInline tcase ps ty ctxt
466+ = let ps' = simpl ps in
453− = case simpleCase tcase ps of
467+ case simpleCase tcase ps' of
468+ CaseDef args sc -> let inl = alwaysInline in
454− CaseDef args sc -> addDef n (CaseOp ty ps args sc) ctxt
469+ addDef n (CaseOp inl ty ps args sc) ctxt
471+ simpl ((l,r) : xs) = (l, simplify ctxt [] r) : simpl xs
456addOperator :: Name -> Type -> Int -> ([Value] -> Maybe Value) -> Context -> Context
473addOperator :: Name -> Type -> Int -> ([Value] -> Maybe Value) -> Context -> Context
457addOperator n ty a op ctxt
474addOperator n ty a op ctxt
@@ -463,7 +480,7 @@ lookupTy n ctxt = do def <- lookupCtxt n ctxt
463 (Function (Fun ty _ _ _)) -> return ty
480 (Function (Fun ty _ _ _)) -> return ty
464 (TyDecl _ ty _) -> return ty
481 (TyDecl _ ty _) -> return ty
465 (Operator ty _ _) -> return ty
482 (Operator ty _ _) -> return ty
466− (CaseOp ty _ _ _) -> return ty
483+ (CaseOp _ ty _ _ _) -> return ty
468lookupP :: Name -> Context -> Maybe Term
485lookupP :: Name -> Context -> Maybe Term
469lookupP n ctxt
486lookupP n ctxt
@@ -471,7 +488,7 @@ lookupP n ctxt
471 case def of
488 case def of
472 (Function (Fun ty _ tm _)) -> return (P Ref n ty)
489 (Function (Fun ty _ tm _)) -> return (P Ref n ty)
473 (TyDecl nt ty hty) -> return (P nt n ty)
490 (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)
475 (Operator ty _ _) -> return (P Ref n ty)
492 (Operator ty _ _) -> return (P Ref n ty)
477lookupDef :: Name -> Context -> Maybe Def
494lookupDef :: Name -> Context -> Maybe Def