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 ++
485 where tidyNames used (Bind (MN i x) b sc)
486 = let n' = uniqueName (UN x) used in
487 Bind n' b $ tidyNames (n':used) sc
488 tidyNames used (Bind n b sc)
489 = let n' = uniqueName n used in
490 Bind n' b $ tidyNames (n':used) sc
493solveDeferred :: Name -> Idris ()
494solveDeferred n = do i <- getIState
495 putIState $ i { idris_metavars =
496 filter (\(n', _) -> n/=n')
499 filter (notMV n) (ibc_write i)
501 where notMV n (IBCMetavar n') = not (n == n')
504getUndefined :: Idris [Name]
505getUndefined = do i <- getIState
506 return (map fst (idris_metavars i) \\ primDefs)
508isMetavarName :: Name -> IState -> Bool
510 = case lookupNames n (tt_ctxt ist) of
511 (t:_) -> isJust $ lookup t (idris_metavars ist)
514getWidth :: Idris ConsoleWidth
515getWidth = fmap idris_consolewidth getIState
517setWidth :: ConsoleWidth -> Idris ()
518setWidth w = do ist <- getIState
519 put ist { idris_consolewidth = w }
521renderWidth :: Idris Int
522renderWidth = do iw <- getWidth
524 InfinitelyWide -> return 100000000
525 ColsWide n -> return (max n 1)
526 AutomaticWidth -> runIO getScreenWidth
530type1Doc :: Doc OutputAnnotation
531type1Doc = (annotate (AnnType "Type" "The type of types, one level up") $ text "Type 1")
534isetPrompt :: String -> Idris ()
535isetPrompt p = do i <- getIState
536 case idris_outputmode i of
537 IdeSlave n -> runIO . putStrLn $ convSExp "set-prompt" p n
539-- | Tell clients how much was parsed and loaded
540isetLoadedRegion :: Idris ()
541isetLoadedRegion = do i <- getIState
542 let span = idris_parsedSpan i
545 case idris_outputmode i of
548 convSExp "set-loaded-region" fc n
551setLogLevel :: Int -> Idris ()
552setLogLevel l = do i <- getIState
553 let opts = idris_options i
554 let opt' = opts { opt_logLevel = l }
555 putIState $ i { idris_options = opt' }
557setCmdLine :: [Opt] -> Idris ()
558setCmdLine opts = do i <- getIState
559 let iopts = idris_options i
560 putIState $ i { idris_options = iopts { opt_cmdline = opts } }
562getCmdLine :: Idris [Opt]
563getCmdLine = do i <- getIState
564 return (opt_cmdline (idris_options i))
566getDumpDefun :: Idris (Maybe FilePath)
567getDumpDefun = do i <- getIState
568 return $ findC (opt_cmdline (idris_options i))
569 where findC [] = Nothing
570 findC (DumpDefun x : _) = Just x
571 findC (_ : xs) = findC xs
573getDumpCases :: Idris (Maybe FilePath)
574getDumpCases = do i <- getIState
575 return $ findC (opt_cmdline (idris_options i))
576 where findC [] = Nothing
577 findC (DumpCases x : _) = Just x
578 findC (_ : xs) = findC xs
581logLevel = do i <- getIState
582 return (opt_logLevel (idris_options i))
584setErrContext :: Bool -> Idris ()
585setErrContext t = do i <- getIState
586 let opts = idris_options i
587 let opt' = opts { opt_errContext = t }
588 putIState $ i { idris_options = opt' }
590errContext :: Idris Bool
591errContext = do i <- getIState
592 return (opt_errContext (idris_options i))
595useREPL = do i <- getIState
596 return (opt_repl (idris_options i))
598setREPL :: Bool -> Idris ()
599setREPL t = do i <- getIState
600 let opts = idris_options i
601 let opt' = opts { opt_repl = t }
602 putIState $ i { idris_options = opt' }
604showOrigErr :: Idris Bool
605showOrigErr = do i <- getIState
606 return (opt_origerr (idris_options i))
608setShowOrigErr :: Bool -> Idris ()
609setShowOrigErr b = do i <- getIState
610 let opts = idris_options i
611 let opt' = opts { opt_origerr = b }
612 putIState $ i { idris_options = opt' }
614setAutoSolve :: Bool -> Idris ()
615setAutoSolve b = do i <- getIState
616 let opts = idris_options i
617 let opt' = opts { opt_autoSolve = b }
618 putIState $ i { idris_options = opt' }
620setNoBanner :: Bool -> Idris ()
621setNoBanner n = do i <- getIState
622 let opts = idris_options i
623 let opt' = opts { opt_nobanner = n }
624 putIState $ i { idris_options = opt' }
626getNoBanner :: Idris Bool
627getNoBanner = do i <- getIState
628 let opts = idris_options i
629 return (opt_nobanner opts)
631setQuiet :: Bool -> Idris ()
632setQuiet q = do i <- getIState
633 let opts = idris_options i
634 let opt' = opts { opt_quiet = q }
635 putIState $ i { idris_options = opt' }
637getQuiet :: Idris Bool
638getQuiet = do i <- getIState
639 let opts = idris_options i
640 return (opt_quiet opts)
642setCodegen :: Codegen -> Idris ()
643setCodegen t = do i <- getIState
644 let opts = idris_options i
645 let opt' = opts { opt_codegen = t }
646 putIState $ i { idris_options = opt' }
648codegen :: Idris Codegen
649codegen = do i <- getIState
650 return (opt_codegen (idris_options i))
652setOutputTy :: OutputType -> Idris ()
653setOutputTy t = do i <- getIState
654 let opts = idris_options i
655 let opt' = opts { opt_outputTy = t }
656 putIState $ i { idris_options = opt' }
658outputTy :: Idris OutputType
659outputTy = do i <- getIState
660 return $ opt_outputTy $ idris_options i
662setIdeSlave :: Bool -> Idris ()
663setIdeSlave True = do i <- getIState
664 putIState $ i { idris_outputmode = (IdeSlave 0), idris_colourRepl = False }
665setIdeSlave False = return ()
667setTargetTriple :: String -> Idris ()
668setTargetTriple t = do i <- getIState
669 let opts = idris_options i
670 opt' = opts { opt_triple = t }
671 putIState $ i { idris_options = opt' }
673targetTriple :: Idris String
674targetTriple = do i <- getIState
675 return (opt_triple (idris_options i))
677setTargetCPU :: String -> Idris ()
678setTargetCPU t = do i <- getIState
679 let opts = idris_options i
680 opt' = opts { opt_cpu = t }
681 putIState $ i { idris_options = opt' }
683targetCPU :: Idris String
684targetCPU = do i <- getIState
685 return (opt_cpu (idris_options i))
687setOptLevel :: Word -> Idris ()
688setOptLevel t = do i <- getIState
689 let opts = idris_options i
690 opt' = opts { opt_optLevel = t }
691 putIState $ i { idris_options = opt' }
693optLevel :: Idris Word
694optLevel = do i <- getIState
695 return (opt_optLevel (idris_options i))
698verbose = do i <- getIState
699 return (opt_verbose (idris_options i))
701setVerbose :: Bool -> Idris ()
702setVerbose t = do i <- getIState
703 let opts = idris_options i
704 let opt' = opts { opt_verbose = t }
705 putIState $ i { idris_options = opt' }
707typeInType :: Idris Bool
708typeInType = do i <- getIState
709 return (opt_typeintype (idris_options i))
711setTypeInType :: Bool -> Idris ()
712setTypeInType t = do i <- getIState
713 let opts = idris_options i
714 let opt' = opts { opt_typeintype = t }
715 putIState $ i { idris_options = opt' }
717coverage :: Idris Bool
718coverage = do i <- getIState
719 return (opt_coverage (idris_options i))
721setCoverage :: Bool -> Idris ()
722setCoverage t = do i <- getIState
723 let opts = idris_options i
724 let opt' = opts { opt_coverage = t }
725 putIState $ i { idris_options = opt' }
727setIBCSubDir :: FilePath -> Idris ()
728setIBCSubDir fp = do i <- getIState
729 let opts = idris_options i
730 let opt' = opts { opt_ibcsubdir = fp }
731 putIState $ i { idris_options = opt' }
733valIBCSubDir :: IState -> Idris FilePath
734valIBCSubDir i = return (opt_ibcsubdir (idris_options i))
736addImportDir :: FilePath -> Idris ()
737addImportDir fp = do i <- getIState
738 let opts = idris_options i
739 let opt' = opts { opt_importdirs = fp : opt_importdirs opts }
740 putIState $ i { idris_options = opt' }
742setImportDirs :: [FilePath] -> Idris ()
743setImportDirs fps = do i <- getIState
744 let opts = idris_options i
745 let opt' = opts { opt_importdirs = fps }
746 putIState $ i { idris_options = opt' }
748allImportDirs :: Idris [FilePath]
749allImportDirs = do i <- getIState
750 let optdirs = opt_importdirs (idris_options i)
751 return ("." : reverse optdirs)
753colourise :: Idris Bool
754colourise = do i <- getIState
755 return $ idris_colourRepl i
757setColourise :: Bool -> Idris ()
758setColourise b = do i <- getIState
759 putIState $ i { idris_colourRepl = b }
761setOutH :: Handle -> Idris ()
762setOutH h = do i <- getIState
763 putIState $ i { idris_outh = h }
766impShow = do i <- getIState
767 return (opt_showimp (idris_options i))
769setImpShow :: Bool -> Idris ()
770setImpShow t = do i <- getIState
771 let opts = idris_options i
772 let opt' = opts { opt_showimp = t }
773 putIState $ i { idris_options = opt' }
775setColour :: ColourType -> IdrisColour -> Idris ()
776setColour ct c = do i <- getIState
777 let newTheme = setColour' ct c (idris_colourTheme i)
778 putIState $ i { idris_colourTheme = newTheme }
779 where setColour' KeywordColour c t = t { keywordColour = c }
780 setColour' BoundVarColour c t = t { boundVarColour = c }
781 setColour' ImplicitColour c t = t { implicitColour = c }
782 setColour' FunctionColour c t = t { functionColour = c }
783 setColour' TypeColour c t = t { typeColour = c }
784 setColour' DataColour c t = t { dataColour = c }
785 setColour' PromptColour c t = t { promptColour = c }
786 setColour' PostulateColour c t = t { postulateColour = c }
788logLvl :: Int -> String -> Idris ()
789logLvl l str = do i <- getIState
790 let lvl = opt_logLevel (idris_options i)
792 case idris_outputmode i of
793 RawOutput -> do runIO $ putStrLn str
795 do let good = SexpList [IntegerAtom (toInteger l), toSExp str]
796 runIO $ putStrLn $ convSExp "log" good n
798cmdOptType :: Opt -> Idris Bool
799cmdOptType x = do i <- getIState
800 return $ x `elem` opt_cmdline (idris_options i)
802iLOG :: String -> Idris ()
805noErrors :: Idris Bool
806noErrors = do i <- getIState
808 Nothing -> return True
811setTypeCase :: Bool -> Idris ()
812setTypeCase t = do i <- getIState
813 let opts = idris_options i
814 let opt' = opts { opt_typecase = t }
815 putIState $ i { idris_options = opt' }
818-- Dealing with parameters
820expandParams :: (Name -> Name) -> [(Name, PTerm)] ->
821 [Name] -> -- all names
822 [Name] -> -- names with no declaration
824expandParams dec ps ns infs tm = en tm
826 -- if we shadow a name (say in a lambda binding) that is used in a call to
827 -- a lifted function, we need access to both names - once in the scope of the
828 -- binding and once to call the lifted functions. So we'll explicitly shadow
829 -- it. (Yes, it's a hack. The alternative would be to resolve names earlier
832 mkShadow (UN n) = MN 0 n
833 mkShadow (MN i n) = MN (i+1) n
834 mkShadow (NS x s) = NS (mkShadow x) s
837 | n `elem` (map fst ps ++ ns)
838 = let n' = mkShadow n in
839 PLam n' (en t) (en (shadow n n' s))
840 | otherwise = PLam n (en t) (en s)
842 | n `elem` (map fst ps ++ ns)
843 = let n' = mkShadow n in -- TODO THINK SHADOWING TacImp?
844 PPi (enTacImp p) n' (en t) (en (shadow n n' s))
845 | otherwise = PPi (enTacImp p) n (en t) (en s)
847 | n `elem` (map fst ps ++ ns)
848 = let n' = mkShadow n in
849 PLet n' (en ty) (en v) (en (shadow n n' s))
850 | otherwise = PLet n (en ty) (en v) (en s)
851 -- FIXME: Should only do this in a type signature!
852 en (PDPair f p (PRef f' n) t r)
853 | n `elem` (map fst ps ++ ns) && t /= Placeholder
854 = let n' = mkShadow n in
855 PDPair f p (PRef f' n') (en t) (en (shadow n n' r))
856 en (PEq f lt rt l r) = PEq f (en lt) (en rt) (en l) (en r)
857 en (PRewrite f l r g) = PRewrite f (en l) (en r) (fmap en g)
858 en (PTyped l r) = PTyped (en l) (en r)
859 en (PPair f p l r) = PPair f p (en l) (en r)
860 en (PDPair f p l t r) = PDPair f p (en l) (en t) (en r)
861 en (PAlternative a as) = PAlternative a (map en as)
862 en (PHidden t) = PHidden (en t)
863 en (PUnifyLog t) = PUnifyLog (en t)
864 en (PDisamb ds t) = PDisamb ds (en t)
865 en (PNoImplicits t) = PNoImplicits (en t)
866 en (PDoBlock ds) = PDoBlock (map (fmap en) ds)
867 en (PProof ts) = PProof (map (fmap en) ts)
868 en (PTactics ts) = PTactics (map (fmap en) ts)
871 | n `nselem` ns = PQuote (Var (dec n))
872 en (PApp fc (PInferRef fc' n) as)
873 | n `nselem` ns = PApp fc (PInferRef fc' (dec n))
874 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
875 en (PApp fc (PRef fc' n) as)
876 | n `elem` infs = PApp fc (PInferRef fc' (dec n))
877 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
878 | n `nselem` ns = PApp fc (PRef fc' (dec n))
879 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
880 en (PAppBind fc (PRef fc' n) as)
881 | n `elem` infs = PAppBind fc (PInferRef fc' (dec n))
882 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
883 | n `nselem` ns = PAppBind fc (PRef fc' (dec n))
884 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
886 | n `elem` infs = PApp fc (PInferRef fc (dec n))
887 (map (pexp . (PRef fc)) (map fst ps))
888 | n `nselem` ns = PApp fc (PRef fc (dec n))
889 (map (pexp . (PRef fc)) (map fst ps))
891 | n `nselem` ns = PApp fc (PInferRef fc (dec n))
892 (map (pexp . (PRef fc)) (map fst ps))
893 en (PApp fc f as) = PApp fc (en f) (map (fmap en) as)
894 en (PAppBind fc f as) = PAppBind fc (en f) (map (fmap en) as)
895 en (PCase fc c os) = PCase fc (en c) (map (pmap en) os)
899 nselem x (y : xs) | nseq x y = True
900 | otherwise = nselem x xs
902 nseq x y = nsroot x == nsroot y
904 enTacImp (TacImp aos st scr) = TacImp aos st (en scr)
905 enTacImp other = other
907expandParamsD :: Bool -> -- True = RHS only
909 (Name -> Name) -> [(Name, PTerm)] -> [Name] -> PDecl -> PDecl
910expandParamsD rhsonly ist dec ps ns (PTy doc argdocs syn fc o n ty)
911 = if n `elem` ns && (not rhsonly)
912 then -- trace (show (n, expandParams dec ps ns ty)) $
913 PTy doc argdocs syn fc o (dec n) (piBindp expl_param ps (expandParams dec ps ns [] ty))
914 else --trace (show (n, expandParams dec ps ns ty)) $
915 PTy doc argdocs syn fc o n (expandParams dec ps ns [] ty)
916expandParamsD rhsonly ist dec ps ns (PPostulate doc syn fc o n ty)
917 = if n `elem` ns && (not rhsonly)
918 then -- trace (show (n, expandParams dec ps ns ty)) $
919 PPostulate doc syn fc o (dec n) (piBind ps
920 (expandParams dec ps ns [] ty))
921 else --trace (show (n, expandParams dec ps ns ty)) $
922 PPostulate doc syn fc o n (expandParams dec ps ns [] ty)
923expandParamsD rhsonly ist dec ps ns (PClauses fc opts n cs)
924 = let n' = if n `elem` ns then dec n else n in
925 PClauses fc opts n' (map expandParamsC cs)
927 expandParamsC (PClause fc n lhs ws rhs ds)
928 = let -- ps' = updateps True (namesIn ist rhs) (zip ps [0..])
929 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
930 lhs' = if rhsonly then lhs else (expandParams dec ps'' ns [] lhs)
931 n' = if n `elem` ns then dec n else n
932 -- names bound on the lhs should not be expanded on the rhs
933 ns' = removeBound lhs ns in
935 (map (expandParams dec ps'' ns' []) ws)
936 (expandParams dec ps'' ns' [] rhs)
937 (map (expandParamsD True ist dec ps'' ns') ds)
938 expandParamsC (PWith fc n lhs ws wval ds)
939 = let -- ps' = updateps True (namesIn ist wval) (zip ps [0..])
940 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
941 lhs' = if rhsonly then lhs else (expandParams dec ps'' ns [] lhs)
942 n' = if n `elem` ns then dec n else n
943 ns' = removeBound lhs ns in
945 (map (expandParams dec ps'' ns' []) ws)
946 (expandParams dec ps'' ns' [] wval)
947 (map (expandParamsD rhsonly ist dec ps'' ns') ds)
948 updateps yn nm [] = []
949 updateps yn nm (((a, t), i):as)
950 | (a `elem` nm) == yn = (a, t) : updateps yn nm as
951 | otherwise = (sMN i ('_' : show n ++ "_u"), t) : updateps yn nm as
953 removeBound lhs ns = ns \\ nub (bnames lhs)
955 bnames (PRef _ n) = [n]
956 bnames (PApp _ _ args) = concatMap bnames (map getTm args)
957 bnames (PPair _ _ l r) = bnames l ++ bnames r
958 bnames (PDPair _ _ l Placeholder r) = bnames l ++ bnames r
961-- | Expands parameters defined in parameter and where blocks inside of declarations
962expandParamsD rhs ist dec ps ns (PData doc argDocs syn fc co pd)
963 = PData doc argDocs syn fc co (expandPData pd)
965 -- just do the type decl, leave constructors alone (parameters will be
967 expandPData (PDatadecl n ty cons)
969 then PDatadecl (dec n) (piBind ps (expandParams dec ps ns [] ty))
971 else PDatadecl n (expandParams dec ps ns [] ty) (map econ cons)
972 econ (doc, argDocs, n, t, fc, fs)
973 = (doc, argDocs, dec n, piBindp expl ps (expandParams dec ps ns [] t), fc, fs)
974expandParamsD rhs ist dec ps ns (PRecord doc syn fc tn tty opts cdoc cn cty)
976 then PRecord doc syn fc (dec tn) (piBind ps (expandParams dec ps ns [] tty))
977 opts cdoc (dec cn) conty
978 else PRecord doc syn fc (dec tn) (expandParams dec ps ns [] tty)
979 opts cdoc (dec cn) conty
980 where conty = piBindp expl ps (expandParams dec ps ns [] cty)
981expandParamsD rhs ist dec ps ns (PParams f params pds)
982 = PParams f (ps ++ map (mapsnd (expandParams dec ps ns [])) params)
983 (map (expandParamsD True ist dec ps ns) pds)
984-- (map (expandParamsD ist dec ps ns) pds)
985expandParamsD rhs ist dec ps ns (PMutual f pds)
986 = PMutual f (map (expandParamsD rhs ist dec ps ns) pds)
987expandParamsD rhs ist dec ps ns (PClass doc info f cs n params pDocs decls)
989 (map (expandParams dec ps ns []) cs)
991 (map (mapsnd (expandParams dec ps ns [])) params)
993 (map (expandParamsD rhs ist dec ps ns) decls)
994expandParamsD rhs ist dec ps ns (PInstance info f cs n params ty cn decls)
996 (map (expandParams dec ps ns []) cs)
998 (map (expandParams dec ps ns []) params)
999 (expandParams dec ps ns [] ty)
1001 (map (expandParamsD rhs ist dec ps ns) decls)
1002expandParamsD rhs ist dec ps ns d = d
1004mapsnd f (x, t) = (x, f t)
1006-- Calculate a priority for a type, for deciding elaboration order
1007-- * if it's just a type variable or concrete type, do it early (0)
1008-- * if there's only type variables and injective constructors, do it next (1)
1009-- * if there's a function type, next (2)
1010-- * finally, everything else (3)
1012getPriority :: IState -> PTerm -> Int
1013getPriority i tm = 1 -- pri tm
1016 case lookupP n (tt_ctxt i) of
1017 ((P (DCon _ _) _ _):_) -> 1
1018 ((P (TCon _ _) _ _):_) -> 1
1019 ((P Ref _ _):_) -> 1
1020 [] -> 0 -- must be locally bound, if it's not an error...
1021 pri (PPi _ _ x y) = max 5 (max (pri x) (pri y))
1025 pri (PEq _ _ _ l r) = max 1 (max (pri l) (pri r))
1026 pri (PRewrite _ l r _) = max 1 (max (pri l) (pri r))
1027 pri (PApp _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.getTm) as)))
1028 pri (PAppBind _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.getTm) as)))
1029 pri (PCase _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.snd) as)))
1030 pri (PTyped l r) = pri l
1031 pri (PPair _ _ l r) = max 1 (max (pri l) (pri r))
1032 pri (PDPair _ _ l t r) = max 1 (max (pri l) (max (pri t) (pri r)))
1033 pri (PAlternative a as) = maximum (map pri as)
1034 pri (PConstant _) = 0
1039addStatics :: Name -> Term -> PTerm -> Idris ()
1040addStatics n tm ptm =
1041 do let (statics, dynamics) = initStatics tm ptm
1042 let stnames = nub $ concatMap freeArgNames (map snd statics)
1043 let dnames = nub $ concatMap freeArgNames (map snd dynamics)
1044 -- also get the arguments which are 'uniquely inferrable' from
1045 -- statics (see sec 4.2 of "Scrapping Your Inefficient Engine")
1046 let statics' = nub $ map fst statics ++
1047 filter (\x -> not (elem x dnames)) stnames
1048 let stpos = staticList statics' tm
1050 when (not (null statics)) $
1051 logLvl 5 $ show n ++ " " ++ show statics' ++ "\n" ++ show dynamics
1052 ++ "\n" ++ show stnames ++ "\n" ++ show dnames
1053 putIState $ i { idris_statics = addDef n stpos (idris_statics i) }
1054 addIBC (IBCStatic n)
1056 initStatics (Bind n (Pi ty) sc) (PPi p _ _ s)
1057 = let (static, dynamic) = initStatics (instantiate (P Bound n ty) sc) s in
1058 if pstatic p == Static then ((n, ty) : static, dynamic)
1059 else if (not (searchArg p))
1060 then (static, (n, ty) : dynamic)
1061 else (static, dynamic)
1062 initStatics t pt = ([], [])
1064 freeArgNames (Bind n (Pi ty) sc)
1065 = nub $ freeArgNames ty
1066 freeArgNames tm = let (_, args) = unApply tm in
1067 concatMap freeNames args
1069 -- if a name appears in a type class or tactic implicit index, it doesn't
1070 -- affect its 'uniquely inferrable' from a static status since these are
1071 -- resolved by searching.
1072 searchArg (Constraint _ _) = True
1073 searchArg (TacImp _ _ _) = True
1076 staticList sts (Bind n (Pi _) sc) = (n `elem` sts) : staticList sts sc
1079-- Dealing with implicit arguments
1081-- Add some bound implicits to the using block if they aren't there already
1083addToUsing :: [Using] -> [(Name, PTerm)] -> [Using]
1084addToUsing us [] = us
1085addToUsing us ((n, t) : ns)
1086 | n `notElem` mapMaybe impName us = addToUsing (us ++ [UImplicit n t]) ns
1087 | otherwise = addToUsing us ns
1088 where impName (UImplicit n _) = Just n
1091-- Add constraint bindings from using block
1093addUsingConstraints :: SyntaxInfo -> FC -> PTerm -> Idris PTerm
1094addUsingConstraints syn fc t
1096 let ns = namesIn [] ist t
1097 let cs = getConstraints t -- check declared constraints
1098 let addconsts = uconsts \\ cs
1099 return (doAdd addconsts ns t)
1100 where uconsts = filter uconst (using syn)
1101 uconst (UConstraint _ _) = True
1105 -- if all of args in ns, then add it
1106 doAdd (UConstraint c args : cs) ns t
1107 | all (\n -> elem n ns) args
1108 = PPi (Constraint [] Dynamic) (sMN 0 "cu")
1109 (mkConst c args) (doAdd cs ns t)
1110 | otherwise = doAdd cs ns t
1112 mkConst c args = PApp fc (PRef fc c)
1113 (map (\n -> PExp 0 [] (sMN 0 "carg") (PRef fc n)) args)
1115 getConstraints (PPi (Constraint _ _) _ c sc)
1116 = getcapp c ++ getConstraints sc
1117 getConstraints (PPi _ _ c sc) = getConstraints sc
1118 getConstraints _ = []
1120 getcapp (PApp _ (PRef _ c) args)
1121 = do ns <- mapM getName args
1122 return (UConstraint c ns)
1125 getName (PExp _ _ _ (PRef _ n)) = return n
1128-- Add implicit bindings from using block, and bind any missing names
1129addUsingImpls :: SyntaxInfo -> Name -> FC -> PTerm -> Idris PTerm
1130addUsingImpls syn n fc t
1131 = do ist <- getIState
1132 let ns = implicitNamesIn (map iname uimpls) ist t
1133 let badnames = filter (\n -> not (implicitable n) &&
1134 n `notElem` (map iname uimpls)) ns
1135 when (not (null badnames)) $
1136 throwError (At fc (Elaborating "type of " n
1137 (NoSuchVariable (head badnames))))
1138 let cs = getArgnames t -- get already bound names
1139 let addimpls = filter (\n -> iname n `notElem` cs) uimpls
1140 -- if all names in the arguments of addconsts appear in ns,
1141 -- add the constraint implicitly
1142 return (bindFree ns (doAdd addimpls ns t))
1143 where uimpls = filter uimpl (using syn)
1144 uimpl (UImplicit _ _) = True
1147 iname (UImplicit n _) = n
1148 iname (UConstraint _ _) = error "Can't happen addUsingImpls"
1151 -- if all of args in ns, then add it
1152 doAdd (UImplicit n ty : cs) ns t
1154 = PPi (Imp [] Dynamic False) n ty (doAdd cs ns t)
1155 | otherwise = doAdd cs ns t
1157 -- bind the free names which weren't in the using block
1160 | elem n (map iname uimpls) = bindFree ns tm
1162 = PPi (Imp [] Dynamic False) n Placeholder (bindFree ns tm)
1164 getArgnames (PPi _ n c sc)
1165 = n : getArgnames sc
1168-- Given the original type and the elaborated type, return the implicitness
1169-- status of each pi-bound argument, and whether it's inaccessible (True) or not.
1171getUnboundImplicits :: IState -> Type -> PTerm -> [(Bool, PArg)]
1172getUnboundImplicits i (Bind n (Pi t) sc) (PPi p n' t' sc')
1173 | n == n' = argInfo n p : getUnboundImplicits i sc sc'
1175 argInfo n (Imp opt _ _) = (True, PImp (getPriority i t') True opt n t')
1176 argInfo n (Exp opt _ _) = (InaccessibleArg `elem` opt,
1177 PExp (getPriority i t') opt n t')
1178 argInfo n (Constraint opt _) = (InaccessibleArg `elem` opt,
1179 PConstraint 10 opt n t')
1180 argInfo n (TacImp opt _ scr) = (InaccessibleArg `elem` opt,
1181 PTacImplicit 10 opt n scr t')
1182getUnboundImplicits i (Bind n (Pi t) sc) tm
1183 = impBind n t : getUnboundImplicits i sc tm
1185 impBind n t = (True, PImp 1 True [] n Placeholder)
1186getUnboundImplicits i sc tm = []
1188-- Add implicit Pi bindings for any names in the term which appear in an
1189-- argument position.
1191-- This has become a right mess already. Better redo it some time...
1192-- TODO: This is obsoleted by the new way of elaborating types, but there's still
1193-- a couple of places which use it. Clean them up!
1194implicit :: ElabInfo -> SyntaxInfo -> Name -> PTerm -> Idris PTerm
1195implicit info syn n ptm = implicit' info syn [] n ptm
1197implicit' :: ElabInfo -> SyntaxInfo -> [Name] -> Name -> PTerm -> Idris PTerm
1198implicit' info syn ignore n ptm
1200 let (tm', impdata) = implicitise syn ignore i ptm
1201 defaultArgCheck (eInfoNames info ++ M.keys (idris_implicits i)) impdata
1202-- let (tm'', spos) = findStatics i tm'
1203 putIState $ i { idris_implicits = addDef n impdata (idris_implicits i) }
1205 logLvl 5 ("Implicit " ++ show n ++ " " ++ show impdata)
1207-- putIState $ i { idris_statics = addDef n spos (idris_statics i) }
1210 -- Detect unknown names in default arguments and throw error if found.
1211 defaultArgCheck :: [Name] -> [PArg] -> Idris ()
1212 defaultArgCheck knowns params = foldM_ notFoundInDefault knowns params
1214 notFoundInDefault :: [Name] -> PArg -> Idris [Name]
1215 notFoundInDefault kns (PTacImplicit _ _ n script _)
1217 case notFound kns (namesIn [] i script) of
1218 Nothing -> return (n:kns)
1219 Just name -> throwError (NoSuchVariable name)
1220 notFoundInDefault kns p = return ((pname p):kns)
1222 notFound :: [Name] -> [Name] -> Maybe Name
1223 notFound kns [] = Nothing
1224 notFound kns (SN (WhereN _ _ _) : ns) = notFound kns ns -- Known already
1225 notFound kns (n:ns) = if elem n kns then notFound kns ns else Just n
1227implicitise :: SyntaxInfo -> [Name] -> IState -> PTerm -> (PTerm, [PArg])
1228implicitise syn ignore ist tm = -- trace ("INCOMING " ++ showImp True tm) $
1229 let (declimps, ns') = execState (imps True [] tm) ([], [])
1230 ns = filter (\n -> implicitable n || elem n (map fst uvars)) $
1231 ns' \\ (map fst pvars ++ no_imp syn ++ ignore)
1232 nsOrder = filter (not . inUsing) ns ++ filter inUsing ns in
1234 then (tm, reverse declimps)
1235 else implicitise syn ignore ist (pibind uvars nsOrder tm)
1237 uvars = map ipair (filter uimplicit (using syn))
1238 pvars = syn_params syn
1240 inUsing n = n `elem` map fst uvars
1242 ipair (UImplicit x y) = (x, y)
1243 uimplicit (UImplicit _ _) = True
1246 dropAll (x:xs) ys | x `elem` ys = dropAll xs ys
1247 | otherwise = x : dropAll xs ys
1250 -- Find names in argument position in a type, suitable for implicit
1252 -- Not the function position, but do everything else...
1253 implNamesIn uv (PApp fc f args) = concatMap (implNamesIn uv) (map getTm args)
1254 implNamesIn uv t = namesIn uv ist t
1256 imps top env (PApp _ f as)
1257 = do (decls, ns) <- get
1258 let isn = concatMap (namesIn uvars ist) (map getTm as)
1259 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1260 imps top env (PPi (Imp l _ _) n ty sc)
1261 = do let isn = nub (implNamesIn uvars ty) `dropAll` [n]
1263 put (PImp (getPriority ist ty) True l n Placeholder : decls,
1264 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1265 imps True (n:env) sc
1266 imps top env (PPi (Exp l _ _) n ty sc)
1267 = do let isn = nub (implNamesIn uvars ty ++ case sc of
1268 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
1270 (decls, ns) <- get -- ignore decls in HO types
1271 put (PExp (getPriority ist ty) l n Placeholder : decls,
1272 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1273 imps True (n:env) sc
1274 imps top env (PPi (Constraint l _) n ty sc)
1275 = do let isn = nub (implNamesIn uvars ty ++ case sc of
1276 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
1278 (decls, ns) <- get -- ignore decls in HO types
1279 put (PConstraint 10 l n Placeholder : decls,
1280 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1281 imps True (n:env) sc
1282 imps top env (PPi (TacImp l _ scr) n ty sc)
1283 = do let isn = nub (implNamesIn uvars ty ++ case sc of
1284 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
1286 (decls, ns) <- get -- ignore decls in HO types
1287 put (PTacImplicit 10 l n scr Placeholder : decls,
1288 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1289 imps True (n:env) sc
1290 imps top env (PEq _ _ _ l r)
1291 = do (decls, ns) <- get
1292 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1293 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1294 imps top env (PRewrite _ l r _)
1295 = do (decls, ns) <- get
1296 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1297 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1298 imps top env (PTyped l r)
1300 imps top env (PPair _ _ l r)
1301 = do (decls, ns) <- get
1302 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1303 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1304 imps top env (PDPair _ _ (PRef _ n) t r)
1305 = do (decls, ns) <- get
1306 let isn = nub (namesIn uvars ist t ++ namesIn uvars ist r) \\ [n]
1307 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
1308 imps top env (PDPair _ _ l t r)
1309 = do (decls, ns) <- get
1310 let isn = namesIn uvars ist l ++ namesIn uvars ist t ++
1312 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
1313 imps top env (PAlternative a as)
1314 = do (decls, ns) <- get
1315 let isn = concatMap (namesIn uvars ist) as
1316 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1317 imps top env (PLam n ty sc)
1318 = do imps False env ty
1319 imps False (n:env) sc
1320 imps top env (PHidden tm) = imps False env tm
1321 imps top env (PUnifyLog tm) = imps False env tm
1322 imps top env (PNoImplicits tm) = imps False env tm
1323 imps top env _ = return ()
1325 pibind using [] sc = sc
1326 pibind using (n:ns) sc
1327 = case lookup n using of
1328 Just ty -> PPi (Imp [] Dynamic False) n ty (pibind using ns sc)
1329 Nothing -> PPi (Imp [] Dynamic False) n Placeholder
1330 (pibind using ns sc)
1332-- Add implicit arguments in function calls
1333addImplPat :: IState -> PTerm -> PTerm
1334addImplPat = addImpl' True [] []
1336addImplBound :: IState -> [Name] -> PTerm -> PTerm
1337addImplBound ist ns = addImpl' False ns [] ist
1339addImplBoundInf :: IState -> [Name] -> [Name] -> PTerm -> PTerm
1340addImplBoundInf ist ns inf = addImpl' False ns inf ist
1342-- | Add the implicit arguments to applications in the term
1343addImpl :: IState -> PTerm -> PTerm
1344addImpl = addImpl' False [] []
1346-- TODO: in patterns, don't add implicits to function names guarded by constructors
1347-- and *not* inside a PHidden
1349addImpl' :: Bool -> [Name] -> [Name] -> IState -> PTerm -> PTerm
1350addImpl' inpat env infns ist ptm
1351 = mkUniqueNames env (ai False (zip env (repeat Nothing)) [] ptm)
1353 ai :: Bool -> [(Name, Maybe PTerm)] -> [[T.Text]] -> PTerm -> PTerm
1354 ai qq env ds (PRef fc f)
1355 | f `elem` infns = PInferRef fc f
1356 | not (f `elem` map fst env) = handleErr $ aiFn inpat inpat qq ist fc f ds []
1357 ai qq env ds (PHidden (PRef fc f))
1358 | not (f `elem` map fst env) = handleErr $ aiFn inpat False qq ist fc f ds []
1359 ai qq env ds (PEq fc lt rt l r)
1360 = let lt' = ai qq env ds lt
1361 rt' = ai qq env ds rt
1363 r' = ai qq env ds r in
1364 PEq fc lt' rt' l' r'
1365 ai qq env ds (PRewrite fc l r g)
1366 = let l' = ai qq env ds l
1368 g' = fmap (ai qq env ds) g in
1369 PRewrite fc l' r' g'
1370 ai qq env ds (PTyped l r)
1371 = let l' = ai qq env ds l
1372 r' = ai qq env ds r in
1374 ai qq env ds (PPair fc p l r)
1375 = let l' = ai qq env ds l
1376 r' = ai qq env ds r in
1378 ai qq env ds (PDPair fc p l t r)
1379 = let l' = ai qq env ds l
1381 r' = ai qq env ds r in
1382 PDPair fc p l' t' r'
1383 ai qq env ds (PAlternative a as)
1384 = let as' = map (ai qq env ds) as in
1386 ai qq env _ (PDisamb ds' as) = ai qq env ds' as
1387 ai qq env ds (PApp fc (PInferRef _ f) as)
1388 = let as' = map (fmap (ai qq env ds)) as in
1389 PApp fc (PInferRef fc f) as'
1390 ai qq env ds (PApp fc ftm@(PRef _ f) as)
1391 | f `elem` infns = ai qq env ds (PApp fc (PInferRef fc f) as)
1392 | not (f `elem` map fst env)
1393 = let as' = map (fmap (ai qq env ds)) as in
1394 handleErr $ aiFn inpat False qq ist fc f ds as'
1395 | Just (Just ty) <- lookup f env =
1396 let as' = map (fmap (ai qq env ds)) as
1397 arity = getPArity ty in
1398 mkPApp fc arity ftm as'
1399 ai qq env ds (PApp fc f as)
1400 = let f' = ai qq env ds f
1401 as' = map (fmap (ai qq env ds)) as in
1403 ai qq env ds (PCase fc c os)
1404 = let c' = ai qq env ds c in
1405 -- leave os alone, because they get lifted into a new pattern match
1406 -- definition which is passed through addImpl again with more scope
1409 ai qq env ds (PLam n ty sc)
1410 = let ty' = ai qq env ds ty
1411 sc' = ai qq ((n, Just ty):env) ds sc in
1413 ai qq env ds (PLet n ty val sc)
1414 = let ty' = ai qq env ds ty
1415 val' = ai qq env ds val
1416 sc' = ai qq ((n, Just ty):env) ds sc in
1418 ai qq env ds (PPi p n ty sc)
1419 = let ty' = ai qq env ds ty
1420 sc' = ai qq ((n, Just ty):env) ds sc in
1422 ai qq env ds (PGoal fc r n sc)
1423 = let r' = ai qq env ds r
1424 sc' = ai qq ((n, Nothing):env) ds sc in
1426 ai qq env ds (PHidden tm) = PHidden (ai qq env ds tm)
1427 -- Don't do PProof or PTactics since implicits get added when scope is
1428 -- properly known in ElabTerm.runTac
1429 ai qq env ds (PRefl fc tm) = PRefl fc (ai qq env ds tm)
1430 ai qq env ds (PUnifyLog tm) = PUnifyLog (ai qq env ds tm)
1431 ai qq env ds (PNoImplicits tm) = PNoImplicits (ai qq env ds tm)
1432 ai qq env ds (PQuasiquote tm g) = PQuasiquote (ai True env ds tm)
1433 (fmap (ai True env ds) g)
1434 ai qq env ds (PUnquote tm) = PUnquote (ai False env ds tm)
1435 ai qq env ds tm = tm
1437 handleErr (Left err) = PElabError err
1438 handleErr (Right x) = x
1440-- if in a pattern, and there are no arguments, and there's no possible
1441-- names with zero explicit arguments, don't add implicits.
1443aiFn :: Bool -> Bool -> Bool -> IState -> FC -> Name -> [[T.Text]] -> [PArg] -> Either Err PTerm
1444aiFn inpat True qq ist fc f ds []
1445 = case lookupDef f (tt_ctxt ist) of
1446 [] -> Right $ PPatvar fc f
1447 alts -> let ialts = lookupCtxtName f (idris_implicits ist) in
1448 -- trace (show f ++ " " ++ show (fc, any (all imp) ialts, ialts, any constructor alts)) $
1449 if (not (vname f) || tcname f
1450 || any (conCaf (tt_ctxt ist)) ialts)
1451-- any constructor alts || any allImp ialts))
1452 then aiFn inpat False qq ist fc f ds [] -- use it as a constructor
1453 else Right $ PPatvar fc f
1454 where imp (PExp _ _ _ _) = False
1457 allImp xs = all imp xs
1458 constructor (TyDecl (DCon _ _) _) = True
1459 constructor _ = False
1461 conCaf ctxt (n, cia) = (isDConName n ctxt || (qq && isTConName n ctxt)) && allImp cia
1463 vname (UN n) = True -- non qualified
1466aiFn inpat expat qq ist fc f ds as
1467 | f `elem` primNames = Right $ PApp fc (PRef fc f) as
1468aiFn inpat expat qq ist fc f ds as
1469 -- This is where namespaces get resolved by adding PAlternative
1470 = do let ns = lookupCtxtName f (idris_implicits ist)
1471 let nh = filter (\(n, _) -> notHidden n) ns
1472 let ns' = case trimAlts ds nh of
1476 [(f',ns)] -> Right $ mkPApp fc (length ns) (PRef fc f') (insertImpl ns as)
1477 [] -> if f `elem` (map fst (idris_metavars ist))
1478 then Right $ PApp fc (PRef fc f) as
1479 else Right $ mkPApp fc (length as) (PRef fc f) as
1482 map (\(f', ns) -> mkPApp fc (length ns) (PRef fc f')
1483 (insertImpl ns as)) alts
1485 trimAlts [] alts = alts
1487 = filter (\(x, _) -> any (\d -> d `isPrefixOf` nspace x) ns) alts
1492 notHidden n = case getAccessibility n of
1497 = case lookupDefAcc n False (tt_ctxt ist) of
1501 insertImpl :: [PArg] -> [PArg] -> [PArg]
1502 insertImpl ps as = insImpAcc M.empty ps (filter exp as) (filter (not.exp) as)
1504 exp (PExp _ _ _ _) = True
1505 exp (PConstraint _ _ _ _) = True
1508 insImpAcc :: M.Map Name PTerm -- accumulated param names & arg terms
1509 -> [PArg] -- parameters
1510 -> [PArg] -- explicit arguments
1511 -> [PArg] -- implicits given
1513 insImpAcc pnas (PExp p l n ty : ps) (PExp _ _ _ tm : given) imps =
1514 PExp p l n tm : insImpAcc (M.insert n tm pnas) ps given imps
1515 insImpAcc pnas (PConstraint p l n ty : ps) (PConstraint _ _ _ tm : given) imps =
1516 PConstraint p l n tm : insImpAcc (M.insert n tm pnas) ps given imps
1517 insImpAcc pnas (PConstraint p l n ty : ps) given imps =
1518 let rtc = PResolveTC fc in
1519 PConstraint p l n rtc : insImpAcc (M.insert n rtc pnas) ps given imps
1520 insImpAcc pnas (PImp p _ l n ty : ps) given imps =
1521 case find n imps [] of
1523 PImp p False l n tm : insImpAcc (M.insert n tm pnas) ps given imps'
1525 PImp p True l n Placeholder :
1526 insImpAcc (M.insert n Placeholder pnas) ps given imps
1527 insImpAcc pnas (PTacImplicit p l n sc' ty : ps) given imps =
1528 let sc = addImpl ist (substMatches (M.toList pnas) sc') in
1529 case find n imps [] of
1531 PTacImplicit p l n sc tm :
1532 insImpAcc (M.insert n tm pnas) ps given imps'
1535 then PTacImplicit p l n sc Placeholder :
1536 insImpAcc (M.insert n Placeholder pnas) ps given imps
1537 else PTacImplicit p l n sc sc :
1538 insImpAcc (M.insert n sc pnas) ps given imps
1539 insImpAcc _ expected [] imps = imps -- so that unused implicits give error
1540 -- TODO: report here, and prune alternatives
1541 insImpAcc _ _ given imps = given ++ imps
1543 find n [] acc = Nothing
1544 find n (PImp _ _ _ n' t : gs) acc
1545 | n == n' = Just (t, reverse acc ++ gs)
1546 find n (PTacImplicit _ _ n' _ t : gs) acc
1547 | n == n' = Just (t, reverse acc ++ gs)
1548 find n (g : gs) acc = find n gs (g : acc)
1550-- replace non-linear occurrences with _
1551-- ASSUMPTION: This is called before adding 'alternatives' because otherwise
1552-- it is hard to get right!
1554stripLinear :: IState -> PTerm -> PTerm
1555stripLinear i tm = evalState (sl tm) [] where
1556 sl :: PTerm -> State [Name] PTerm
1558 | (_:_) <- lookupTy f (tt_ctxt i)
1559 = return $ PRef fc f
1560 | otherwise = do ns <- get
1562 then return Placeholder
1563 else do put (f : ns)
1568 then return Placeholder
1569 else do put (f : ns)
1570 return (PPatvar fc f)
1571 sl t@(PAlternative _ (a : as)) = do sl a
1573 sl (PApp fc fn args) = do -- Just the args, fn isn't matchable as a var
1574 args' <- mapM slA args
1575 return $ PApp fc fn args'
1576 where slA (PImp p m l n t) = do t' <- sl t
1577 return $ PImp p m l n t'
1578 slA (PExp p l n t) = do t' <- sl t
1579 return $ PExp p l n t'
1580 slA (PConstraint p l n t)
1582 return $ PConstraint p l n t'
1583 slA (PTacImplicit p l n sc t)
1585 return $ PTacImplicit p l n sc t'
1588-- Remove functions which aren't applied to anything, which must then
1589-- be resolved by unification. Assume names resolved and alternatives
1590-- filled in (so no ambiguity).
1592stripUnmatchable :: IState -> PTerm -> PTerm
1593stripUnmatchable i (PApp fc fn args) = PApp fc fn (fmap (fmap su) args) where
1594 su :: PTerm -> PTerm
1596 | (Bind n (Pi t) sc :_) <- lookupTy f (tt_ctxt i)
1598 su (PApp fc fn args)
1599 = PApp fc fn (fmap (fmap su) args)
1600 su (PAlternative b alts)
1601 = let alts' = filter (/= Placeholder) (map su alts) in
1602 if null alts' then Placeholder
1603 else PAlternative b alts'
1604 su (PPair fc p l r) = PPair fc p (su l) (su r)
1605 su (PDPair fc p l t r) = PDPair fc p (su l) (su t) (su r)
1607stripUnmatchable i tm = tm
1610mkPApp fc a f as = let rest = drop a as in
1611 appRest fc (PApp fc f (take a as)) rest
1614 appRest fc f (a : as) = appRest fc (PApp fc f [a]) as
1616-- Find 'static' argument positions
1617-- (the declared ones, plus any names in argument position in the declared
1619-- FIXME: It's possible that this really has to happen after elaboration
1621findStatics :: IState -> PTerm -> (PTerm, [Bool])
1622findStatics ist tm = trace (show tm) $
1623 let (ns, ss) = fs tm in
1624 runState (pos ns ss tm) []
1625 where fs (PPi p n t sc)
1626 | Static <- pstatic p
1627 = let (ns, ss) = fs sc in
1628 (namesIn [] ist t : ns, n : ss)
1629 | otherwise = let (ns, ss) = fs sc in
1633 inOne n ns = length (filter id (map (elem n) ns)) == 1
1635 pos ns ss (PPi p n t sc)
1636 | elem n ss = do sc' <- pos ns ss sc
1639 return (PPi (p { pstatic = Static }) n t sc')
1640 | otherwise = do sc' <- pos ns ss sc
1643 return (PPi p n t sc')
1644 pos ns ss t = return t
1646-- for 6.12/7 compatibility
1647data EitherErr a b = LeftErr a | RightOK b
1649instance Monad (EitherErr a) where
1652 (LeftErr e) >>= k = LeftErr e
1653 RightOK v >>= k = k v
1655toEither (LeftErr e) = Left e
1656toEither (RightOK ho) = Right ho
1658-- syntactic match of a against b, returning pair of variables in a
1659-- and what they match. Returns the pair that failed if not a match.
1661matchClause :: IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
1662matchClause = matchClause' False
1664matchClause' :: Bool -> IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
1665matchClause' names i x y = checkRpts $ match (fullApp x) (fullApp y) where
1666 matchArg x y = match (fullApp (getTm x)) (fullApp (getTm y))
1668 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
1671 match' x y = match (fullApp x) (fullApp y)
1672 match (PApp _ (PRef _ (NS (UN fi) [b])) [_,_,x]) x'
1673 | fi == txt "fromInteger" && b == txt "builtins",
1674 PConstant (I _) <- getTm x = match (getTm x) x'
1675 match x' (PApp _ (PRef _ (NS (UN fi) [b])) [_,_,x])
1676 | fi == txt "fromInteger" && b == txt "builtins",
1677 PConstant (I _) <- getTm x = match (getTm x) x'
1678 match (PApp _ (PRef _ (UN l)) [_,x]) x' | l == txt "lazy" = match (getTm x) x'
1679 match x (PApp _ (PRef _ (UN l)) [_,x']) | l == txt "lazy" = match x (getTm x')
1680 match (PApp _ f args) (PApp _ f' args')
1681 | length args == length args'
1682 = do mf <- match' f f'
1683 ms <- zipWithM matchArg args args'
1684 return (mf ++ concat ms)
1685 match (PRef f n) (PApp _ x []) = match (PRef f n) x
1686 match (PPatvar f n) xr = match (PRef f n) xr
1687 match xr (PPatvar f n) = match xr (PRef f n)
1688 match (PApp _ x []) (PRef f n) = match x (PRef f n)
1689 match (PRef _ n) tm@(PRef _ n')
1690 | n == n' && not names &&
1691 (not (isConName n (tt_ctxt i) || isFnName n (tt_ctxt i))
1692 || tm == Placeholder)
1694 -- if one namespace is missing, drop the other
1695 | n == n' || n == dropNS n' || dropNS n == n' = return []
1696 where dropNS (NS n _) = n
1699 | not names && (not (isConName n (tt_ctxt i) ||
1700 isFnName n (tt_ctxt i)) || tm == Placeholder)
1702 match (PEq _ _ _ l r) (PEq _ _ _ l' r')
1703 = do ml <- match' l l'
1706 match (PRewrite _ l r _) (PRewrite _ l' r' _)
1707 = do ml <- match' l l'
1710 match (PTyped l r) (PTyped l' r') = do ml <- match l l'
1713 match (PTyped l r) x = match l x
1714 match x (PTyped l r) = match x l
1715 match (PPair _ _ l r) (PPair _ _ l' r') = do ml <- match' l l'
1718 match (PDPair _ _ l t r) (PDPair _ _ l' t' r') = do ml <- match' l l'
1721 return (ml ++ mt ++ mr)
1722 match (PAlternative a as) (PAlternative a' as')
1723 = do ms <- zipWithM match' as as'
1725 match a@(PAlternative _ as) b
1726 = do let ms = zipWith match' as (repeat b)
1727 case (rights (map toEither ms)) of
1730 match (PCase _ _ _) _ = return [] -- lifted out
1731 match (PMetavar _) _ = return [] -- modified
1732 match (PInferRef _ _) _ = return [] -- modified
1733 match (PQuote _) _ = return []
1734 match (PProof _) _ = return []
1735 match (PTactics _) _ = return []
1736 match (PRefl _ _) (PRefl _ _) = return []
1737 match (PResolveTC _) (PResolveTC _) = return []
1738 match (PTrue _ _) (PTrue _ _) = return []
1739 match (PFalse _) (PFalse _) = return []
1740 match (PReturn _) (PReturn _) = return []
1741 match (PPi _ _ t s) (PPi _ _ t' s') = do mt <- match' t t'
1744 match (PLam _ t s) (PLam _ t' s') = do mt <- match' t t'
1747 match (PLet _ t ty s) (PLet _ t' ty' s') = do mt <- match' t t'
1748 mty <- match' ty ty'
1750 return (mt ++ mty ++ ms)
1751 match (PHidden x) (PHidden y) = match' x y
1752 match (PUnifyLog x) y = match' x y
1753 match x (PUnifyLog y) = match' x y
1754 match (PNoImplicits x) y = match' x y
1755 match x (PNoImplicits y) = match' x y
1756 match Placeholder _ = return []
1757 match _ Placeholder = return []
1758 match (PResolveTC _) _ = return []
1759 match a b | a == b = return []
1760 | otherwise = LeftErr (a, b)
1762 checkRpts (RightOK ms) = check ms where
1764 | Just t' <- lookup n xs = if t/=t' && t/=Placeholder && t'/=Placeholder
1767 check (_:xs) = check xs
1769 checkRpts (LeftErr x) = Left x
1771substMatches :: [(Name, PTerm)] -> PTerm -> PTerm
1772substMatches ms = substMatchesShadow ms []
1774substMatchesShadow :: [(Name, PTerm)] -> [Name] -> PTerm -> PTerm
1775substMatchesShadow [] shs t = t
1776substMatchesShadow ((n,tm):ns) shs t
1777 = substMatchShadow n shs tm (substMatchesShadow ns shs t)
1779substMatch :: Name -> PTerm -> PTerm -> PTerm
1780substMatch n = substMatchShadow n []
1782substMatchShadow :: Name -> [Name] -> PTerm -> PTerm -> PTerm
1783substMatchShadow n shs tm t = sm shs t where
1784 sm xs (PRef _ n') | n == n' = tm
1785 sm xs (PLam x t sc) = PLam x (sm xs t) (sm xs sc)
1786 sm xs (PPi p x t sc)
1788 = let x' = nextName x in
1789 PPi p x' (sm (x':xs) (substMatch x (PRef emptyFC x') t))
1790 (sm (x':xs) (substMatch x (PRef emptyFC x') sc))
1791 | otherwise = PPi p x (sm xs t) (sm (x : xs) sc)
1792 sm xs (PApp f x as) = fullApp $ PApp f (sm xs x) (map (fmap (sm xs)) as)
1793 sm xs (PCase f x as) = PCase f (sm xs x) (map (pmap (sm xs)) as)
1794 sm xs (PEq f xt yt x y) = PEq f (sm xs xt) (sm xs yt) (sm xs x) (sm xs y)
1795 sm xs (PRewrite f x y tm) = PRewrite f (sm xs x) (sm xs y)
1797 sm xs (PTyped x y) = PTyped (sm xs x) (sm xs y)
1798 sm xs (PPair f p x y) = PPair f p (sm xs x) (sm xs y)
1799 sm xs (PDPair f p x t y) = PDPair f p (sm xs x) (sm xs t) (sm xs y)
1800 sm xs (PAlternative a as) = PAlternative a (map (sm xs) as)
1801 sm xs (PHidden x) = PHidden (sm xs x)
1802 sm xs (PUnifyLog x) = PUnifyLog (sm xs x)
1803 sm xs (PNoImplicits x) = PNoImplicits (sm xs x)
1806 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
1809shadow :: Name -> Name -> PTerm -> PTerm
1810shadow n n' t = sm t where
1811 sm (PRef fc x) | n == x = PRef fc n'
1812 sm (PLam x t sc) | n /= x = PLam x (sm t) (sm sc)
1813 sm (PPi p x t sc) | n /=x = PPi p x (sm t) (sm sc)
1814 sm (PLet x t v sc) | n /= x = PLet x (sm t) (sm v) (sm sc)
1815 sm (PApp f x as) = PApp f (sm x) (map (fmap sm) as)
1816 sm (PAppBind f x as) = PAppBind f (sm x) (map (fmap sm) as)
1817 sm (PCase f x as) = PCase f (sm x) (map (pmap sm) as)
1818 sm (PEq f xt yt x y) = PEq f (sm xt) (sm yt) (sm x) (sm y)
1819 sm (PRewrite f x y tm) = PRewrite f (sm x) (sm y) (fmap sm tm)
1820 sm (PTyped x y) = PTyped (sm x) (sm y)
1821 sm (PPair f p x y) = PPair f p (sm x) (sm y)
1822 sm (PDPair f p x t y) = PDPair f p (sm x) (sm t) (sm y)
1823 sm (PAlternative a as) = PAlternative a (map sm as)
1824 sm (PTactics ts) = PTactics (map (fmap sm) ts)
1825 sm (PProof ts) = PProof (map (fmap sm) ts)
1826 sm (PHidden x) = PHidden (sm x)
1827 sm (PUnifyLog x) = PUnifyLog (sm x)
1828 sm (PNoImplicits x) = PNoImplicits (sm x)
1831-- Rename any binders which are repeated (so that we don't have to mess
1832-- about with shadowing anywhere else).
1834mkUniqueNames :: [Name] -> PTerm -> PTerm
1835mkUniqueNames env tm = evalState (mkUniq tm) env where
1836 inScope = boundNamesIn tm
1838 mkUniqA arg = do t' <- mkUniq (getTm arg)
1839 return (arg { getTm = t' })
1841 -- Initialise the unique name with the environment length (so we're not
1842 -- looking for too long...)
1843 initN (UN n) l = UN $ txt (str n ++ show l)
1844 initN (MN i s) l = MN (i+l) s
1847 -- FIXME: Probably ought to do this for completeness! It's fine as
1848 -- long as there are no bindings inside tactics though.
1849 mkUniqT tac = return tac
1851 mkUniq :: PTerm -> State [Name] PTerm
1852 mkUniq (PLam n ty sc)
1856 then do let n' = uniqueName (initN n (length env))
1858 return (n', shadow n n' sc)
1863 return $! PLam n' ty' sc''
1864 mkUniq (PPi p n ty sc)
1868 then do let n' = uniqueName (initN n (length env))
1870 return (n', shadow n n' sc)
1875 return $! PPi p n' ty' sc''
1876 mkUniq (PLet n ty val sc)
1880 then do let n' = uniqueName (initN n (length env))
1882 return (n', shadow n n' sc)
1885 ty' <- mkUniq ty; val' <- mkUniq val
1887 return $! PLet n' ty' val' sc''
1888 mkUniq (PApp fc t args)
1890 args' <- mapM mkUniqA args
1891 return $! PApp fc t' args'
1892 mkUniq (PAppBind fc t args)
1894 args' <- mapM mkUniqA args
1895 return $! PAppBind fc t' args'
1896 mkUniq (PCase fc t alts)
1898 alts' <- mapM (\(x,y)-> do x' <- mkUniq x; y' <- mkUniq y
1899 return (x', y')) alts
1900 return $! PCase fc t' alts'
1901 mkUniq (PPair fc p l r)
1902 = do l' <- mkUniq l; r' <- mkUniq r
1903 return $! PPair fc p l' r'
1904 mkUniq (PDPair fc p (PRef fc' n) t sc)
1907 (n', sc') <- if n `elem` env
1908 then do let n' = uniqueName n (env ++ inScope)
1909 return (n', shadow n n' sc)
1914 return $! PDPair fc p (PRef fc' n') t' sc''
1915 mkUniq (PDPair fc p l t r)
1916 = do l' <- mkUniq l; t' <- mkUniq t; r' <- mkUniq r
1917 return $! PDPair fc p l' t' r'
1918 mkUniq (PAlternative b as)
1919 = liftM (PAlternative b) (mapM mkUniq as)
1920 mkUniq (PHidden t) = liftM PHidden (mkUniq t)
1921 mkUniq (PUnifyLog t) = liftM PUnifyLog (mkUniq t)
1922 mkUniq (PDisamb n t) = liftM (PDisamb n) (mkUniq t)
1923 mkUniq (PNoImplicits t) = liftM PNoImplicits (mkUniq t)
1924 mkUniq (PProof ts) = liftM PProof (mapM mkUniqT ts)
1925 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