@@ -3,7 +3,7 @@
33
44module Core.Evaluate(normalise, normaliseTrace, normaliseC, normaliseAll,
55 simplify, specialise, hnf, convEq, convEq',
6− Def(..), CaseInfo(..),
6+ Def(..), CaseInfo(..), CaseDefs(..),
77 Accessibility(..), Totality(..), PReason(..),
88 Context, initContext, ctxtAlist, uconstraints, next_tvar,
99 addToCtxt, setAccess, setTotal, addCtxtDef, addTyDecl,
@@ -186,9 +186,12 @@ eval traceon ctxt ntimes genv tm opts = ev ntimes [] True [] tm where
186186 ev ntimes (n:stk) True env tm
187187 [(TyDecl nt ty, _)] -> do vty <- ev ntimes stk True env ty
188188 return $ VP nt n vty
189− [(CaseOp ci _ _ _ [] tree _ _, acc)]
190− | acc == Public -> -- unoptimised version
191− if blockSimplify ci n stk
189+ [(CaseOp ci _ _ _ cd, acc)]
190+ | acc == Public &&
191+ null (fst (cases_totcheck cd)) -> -- unoptimised version
192+ let (_, tree) = if simpl then cases_totcheck cd
193+ else cases_compiletime cd in
194+ if blockSimplify ci n stk
192195 then liftM (VP Ref n) (ev ntimes stk top env ty)
193196 else do c <- evCase ntimes n (n:stk) top env [] [] tree
194197 case c of
@@ -256,9 +259,11 @@ eval traceon ctxt ntimes genv tm opts = ev ntimes [] True [] tm where
256259 if u then
257260 do let val = lookupDefAcc n atRepl ctxt
258261 case val of
259− [(CaseOp ci _ _ _ ns tree _ _, acc)]
262+ [(CaseOp ci _ _ _ cd, acc)]
260263 | acc == Public -> -- unoptimised version
261− if blockSimplify ci n stk
264+ let (ns, tree) = if simpl then cases_totcheck cd
265+ else cases_compiletime cd in
266+ if blockSimplify ci n stk
262267 then return $ unload env (VP Ref n ty) args
263268 else do c <- evCase ntimes n (n:stk) top env ns args tree
264269 case c of
@@ -488,9 +493,11 @@ convEq ctxt = ceq [] where
488493 sameDefs ps x y = case (lookupDef x ctxt, lookupDef y ctxt) of
489494 ([Function _ xdef], [Function _ ydef])
490495 -> ceq ((x,y):ps) xdef ydef
491− ([CaseOp _ _ _ _ _ xdef _ _],
492− [CaseOp _ _ _ _ _ ydef _ _])
493− -> caseeq ((x,y):ps) xdef ydef
496+ ([CaseOp _ _ _ _ xd],
497+ [CaseOp _ _ _ _ yd])
498+ -> let (_, xdef) = cases_compiletime xd
499+ (_, ydef) = cases_compiletime yd in
500+ caseeq ((x,y):ps) xdef ydef
494501 _ -> return False
495502
496503-- SPECIALISATION -----------------------------------------------------------
@@ -514,9 +521,16 @@ data Def = Function Type Term
514521 | CaseOp CaseInfo
515522 Type
516523 [Either Term (Term, Term)] -- original definition
517− [([Name], Term, Term)] -- simplified definition
518− [Name] SC -- Compile time case definition
519− [Name] SC -- Run time cae definitions
524+ [([Name], Term, Term)] -- simplified for totality check definition
525+ CaseDefs
526+-- [Name] SC -- Compile time case definition
527+-- [Name] SC -- Run time cae definitions
528+
529+data CaseDefs = CaseDefs {
530+ cases_totcheck :: ([Name], SC),
531+ cases_compiletime :: ([Name], SC),
532+ cases_runtime :: ([Name], SC)
533+ }
520534
521535data CaseInfo = CaseInfo {
522536 case_inlinable :: Bool,
@@ -526,13 +540,21 @@ data CaseInfo = CaseInfo {
526540{-!
527541deriving instance Binary Def
528542!-}
543+{-!
544+deriving instance Binary CaseInfo
545+!-}
546+{-!
547+deriving instance Binary CaseDefs
548+!-}
529549
530550instance Show Def where
531551 show (Function ty tm) = "Function: " ++ show (ty, tm)
532552 show (TyDecl nt ty) = "TyDecl: " ++ show nt ++ " " ++ show ty
533553 show (Operator ty _ _) = "Operator: " ++ show ty
534− show (CaseOp (CaseInfo inlc inlr) ty ps_in ps ns sc ns' sc')
535− = "Case: " ++ show ty ++ " " ++ show ps ++ "\n" ++
554+ show (CaseOp (CaseInfo inlc inlr) ty ps_in ps cd)
555+ = let (ns, sc) = cases_compiletime cd
556+ (ns', sc') = cases_runtime cd in
557+ "Case: " ++ show ty ++ " " ++ show ps ++ "\n" ++
536558 show ns ++ " " ++ show sc ++ "\n" ++
537559 show ns' ++ " " ++ show sc' ++ "\n" ++
538560 if inlc then "Inlinable\n" else "Not inlinable\n"
@@ -666,9 +688,10 @@ addCasedef n ci@(CaseInfo alwaysInline tcdict)
666688 (OK (CaseDef args sc _), OK (CaseDef args' sc' _)) ->
667689 let inl = alwaysInline -- || tcdict
668690 inlc = (inl || small n args sc') && (not asserted)
669− inlr = inl || small n args sc' in
691+ inlr = inl || small n args sc'
692+ cdef = CaseDefs (args, sc) (args, sc) (args', sc') in
670693 addDef n (CaseOp (ci { case_inlinable = inlc })
671− ty ps_in ps args sc args' sc',
694+ ty ps_in ps cdef,
672695 access, Unchecked) ctxt in
673696 uctxt { definitions = ctxt' }
674697
@@ -676,15 +699,15 @@ simplifyCasedef :: Name -> Context -> Context
676699simplifyCasedef n uctxt
677700 = let ctxt = definitions uctxt
678701 ctxt' = case lookupCtxt n ctxt of
679− [(CaseOp ci ty [] ps args sc args' sc', acc, tot)] ->
702+ [(CaseOp ci ty [] ps _, acc, tot)] ->
680703 ctxt -- nothing to simplify (or already done...)
681− [(CaseOp ci ty ps_in ps args sc args' sc', acc, tot)] ->
704+ [(CaseOp ci ty ps_in ps cd, acc, tot)] ->
682705 let ps_in' = map simpl ps_in
683706 pdef = map debind ps_in' in
684707 case simpleCase False True False CompileTime (FC "" 0) pdef of
685708 OK (CaseDef args sc _) ->
686709 addDef n (CaseOp ci
687− ty ps_in' ps args sc args' sc',
710+ ty ps_in' ps (cd { cases_totcheck = (args, sc) }),
688711 acc, tot) ctxt
689712 Error err -> error (show err)
690713 _ -> ctxt in
@@ -722,7 +745,7 @@ lookupTy n ctxt
722745 (Function ty _) -> return ty
723746 (TyDecl _ ty) -> return ty
724747 (Operator ty _ _) -> return ty
725− (CaseOp _ ty _ _ _ _ _ _) -> return ty
748+ (CaseOp _ ty _ _ _) -> return ty
726749
727750isConName :: Name -> Context -> Bool
728751isConName n ctxt
@@ -738,7 +761,7 @@ isFnName n ctxt
738761 case tfst def of
739762 (Function _ _) -> return True
740763 (Operator _ _ _) -> return True
741− (CaseOp _ _ _ _ _ _ _ _) -> return True
764+ (CaseOp _ _ _ _ _) -> return True
742765 _ -> return False
743766
744767lookupP :: Name -> Context -> [Term]
@@ -747,7 +770,7 @@ lookupP n ctxt
747770 p <- case def of
748771 (Function ty tm, a, _) -> return (P Ref n ty, a)
749772 (TyDecl nt ty, a, _) -> return (P nt n ty, a)
750− (CaseOp _ ty _ _ _ _ _ _, a, _) -> return (P Ref n ty, a)
773+ (CaseOp _ ty _ _ _, a, _) -> return (P Ref n ty, a)
751774 (Operator ty _ _, a, _) -> return (P Ref n ty, a)
752775 case snd p of
753776 Hidden -> []