@@ -3,7 +3,8 @@
33
44module Core.Evaluate(normalise, normaliseTrace, normaliseC, normaliseAll,
55 simplify, specialise, hnf, convEq, convEq',
6− Def(..), Accessibility(..), Totality(..), PReason(..),
6+ Def(..), CaseInfo(..),
7+ Accessibility(..), Totality(..), PReason(..),
78 Context, initContext, ctxtAlist, uconstraints, next_tvar,
89 addToCtxt, setAccess, setTotal, addCtxtDef, addTyDecl,
910 addDatatype, addCasedef, simplifyCasedef, addOperator,
@@ -24,7 +25,11 @@ data EvalState = ES { limited :: [(Name, Int)],
2425
2526type Eval a = State EvalState a
2627
27−data EvalOpt = Spec | HNF | Simplify Bool | AtREPL
28+data EvalOpt = Spec
29+ | HNF
30+ | Simplify Bool -- simplifying - if True, we're doing it to help
31+ -- totality checking so reduce dictionaries too
32+ | AtREPL
2833 deriving (Show, Eq)
2934
3035initEval = ES [] 0
@@ -95,14 +100,14 @@ specialise ctxt env limits t
95100-- | Like normalise, but we only reduce functions that are marked as okay to
96101-- inline (and probably shouldn't reduce lets?)
97102simplify :: Context -> Bool -> Env -> TT Name -> TT Name
98−simplify ctxt runtime env t
103+simplify ctxt alldicts env t
99104 = evalState (do val <- eval False ctxt [(UN "lazy", 0),
100105 (UN "assert_smaller", 0),
101106 (UN "par", 0),
102107 (UN "prim__syntactic_eq", 0),
103108 (UN "fork", 0)]
104109 (map finalEntry env) (finalise t)
105− [Simplify runtime]
110+ [Simplify alldicts]
106111 quote 0 val) initEval
107112
108113-- | Reduce a term to head normal form
@@ -168,9 +173,11 @@ eval traceon ctxt ntimes genv tm opts = ev ntimes [] True [] tm where
168173 atRepl = AtREPL `elem` opts
169174 hnf = HNF `elem` opts
170175
171− canSimplify inl inr n stk
172− = (Simplify False `elem` opts && (not inl || elem n stk))
173− || (Simplify True `elem` opts && (not inr || elem n stk))
176+ -- returns 'True' if the function should block
177+ -- normal evaluation should return false
178+ blockSimplify (CaseInfo inl dict) n stk
179+ = (Simplify False `elem` opts && (not (inl || dict) || elem n stk))
180+ || (Simplify True `elem` opts && (not inl || elem n stk))
174181
175182 ev ntimes stk top env (P _ n ty)
176183 | Just (Let t v) <- lookup n genv = ev ntimes stk top env v
@@ -185,9 +192,9 @@ eval traceon ctxt ntimes genv tm opts = ev ntimes [] True [] tm where
185192 ev ntimes (n:stk) True env tm
186193 [(TyDecl nt ty, _)] -> do vty <- ev ntimes stk True env ty
187194 return $ VP nt n vty
188− [(CaseOp inl inr _ _ _ [] tree _ _, acc)]
195+ [(CaseOp ci _ _ _ [] tree _ _, acc)]
189196 | acc == Public || simpl -> -- unoptimised version
190− if canSimplify inl inr n stk
197+ if blockSimplify ci n stk
191198 then liftM (VP Ref n) (ev ntimes stk top env ty)
192199 else do c <- evCase ntimes n (n:stk) top env [] [] tree
193200 case c of
@@ -260,9 +267,9 @@ eval traceon ctxt ntimes genv tm opts = ev ntimes [] True [] tm where
260267 if u then
261268 do let val = lookupDefAcc n atRepl ctxt
262269 case val of
263− [(CaseOp inl inr _ _ _ ns tree _ _, acc)]
270+ [(CaseOp ci _ _ _ ns tree _ _, acc)]
264271 | acc == Public -> -- unoptimised version
265− if canSimplify inl inr n stk
272+ if blockSimplify ci n stk
266273 then return $ unload env (VP Ref n ty) args
267274 else do c <- evCase ntimes n (n:stk) top env ns args tree
268275 case c of
@@ -470,7 +477,7 @@ eval_hnf ctxt statics genv tm = ev [] tm where
470477 ev env (P Ref n ty) = case lookupDef n ctxt of
471478 [Function _ t] -> ev env t
472479 [TyDecl nt ty] -> return $ HP nt n ty
473− [CaseOp inl _ _ _ _ [] tree _ _] ->
480+ [CaseOp _ _ _ _ [] tree _ _] ->
474481 do c <- evCase env [] [] tree
475482 case c of
476483 (Nothing, _, _) -> return $ HP Ref n ty
@@ -500,7 +507,7 @@ eval_hnf ctxt statics genv tm = ev [] tm where
500507 app <- apply env sc' as
501508 wknH (-1) app
502509 apply env (HP Ref n ty) args
503− | [CaseOp _ _ _ _ _ ns tree _ _] <- lookupDef n ctxt
510+ | [CaseOp _ _ _ _ ns tree _ _] <- lookupDef n ctxt
504511 = do c <- evCase env ns args tree
505512 case c of
506513 (Nothing, _, env') -> return $ unload env' (HP Ref n ty) args
@@ -638,8 +645,8 @@ convEq ctxt = ceq [] where
638645 sameDefs ps x y = case (lookupDef x ctxt, lookupDef y ctxt) of
639646 ([Function _ xdef], [Function _ ydef])
640647 -> ceq ((x,y):ps) xdef ydef
641− ([CaseOp _ _ _ _ _ _ xdef _ _],
642− [CaseOp _ _ _ _ _ _ ydef _ _])
648+ ([CaseOp _ _ _ _ _ xdef _ _],
649+ [CaseOp _ _ _ _ _ ydef _ _])
643650 -> caseeq ((x,y):ps) xdef ydef
644651 _ -> return False
645652
@@ -661,12 +668,18 @@ spec ctxt statics genv tm = error "spec undefined"
661668data Def = Function Type Term
662669 | TyDecl NameType Type
663670 | Operator Type Int ([Value] -> Maybe Value)
664− | CaseOp Bool Bool -- compile-time/run-time inlinable
671+ | CaseOp CaseInfo
665672 Type
666673 [Either Term (Term, Term)] -- original definition
667674 [([Name], Term, Term)] -- simplified definition
668675 [Name] SC -- Compile time case definition
669676 [Name] SC -- Run time cae definitions
677+
678+data CaseInfo = CaseInfo {
679+ case_inlinable :: Bool,
680+ tc_dictionary :: Bool
681+ }
682+
670683{-!
671684deriving instance Binary Def
672685!-}
@@ -675,7 +688,7 @@ instance Show Def where
675688 show (Function ty tm) = "Function: " ++ show (ty, tm)
676689 show (TyDecl nt ty) = "TyDecl: " ++ show nt ++ " " ++ show ty
677690 show (Operator ty _ _) = "Operator: " ++ show ty
678− show (CaseOp inlc inlr ty ps_in ps ns sc ns' sc')
691+ show (CaseOp (CaseInfo inlc inlr) ty ps_in ps ns sc ns' sc')
679692 = "Case: " ++ show ty ++ " " ++ show ps ++ "\n" ++
680693 show ns ++ " " ++ show sc ++ "\n" ++
681694 show ns' ++ " " ++ show sc' ++ "\n" ++
@@ -793,12 +806,14 @@ addDatatype (Data n tag ty cons) uctxt
793806 addCons (tag+1) cons (addDef n
794807 (TyDecl (DCon tag (arity ty')) ty, Public, Unchecked) ctxt)
795808
796−addCasedef :: Name -> Bool -> Bool -> Bool -> Bool -> Bool ->
809+-- FIXME: Too many arguments! Refactor all these Bools.
810+addCasedef :: Name -> CaseInfo -> Bool -> Bool -> Bool -> Bool ->
797811 [Either Term (Term, Term)] ->
798812 [([Name], Term, Term)] ->
799813 [([Name], Term, Term)] ->
800814 Type -> Context -> Context
801−addCasedef n alwaysInline tcase covering reflect asserted ps_in ps psrt ty uctxt
815+addCasedef n ci@(CaseInfo alwaysInline tcdict)
816+ tcase covering reflect asserted ps_in ps psrt ty uctxt
802817 = let ctxt = definitions uctxt
803818 access = case lookupDefAcc n False uctxt of
804819 [(_, acc)] -> acc
@@ -806,10 +821,10 @@ addCasedef n alwaysInline tcase covering reflect asserted ps_in ps psrt ty uctxt
806821 ctxt' = case (simpleCase tcase covering reflect CompileTime (FC "" 0) ps,
807822 simpleCase tcase covering reflect RunTime (FC "" 0) psrt) of
808823 (OK (CaseDef args sc _), OK (CaseDef args' sc' _)) ->
809− let inl = alwaysInline
824+ let inl = alwaysInline || tcdict
810825 inlc = (inl || small n args sc') && (not asserted)
811826 inlr = inl || small n args sc' in
812− addDef n (CaseOp inlc inlr
827+ addDef n (CaseOp (ci { case_inlinable = inlc })
813828 ty ps_in ps args sc args' sc',
814829 access, Unchecked) ctxt in
815830 uctxt { definitions = ctxt' }
@@ -818,14 +833,14 @@ simplifyCasedef :: Name -> Context -> Context
818833simplifyCasedef n uctxt
819834 = let ctxt = definitions uctxt
820835 ctxt' = case lookupCtxt n ctxt of
821− [(CaseOp inl inr ty [] ps args sc args' sc', acc, tot)] ->
836+ [(CaseOp ci ty [] ps args sc args' sc', acc, tot)] ->
822837 ctxt -- nothing to simplify (or already done...)
823− [(CaseOp inl inr ty ps_in ps args sc args' sc', acc, tot)] ->
838+ [(CaseOp ci ty ps_in ps args sc args' sc', acc, tot)] ->
824839 let ps_in' = map simpl ps_in
825840 pdef = map debind ps_in' in
826841 case simpleCase False True False CompileTime (FC "" 0) pdef of
827842 OK (CaseDef args sc _) ->
828− addDef n (CaseOp inl inr
843+ addDef n (CaseOp ci
829844 ty ps_in' ps args sc args' sc',
830845 acc, tot) ctxt
831846 _ -> ctxt in
@@ -863,7 +878,7 @@ lookupTy n ctxt
863878 (Function ty _) -> return ty
864879 (TyDecl _ ty) -> return ty
865880 (Operator ty _ _) -> return ty
866− (CaseOp _ _ ty _ _ _ _ _ _) -> return ty
881+ (CaseOp _ ty _ _ _ _ _ _) -> return ty
867882
868883isConName :: Name -> Context -> Bool
869884isConName n ctxt
@@ -879,7 +894,7 @@ isFnName n ctxt
879894 case tfst def of
880895 (Function _ _) -> return True
881896 (Operator _ _ _) -> return True
882− (CaseOp _ _ _ _ _ _ _ _ _) -> return True
897+ (CaseOp _ _ _ _ _ _ _ _) -> return True
883898 _ -> return False
884899
885900lookupP :: Name -> Context -> [Term]
@@ -888,7 +903,7 @@ lookupP n ctxt
888903 p <- case def of
889904 (Function ty tm, a, _) -> return (P Ref n ty, a)
890905 (TyDecl nt ty, a, _) -> return (P nt n ty, a)
891− (CaseOp _ _ ty _ _ _ _ _ _, a, _) -> return (P Ref n ty, a)
906+ (CaseOp _ ty _ _ _ _ _ _, a, _) -> return (P Ref n ty, a)
892907 (Operator ty _ _, a, _) -> return (P Ref n ty, a)
893908 case snd p of
894909 Hidden -> []