1{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, DeriveFunctor,
2 TypeSynonymInstances, PatternGuards #-}
4module Idris.AbsSyntax(module Idris.AbsSyntax, module Idris.AbsSyntaxTree) where
7import Idris.Core.Evaluate
8import Idris.Core.Elaborate hiding (Tactic(..))
9import Idris.Core.Typecheck
10import Idris.AbsSyntaxTree
12import Idris.Docstrings
13import Idris.IdeSlave hiding (Opt(..))
14import IRTS.CodegenCommon
15import Util.DynamicLinker
17import System.Console.Haskeline
20import Control.Monad.State
21import Control.Monad.Error(throwError)
25import qualified Data.Text as T
27import qualified Data.Map as M
29import qualified Data.Set as S
30import Data.Word (Word)
34import Control.Monad.Error (throwError, catchError)
35import System.IO.Error(isUserError, ioeGetErrorString, tryIOError)
41getContext :: Idris Context
42getContext = do i <- getIState; return (tt_ctxt i)
44forCodegen :: Codegen -> [(Codegen, a)] -> [a]
45forCodegen tgt xs = [x | (tgt', x) <- xs, tgt == tgt']
47getObjectFiles :: Codegen -> Idris [FilePath]
48getObjectFiles tgt = do i <- getIState; return (forCodegen tgt $ idris_objs i)
50addObjectFile :: Codegen -> FilePath -> Idris ()
51addObjectFile tgt f = do i <- getIState; putIState $ i { idris_objs = nub $ (tgt, f) : idris_objs i }
53getLibs :: Codegen -> Idris [String]
54getLibs tgt = do i <- getIState; return (forCodegen tgt $ idris_libs i)
56addLib :: Codegen -> String -> Idris ()
57addLib tgt f = do i <- getIState; putIState $ i { idris_libs = nub $ (tgt, f) : idris_libs i }
59getFlags :: Codegen -> Idris [String]
60getFlags tgt = do i <- getIState; return (forCodegen tgt $ idris_cgflags i)
62addFlag :: Codegen -> String -> Idris ()
63addFlag tgt f = do i <- getIState; putIState $ i { idris_cgflags = nub $ (tgt, f) : idris_cgflags i }
65addDyLib :: [String] -> Idris (Either DynamicLib String)
66addDyLib libs = do i <- getIState
67 let ls = idris_dynamic_libs i
68 let importdirs = opt_importdirs (idris_options i)
69 case mapMaybe (findDyLib ls) libs of
70 x:_ -> return (Left x)
72 handle <- lift . lift .
73 mapM (\l -> catchIO (tryLoadLib importdirs l)
74 (\_ -> return Nothing)) $ libs
76 Nothing -> return (Right $ "Could not load dynamic alternatives \"" ++
77 concat (intersperse "," libs) ++ "\"")
78 Just x -> do putIState $ i { idris_dynamic_libs = x:ls }
80 where findDyLib :: [DynamicLib] -> String -> Maybe DynamicLib
81 findDyLib [] l = Nothing
82 findDyLib (lib:libs) l | l == lib_name lib = Just lib
83 | otherwise = findDyLib libs l
86addHdr :: Codegen -> String -> Idris ()
87addHdr tgt f = do i <- getIState; putIState $ i { idris_hdrs = nub $ (tgt, f) : idris_hdrs i }
89addImported :: FilePath -> Idris ()
90addImported f = do i <- getIState
91 putIState $ i { idris_imported = nub $ f : idris_imported i }
93addLangExt :: LanguageExt -> Idris ()
94addLangExt TypeProviders = do i <- getIState
96 idris_language_extensions = TypeProviders : idris_language_extensions i
98addLangExt ErrorReflection = do i <- getIState
100 idris_language_extensions = ErrorReflection : idris_language_extensions i
103addTrans :: (Term, Term) -> Idris ()
104addTrans t = do i <- getIState
105 putIState $ i { idris_transforms = t : idris_transforms i }
107addErrRev :: (Term, Term) -> Idris ()
108addErrRev t = do i <- getIState
109 putIState $ i { idris_errRev = t : idris_errRev i }
111totcheck :: (FC, Name) -> Idris ()
112totcheck n = do i <- getIState; putIState $ i { idris_totcheck = idris_totcheck i ++ [n] }
114defer_totcheck :: (FC, Name) -> Idris ()
117 putIState $ i { idris_defertotcheck = nub (idris_defertotcheck i ++ [n]) }
119clear_totcheck :: Idris ()
120clear_totcheck = do i <- getIState; putIState $ i { idris_totcheck = [] }
122setFlags :: Name -> [FnOpt] -> Idris ()
123setFlags n fs = do i <- getIState; putIState $ i { idris_flags = addDef n fs (idris_flags i) }
125setAccessibility :: Name -> Accessibility -> Idris ()
128 let ctxt = setAccess n a (tt_ctxt i)
129 putIState $ i { tt_ctxt = ctxt }
131setTotality :: Name -> Totality -> Idris ()
134 let ctxt = setTotal n a (tt_ctxt i)
135 putIState $ i { tt_ctxt = ctxt }
137getTotality :: Name -> Idris Totality
140 case lookupTotal n (tt_ctxt i) of
142 _ -> return (Total [])
144-- Get coercions which might return the required type
145getCoercionsTo :: IState -> Type -> [Name]
147 let cs = idris_coercions i
148 (fn,_) = unApply (getRetTy ty) in
150 where findCoercions t [] = []
151 findCoercions t (n : ns) =
152 let ps = case lookupTy n (tt_ctxt i) of
153 [ty'] -> case unApply (getRetTy ty') of
155 if t == t' then [n] else []
157 ps ++ findCoercions t ns
159addToCG :: Name -> CGInfo -> Idris ()
162 putIState $ i { idris_callgraph = addDef n cg (idris_callgraph i) }
164addTyInferred :: Name -> Idris ()
167 putIState $ i { idris_tyinfodata =
168 addDef n TIPartial (idris_tyinfodata i) }
170addTyInfConstraints :: FC -> [(Term, Term)] -> Idris ()
171addTyInfConstraints fc ts = do logLvl 2 $ "TI missing: " ++ show ts
172 mapM_ addConstraint ts
174 where addConstraint (x, y) = findMVApps x y
177 = do let (fx, argsx) = unApply x
178 let (fy, argsy) = unApply y
183 else mapM_ addConstraint (zip argsx argsy)
185 tryAddMV (P _ mv _) y =
187 case lookup mv (idris_metavars ist) of
188 Just _ -> addConstraintRule mv y
190 tryAddMV _ _ = return ()
192 addConstraintRule :: Name -> Term -> Idris ()
193 addConstraintRule n t
195 logLvl 1 $ "TI constraint: " ++ show (n, t)
196 case lookupCtxt n (idris_tyinfodata ist) of
198 do mapM_ (checkConsistent t) ts
199 let ti' = addDef n (TISolution (t : ts))
200 (idris_tyinfodata ist)
201 put $ ist { idris_tyinfodata = ti' }
203 do let ti' = addDef n (TISolution [t])
204 (idris_tyinfodata ist)
205 put $ ist { idris_tyinfodata = ti' }
207 -- Check a solution is consistent with previous solutions
208 -- Meaning: If heads are both data types, they had better be the
210 checkConsistent :: Term -> Term -> Idris ()
211 checkConsistent x y =
212 do let (fx, _) = unApply x
213 let (fy, _) = unApply y
215 (P (TCon _ _) n _, P (TCon _ _) n' _) -> errWhen (n/=n)
216 (P (TCon _ _) n _, Constant _) -> errWhen True
217 (Constant _, P (TCon _ _) n' _) -> errWhen True
218 (P (DCon _ _) n _, P (DCon _ _) n' _) -> errWhen (n/=n)
223 (CantUnify False x y (Msg "") [] 0))
224 errWhen False = return ()
226isTyInferred :: Name -> Idris Bool
229 case lookupCtxt n (idris_tyinfodata i) of
230 [TIPartial] -> return True
233-- | Adds error handlers for a particular function and argument. If names are
234-- ambiguous, all matching handlers are updated.
235addFunctionErrorHandlers :: Name -> Name -> [Name] -> Idris ()
236addFunctionErrorHandlers f arg hs =
238 let oldHandlers = idris_function_errorhandlers i
239 let newHandlers = flip (addDef f) oldHandlers $
240 case lookupCtxtExact f oldHandlers of
241 Nothing -> M.singleton arg (S.fromList hs)
242 Just (oldHandlers) -> M.insertWith S.union arg (S.fromList hs) oldHandlers
243 -- will always be one of those two, thus no extra case
244 putIState $ i { idris_function_errorhandlers = newHandlers }
246getFunctionErrorHandlers :: Name -> Name -> Idris [Name]
247getFunctionErrorHandlers f arg = do i <- getIState
248 return . maybe [] S.toList $
249 undefined --lookup arg =<< lookupCtxtExact f (idris_function_errorhandlers i)
252-- Trace all the names in a call graph starting at the given name
253getAllNames :: Name -> Idris [Name]
254getAllNames n = allNames [] n
256allNames :: [Name] -> Name -> Idris [Name]
257allNames ns n | n `elem` ns = return []
258allNames ns n = do i <- getIState
259 case lookupCtxtExact n (idris_callgraph i) of
260 Just ns' -> do more <- mapM (allNames (n:ns)) (map fst (calls ns'))
261 return (nub (n : concat more))
264addCoercion :: Name -> Idris ()
265addCoercion n = do i <- getIState
266 putIState $ i { idris_coercions = nub $ n : idris_coercions i }
268addDocStr :: Name -> Docstring -> [(Name, Docstring)] -> Idris ()
271 putIState $ i { idris_docstrings = addDef n (doc, args) (idris_docstrings i) }
273addNameHint :: Name -> Name -> Idris ()
276 ty' <- case lookupCtxtName ty (idris_implicits i) of
277 [(tyn, _)] -> return tyn
278 [] -> throwError (NoSuchVariable ty)
279 tyns -> throwError (CantResolveAlts (map fst tyns))
280 let ns' = case lookupCtxt ty' (idris_namehints i) of
283 putIState $ i { idris_namehints = addDef ty' ns' (idris_namehints i) }
285getNameHints :: IState -> Name -> [Name]
286getNameHints i (UN arr) | arr == txt "->" = [sUN "f",sUN "g"]
288 case lookupCtxt n (idris_namehints i) of
292addToCalledG :: Name -> [Name] -> Idris ()
293addToCalledG n ns = return () -- TODO
295-- Add a class instance function. Dodgy hack: Put integer instances first in the
296-- list so they are resolved by default.
297-- Dodgy hack 2: put constraint chasers (@@) last
299addInstance :: Bool -> Name -> Name -> Idris ()
301 = do ist <- getIState
302 case lookupCtxt n (idris_classes ist) of
303 [CI a b c d e ins] ->
304 do let cs = addDef n (CI a b c d e (addI i ins)) (idris_classes ist)
305 putIState $ ist { idris_classes = cs }
306 _ -> do let cs = addDef n (CI (sMN 0 "none") [] [] [] [] [i]) (idris_classes ist)
307 putIState $ ist { idris_classes = cs }
308 where addI i ins | int = i : ins
309 | chaser n = ins ++ [i]
310 | otherwise = insI i ins
312 insI i (n : ns) | chaser n = i : n : ns
313 | otherwise = n : insI i ns
316 | ('@':'@':_) <- str nm = True
317 chaser (NS n _) = chaser n
320addClass :: Name -> ClassInfo -> Idris ()
322 = do ist <- getIState
323 let i' = case lookupCtxt n (idris_classes ist) of
324 [c] -> c { class_instances = class_instances i }
326 putIState $ ist { idris_classes = addDef n i' (idris_classes ist) }
328addIBC :: IBCWrite -> Idris ()
331 when (notDef (ibc_write i)) $
332 putIState $ i { ibc_write = ibc : ibc_write i }
333 where notDef [] = True
334 notDef (IBCDef n': is) | n == n' = False
335 notDef (_ : is) = notDef is
336addIBC ibc = do i <- getIState; putIState $ i { ibc_write = ibc : ibc_write i }
339clearIBC = do i <- getIState; putIState $ i { ibc_write = [] }
341resetNameIdx :: Idris ()
342resetNameIdx = do i <- getIState
343 put (i { idris_nameIdx = (0, emptyContext) })
345-- Used to preserve sharing of names
346addNameIdx :: Name -> Idris (Int, Name)
347addNameIdx n = do i <- getIState
348 let (i', x) = addNameIdx' i n
351addNameIdx' :: IState -> Name -> (IState, (Int, Name))
353 = let idxs = snd (idris_nameIdx i) in
354 case lookupCtxt n idxs of
356 _ -> let i' = fst (idris_nameIdx i) + 1 in
357 (i { idris_nameIdx = (i', addDef n (i', n) idxs) }, (i', n))
359getHdrs :: Codegen -> Idris [String]
360getHdrs tgt = do i <- getIState; return (forCodegen tgt $ idris_hdrs i)
362getImported :: Idris [FilePath]
363getImported = do i <- getIState; return (idris_imported i)
365setErrSpan :: FC -> Idris ()
366setErrSpan x = do i <- getIState;
368 Nothing -> putIState $ i { errSpan = Just x }
372clearErr = do i <- getIState
373 putIState $ i { errSpan = Nothing }
375getSO :: Idris (Maybe String)
376getSO = do i <- getIState
377 return (compiled_so i)
379setSO :: Maybe String -> Idris ()
380setSO s = do i <- getIState
381 putIState $ (i { compiled_so = s })
383getIState :: Idris IState
386putIState :: IState -> Idris ()
389withContext :: (IState -> Ctxt a) -> Name -> b -> (a -> Idris b) -> Idris b
390withContext ctx name dflt action = do
392 case lookupCtxt name (ctx ist) of
396withContext_ :: (IState -> Ctxt a) -> Name -> (a -> Idris ()) -> Idris ()
397withContext_ ctx name action = withContext ctx name () action
399-- | A version of liftIO that puts errors into the exception type of the Idris monad
400runIO :: IO a -> Idris a
401runIO x = liftIO (tryIOError x) >>= either (throwError . Msg . show) return
402-- TODO: create specific Idris exceptions for specific IO errors such as "openFile: does not exist"
405getName = do i <- getIState;
406 let idx = idris_name i;
407 putIState $ (i { idris_name = idx + 1 })
410-- InternalApp keeps track of the real function application for making case splits from, not the application the
411-- programmer wrote, which doesn't have the whole context in any case other than top level definitions
412addInternalApp :: FilePath -> Int -> PTerm -> Idris ()
415 putIState (i { idris_lineapps = ((fp, l), t) : idris_lineapps i })
417getInternalApp :: FilePath -> Int -> Idris PTerm
418getInternalApp fp l = do i <- getIState
419 case lookup (fp, l) (idris_lineapps i) of
421 Nothing -> return Placeholder
422 -- TODO: What if it's not there?
424-- Pattern definitions are only used for coverage checking, so erase them
426clearOrigPats :: Idris ()
427clearOrigPats = do i <- get
428 let ps = idris_patdefs i
429 let ps' = mapCtxt (\ (_,miss) -> ([], miss)) ps
430 put (i { idris_patdefs = ps' })
432-- Erase types from Ps in the context (basically ending up with what's in
433-- the .ibc, which is all we need after all the analysis is done)
434clearPTypes :: Idris ()
435clearPTypes = do i <- get
437 put (i { tt_ctxt = mapDefCtxt pErase ctxt })
438 where pErase (CaseOp c t tys orig tot cds)
439 = CaseOp c t tys orig [] (pErase' cds)
441 pErase' (CaseDefs _ (cs, c) _ rs)
442 = let c' = (cs, fmap pEraseType c) in
445checkUndefined :: FC -> Name -> Idris ()
449 (_:_) -> throwError . Msg $ show fc ++ ":" ++
450 show n ++ " already defined"
453isUndefined :: FC -> Name -> Idris Bool
457 (_:_) -> return False
460setContext :: Context -> Idris ()
461setContext ctxt = do i <- getIState; putIState $ (i { tt_ctxt = ctxt } )
463updateContext :: (Context -> Context) -> Idris ()
464updateContext f = do i <- getIState; putIState $ (i { tt_ctxt = f (tt_ctxt i) } )
466addConstraints :: FC -> (Int, [UConstraint]) -> Idris ()
467addConstraints fc (v, cs)
470 let ctxt' = ctxt { uconstraints = cs ++ uconstraints ctxt,
472 let ics = zip cs (repeat fc) ++ idris_constraints i
473 putIState $ i { tt_ctxt = ctxt', idris_constraints = ics }
475addDeferred = addDeferred' Ref
476addDeferredTyCon = addDeferred' (TCon 0 0)
478addDeferred' :: NameType -> [(Name, (Int, Maybe Name, Type, Bool))] -> Idris ()
480 = do mapM_ (\(n, (i, _, t, _)) -> updateContext (addTyDecl n nt (tidyNames [] t))) ns
481 mapM_ (\(n, _) -> when (not (n `elem` primDefs)) $ addIBC (IBCMetavar n)) ns
483 putIState $ i { idris_metavars = map (\(n, (i, top, _, isTopLevel)) -> (n, (top, i, isTopLevel))) ns ++
486 -- 'tidyNames' is to generate user accessible names in case they are
487 -- needed in tactic scripts
488 tidyNames used (Bind (MN i x) b sc)
489 = let n' = uniqueName (UN x) used in
490 Bind n' b $ tidyNames (n':used) sc
491 tidyNames used (Bind n b sc)
492 = let n' = uniqueName n used in
493 Bind n' b $ tidyNames (n':used) sc
496solveDeferred :: Name -> Idris ()
497solveDeferred n = do i <- getIState
498 putIState $ i { idris_metavars =
499 filter (\(n', _) -> n/=n')
502 filter (notMV n) (ibc_write i)
504 where notMV n (IBCMetavar n') = not (n == n')
507getUndefined :: Idris [Name]
508getUndefined = do i <- getIState
509 return (map fst (idris_metavars i) \\ primDefs)
511isMetavarName :: Name -> IState -> Bool
513 = case lookupNames n (tt_ctxt ist) of
514 (t:_) -> isJust $ lookup t (idris_metavars ist)
517getWidth :: Idris ConsoleWidth
518getWidth = fmap idris_consolewidth getIState
520setWidth :: ConsoleWidth -> Idris ()
521setWidth w = do ist <- getIState
522 put ist { idris_consolewidth = w }
524renderWidth :: Idris Int
525renderWidth = do iw <- getWidth
527 InfinitelyWide -> return 100000000
528 ColsWide n -> return (max n 1)
529 AutomaticWidth -> runIO getScreenWidth
533type1Doc :: Doc OutputAnnotation
534type1Doc = (annotate (AnnType "Type" "The type of types, one level up") $ text "Type 1")
537isetPrompt :: String -> Idris ()
538isetPrompt p = do i <- getIState
539 case idris_outputmode i of
540 IdeSlave n -> runIO . putStrLn $ convSExp "set-prompt" p n
542-- | Tell clients how much was parsed and loaded
543isetLoadedRegion :: Idris ()
544isetLoadedRegion = do i <- getIState
545 let span = idris_parsedSpan i
548 case idris_outputmode i of
551 convSExp "set-loaded-region" fc n
554setLogLevel :: Int -> Idris ()
555setLogLevel l = do i <- getIState
556 let opts = idris_options i
557 let opt' = opts { opt_logLevel = l }
558 putIState $ i { idris_options = opt' }
560setCmdLine :: [Opt] -> Idris ()
561setCmdLine opts = do i <- getIState
562 let iopts = idris_options i
563 putIState $ i { idris_options = iopts { opt_cmdline = opts } }
565getCmdLine :: Idris [Opt]
566getCmdLine = do i <- getIState
567 return (opt_cmdline (idris_options i))
569getDumpDefun :: Idris (Maybe FilePath)
570getDumpDefun = do i <- getIState
571 return $ findC (opt_cmdline (idris_options i))
572 where findC [] = Nothing
573 findC (DumpDefun x : _) = Just x
574 findC (_ : xs) = findC xs
576getDumpCases :: Idris (Maybe FilePath)
577getDumpCases = do i <- getIState
578 return $ findC (opt_cmdline (idris_options i))
579 where findC [] = Nothing
580 findC (DumpCases x : _) = Just x
581 findC (_ : xs) = findC xs
584logLevel = do i <- getIState
585 return (opt_logLevel (idris_options i))
587setErrContext :: Bool -> Idris ()
588setErrContext t = do i <- getIState
589 let opts = idris_options i
590 let opt' = opts { opt_errContext = t }
591 putIState $ i { idris_options = opt' }
593errContext :: Idris Bool
594errContext = do i <- getIState
595 return (opt_errContext (idris_options i))
598useREPL = do i <- getIState
599 return (opt_repl (idris_options i))
601setREPL :: Bool -> Idris ()
602setREPL t = do i <- getIState
603 let opts = idris_options i
604 let opt' = opts { opt_repl = t }
605 putIState $ i { idris_options = opt' }
607showOrigErr :: Idris Bool
608showOrigErr = do i <- getIState
609 return (opt_origerr (idris_options i))
611setShowOrigErr :: Bool -> Idris ()
612setShowOrigErr b = do i <- getIState
613 let opts = idris_options i
614 let opt' = opts { opt_origerr = b }
615 putIState $ i { idris_options = opt' }
617setAutoSolve :: Bool -> Idris ()
618setAutoSolve b = do i <- getIState
619 let opts = idris_options i
620 let opt' = opts { opt_autoSolve = b }
621 putIState $ i { idris_options = opt' }
623setNoBanner :: Bool -> Idris ()
624setNoBanner n = do i <- getIState
625 let opts = idris_options i
626 let opt' = opts { opt_nobanner = n }
627 putIState $ i { idris_options = opt' }
629getNoBanner :: Idris Bool
630getNoBanner = do i <- getIState
631 let opts = idris_options i
632 return (opt_nobanner opts)
634setQuiet :: Bool -> Idris ()
635setQuiet q = do i <- getIState
636 let opts = idris_options i
637 let opt' = opts { opt_quiet = q }
638 putIState $ i { idris_options = opt' }
640getQuiet :: Idris Bool
641getQuiet = do i <- getIState
642 let opts = idris_options i
643 return (opt_quiet opts)
645setCodegen :: Codegen -> Idris ()
646setCodegen t = do i <- getIState
647 let opts = idris_options i
648 let opt' = opts { opt_codegen = t }
649 putIState $ i { idris_options = opt' }
651codegen :: Idris Codegen
652codegen = do i <- getIState
653 return (opt_codegen (idris_options i))
655setOutputTy :: OutputType -> Idris ()
656setOutputTy t = do i <- getIState
657 let opts = idris_options i
658 let opt' = opts { opt_outputTy = t }
659 putIState $ i { idris_options = opt' }
661outputTy :: Idris OutputType
662outputTy = do i <- getIState
663 return $ opt_outputTy $ idris_options i
665setIdeSlave :: Bool -> Idris ()
666setIdeSlave True = do i <- getIState
667 putIState $ i { idris_outputmode = (IdeSlave 0), idris_colourRepl = False }
668setIdeSlave False = return ()
670setTargetTriple :: String -> Idris ()
671setTargetTriple t = do i <- getIState
672 let opts = idris_options i
673 opt' = opts { opt_triple = t }
674 putIState $ i { idris_options = opt' }
676targetTriple :: Idris String
677targetTriple = do i <- getIState
678 return (opt_triple (idris_options i))
680setTargetCPU :: String -> Idris ()
681setTargetCPU t = do i <- getIState
682 let opts = idris_options i
683 opt' = opts { opt_cpu = t }
684 putIState $ i { idris_options = opt' }
686targetCPU :: Idris String
687targetCPU = do i <- getIState
688 return (opt_cpu (idris_options i))
690setOptLevel :: Word -> Idris ()
691setOptLevel t = do i <- getIState
692 let opts = idris_options i
693 opt' = opts { opt_optLevel = t }
694 putIState $ i { idris_options = opt' }
696optLevel :: Idris Word
697optLevel = do i <- getIState
698 return (opt_optLevel (idris_options i))
701verbose = do i <- getIState
702 return (opt_verbose (idris_options i))
704setVerbose :: Bool -> Idris ()
705setVerbose t = do i <- getIState
706 let opts = idris_options i
707 let opt' = opts { opt_verbose = t }
708 putIState $ i { idris_options = opt' }
710typeInType :: Idris Bool
711typeInType = do i <- getIState
712 return (opt_typeintype (idris_options i))
714setTypeInType :: Bool -> Idris ()
715setTypeInType t = do i <- getIState
716 let opts = idris_options i
717 let opt' = opts { opt_typeintype = t }
718 putIState $ i { idris_options = opt' }
720coverage :: Idris Bool
721coverage = do i <- getIState
722 return (opt_coverage (idris_options i))
724setCoverage :: Bool -> Idris ()
725setCoverage t = do i <- getIState
726 let opts = idris_options i
727 let opt' = opts { opt_coverage = t }
728 putIState $ i { idris_options = opt' }
730setIBCSubDir :: FilePath -> Idris ()
731setIBCSubDir fp = do i <- getIState
732 let opts = idris_options i
733 let opt' = opts { opt_ibcsubdir = fp }
734 putIState $ i { idris_options = opt' }
736valIBCSubDir :: IState -> Idris FilePath
737valIBCSubDir i = return (opt_ibcsubdir (idris_options i))
739addImportDir :: FilePath -> Idris ()
740addImportDir fp = do i <- getIState
741 let opts = idris_options i
742 let opt' = opts { opt_importdirs = fp : opt_importdirs opts }
743 putIState $ i { idris_options = opt' }
745setImportDirs :: [FilePath] -> Idris ()
746setImportDirs fps = do i <- getIState
747 let opts = idris_options i
748 let opt' = opts { opt_importdirs = fps }
749 putIState $ i { idris_options = opt' }
751allImportDirs :: Idris [FilePath]
752allImportDirs = do i <- getIState
753 let optdirs = opt_importdirs (idris_options i)
754 return ("." : reverse optdirs)
756colourise :: Idris Bool
757colourise = do i <- getIState
758 return $ idris_colourRepl i
760setColourise :: Bool -> Idris ()
761setColourise b = do i <- getIState
762 putIState $ i { idris_colourRepl = b }
764setOutH :: Handle -> Idris ()
765setOutH h = do i <- getIState
766 putIState $ i { idris_outh = h }
769impShow = do i <- getIState
770 return (opt_showimp (idris_options i))
772setImpShow :: Bool -> Idris ()
773setImpShow t = do i <- getIState
774 let opts = idris_options i
775 let opt' = opts { opt_showimp = t }
776 putIState $ i { idris_options = opt' }
778setColour :: ColourType -> IdrisColour -> Idris ()
779setColour ct c = do i <- getIState
780 let newTheme = setColour' ct c (idris_colourTheme i)
781 putIState $ i { idris_colourTheme = newTheme }
782 where setColour' KeywordColour c t = t { keywordColour = c }
783 setColour' BoundVarColour c t = t { boundVarColour = c }
784 setColour' ImplicitColour c t = t { implicitColour = c }
785 setColour' FunctionColour c t = t { functionColour = c }
786 setColour' TypeColour c t = t { typeColour = c }
787 setColour' DataColour c t = t { dataColour = c }
788 setColour' PromptColour c t = t { promptColour = c }
789 setColour' PostulateColour c t = t { postulateColour = c }
791logLvl :: Int -> String -> Idris ()
792logLvl l str = do i <- getIState
793 let lvl = opt_logLevel (idris_options i)
795 case idris_outputmode i of
796 RawOutput -> do runIO $ putStrLn str
798 do let good = SexpList [IntegerAtom (toInteger l), toSExp str]
799 runIO $ putStrLn $ convSExp "log" good n
801cmdOptType :: Opt -> Idris Bool
802cmdOptType x = do i <- getIState
803 return $ x `elem` opt_cmdline (idris_options i)
805iLOG :: String -> Idris ()
808noErrors :: Idris Bool
809noErrors = do i <- getIState
811 Nothing -> return True
814setTypeCase :: Bool -> Idris ()
815setTypeCase t = do i <- getIState
816 let opts = idris_options i
817 let opt' = opts { opt_typecase = t }
818 putIState $ i { idris_options = opt' }
821-- Dealing with parameters
823expandParams :: (Name -> Name) -> [(Name, PTerm)] ->
824 [Name] -> -- all names
825 [Name] -> -- names with no declaration
827expandParams dec ps ns infs tm = en tm
829 -- if we shadow a name (say in a lambda binding) that is used in a call to
830 -- a lifted function, we need access to both names - once in the scope of the
831 -- binding and once to call the lifted functions. So we'll explicitly shadow
832 -- it. (Yes, it's a hack. The alternative would be to resolve names earlier
835 mkShadow (UN n) = MN 0 n
836 mkShadow (MN i n) = MN (i+1) n
837 mkShadow (NS x s) = NS (mkShadow x) s
840 | n `elem` (map fst ps ++ ns)
841 = let n' = mkShadow n in
842 PLam n' (en t) (en (shadow n n' s))
843 | otherwise = PLam n (en t) (en s)
845 | n `elem` (map fst ps ++ ns)
846 = let n' = mkShadow n in -- TODO THINK SHADOWING TacImp?
847 PPi (enTacImp p) n' (en t) (en (shadow n n' s))
848 | otherwise = PPi (enTacImp p) n (en t) (en s)
850 | n `elem` (map fst ps ++ ns)
851 = let n' = mkShadow n in
852 PLet n' (en ty) (en v) (en (shadow n n' s))
853 | otherwise = PLet n (en ty) (en v) (en s)
854 -- FIXME: Should only do this in a type signature!
855 en (PDPair f p (PRef f' n) t r)
856 | n `elem` (map fst ps ++ ns) && t /= Placeholder
857 = let n' = mkShadow n in
858 PDPair f p (PRef f' n') (en t) (en (shadow n n' r))
859 en (PEq f lt rt l r) = PEq f (en lt) (en rt) (en l) (en r)
860 en (PRewrite f l r g) = PRewrite f (en l) (en r) (fmap en g)
861 en (PTyped l r) = PTyped (en l) (en r)
862 en (PPair f p l r) = PPair f p (en l) (en r)
863 en (PDPair f p l t r) = PDPair f p (en l) (en t) (en r)
864 en (PAlternative a as) = PAlternative a (map en as)
865 en (PHidden t) = PHidden (en t)
866 en (PUnifyLog t) = PUnifyLog (en t)
867 en (PDisamb ds t) = PDisamb ds (en t)
868 en (PNoImplicits t) = PNoImplicits (en t)
869 en (PDoBlock ds) = PDoBlock (map (fmap en) ds)
870 en (PProof ts) = PProof (map (fmap en) ts)
871 en (PTactics ts) = PTactics (map (fmap en) ts)
874 | n `nselem` ns = PQuote (Var (dec n))
875 en (PApp fc (PInferRef fc' n) as)
876 | n `nselem` ns = PApp fc (PInferRef fc' (dec n))
877 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
878 en (PApp fc (PRef fc' n) as)
879 | n `elem` infs = PApp fc (PInferRef fc' (dec n))
880 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
881 | n `nselem` ns = PApp fc (PRef fc' (dec n))
882 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
883 en (PAppBind fc (PRef fc' n) as)
884 | n `elem` infs = PAppBind fc (PInferRef fc' (dec n))
885 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
886 | n `nselem` ns = PAppBind fc (PRef fc' (dec n))
887 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
889 | n `elem` infs = PApp fc (PInferRef fc (dec n))
890 (map (pexp . (PRef fc)) (map fst ps))
891 | n `nselem` ns = PApp fc (PRef fc (dec n))
892 (map (pexp . (PRef fc)) (map fst ps))
894 | n `nselem` ns = PApp fc (PInferRef fc (dec n))
895 (map (pexp . (PRef fc)) (map fst ps))
896 en (PApp fc f as) = PApp fc (en f) (map (fmap en) as)
897 en (PAppBind fc f as) = PAppBind fc (en f) (map (fmap en) as)
898 en (PCase fc c os) = PCase fc (en c) (map (pmap en) os)
902 nselem x (y : xs) | nseq x y = True
903 | otherwise = nselem x xs
905 nseq x y = nsroot x == nsroot y
907 enTacImp (TacImp aos st scr) = TacImp aos st (en scr)
908 enTacImp other = other
910expandParamsD :: Bool -> -- True = RHS only
912 (Name -> Name) -> [(Name, PTerm)] -> [Name] -> PDecl -> PDecl
913expandParamsD rhsonly ist dec ps ns (PTy doc argdocs syn fc o n ty)
914 = if n `elem` ns && (not rhsonly)
915 then -- trace (show (n, expandParams dec ps ns ty)) $
916 PTy doc argdocs syn fc o (dec n) (piBindp expl_param ps (expandParams dec ps ns [] ty))
917 else --trace (show (n, expandParams dec ps ns ty)) $
918 PTy doc argdocs syn fc o n (expandParams dec ps ns [] ty)
919expandParamsD rhsonly ist dec ps ns (PPostulate doc syn fc o n ty)
920 = if n `elem` ns && (not rhsonly)
921 then -- trace (show (n, expandParams dec ps ns ty)) $
922 PPostulate doc syn fc o (dec n) (piBind ps
923 (expandParams dec ps ns [] ty))
924 else --trace (show (n, expandParams dec ps ns ty)) $
925 PPostulate doc syn fc o n (expandParams dec ps ns [] ty)
926expandParamsD rhsonly ist dec ps ns (PClauses fc opts n cs)
927 = let n' = if n `elem` ns then dec n else n in
928 PClauses fc opts n' (map expandParamsC cs)
930 expandParamsC (PClause fc n lhs ws rhs ds)
931 = let -- ps' = updateps True (namesIn ist rhs) (zip ps [0..])
932 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
933 lhs' = if rhsonly then lhs else (expandParams dec ps'' ns [] lhs)
934 n' = if n `elem` ns then dec n else n
935 -- names bound on the lhs should not be expanded on the rhs
936 ns' = removeBound lhs ns in
938 (map (expandParams dec ps'' ns' []) ws)
939 (expandParams dec ps'' ns' [] rhs)
940 (map (expandParamsD True ist dec ps'' ns') ds)
941 expandParamsC (PWith fc n lhs ws wval ds)
942 = let -- ps' = updateps True (namesIn ist wval) (zip ps [0..])
943 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
944 lhs' = if rhsonly then lhs else (expandParams dec ps'' ns [] lhs)
945 n' = if n `elem` ns then dec n else n
946 ns' = removeBound lhs ns in
948 (map (expandParams dec ps'' ns' []) ws)
949 (expandParams dec ps'' ns' [] wval)
950 (map (expandParamsD rhsonly ist dec ps'' ns') ds)
951 updateps yn nm [] = []
952 updateps yn nm (((a, t), i):as)
953 | (a `elem` nm) == yn = (a, t) : updateps yn nm as
954 | otherwise = (sMN i ('_' : show n ++ "_u"), t) : updateps yn nm as
956 removeBound lhs ns = ns \\ nub (bnames lhs)
958 bnames (PRef _ n) = [n]
959 bnames (PApp _ _ args) = concatMap bnames (map getTm args)
960 bnames (PPair _ _ l r) = bnames l ++ bnames r
961 bnames (PDPair _ _ l Placeholder r) = bnames l ++ bnames r
964-- | Expands parameters defined in parameter and where blocks inside of declarations
965expandParamsD rhs ist dec ps ns (PData doc argDocs syn fc co pd)
966 = PData doc argDocs syn fc co (expandPData pd)
968 -- just do the type decl, leave constructors alone (parameters will be
970 expandPData (PDatadecl n ty cons)
972 then PDatadecl (dec n) (piBind ps (expandParams dec ps ns [] ty))
974 else PDatadecl n (expandParams dec ps ns [] ty) (map econ cons)
975 econ (doc, argDocs, n, t, fc, fs)
976 = (doc, argDocs, dec n, piBindp expl ps (expandParams dec ps ns [] t), fc, fs)
977expandParamsD rhs ist dec ps ns (PRecord doc syn fc tn tty opts cdoc cn cty)
979 then PRecord doc syn fc (dec tn) (piBind ps (expandParams dec ps ns [] tty))
980 opts cdoc (dec cn) conty
981 else PRecord doc syn fc (dec tn) (expandParams dec ps ns [] tty)
982 opts cdoc (dec cn) conty
983 where conty = piBindp expl ps (expandParams dec ps ns [] cty)
984expandParamsD rhs ist dec ps ns (PParams f params pds)
985 = PParams f (ps ++ map (mapsnd (expandParams dec ps ns [])) params)
986 (map (expandParamsD True ist dec ps ns) pds)
987-- (map (expandParamsD ist dec ps ns) pds)
988expandParamsD rhs ist dec ps ns (PMutual f pds)
989 = PMutual f (map (expandParamsD rhs ist dec ps ns) pds)
990expandParamsD rhs ist dec ps ns (PClass doc info f cs n params pDocs decls)
992 (map (expandParams dec ps ns []) cs)
994 (map (mapsnd (expandParams dec ps ns [])) params)
996 (map (expandParamsD rhs ist dec ps ns) decls)
997expandParamsD rhs ist dec ps ns (PInstance info f cs n params ty cn decls)
999 (map (expandParams dec ps ns []) cs)
1001 (map (expandParams dec ps ns []) params)
1002 (expandParams dec ps ns [] ty)
1004 (map (expandParamsD rhs ist dec ps ns) decls)
1005expandParamsD rhs ist dec ps ns d = d
1007mapsnd f (x, t) = (x, f t)
1009-- Calculate a priority for a type, for deciding elaboration order
1010-- * if it's just a type variable or concrete type, do it early (0)
1011-- * if there's only type variables and injective constructors, do it next (1)
1012-- * if there's a function type, next (2)
1013-- * finally, everything else (3)
1015getPriority :: IState -> PTerm -> Int
1016getPriority i tm = 1 -- pri tm
1019 case lookupP n (tt_ctxt i) of
1020 ((P (DCon _ _) _ _):_) -> 1
1021 ((P (TCon _ _) _ _):_) -> 1
1022 ((P Ref _ _):_) -> 1
1023 [] -> 0 -- must be locally bound, if it's not an error...
1024 pri (PPi _ _ x y) = max 5 (max (pri x) (pri y))
1028 pri (PEq _ _ _ l r) = max 1 (max (pri l) (pri r))
1029 pri (PRewrite _ l r _) = max 1 (max (pri l) (pri r))
1030 pri (PApp _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.getTm) as)))
1031 pri (PAppBind _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.getTm) as)))
1032 pri (PCase _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.snd) as)))
1033 pri (PTyped l r) = pri l
1034 pri (PPair _ _ l r) = max 1 (max (pri l) (pri r))
1035 pri (PDPair _ _ l t r) = max 1 (max (pri l) (max (pri t) (pri r)))
1036 pri (PAlternative a as) = maximum (map pri as)
1037 pri (PConstant _) = 0
1042addStatics :: Name -> Term -> PTerm -> Idris ()
1043addStatics n tm ptm =
1044 do let (statics, dynamics) = initStatics tm ptm
1045 let stnames = nub $ concatMap freeArgNames (map snd statics)
1046 let dnames = nub $ concatMap freeArgNames (map snd dynamics)
1047 -- also get the arguments which are 'uniquely inferrable' from
1048 -- statics (see sec 4.2 of "Scrapping Your Inefficient Engine")
1049 let statics' = nub $ map fst statics ++
1050 filter (\x -> not (elem x dnames)) stnames
1051 let stpos = staticList statics' tm
1053 when (not (null statics)) $
1054 logLvl 5 $ show n ++ " " ++ show statics' ++ "\n" ++ show dynamics
1055 ++ "\n" ++ show stnames ++ "\n" ++ show dnames
1056 putIState $ i { idris_statics = addDef n stpos (idris_statics i) }
1057 addIBC (IBCStatic n)
1059 initStatics (Bind n (Pi ty) sc) (PPi p _ _ s)
1060 = let (static, dynamic) = initStatics (instantiate (P Bound n ty) sc) s in
1061 if pstatic p == Static then ((n, ty) : static, dynamic)
1062 else if (not (searchArg p))
1063 then (static, (n, ty) : dynamic)
1064 else (static, dynamic)
1065 initStatics t pt = ([], [])
1067 freeArgNames (Bind n (Pi ty) sc)
1068 = nub $ freeArgNames ty
1069 freeArgNames tm = let (_, args) = unApply tm in
1070 concatMap freeNames args
1072 -- if a name appears in a type class or tactic implicit index, it doesn't
1073 -- affect its 'uniquely inferrable' from a static status since these are
1074 -- resolved by searching.
1075 searchArg (Constraint _ _) = True
1076 searchArg (TacImp _ _ _) = True
1079 staticList sts (Bind n (Pi _) sc) = (n `elem` sts) : staticList sts sc
1082-- Dealing with implicit arguments
1084-- Add some bound implicits to the using block if they aren't there already
1086addToUsing :: [Using] -> [(Name, PTerm)] -> [Using]
1087addToUsing us [] = us
1088addToUsing us ((n, t) : ns)
1089 | n `notElem` mapMaybe impName us = addToUsing (us ++ [UImplicit n t]) ns
1090 | otherwise = addToUsing us ns
1091 where impName (UImplicit n _) = Just n
1094-- Add constraint bindings from using block
1096addUsingConstraints :: SyntaxInfo -> FC -> PTerm -> Idris PTerm
1097addUsingConstraints syn fc t
1099 let ns = namesIn [] ist t
1100 let cs = getConstraints t -- check declared constraints
1101 let addconsts = uconsts \\ cs
1102 return (doAdd addconsts ns t)
1103 where uconsts = filter uconst (using syn)
1104 uconst (UConstraint _ _) = True
1108 -- if all of args in ns, then add it
1109 doAdd (UConstraint c args : cs) ns t
1110 | all (\n -> elem n ns) args
1111 = PPi (Constraint [] Dynamic) (sMN 0 "cu")
1112 (mkConst c args) (doAdd cs ns t)
1113 | otherwise = doAdd cs ns t
1115 mkConst c args = PApp fc (PRef fc c)
1116 (map (\n -> PExp 0 [] (sMN 0 "carg") (PRef fc n)) args)
1118 getConstraints (PPi (Constraint _ _) _ c sc)
1119 = getcapp c ++ getConstraints sc
1120 getConstraints (PPi _ _ c sc) = getConstraints sc
1121 getConstraints _ = []
1123 getcapp (PApp _ (PRef _ c) args)
1124 = do ns <- mapM getName args
1125 return (UConstraint c ns)
1128 getName (PExp _ _ _ (PRef _ n)) = return n
1131-- Add implicit bindings from using block, and bind any missing names
1132addUsingImpls :: SyntaxInfo -> Name -> FC -> PTerm -> Idris PTerm
1133addUsingImpls syn n fc t
1134 = do ist <- getIState
1135 let ns = implicitNamesIn (map iname uimpls) ist t
1136 let badnames = filter (\n -> not (implicitable n) &&
1137 n `notElem` (map iname uimpls)) ns
1138 when (not (null badnames)) $
1139 throwError (At fc (Elaborating "type of " n
1140 (NoSuchVariable (head badnames))))
1141 let cs = getArgnames t -- get already bound names
1142 let addimpls = filter (\n -> iname n `notElem` cs) uimpls
1143 -- if all names in the arguments of addconsts appear in ns,
1144 -- add the constraint implicitly
1145 return (bindFree ns (doAdd addimpls ns t))
1146 where uimpls = filter uimpl (using syn)
1147 uimpl (UImplicit _ _) = True
1150 iname (UImplicit n _) = n
1151 iname (UConstraint _ _) = error "Can't happen addUsingImpls"
1154 -- if all of args in ns, then add it
1155 doAdd (UImplicit n ty : cs) ns t
1157 = PPi (Imp [] Dynamic False) n ty (doAdd cs ns t)
1158 | otherwise = doAdd cs ns t
1160 -- bind the free names which weren't in the using block
1163 | elem n (map iname uimpls) = bindFree ns tm
1165 = PPi (Imp [] Dynamic False) n Placeholder (bindFree ns tm)
1167 getArgnames (PPi _ n c sc)
1168 = n : getArgnames sc
1171-- Given the original type and the elaborated type, return the implicitness
1172-- status of each pi-bound argument, and whether it's inaccessible (True) or not.
1174getUnboundImplicits :: IState -> Type -> PTerm -> [(Bool, PArg)]
1175getUnboundImplicits i (Bind n (Pi t) sc) (PPi p n' t' sc')
1176 | n == n' = argInfo n p : getUnboundImplicits i sc sc'
1178 argInfo n (Imp opt _ _) = (True, PImp (getPriority i t') True opt n t')
1179 argInfo n (Exp opt _ _) = (InaccessibleArg `elem` opt,
1180 PExp (getPriority i t') opt n t')
1181 argInfo n (Constraint opt _) = (InaccessibleArg `elem` opt,
1182 PConstraint 10 opt n t')
1183 argInfo n (TacImp opt _ scr) = (InaccessibleArg `elem` opt,
1184 PTacImplicit 10 opt n scr t')
1185getUnboundImplicits i (Bind n (Pi t) sc) tm
1186 = impBind n t : getUnboundImplicits i sc tm
1188 impBind n t = (True, PImp 1 True [] n Placeholder)
1189getUnboundImplicits i sc tm = []
1191-- Add implicit Pi bindings for any names in the term which appear in an
1192-- argument position.
1194-- This has become a right mess already. Better redo it some time...
1195-- TODO: This is obsoleted by the new way of elaborating types, but there's still
1196-- a couple of places which use it. Clean them up!
1197implicit :: ElabInfo -> SyntaxInfo -> Name -> PTerm -> Idris PTerm
1198implicit info syn n ptm = implicit' info syn [] n ptm
1200implicit' :: ElabInfo -> SyntaxInfo -> [Name] -> Name -> PTerm -> Idris PTerm
1201implicit' info syn ignore n ptm
1203 let (tm', impdata) = implicitise syn ignore i ptm
1204 defaultArgCheck (eInfoNames info ++ M.keys (idris_implicits i)) impdata
1205-- let (tm'', spos) = findStatics i tm'
1206 putIState $ i { idris_implicits = addDef n impdata (idris_implicits i) }
1208 logLvl 5 ("Implicit " ++ show n ++ " " ++ show impdata)
1210-- putIState $ i { idris_statics = addDef n spos (idris_statics i) }
1213 -- Detect unknown names in default arguments and throw error if found.
1214 defaultArgCheck :: [Name] -> [PArg] -> Idris ()
1215 defaultArgCheck knowns params = foldM_ notFoundInDefault knowns params
1217 notFoundInDefault :: [Name] -> PArg -> Idris [Name]
1218 notFoundInDefault kns (PTacImplicit _ _ n script _)
1220 case notFound kns (namesIn [] i script) of
1221 Nothing -> return (n:kns)
1222 Just name -> throwError (NoSuchVariable name)
1223 notFoundInDefault kns p = return ((pname p):kns)
1225 notFound :: [Name] -> [Name] -> Maybe Name
1226 notFound kns [] = Nothing
1227 notFound kns (SN (WhereN _ _ _) : ns) = notFound kns ns -- Known already
1228 notFound kns (n:ns) = if elem n kns then notFound kns ns else Just n
1230implicitise :: SyntaxInfo -> [Name] -> IState -> PTerm -> (PTerm, [PArg])
1231implicitise syn ignore ist tm = -- trace ("INCOMING " ++ showImp True tm) $
1232 let (declimps, ns') = execState (imps True [] tm) ([], [])
1233 ns = filter (\n -> implicitable n || elem n (map fst uvars)) $
1234 ns' \\ (map fst pvars ++ no_imp syn ++ ignore)
1235 nsOrder = filter (not . inUsing) ns ++ filter inUsing ns in
1237 then (tm, reverse declimps)
1238 else implicitise syn ignore ist (pibind uvars nsOrder tm)
1240 uvars = map ipair (filter uimplicit (using syn))
1241 pvars = syn_params syn
1243 inUsing n = n `elem` map fst uvars
1245 ipair (UImplicit x y) = (x, y)
1246 uimplicit (UImplicit _ _) = True
1249 dropAll (x:xs) ys | x `elem` ys = dropAll xs ys
1250 | otherwise = x : dropAll xs ys
1253 -- Find names in argument position in a type, suitable for implicit
1255 -- Not the function position, but do everything else...
1256 implNamesIn uv (PApp fc f args) = concatMap (implNamesIn uv) (map getTm args)
1257 implNamesIn uv t = namesIn uv ist t
1259 imps top env (PApp _ f as)
1260 = do (decls, ns) <- get
1261 let isn = concatMap (namesIn uvars ist) (map getTm as)
1262 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1263 imps top env (PPi (Imp l _ _) n ty sc)
1264 = do let isn = nub (implNamesIn uvars ty) `dropAll` [n]
1266 put (PImp (getPriority ist ty) True l n Placeholder : decls,
1267 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1268 imps True (n:env) sc
1269 imps top env (PPi (Exp l _ _) n ty sc)
1270 = do let isn = nub (implNamesIn uvars ty ++ case sc of
1271 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
1273 (decls, ns) <- get -- ignore decls in HO types
1274 put (PExp (getPriority ist ty) l n Placeholder : decls,
1275 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1276 imps True (n:env) sc
1277 imps top env (PPi (Constraint l _) n ty sc)
1278 = do let isn = nub (implNamesIn uvars ty ++ case sc of
1279 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
1281 (decls, ns) <- get -- ignore decls in HO types
1282 put (PConstraint 10 l n Placeholder : decls,
1283 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1284 imps True (n:env) sc
1285 imps top env (PPi (TacImp l _ scr) n ty sc)
1286 = do let isn = nub (implNamesIn uvars ty ++ case sc of
1287 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
1289 (decls, ns) <- get -- ignore decls in HO types
1290 put (PTacImplicit 10 l n scr Placeholder : decls,
1291 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1292 imps True (n:env) sc
1293 imps top env (PEq _ _ _ l r)
1294 = do (decls, ns) <- get
1295 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1296 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1297 imps top env (PRewrite _ l r _)
1298 = do (decls, ns) <- get
1299 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1300 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1301 imps top env (PTyped l r)
1303 imps top env (PPair _ _ l r)
1304 = do (decls, ns) <- get
1305 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1306 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1307 imps top env (PDPair _ _ (PRef _ n) t r)
1308 = do (decls, ns) <- get
1309 let isn = nub (namesIn uvars ist t ++ namesIn uvars ist r) \\ [n]
1310 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
1311 imps top env (PDPair _ _ l t r)
1312 = do (decls, ns) <- get
1313 let isn = namesIn uvars ist l ++ namesIn uvars ist t ++
1315 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
1316 imps top env (PAlternative a as)
1317 = do (decls, ns) <- get
1318 let isn = concatMap (namesIn uvars ist) as
1319 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1320 imps top env (PLam n ty sc)
1321 = do imps False env ty
1322 imps False (n:env) sc
1323 imps top env (PHidden tm) = imps False env tm
1324 imps top env (PUnifyLog tm) = imps False env tm
1325 imps top env (PNoImplicits tm) = imps False env tm
1326 imps top env _ = return ()
1328 pibind using [] sc = sc
1329 pibind using (n:ns) sc
1330 = case lookup n using of
1331 Just ty -> PPi (Imp [] Dynamic False) n ty (pibind using ns sc)
1332 Nothing -> PPi (Imp [] Dynamic False) n Placeholder
1333 (pibind using ns sc)
1335-- Add implicit arguments in function calls
1336addImplPat :: IState -> PTerm -> PTerm
1337addImplPat = addImpl' True [] []
1339addImplBound :: IState -> [Name] -> PTerm -> PTerm
1340addImplBound ist ns = addImpl' False ns [] ist
1342addImplBoundInf :: IState -> [Name] -> [Name] -> PTerm -> PTerm
1343addImplBoundInf ist ns inf = addImpl' False ns inf ist
1345-- | Add the implicit arguments to applications in the term
1346addImpl :: IState -> PTerm -> PTerm
1347addImpl = addImpl' False [] []
1349-- TODO: in patterns, don't add implicits to function names guarded by constructors
1350-- and *not* inside a PHidden
1352addImpl' :: Bool -> [Name] -> [Name] -> IState -> PTerm -> PTerm
1353addImpl' inpat env infns ist ptm
1354 = mkUniqueNames env (ai False (zip env (repeat Nothing)) [] ptm)
1356 ai :: Bool -> [(Name, Maybe PTerm)] -> [[T.Text]] -> PTerm -> PTerm
1357 ai qq env ds (PRef fc f)
1358 | f `elem` infns = PInferRef fc f
1359 | not (f `elem` map fst env) = handleErr $ aiFn inpat inpat qq ist fc f ds []
1360 ai qq env ds (PHidden (PRef fc f))
1361 | not (f `elem` map fst env) = handleErr $ aiFn inpat False qq ist fc f ds []
1362 ai qq env ds (PEq fc lt rt l r)
1363 = let lt' = ai qq env ds lt
1364 rt' = ai qq env ds rt
1366 r' = ai qq env ds r in
1367 PEq fc lt' rt' l' r'
1368 ai qq env ds (PRewrite fc l r g)
1369 = let l' = ai qq env ds l
1371 g' = fmap (ai qq env ds) g in
1372 PRewrite fc l' r' g'
1373 ai qq env ds (PTyped l r)
1374 = let l' = ai qq env ds l
1375 r' = ai qq env ds r in
1377 ai qq env ds (PPair fc p l r)
1378 = let l' = ai qq env ds l
1379 r' = ai qq env ds r in
1381 ai qq env ds (PDPair fc p l t r)
1382 = let l' = ai qq env ds l
1384 r' = ai qq env ds r in
1385 PDPair fc p l' t' r'
1386 ai qq env ds (PAlternative a as)
1387 = let as' = map (ai qq env ds) as in
1389 ai qq env _ (PDisamb ds' as) = ai qq env ds' as
1390 ai qq env ds (PApp fc (PInferRef _ f) as)
1391 = let as' = map (fmap (ai qq env ds)) as in
1392 PApp fc (PInferRef fc f) as'
1393 ai qq env ds (PApp fc ftm@(PRef _ f) as)
1394 | f `elem` infns = ai qq env ds (PApp fc (PInferRef fc f) as)
1395 | not (f `elem` map fst env)
1396 = let as' = map (fmap (ai qq env ds)) as in
1397 handleErr $ aiFn inpat False qq ist fc f ds as'
1398 | Just (Just ty) <- lookup f env =
1399 let as' = map (fmap (ai qq env ds)) as
1400 arity = getPArity ty in
1401 mkPApp fc arity ftm as'
1402 ai qq env ds (PApp fc f as)
1403 = let f' = ai qq env ds f
1404 as' = map (fmap (ai qq env ds)) as in
1406 ai qq env ds (PCase fc c os)
1407 = let c' = ai qq env ds c in
1408 -- leave os alone, because they get lifted into a new pattern match
1409 -- definition which is passed through addImpl again with more scope
1412 ai qq env ds (PLam n ty sc)
1413 = let ty' = ai qq env ds ty
1414 sc' = ai qq ((n, Just ty):env) ds sc in
1416 ai qq env ds (PLet n ty val sc)
1417 = let ty' = ai qq env ds ty
1418 val' = ai qq env ds val
1419 sc' = ai qq ((n, Just ty):env) ds sc in
1421 ai qq env ds (PPi p n ty sc)
1422 = let ty' = ai qq env ds ty
1423 sc' = ai qq ((n, Just ty):env) ds sc in
1425 ai qq env ds (PGoal fc r n sc)
1426 = let r' = ai qq env ds r
1427 sc' = ai qq ((n, Nothing):env) ds sc in
1429 ai qq env ds (PHidden tm) = PHidden (ai qq env ds tm)
1430 -- Don't do PProof or PTactics since implicits get added when scope is
1431 -- properly known in ElabTerm.runTac
1432 ai qq env ds (PRefl fc tm) = PRefl fc (ai qq env ds tm)
1433 ai qq env ds (PUnifyLog tm) = PUnifyLog (ai qq env ds tm)
1434 ai qq env ds (PNoImplicits tm) = PNoImplicits (ai qq env ds tm)
1435 ai qq env ds (PQuasiquote tm g) = PQuasiquote (ai True env ds tm)
1436 (fmap (ai True env ds) g)
1437 ai qq env ds (PUnquote tm) = PUnquote (ai False env ds tm)
1438 ai qq env ds tm = tm
1440 handleErr (Left err) = PElabError err
1441 handleErr (Right x) = x
1443-- if in a pattern, and there are no arguments, and there's no possible
1444-- names with zero explicit arguments, don't add implicits.
1446aiFn :: Bool -> Bool -> Bool -> IState -> FC -> Name -> [[T.Text]] -> [PArg] -> Either Err PTerm
1447aiFn inpat True qq ist fc f ds []
1448 = case lookupDef f (tt_ctxt ist) of
1449 [] -> Right $ PPatvar fc f
1450 alts -> let ialts = lookupCtxtName f (idris_implicits ist) in
1451 -- trace (show f ++ " " ++ show (fc, any (all imp) ialts, ialts, any constructor alts)) $
1452 if (not (vname f) || tcname f
1453 || any (conCaf (tt_ctxt ist)) ialts)
1454-- any constructor alts || any allImp ialts))
1455 then aiFn inpat False qq ist fc f ds [] -- use it as a constructor
1456 else Right $ PPatvar fc f
1457 where imp (PExp _ _ _ _) = False
1460 allImp xs = all imp xs
1461 constructor (TyDecl (DCon _ _) _) = True
1462 constructor _ = False
1464 conCaf ctxt (n, cia) = (isDConName n ctxt || (qq && isTConName n ctxt)) && allImp cia
1466 vname (UN n) = True -- non qualified
1469aiFn inpat expat qq ist fc f ds as
1470 | f `elem` primNames = Right $ PApp fc (PRef fc f) as
1471aiFn inpat expat qq ist fc f ds as
1472 -- This is where namespaces get resolved by adding PAlternative
1473 = do let ns = lookupCtxtName f (idris_implicits ist)
1474 let nh = filter (\(n, _) -> notHidden n) ns
1475 let ns' = case trimAlts ds nh of
1479 [(f',ns)] -> Right $ mkPApp fc (length ns) (PRef fc f') (insertImpl ns as)
1480 [] -> if f `elem` (map fst (idris_metavars ist))
1481 then Right $ PApp fc (PRef fc f) as
1482 else Right $ mkPApp fc (length as) (PRef fc f) as
1485 map (\(f', ns) -> mkPApp fc (length ns) (PRef fc f')
1486 (insertImpl ns as)) alts
1488 trimAlts [] alts = alts
1490 = filter (\(x, _) -> any (\d -> d `isPrefixOf` nspace x) ns) alts
1495 notHidden n = case getAccessibility n of
1500 = case lookupDefAcc n False (tt_ctxt ist) of
1504 insertImpl :: [PArg] -> [PArg] -> [PArg]
1505 insertImpl ps as = insImpAcc M.empty ps (filter exp as) (filter (not.exp) as)
1507 exp (PExp _ _ _ _) = True
1508 exp (PConstraint _ _ _ _) = True
1511 insImpAcc :: M.Map Name PTerm -- accumulated param names & arg terms
1512 -> [PArg] -- parameters
1513 -> [PArg] -- explicit arguments
1514 -> [PArg] -- implicits given
1516 insImpAcc pnas (PExp p l n ty : ps) (PExp _ _ _ tm : given) imps =
1517 PExp p l n tm : insImpAcc (M.insert n tm pnas) ps given imps
1518 insImpAcc pnas (PConstraint p l n ty : ps) (PConstraint _ _ _ tm : given) imps =
1519 PConstraint p l n tm : insImpAcc (M.insert n tm pnas) ps given imps
1520 insImpAcc pnas (PConstraint p l n ty : ps) given imps =
1521 let rtc = PResolveTC fc in
1522 PConstraint p l n rtc : insImpAcc (M.insert n rtc pnas) ps given imps
1523 insImpAcc pnas (PImp p _ l n ty : ps) given imps =
1524 case find n imps [] of
1526 PImp p False l n tm : insImpAcc (M.insert n tm pnas) ps given imps'
1528 PImp p True l n Placeholder :
1529 insImpAcc (M.insert n Placeholder pnas) ps given imps
1530 insImpAcc pnas (PTacImplicit p l n sc' ty : ps) given imps =
1531 let sc = addImpl ist (substMatches (M.toList pnas) sc') in
1532 case find n imps [] of
1534 PTacImplicit p l n sc tm :
1535 insImpAcc (M.insert n tm pnas) ps given imps'
1538 then PTacImplicit p l n sc Placeholder :
1539 insImpAcc (M.insert n Placeholder pnas) ps given imps
1540 else PTacImplicit p l n sc sc :
1541 insImpAcc (M.insert n sc pnas) ps given imps
1542 insImpAcc _ expected [] imps = imps -- so that unused implicits give error
1543 -- TODO: report here, and prune alternatives
1544 insImpAcc _ _ given imps = given ++ imps
1546 find n [] acc = Nothing
1547 find n (PImp _ _ _ n' t : gs) acc
1548 | n == n' = Just (t, reverse acc ++ gs)
1549 find n (PTacImplicit _ _ n' _ t : gs) acc
1550 | n == n' = Just (t, reverse acc ++ gs)
1551 find n (g : gs) acc = find n gs (g : acc)
1553-- replace non-linear occurrences with _
1554-- ASSUMPTION: This is called before adding 'alternatives' because otherwise
1555-- it is hard to get right!
1557stripLinear :: IState -> PTerm -> PTerm
1558stripLinear i tm = evalState (sl tm) [] where
1559 sl :: PTerm -> State [Name] PTerm
1561 | (_:_) <- lookupTy f (tt_ctxt i)
1562 = return $ PRef fc f
1563 | otherwise = do ns <- get
1565 then return Placeholder
1566 else do put (f : ns)
1571 then return Placeholder
1572 else do put (f : ns)
1573 return (PPatvar fc f)
1574 sl t@(PAlternative _ (a : as)) = do sl a
1576 sl (PApp fc fn args) = do -- Just the args, fn isn't matchable as a var
1577 args' <- mapM slA args
1578 return $ PApp fc fn args'
1579 where slA (PImp p m l n t) = do t' <- sl t
1580 return $ PImp p m l n t'
1581 slA (PExp p l n t) = do t' <- sl t
1582 return $ PExp p l n t'
1583 slA (PConstraint p l n t)
1585 return $ PConstraint p l n t'
1586 slA (PTacImplicit p l n sc t)
1588 return $ PTacImplicit p l n sc t'
1591-- Remove functions which aren't applied to anything, which must then
1592-- be resolved by unification. Assume names resolved and alternatives
1593-- filled in (so no ambiguity).
1595stripUnmatchable :: IState -> PTerm -> PTerm
1596stripUnmatchable i (PApp fc fn args) = PApp fc fn (fmap (fmap su) args) where
1597 su :: PTerm -> PTerm
1599 | (Bind n (Pi t) sc :_) <- lookupTy f (tt_ctxt i)
1601 su (PApp fc fn args)
1602 = PApp fc fn (fmap (fmap su) args)
1603 su (PAlternative b alts)
1604 = let alts' = filter (/= Placeholder) (map su alts) in
1605 if null alts' then Placeholder
1606 else PAlternative b alts'
1607 su (PPair fc p l r) = PPair fc p (su l) (su r)
1608 su (PDPair fc p l t r) = PDPair fc p (su l) (su t) (su r)
1610stripUnmatchable i tm = tm
1613mkPApp fc a f as = let rest = drop a as in
1614 appRest fc (PApp fc f (take a as)) rest
1617 appRest fc f (a : as) = appRest fc (PApp fc f [a]) as
1619-- Find 'static' argument positions
1620-- (the declared ones, plus any names in argument position in the declared
1622-- FIXME: It's possible that this really has to happen after elaboration
1624findStatics :: IState -> PTerm -> (PTerm, [Bool])
1625findStatics ist tm = trace (show tm) $
1626 let (ns, ss) = fs tm in
1627 runState (pos ns ss tm) []
1628 where fs (PPi p n t sc)
1629 | Static <- pstatic p
1630 = let (ns, ss) = fs sc in
1631 (namesIn [] ist t : ns, n : ss)
1632 | otherwise = let (ns, ss) = fs sc in
1636 inOne n ns = length (filter id (map (elem n) ns)) == 1
1638 pos ns ss (PPi p n t sc)
1639 | elem n ss = do sc' <- pos ns ss sc
1642 return (PPi (p { pstatic = Static }) n t sc')
1643 | otherwise = do sc' <- pos ns ss sc
1646 return (PPi p n t sc')
1647 pos ns ss t = return t
1649-- for 6.12/7 compatibility
1650data EitherErr a b = LeftErr a | RightOK b
1652instance Monad (EitherErr a) where
1655 (LeftErr e) >>= k = LeftErr e
1656 RightOK v >>= k = k v
1658toEither (LeftErr e) = Left e
1659toEither (RightOK ho) = Right ho
1661-- syntactic match of a against b, returning pair of variables in a
1662-- and what they match. Returns the pair that failed if not a match.
1664matchClause :: IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
1665matchClause = matchClause' False
1667matchClause' :: Bool -> IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
1668matchClause' names i x y = checkRpts $ match (fullApp x) (fullApp y) where
1669 matchArg x y = match (fullApp (getTm x)) (fullApp (getTm y))
1671 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
1674 match' x y = match (fullApp x) (fullApp y)
1675 match (PApp _ (PRef _ (NS (UN fi) [b])) [_,_,x]) x'
1676 | fi == txt "fromInteger" && b == txt "builtins",
1677 PConstant (I _) <- getTm x = match (getTm x) x'
1678 match x' (PApp _ (PRef _ (NS (UN fi) [b])) [_,_,x])
1679 | fi == txt "fromInteger" && b == txt "builtins",
1680 PConstant (I _) <- getTm x = match (getTm x) x'
1681 match (PApp _ (PRef _ (UN l)) [_,x]) x' | l == txt "lazy" = match (getTm x) x'
1682 match x (PApp _ (PRef _ (UN l)) [_,x']) | l == txt "lazy" = match x (getTm x')
1683 match (PApp _ f args) (PApp _ f' args')
1684 | length args == length args'
1685 = do mf <- match' f f'
1686 ms <- zipWithM matchArg args args'
1687 return (mf ++ concat ms)
1688 match (PRef f n) (PApp _ x []) = match (PRef f n) x
1689 match (PPatvar f n) xr = match (PRef f n) xr
1690 match xr (PPatvar f n) = match xr (PRef f n)
1691 match (PApp _ x []) (PRef f n) = match x (PRef f n)
1692 match (PRef _ n) tm@(PRef _ n')
1693 | n == n' && not names &&
1694 (not (isConName n (tt_ctxt i) || isFnName n (tt_ctxt i))
1695 || tm == Placeholder)
1697 -- if one namespace is missing, drop the other
1698 | n == n' || n == dropNS n' || dropNS n == n' = return []
1699 where dropNS (NS n _) = n
1702 | not names && (not (isConName n (tt_ctxt i) ||
1703 isFnName n (tt_ctxt i)) || tm == Placeholder)
1705 match (PEq _ _ _ l r) (PEq _ _ _ l' r')
1706 = do ml <- match' l l'
1709 match (PRewrite _ l r _) (PRewrite _ l' r' _)
1710 = do ml <- match' l l'
1713 match (PTyped l r) (PTyped l' r') = do ml <- match l l'
1716 match (PTyped l r) x = match l x
1717 match x (PTyped l r) = match x l
1718 match (PPair _ _ l r) (PPair _ _ l' r') = do ml <- match' l l'
1721 match (PDPair _ _ l t r) (PDPair _ _ l' t' r') = do ml <- match' l l'
1724 return (ml ++ mt ++ mr)
1725 match (PAlternative a as) (PAlternative a' as')
1726 = do ms <- zipWithM match' as as'
1728 match a@(PAlternative _ as) b
1729 = do let ms = zipWith match' as (repeat b)
1730 case (rights (map toEither ms)) of
1733 match (PCase _ _ _) _ = return [] -- lifted out
1734 match (PMetavar _) _ = return [] -- modified
1735 match (PInferRef _ _) _ = return [] -- modified
1736 match (PQuote _) _ = return []
1737 match (PProof _) _ = return []
1738 match (PTactics _) _ = return []
1739 match (PRefl _ _) (PRefl _ _) = return []
1740 match (PResolveTC _) (PResolveTC _) = return []
1741 match (PTrue _ _) (PTrue _ _) = return []
1742 match (PFalse _) (PFalse _) = return []
1743 match (PReturn _) (PReturn _) = return []
1744 match (PPi _ _ t s) (PPi _ _ t' s') = do mt <- match' t t'
1747 match (PLam _ t s) (PLam _ t' s') = do mt <- match' t t'
1750 match (PLet _ t ty s) (PLet _ t' ty' s') = do mt <- match' t t'
1751 mty <- match' ty ty'
1753 return (mt ++ mty ++ ms)
1754 match (PHidden x) (PHidden y) = match' x y
1755 match (PUnifyLog x) y = match' x y
1756 match x (PUnifyLog y) = match' x y
1757 match (PNoImplicits x) y = match' x y
1758 match x (PNoImplicits y) = match' x y
1759 match Placeholder _ = return []
1760 match _ Placeholder = return []
1761 match (PResolveTC _) _ = return []
1762 match a b | a == b = return []
1763 | otherwise = LeftErr (a, b)
1765 checkRpts (RightOK ms) = check ms where
1767 | Just t' <- lookup n xs = if t/=t' && t/=Placeholder && t'/=Placeholder
1770 check (_:xs) = check xs
1772 checkRpts (LeftErr x) = Left x
1774substMatches :: [(Name, PTerm)] -> PTerm -> PTerm
1775substMatches ms = substMatchesShadow ms []
1777substMatchesShadow :: [(Name, PTerm)] -> [Name] -> PTerm -> PTerm
1778substMatchesShadow [] shs t = t
1779substMatchesShadow ((n,tm):ns) shs t
1780 = substMatchShadow n shs tm (substMatchesShadow ns shs t)
1782substMatch :: Name -> PTerm -> PTerm -> PTerm
1783substMatch n = substMatchShadow n []
1785substMatchShadow :: Name -> [Name] -> PTerm -> PTerm -> PTerm
1786substMatchShadow n shs tm t = sm shs t where
1787 sm xs (PRef _ n') | n == n' = tm
1788 sm xs (PLam x t sc) = PLam x (sm xs t) (sm xs sc)
1789 sm xs (PPi p x t sc)
1791 = let x' = nextName x in
1792 PPi p x' (sm (x':xs) (substMatch x (PRef emptyFC x') t))
1793 (sm (x':xs) (substMatch x (PRef emptyFC x') sc))
1794 | otherwise = PPi p x (sm xs t) (sm (x : xs) sc)
1795 sm xs (PApp f x as) = fullApp $ PApp f (sm xs x) (map (fmap (sm xs)) as)
1796 sm xs (PCase f x as) = PCase f (sm xs x) (map (pmap (sm xs)) as)
1797 sm xs (PEq f xt yt x y) = PEq f (sm xs xt) (sm xs yt) (sm xs x) (sm xs y)
1798 sm xs (PRewrite f x y tm) = PRewrite f (sm xs x) (sm xs y)
1800 sm xs (PTyped x y) = PTyped (sm xs x) (sm xs y)
1801 sm xs (PPair f p x y) = PPair f p (sm xs x) (sm xs y)
1802 sm xs (PDPair f p x t y) = PDPair f p (sm xs x) (sm xs t) (sm xs y)
1803 sm xs (PAlternative a as) = PAlternative a (map (sm xs) as)
1804 sm xs (PHidden x) = PHidden (sm xs x)
1805 sm xs (PUnifyLog x) = PUnifyLog (sm xs x)
1806 sm xs (PNoImplicits x) = PNoImplicits (sm xs x)
1809 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
1812shadow :: Name -> Name -> PTerm -> PTerm
1813shadow n n' t = sm t where
1814 sm (PRef fc x) | n == x = PRef fc n'
1815 sm (PLam x t sc) | n /= x = PLam x (sm t) (sm sc)
1816 sm (PPi p x t sc) | n /=x = PPi p x (sm t) (sm sc)
1817 sm (PLet x t v sc) | n /= x = PLet x (sm t) (sm v) (sm sc)
1818 sm (PApp f x as) = PApp f (sm x) (map (fmap sm) as)
1819 sm (PAppBind f x as) = PAppBind f (sm x) (map (fmap sm) as)
1820 sm (PCase f x as) = PCase f (sm x) (map (pmap sm) as)
1821 sm (PEq f xt yt x y) = PEq f (sm xt) (sm yt) (sm x) (sm y)
1822 sm (PRewrite f x y tm) = PRewrite f (sm x) (sm y) (fmap sm tm)
1823 sm (PTyped x y) = PTyped (sm x) (sm y)
1824 sm (PPair f p x y) = PPair f p (sm x) (sm y)
1825 sm (PDPair f p x t y) = PDPair f p (sm x) (sm t) (sm y)
1826 sm (PAlternative a as) = PAlternative a (map sm as)
1827 sm (PTactics ts) = PTactics (map (fmap sm) ts)
1828 sm (PProof ts) = PProof (map (fmap sm) ts)
1829 sm (PHidden x) = PHidden (sm x)
1830 sm (PUnifyLog x) = PUnifyLog (sm x)
1831 sm (PNoImplicits x) = PNoImplicits (sm x)
1834-- Rename any binders which are repeated (so that we don't have to mess
1835-- about with shadowing anywhere else).
1837mkUniqueNames :: [Name] -> PTerm -> PTerm
1838mkUniqueNames env tm = evalState (mkUniq tm) env where
1839 inScope = boundNamesIn tm
1841 mkUniqA arg = do t' <- mkUniq (getTm arg)
1842 return (arg { getTm = t' })
1844 -- Initialise the unique name with the environment length (so we're not
1845 -- looking for too long...)
1846 initN (UN n) l = UN $ txt (str n ++ show l)
1847 initN (MN i s) l = MN (i+l) s
1850 -- FIXME: Probably ought to do this for completeness! It's fine as
1851 -- long as there are no bindings inside tactics though.
1852 mkUniqT tac = return tac
1854 mkUniq :: PTerm -> State [Name] PTerm
1855 mkUniq (PLam n ty sc)
1859 then do let n' = uniqueName (initN n (length env))
1861 return (n', shadow n n' sc)
1866 return $! PLam n' ty' sc''
1867 mkUniq (PPi p n ty sc)
1871 then do let n' = uniqueName (initN n (length env))
1873 return (n', shadow n n' sc)
1878 return $! PPi p n' ty' sc''
1879 mkUniq (PLet n ty val sc)
1883 then do let n' = uniqueName (initN n (length env))
1885 return (n', shadow n n' sc)
1888 ty' <- mkUniq ty; val' <- mkUniq val
1890 return $! PLet n' ty' val' sc''
1891 mkUniq (PApp fc t args)
1893 args' <- mapM mkUniqA args
1894 return $! PApp fc t' args'
1895 mkUniq (PAppBind fc t args)
1897 args' <- mapM mkUniqA args
1898 return $! PAppBind fc t' args'
1899 mkUniq (PCase fc t alts)
1901 alts' <- mapM (\(x,y)-> do x' <- mkUniq x; y' <- mkUniq y
1902 return (x', y')) alts
1903 return $! PCase fc t' alts'
1904 mkUniq (PPair fc p l r)
1905 = do l' <- mkUniq l; r' <- mkUniq r
1906 return $! PPair fc p l' r'
1907 mkUniq (PDPair fc p (PRef fc' n) t sc)
1910 (n', sc') <- if n `elem` env
1911 then do let n' = uniqueName n (env ++ inScope)
1912 return (n', shadow n n' sc)
1917 return $! PDPair fc p (PRef fc' n') t' sc''
1918 mkUniq (PDPair fc p l t r)
1919 = do l' <- mkUniq l; t' <- mkUniq t; r' <- mkUniq r
1920 return $! PDPair fc p l' t' r'
1921 mkUniq (PAlternative b as)
1922 = liftM (PAlternative b) (mapM mkUniq as)
1923 mkUniq (PHidden t) = liftM PHidden (mkUniq t)
1924 mkUniq (PUnifyLog t) = liftM PUnifyLog (mkUniq t)
1925 mkUniq (PDisamb n t) = liftM (PDisamb n) (mkUniq t)
1926 mkUniq (PNoImplicits t) = liftM PNoImplicits (mkUniq t)
1927 mkUniq (PProof ts) = liftM PProof (mapM mkUniqT ts)
1928 mkUniq (PTactics ts) = liftM PTactics (mapM mkUniqT ts)
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list