@@ -19,7 +19,7 @@ import Idris.Core.Unify
19import Idris.Core.DeepSeq
19import Idris.Core.DeepSeq
21import Control.DeepSeq
21import Control.DeepSeq
22−import Control.Monad.State
22+import Control.Monad.State.Strict
23import Data.Char
23import Data.Char
24import Data.List
24import Data.List
25import Debug.Trace
25import Debug.Trace
@@ -48,7 +48,7 @@ proofFail :: Elab' aux a -> Elab' aux a
48proofFail e = do s <- get
48proofFail e = do s <- get
49 case runStateT e s of
49 case runStateT e s of
50 OK (a, s') -> do put s'
50 OK (a, s') -> do put s'
51− return a
51+ return $! a
52 Error err -> lift $ Error (ProofSearchFail err)
52 Error err -> lift $ Error (ProofSearchFail err)
54explicit :: Name -> Elab' aux ()
54explicit :: Name -> Elab' aux ()
@@ -77,7 +77,7 @@ getNameFrom n = do (ES (p, a) s e) <- get
77 then MN (next+500) x
77 then MN (next+500) x
78 else MN (next+100) x
78 else MN (next+100) x
79 NS (UN x) s -> MN (next+100) x
79 NS (UN x) s -> MN (next+100) x
80− return n'
80+ return $! n'
82setNextName :: Elab' aux ()
82setNextName :: Elab' aux ()
83setNextName = do env <- get_env
83setNextName = do env <- get_env
@@ -98,7 +98,7 @@ errAt :: String -> Name -> Elab' aux a -> Elab' aux a
98errAt thing n elab = do s <- get
98errAt thing n elab = do s <- get
99 case runStateT elab s of
99 case runStateT elab s of
100 OK (a, s') -> do put s'
100 OK (a, s') -> do put s'
101− return a
101+ return $! a
102 Error (At f e) ->
102 Error (At f e) ->
103 lift $ Error (At f (Elaborating thing n e))
103 lift $ Error (At f (Elaborating thing n e))
104 Error e -> lift $ Error (Elaborating thing n e)
104 Error e -> lift $ Error (Elaborating thing n e)
@@ -107,7 +107,7 @@ erun :: FC -> Elab' aux a -> Elab' aux a
107erun f elab = do s <- get
107erun f elab = do s <- get
108 case runStateT elab s of
108 case runStateT elab s of
109 OK (a, s') -> do put s'
109 OK (a, s') -> do put s'
110− return a
110+ return $! a
111 Error (ProofSearchFail (At f e))
111 Error (ProofSearchFail (At f e))
112 -> lift $ Error (ProofSearchFail (At f e))
112 -> lift $ Error (ProofSearchFail (At f e))
113 Error (At f e) -> lift $ Error (At f e)
113 Error (At f e) -> lift $ Error (At f e)
@@ -125,7 +125,7 @@ initElaborator = newProof
125elaborate :: Context -> Name -> Type -> aux -> Elab' aux a -> TC (a, String)
125elaborate :: Context -> Name -> Type -> aux -> Elab' aux a -> TC (a, String)
126elaborate ctxt n ty d elab = do let ps = initElaborator n ctxt ty
126elaborate ctxt n ty d elab = do let ps = initElaborator n ctxt ty
127 (a, ES ps' str _) <- runElab d elab ps
127 (a, ES ps' str _) <- runElab d elab ps
128− return (a, str)
128+ return $! (a, str)
130force_term :: Elab' aux ()
130force_term :: Elab' aux ()
131force_term = do ES (ps, a) l p <- get
131force_term = do ES (ps, a) l p <- get
@@ -137,7 +137,7 @@ updateAux f = do ES (ps, a) l p <- get
138getAux :: Elab' aux aux
138getAux :: Elab' aux aux
139getAux = do ES (ps, a) _ _ <- get
139getAux = do ES (ps, a) _ _ <- get
140− return a
140+ return $! a
142unifyLog :: Bool -> Elab' aux ()
142unifyLog :: Bool -> Elab' aux ()
143unifyLog log = do ES (ps, a) l p <- get
143unifyLog log = do ES (ps, a) l p <- get
@@ -146,14 +146,14 @@ unifyLog log = do ES (ps, a) l p <- get
146processTactic' t = do ES (p, a) logs prev <- get
146processTactic' t = do ES (p, a) logs prev <- get
147 (p', log) <- lift $ processTactic t p
147 (p', log) <- lift $ processTactic t p
148 put (ES (p', a) (logs ++ log) prev)
148 put (ES (p', a) (logs ++ log) prev)
149− return ()
149+ return $! ()
151-- Some handy gadgets for pulling out bits of state
151-- Some handy gadgets for pulling out bits of state
153-- get the global context
153-- get the global context
154get_context :: Elab' aux Context
154get_context :: Elab' aux Context
155get_context = do ES p _ _ <- get
155get_context = do ES p _ _ <- get
156− return (context (fst p))
156+ return $! (context (fst p))
158-- update the context
158-- update the context
159-- (should only be used for adding temporary definitions or all sorts of
159-- (should only be used for adding temporary definitions or all sorts of
@@ -165,7 +165,7 @@ set_context ctxt = do ES (p, a) logs prev <- get
165-- get the proof term
165-- get the proof term
166get_term :: Elab' aux Term
166get_term :: Elab' aux Term
167get_term = do ES p _ _ <- get
167get_term = do ES p _ _ <- get
168− return (pterm (fst p))
168+ return $! (pterm (fst p))
170-- get the proof term
170-- get the proof term
171update_term :: (Term -> Term) -> Elab' aux ()
171update_term :: (Term -> Term) -> Elab' aux ()
@@ -180,24 +180,24 @@ get_env = do ES p _ _ <- get
181get_holes :: Elab' aux [Name]
181get_holes :: Elab' aux [Name]
182get_holes = do ES p _ _ <- get
182get_holes = do ES p _ _ <- get
183− return (holes (fst p))
183+ return $! (holes (fst p))
185get_probs :: Elab' aux Fails
185get_probs :: Elab' aux Fails
186get_probs = do ES p _ _ <- get
186get_probs = do ES p _ _ <- get
187− return (problems (fst p))
187+ return $! (problems (fst p))
189-- get the current goal type
189-- get the current goal type
190goal :: Elab' aux Type
190goal :: Elab' aux Type
191goal = do ES p _ _ <- get
191goal = do ES p _ _ <- get
192 b <- lift $ goalAtFocus (fst p)
192 b <- lift $ goalAtFocus (fst p)
193− return (binderTy b)
193+ return $! (binderTy b)
195-- Get the guess at the current hole, if there is one
195-- Get the guess at the current hole, if there is one
196get_guess :: Elab' aux Type
196get_guess :: Elab' aux Type
197get_guess = do ES p _ _ <- get
197get_guess = do ES p _ _ <- get
198 b <- lift $ goalAtFocus (fst p)
198 b <- lift $ goalAtFocus (fst p)
199 case b of
199 case b of
200− Guess t v -> return v
200+ Guess t v -> return $! v
201 _ -> fail "Not a guess"
201 _ -> fail "Not a guess"
203-- typecheck locally
203-- typecheck locally
@@ -205,22 +205,22 @@ get_type :: Raw -> Elab' aux Type
205get_type tm = do ctxt <- get_context
205get_type tm = do ctxt <- get_context
206 env <- get_env
206 env <- get_env
207 (val, ty) <- lift $ check ctxt env tm
207 (val, ty) <- lift $ check ctxt env tm
208− return (finalise ty)
208+ return $! (finalise ty)
210get_type_val :: Raw -> Elab' aux (Term, Type)
210get_type_val :: Raw -> Elab' aux (Term, Type)
211get_type_val tm = do ctxt <- get_context
211get_type_val tm = do ctxt <- get_context
212 env <- get_env
212 env <- get_env
213 (val, ty) <- lift $ check ctxt env tm
213 (val, ty) <- lift $ check ctxt env tm
214− return (finalise val, finalise ty)
214+ return $! (finalise val, finalise ty)
216-- get holes we've deferred for later definition
216-- get holes we've deferred for later definition
217get_deferred :: Elab' aux [Name]
217get_deferred :: Elab' aux [Name]
218get_deferred = do ES p _ _ <- get
218get_deferred = do ES p _ _ <- get
219− return (deferred (fst p))
219+ return $! (deferred (fst p))
221checkInjective :: (Term, Term, Term) -> Elab' aux ()
221checkInjective :: (Term, Term, Term) -> Elab' aux ()
222checkInjective (tm, l, r) = do ctxt <- get_context
222checkInjective (tm, l, r) = do ctxt <- get_context
223− if isInj ctxt tm then return ()
223+ if isInj ctxt tm then return $! ()
224 else lift $ tfail (NotInjective tm l r)
224 else lift $ tfail (NotInjective tm l r)
225 where isInj ctxt (P _ n _)
225 where isInj ctxt (P _ n _)
226 | isConName n ctxt = True
226 | isConName n ctxt = True
@@ -233,7 +233,7 @@ checkInjective (tm, l, r) = do ctxt <- get_context
233-- get instance argument names
233-- get instance argument names
234get_instances :: Elab' aux [Name]
234get_instances :: Elab' aux [Name]
235get_instances = do ES p _ _ <- get
235get_instances = do ES p _ _ <- get
236− return (instances (fst p))
236+ return $! (instances (fst p))
238-- given a desired hole name, return a unique hole name
238-- given a desired hole name, return a unique hole name
239unique_hole = unique_hole' False
239unique_hole = unique_hole' False
@@ -251,13 +251,13 @@ unique_hole' reusable n
251-- then return n
251-- then return n
252-- else getNameFrom n
252-- else getNameFrom n
253-- _ -> getNameFrom n
253-- _ -> getNameFrom n
254− return $ uniqueNameCtxt (context (fst p)) n nouse
254+ return $! uniqueNameCtxt (context (fst p)) n nouse
255 ES (p, a) s u <- get
255 ES (p, a) s u <- get
256 case n' of
256 case n' of
257 MN i _ -> when (i >= nextname p) $
257 MN i _ -> when (i >= nextname p) $
258 put (ES (p { nextname = i + 1 }, a) s u)
258 put (ES (p { nextname = i + 1 }, a) s u)
259− _ -> return ()
259+ _ -> return $! ()
260− return n'
260+ return $! n'
262 bound_in (Bind n b sc) = n : bi b ++ bound_in sc
262 bound_in (Bind n b sc) = n : bi b ++ bound_in sc
@@ -273,7 +273,7 @@ elog str = do ES p logs prev <- get
274getLog :: Elab' aux String
274getLog :: Elab' aux String
275getLog = do ES p logs _ <- get
275getLog = do ES p logs _ <- get
276− return logs
276+ return $! logs
278-- The primitives, from ProofState
278-- The primitives, from ProofState
@@ -357,9 +357,9 @@ patvar n = do env <- get_env
357 hs <- get_holes
357 hs <- get_holes
358 if (n `elem` map fst env) then do apply (Var n) []; solve
358 if (n `elem` map fst env) then do apply (Var n) []; solve
359 else do n' <- case n of
359 else do n' <- case n of
360− UN _ -> return n
360+ UN _ -> return $! n
361 MN _ _ -> unique_hole n
361 MN _ _ -> unique_hole n
362− NS _ _ -> return n
362+ NS _ _ -> return $! n
363 processTactic' (PatVar n')
363 processTactic' (PatVar n')
365patbind :: Name -> Elab' aux ()
365patbind :: Name -> Elab' aux ()
@@ -399,7 +399,7 @@ reorder_claims n = processTactic' (Reorder n)
399qed :: Elab' aux Term
399qed :: Elab' aux Term
400qed = do processTactic' QED
400qed = do processTactic' QED
401 ES p _ _ <- get
401 ES p _ _ <- get
402− return (pterm (fst p))
402+ return $! (pterm (fst p))
404undo :: Elab' aux ()
404undo :: Elab' aux ()
405undo = processTactic' Undo
405undo = processTactic' Undo
@@ -420,7 +420,7 @@ prepare_apply fn imps =
420-- case claims of
420-- case claims of
421-- [] -> return ()
421-- [] -> return ()
422-- (h : _) -> reorder_claims h
422-- (h : _) -> reorder_claims h
423− return claims
423+ return $! claims
425 mkClaims (Bind n' (Pi t_in) sc) (i : is) claims hs =
425 mkClaims (Bind n' (Pi t_in) sc) (i : is) claims hs =
426 do let t = rebind hs t_in
426 do let t = rebind hs t_in
@@ -431,7 +431,7 @@ prepare_apply fn imps =
431 claim n (forget t)
431 claim n (forget t)
432 when i (movelast n)
432 when i (movelast n)
433 mkClaims sc' is (n : claims) hs
433 mkClaims sc' is (n : claims) hs
434− mkClaims t [] claims _ = return (reverse claims)
434+ mkClaims t [] claims _ = return $! (reverse claims)
435 mkClaims _ _ _ _
435 mkClaims _ _ _ _
436 | Var n <- fn
436 | Var n <- fn
437 = do ctxt <- get_context
437 = do ctxt <- get_context
@@ -462,13 +462,10 @@ match_apply = apply' match_fill
462apply' :: (Raw -> Elab' aux ()) -> Raw -> [(Bool, Int)] -> Elab' aux [Name]
462apply' :: (Raw -> Elab' aux ()) -> Raw -> [(Bool, Int)] -> Elab' aux [Name]
463apply' fillt fn imps =
463apply' fillt fn imps =
464 do args <- prepare_apply fn (map fst imps)
464 do args <- prepare_apply fn (map fst imps)
467 -- _Don't_ solve the arguments we're specifying by hand.
465 -- _Don't_ solve the arguments we're specifying by hand.
468 -- (remove from unified list before calling end_unify)
466 -- (remove from unified list before calling end_unify)
469 -- HMMM: Actually, if we get it wrong, the typechecker will complain!
467 -- HMMM: Actually, if we get it wrong, the typechecker will complain!
470 -- so do nothing
468 -- so do nothing
472 hs <- get_holes
469 hs <- get_holes
473 ES (p, a) s prev <- get
470 ES (p, a) s prev <- get
474 let dont = head hs : dontunify p ++
471 let dont = head hs : dontunify p ++
@@ -484,12 +481,9 @@ apply' fillt fn imps =
484 put (ES (p { dontunify = dont, unified = (n, unify),
481 put (ES (p { dontunify = dont, unified = (n, unify),
485 notunified = notunify ++ notunified p }, a) s prev)
482 notunified = notunify ++ notunified p }, a) s prev)
486 fillt (raw_apply fn (map Var args))
483 fillt (raw_apply fn (map Var args))
489-- trace ("Goal " ++ show g ++ "\n" ++ show (fn, imps, unify) ++ "\n" ++ show ptm) $
484-- trace ("Goal " ++ show g ++ "\n" ++ show (fn, imps, unify) ++ "\n" ++ show ptm) $
490 end_unify
485 end_unify
492− return (map (updateUnify unify) args)
486+ return $! (map (updateUnify unify) args)
493 where updateUnify us n = case lookup n us of
487 where updateUnify us n = case lookup n us of
494 Just (P _ t _) -> t
488 Just (P _ t _) -> t
@@ -503,7 +497,7 @@ apply2 fn elabs =
503 let (n, hs) = unified p
497 let (n, hs) = unified p
504 end_unify
498 end_unify
506− where elabArgs [] [] = return ()
500+ where elabArgs [] [] = return $! ()
507 elabArgs (n:ns) (Just e:es) = do focus n; e
501 elabArgs (n:ns) (Just e:es) = do focus n; e
508 elabArgs ns es
502 elabArgs ns es
509 elabArgs (n:ns) (_:es) = elabArgs ns es
503 elabArgs (n:ns) (_:es) = elabArgs ns es
@@ -534,18 +528,18 @@ apply_elab n args =
534 let sc' = instantiate (P Bound n t) sc
528 let sc' = instantiate (P Bound n t) sc
535 claim n (forget t)
529 claim n (forget t)
536 case i of
530 case i of
537− Nothing -> return ()
531+ Nothing -> return $! ()
538 Just _ -> -- don't solve by unification as there is an explicit value
532 Just _ -> -- don't solve by unification as there is an explicit value
539 do ES (p, a) s prev <- get
533 do ES (p, a) s prev <- get
540 put (ES (p { dontunify = n : dontunify p }, a) s prev)
534 put (ES (p { dontunify = n : dontunify p }, a) s prev)
541 doClaims sc' is ((n, i) : claims)
535 doClaims sc' is ((n, i) : claims)
542− doClaims t [] claims = return (reverse claims)
536+ doClaims t [] claims = return $! (reverse claims)
543 doClaims _ _ _ = fail $ "Wrong number of arguments for " ++ show n
537 doClaims _ _ _ = fail $ "Wrong number of arguments for " ++ show n
545 elabClaims failed r []
539 elabClaims failed r []
546− | null failed = return ()
540+ | null failed = return $! ()
547 | otherwise = if r then elabClaims [] False failed
541 | otherwise = if r then elabClaims [] False failed
548− else return ()
542+ else return $! ()
549 elabClaims failed r ((n, Nothing) : xs) = elabClaims failed r xs
543 elabClaims failed r ((n, Nothing) : xs) = elabClaims failed r xs
550 elabClaims failed r (e@(n, Just (_, elaboration)) : xs)
544 elabClaims failed r (e@(n, Just (_, elaboration)) : xs)
551 | r = try (do ES p _ _ <- get
545 | r = try (do ES p _ _ <- get
@@ -563,7 +557,7 @@ checkPiGoal :: Name -> Elab' aux ()
563checkPiGoal n
557checkPiGoal n
564 = do g <- goal
558 = do g <- goal
565 case g of
559 case g of
566− Bind _ (Pi _) _ -> return ()
560+ Bind _ (Pi _) _ -> return $! ()
567 _ -> do a <- getNameFrom (MN 0 "pargTy")
561 _ -> do a <- getNameFrom (MN 0 "pargTy")
568 b <- getNameFrom (MN 0 "pretTy")
562 b <- getNameFrom (MN 0 "pretTy")
569 f <- getNameFrom (MN 0 "pf")
563 f <- getNameFrom (MN 0 "pf")
@@ -623,7 +617,7 @@ no_errors tac
623 ((x,y,env,err) : _) ->
617 ((x,y,env,err) : _) ->
624 let env' = map (\(x, b) -> (x, binderTy b)) env in
618 let env' = map (\(x, b) -> (x, binderTy b)) env in
625 lift $ tfail $ CantUnify False x y err env' 0
619 lift $ tfail $ CantUnify False x y err env' 0
626− else return ()
620+ else return $! ()
628-- Try a tactic, if it fails, try another
622-- Try a tactic, if it fails, try another
629try :: Elab' aux a -> Elab' aux a -> Elab' aux a
623try :: Elab' aux a -> Elab' aux a -> Elab' aux a
@@ -635,10 +629,10 @@ try' t1 t2 proofSearch
635 ps <- get_probs
629 ps <- get_probs
636 case prunStateT 999999 False ps t1 s of
630 case prunStateT 999999 False ps t1 s of
637 OK ((v, _), s') -> do put s'
631 OK ((v, _), s') -> do put s'
638− return v
632+ return $! v
639 Error e1 -> if recoverableErr e1 then
633 Error e1 -> if recoverableErr e1 then
640 do case runStateT t2 s of
634 do case runStateT t2 s of
641− OK (v, s') -> do put s'; return v
635+ OK (v, s') -> do put s'; return $! v
642 Error e2 -> if score e1 >= score e2
636 Error e2 -> if score e1 >= score e2
643 then lift (tfail e1)
637 then lift (tfail e1)
644 else lift (tfail e2)
638 else lift (tfail e2)
@@ -675,8 +669,8 @@ tryAll xs = tryAll' [] 999999 (cantResolve, 0) (map fst xs)
675 case prunStateT pmax True ps x s of
669 case prunStateT pmax True ps x s of
676 OK ((v, newps), s') ->
670 OK ((v, newps), s') ->
677 do let cs' = if (newps < pmax)
671 do let cs' = if (newps < pmax)
678− then [do put s'; return v]
672+ then [do put s'; return $! v]
679− else (do put s'; return v) : cs
673+ else (do put s'; return $! v) : cs
680 tryAll' cs' newps f xs
674 tryAll' cs' newps f xs
681 Error err -> do put s
675 Error err -> do put s
682 if (score err) < 100
676 if (score err) < 100