on bab6c7b help sign in
Idris-dev/src/Idris/AbsSyntax.hs
1744 lines 72 kB history raw
1{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, DeriveFunctor,
2 TypeSynonymInstances, PatternGuards #-}
4module Idris.AbsSyntax(module Idris.AbsSyntax, module Idris.AbsSyntaxTree) where
6import Idris.Core.TT
7import Idris.Core.Evaluate
8import Idris.Core.Elaborate hiding (Tactic(..))
9import Idris.Core.Typecheck
10import Idris.AbsSyntaxTree
11import Idris.Colours
12import Idris.IdeSlave
13import IRTS.CodegenCommon
14import Util.DynamicLinker
16import Paths_idris
18import System.Console.Haskeline
19import System.IO
21import Control.Monad.State
22import Control.Monad.Error(throwError)
24import Data.List
25import Data.Char
26import qualified Data.Text as T
27import Data.Either
28import qualified Data.Map as M
29import Data.Maybe
30import qualified Data.Set as S
31import Data.Word (Word)
33import Debug.Trace
35import Control.Monad.Error (throwError, catchError)
36import System.IO.Error(isUserError, ioeGetErrorString, tryIOError)
38import Util.Pretty
39import Util.System
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 case mapMaybe (findDyLib ls) libs of
69 x:_ -> return (Left x)
70 [] -> do
71 handle <- lift . lift $ mapM (\l -> catchIO (tryLoadLib l) (\_ -> return Nothing)) $ libs
72 case msum handle of
73 Nothing -> return (Right $ "Could not load dynamic alternatives \"" ++
74 concat (intersperse "," libs) ++ "\"")
75 Just x -> do putIState $ i { idris_dynamic_libs = x:ls }
76 return (Left x)
77 where findDyLib :: [DynamicLib] -> String -> Maybe DynamicLib
78 findDyLib [] l = Nothing
79 findDyLib (lib:libs) l | l == lib_name lib = Just lib
80 | otherwise = findDyLib libs l
83addHdr :: Codegen -> String -> Idris ()
84addHdr tgt f = do i <- getIState; putIState $ i { idris_hdrs = nub $ (tgt, f) : idris_hdrs i }
86addLangExt :: LanguageExt -> Idris ()
87addLangExt TypeProviders = do i <- getIState
88 putIState $ i {
89 idris_language_extensions = TypeProviders : idris_language_extensions i
90 }
91addLangExt ErrorReflection = do i <- getIState
92 putIState $ i {
93 idris_language_extensions = ErrorReflection : idris_language_extensions i
94 }
96addTrans :: (Term, Term) -> Idris ()
97addTrans t = do i <- getIState
98 putIState $ i { idris_transforms = t : idris_transforms i }
100totcheck :: (FC, Name) -> Idris ()
101totcheck n = do i <- getIState; putIState $ i { idris_totcheck = idris_totcheck i ++ [n] }
103defer_totcheck :: (FC, Name) -> Idris ()
104defer_totcheck n
105 = do i <- getIState;
106 putIState $ i { idris_defertotcheck = nub (idris_defertotcheck i ++ [n]) }
108clear_totcheck :: Idris ()
109clear_totcheck = do i <- getIState; putIState $ i { idris_totcheck = [] }
111setFlags :: Name -> [FnOpt] -> Idris ()
112setFlags n fs = do i <- getIState; putIState $ i { idris_flags = addDef n fs (idris_flags i) }
114setAccessibility :: Name -> Accessibility -> Idris ()
115setAccessibility n a
116 = do i <- getIState
117 let ctxt = setAccess n a (tt_ctxt i)
118 putIState $ i { tt_ctxt = ctxt }
120setTotality :: Name -> Totality -> Idris ()
121setTotality n a
122 = do i <- getIState
123 let ctxt = setTotal n a (tt_ctxt i)
124 putIState $ i { tt_ctxt = ctxt }
126getTotality :: Name -> Idris Totality
127getTotality n
128 = do i <- getIState
129 case lookupTotal n (tt_ctxt i) of
130 [t] -> return t
131 _ -> return (Total [])
133-- Get coercions which might return the required type
134getCoercionsTo :: IState -> Type -> [Name]
135getCoercionsTo i ty =
136 let cs = idris_coercions i
137 (fn,_) = unApply (getRetTy ty) in
138 findCoercions fn cs
139 where findCoercions t [] = []
140 findCoercions t (n : ns) =
141 let ps = case lookupTy n (tt_ctxt i) of
142 [ty'] -> case unApply (getRetTy ty') of
143 (t', _) ->
144 if t == t' then [n] else []
145 _ -> [] in
146 ps ++ findCoercions t ns
148addToCG :: Name -> CGInfo -> Idris ()
149addToCG n cg
150 = do i <- getIState
151 putIState $ i { idris_callgraph = addDef n cg (idris_callgraph i) }
153-- | Adds error handlers for a particular function and argument. If names are is ambiguous, all matching handlers are updated.
154addFunctionErrorHandlers :: Name -> Name -> [Name] -> Idris ()
155addFunctionErrorHandlers f arg hs =
156 do i <- getIState
157 let oldHandlers = idris_function_errorhandlers i
158 let newHandlers = flip (addDef f) oldHandlers $
159 case lookupCtxtExact f oldHandlers of
160 Nothing -> M.singleton arg (S.fromList hs)
161 Just (oldHandlers) -> M.insertWith S.union arg (S.fromList hs) oldHandlers
162 -- will always be one of those two, thus no extra case
163 putIState $ i { idris_function_errorhandlers = newHandlers }
165getFunctionErrorHandlers :: Name -> Name -> Idris [Name]
166getFunctionErrorHandlers f arg = do i <- getIState
167 return . maybe [] S.toList $
168 undefined --lookup arg =<< lookupCtxtExact f (idris_function_errorhandlers i)
171-- Trace all the names in a call graph starting at the given name
172getAllNames :: Name -> Idris [Name]
173getAllNames n = allNames [] n
175allNames :: [Name] -> Name -> Idris [Name]
176allNames ns n | n `elem` ns = return []
177allNames ns n = do i <- getIState
178 case lookupCtxtExact n (idris_callgraph i) of
179 Just ns' -> do more <- mapM (allNames (n:ns)) (map fst (calls ns'))
180 return (nub (n : concat more))
181 _ -> return [n]
183addCoercion :: Name -> Idris ()
184addCoercion n = do i <- getIState
185 putIState $ i { idris_coercions = nub $ n : idris_coercions i }
187addDocStr :: Name -> String -> Idris ()
188addDocStr n doc
189 = do i <- getIState
190 putIState $ i { idris_docstrings = addDef n doc (idris_docstrings i) }
192addNameHint :: Name -> Name -> Idris ()
193addNameHint ty n
194 = do i <- getIState
195 ty' <- case lookupCtxtName ty (idris_implicits i) of
196 [(tyn, _)] -> return tyn
197 [] -> throwError (NoSuchVariable ty)
198 tyns -> throwError (CantResolveAlts (map show (map fst tyns)))
199 let ns' = case lookupCtxt ty' (idris_namehints i) of
200 [ns] -> ns ++ [n]
201 _ -> [n]
202 putIState $ i { idris_namehints = addDef ty' ns' (idris_namehints i) }
204getNameHints :: IState -> Name -> [Name]
205getNameHints i (UN arr) | arr == txt "->" = [sUN "f",sUN "g"]
206getNameHints i n =
207 case lookupCtxt n (idris_namehints i) of
208 [ns] -> ns
209 _ -> []
211addToCalledG :: Name -> [Name] -> Idris ()
212addToCalledG n ns = return () -- TODO
214-- Add a class instance function. Dodgy hack: Put integer instances first in the
215-- list so they are resolved by default.
216-- Dodgy hack 2: put constraint chasers (@@) last
218addInstance :: Bool -> Name -> Name -> Idris ()
219addInstance int n i
220 = do ist <- getIState
221 case lookupCtxt n (idris_classes ist) of
222 [CI a b c d e ins] ->
223 do let cs = addDef n (CI a b c d e (addI i ins)) (idris_classes ist)
224 putIState $ ist { idris_classes = cs }
225 _ -> do let cs = addDef n (CI (sMN 0 "none") [] [] [] [] [i]) (idris_classes ist)
226 putIState $ ist { idris_classes = cs }
227 where addI i ins | int = i : ins
228 | chaser n = ins ++ [i]
229 | otherwise = insI i ins
230 insI i [] = [i]
231 insI i (n : ns) | chaser n = i : n : ns
232 | otherwise = n : insI i ns
234 chaser (UN nm)
235 | ('@':'@':_) <- str nm = True
236 chaser (NS n _) = chaser n
237 chaser _ = False
239addClass :: Name -> ClassInfo -> Idris ()
240addClass n i
241 = do ist <- getIState
242 let i' = case lookupCtxt n (idris_classes ist) of
243 [c] -> c { class_instances = class_instances i }
244 _ -> i
245 putIState $ ist { idris_classes = addDef n i' (idris_classes ist) }
247addIBC :: IBCWrite -> Idris ()
248addIBC ibc@(IBCDef n)
249 = do i <- getIState
250 when (notDef (ibc_write i)) $
251 putIState $ i { ibc_write = ibc : ibc_write i }
252 where notDef [] = True
253 notDef (IBCDef n': is) | n == n' = False
254 notDef (_ : is) = notDef is
255addIBC ibc = do i <- getIState; putIState $ i { ibc_write = ibc : ibc_write i }
257clearIBC :: Idris ()
258clearIBC = do i <- getIState; putIState $ i { ibc_write = [] }
260resetNameIdx :: Idris ()
261resetNameIdx = do i <- getIState
262 put (i { idris_nameIdx = (0, emptyContext) })
264-- Used to preserve sharing of names
265addNameIdx :: Name -> Idris (Int, Name)
266addNameIdx n = do i <- getIState
267 let (i', x) = addNameIdx' i n
268 return x
270addNameIdx' :: IState -> Name -> (IState, (Int, Name))
271addNameIdx' i n
272 = let idxs = snd (idris_nameIdx i) in
273 case lookupCtxt n idxs of
274 [x] -> (i, x)
275 _ -> let i' = fst (idris_nameIdx i) + 1 in
276 (i { idris_nameIdx = (i', addDef n (i', n) idxs) }, (i', n))
278getHdrs :: Codegen -> Idris [String]
279getHdrs tgt = do i <- getIState; return (forCodegen tgt $ idris_hdrs i)
281setErrLine :: Int -> Idris ()
282setErrLine x = do i <- getIState;
283 case (errLine i) of
284 Nothing -> putIState $ i { errLine = Just x }
285 Just _ -> return ()
287clearErr :: Idris ()
288clearErr = do i <- getIState
289 putIState $ i { errLine = Nothing }
291getSO :: Idris (Maybe String)
292getSO = do i <- getIState
293 return (compiled_so i)
295setSO :: Maybe String -> Idris ()
296setSO s = do i <- getIState
297 putIState $ (i { compiled_so = s })
299getIState :: Idris IState
300getIState = get
302putIState :: IState -> Idris ()
303putIState = put
305-- | A version of liftIO that puts errors into the exception type of the Idris monad
306runIO :: IO a -> Idris a
307runIO x = liftIO (tryIOError x) >>= either (throwError . Msg . show) return
308-- TODO: create specific Idris exceptions for specific IO errors such as "openFile: does not exist"
310getName :: Idris Int
311getName = do i <- getIState;
312 let idx = idris_name i;
313 putIState $ (i { idris_name = idx + 1 })
314 return idx
316addInternalApp :: FilePath -> Int -> PTerm -> Idris ()
317addInternalApp fp l t
318 = do i <- getIState
319 putIState (i { idris_lineapps = ((fp, l), t) : idris_lineapps i })
321getInternalApp :: FilePath -> Int -> Idris PTerm
322getInternalApp fp l = do i <- getIState
323 case lookup (fp, l) (idris_lineapps i) of
324 Just n' -> return n'
325 Nothing -> return Placeholder
326 -- TODO: What if it's not there?
328-- Pattern definitions are only used for coverage checking, so erase them
329-- when we're done
330clearOrigPats :: Idris ()
331clearOrigPats = do i <- get
332 let ps = idris_patdefs i
333 let ps' = mapCtxt (\ (_,miss) -> ([], miss)) ps
334 put (i { idris_patdefs = ps' })
336-- Erase types from Ps in the context (basically ending up with what's in
337-- the .ibc, which is all we need after all the analysis is done)
338clearPTypes :: Idris ()
339clearPTypes = do i <- get
340 let ctxt = tt_ctxt i
341 put (i { tt_ctxt = mapDefCtxt pErase ctxt })
342 where pErase (CaseOp c t tys orig tot cds)
343 = CaseOp c t tys orig [] (pErase' cds)
344 pErase x = x
345 pErase' (CaseDefs _ (cs, c) _ rs)
346 = let c' = (cs, fmap pEraseType c) in
347 CaseDefs c' c' c' rs
349checkUndefined :: FC -> Name -> Idris ()
350checkUndefined fc n
351 = do i <- getContext
352 case lookupTy n i of
353 (_:_) -> throwError . Msg $ show fc ++ ":" ++
354 show n ++ " already defined"
355 _ -> return ()
357isUndefined :: FC -> Name -> Idris Bool
358isUndefined fc n
359 = do i <- getContext
360 case lookupTy n i of
361 (_:_) -> return False
362 _ -> return True
364setContext :: Context -> Idris ()
365setContext ctxt = do i <- getIState; putIState $ (i { tt_ctxt = ctxt } )
367updateContext :: (Context -> Context) -> Idris ()
368updateContext f = do i <- getIState; putIState $ (i { tt_ctxt = f (tt_ctxt i) } )
370addConstraints :: FC -> (Int, [UConstraint]) -> Idris ()
371addConstraints fc (v, cs)
372 = do i <- getIState
373 let ctxt = tt_ctxt i
374 let ctxt' = ctxt { uconstraints = cs ++ uconstraints ctxt,
375 next_tvar = v }
376 let ics = zip cs (repeat fc) ++ idris_constraints i
377 putIState $ i { tt_ctxt = ctxt', idris_constraints = ics }
379addDeferred = addDeferred' Ref
380addDeferredTyCon = addDeferred' (TCon 0 0)
382addDeferred' :: NameType -> [(Name, (Int, Maybe Name, Type, Bool))] -> Idris ()
383addDeferred' nt ns
384 = do mapM_ (\(n, (i, _, t, _)) -> updateContext (addTyDecl n nt (tidyNames [] t))) ns
385 i <- getIState
386 putIState $ i { idris_metavars = map (\(n, (i, top, _, isTopLevel)) -> (n, (top, i, isTopLevel))) ns ++
387 idris_metavars i }
388 where tidyNames used (Bind (MN i x) b sc)
389 = let n' = uniqueName (UN x) used in
390 Bind n' b $ tidyNames (n':used) sc
391 tidyNames used (Bind n b sc)
392 = let n' = uniqueName n used in
393 Bind n' b $ tidyNames (n':used) sc
394 tidyNames used b = b
396solveDeferred :: Name -> Idris ()
397solveDeferred n = do i <- getIState
398 putIState $ i { idris_metavars =
399 filter (\(n', _) -> n/=n')
400 (idris_metavars i) }
402getUndefined :: Idris [Name]
403getUndefined = do i <- getIState
404 return (map fst (idris_metavars i) \\ primDefs)
406ihPrintResult :: Handle -> String -> Idris ()
407ihPrintResult h s = do i <- getIState
408 case idris_outputmode i of
409 RawOutput -> case s of
410 "" -> return ()
411 s -> runIO $ hPutStrLn h s
412 IdeSlave n ->
413 let good = SexpList [SymbolAtom "ok", toSExp s] in
414 runIO $ hPutStrLn h $ convSExp "return" good n
416ihPrintError :: Handle -> String -> Idris ()
417ihPrintError h s = do i <- getIState
418 case idris_outputmode i of
419 RawOutput -> case s of
420 "" -> return ()
421 s -> runIO $ hPutStrLn h s
422 IdeSlave n ->
423 let good = SexpList [SymbolAtom "error", toSExp s] in
424 runIO . hPutStrLn h $ convSExp "return" good n
426ihputStrLn :: Handle -> String -> Idris ()
427ihputStrLn h s = do i <- getIState
428 case idris_outputmode i of
429 RawOutput -> runIO $ hPutStrLn h s
430 IdeSlave n -> runIO . hPutStrLn h $ convSExp "write-string" s n
432iputStrLn = ihputStrLn stdout
433iPrintError = ihPrintError stdout
434iPrintResult = ihPrintResult stdout
435iWarn = ihWarn stdout
437ideslavePutSExp :: SExpable a => String -> a -> Idris ()
438ideslavePutSExp cmd info = do i <- getIState
439 case idris_outputmode i of
440 IdeSlave n -> runIO . putStrLn $ convSExp cmd info n
441 _ -> return ()
443-- this needs some typing magic and more structured output towards emacs
444iputGoal :: String -> Idris ()
445iputGoal s = do i <- getIState
446 case idris_outputmode i of
447 RawOutput -> runIO $ putStrLn s
448 IdeSlave n -> runIO . putStrLn $ convSExp "write-goal" s n
450isetPrompt :: String -> Idris ()
451isetPrompt p = do i <- getIState
452 case idris_outputmode i of
453 IdeSlave n -> runIO . putStrLn $ convSExp "set-prompt" p n
455ihWarn :: Handle -> FC -> String -> Idris ()
456ihWarn h fc err = do i <- getIState
457 case idris_outputmode i of
458 RawOutput -> runIO $ hPutStrLn h (show fc ++ ":" ++ err)
459 IdeSlave n -> runIO $ hPutStrLn h $ convSExp "warning" (fc_fname fc, fc_line fc, fc_column fc, err) n
461setLogLevel :: Int -> Idris ()
462setLogLevel l = do i <- getIState
463 let opts = idris_options i
464 let opt' = opts { opt_logLevel = l }
465 putIState $ i { idris_options = opt' }
467setCmdLine :: [Opt] -> Idris ()
468setCmdLine opts = do i <- getIState
469 let iopts = idris_options i
470 putIState $ i { idris_options = iopts { opt_cmdline = opts } }
472getCmdLine :: Idris [Opt]
473getCmdLine = do i <- getIState
474 return (opt_cmdline (idris_options i))
476getDumpDefun :: Idris (Maybe FilePath)
477getDumpDefun = do i <- getIState
478 return $ findC (opt_cmdline (idris_options i))
479 where findC [] = Nothing
480 findC (DumpDefun x : _) = Just x
481 findC (_ : xs) = findC xs
483getDumpCases :: Idris (Maybe FilePath)
484getDumpCases = do i <- getIState
485 return $ findC (opt_cmdline (idris_options i))
486 where findC [] = Nothing
487 findC (DumpCases x : _) = Just x
488 findC (_ : xs) = findC xs
490logLevel :: Idris Int
491logLevel = do i <- getIState
492 return (opt_logLevel (idris_options i))
494setErrContext :: Bool -> Idris ()
495setErrContext t = do i <- getIState
496 let opts = idris_options i
497 let opt' = opts { opt_errContext = t }
498 putIState $ i { idris_options = opt' }
500errContext :: Idris Bool
501errContext = do i <- getIState
502 return (opt_errContext (idris_options i))
504useREPL :: Idris Bool
505useREPL = do i <- getIState
506 return (opt_repl (idris_options i))
508setREPL :: Bool -> Idris ()
509setREPL t = do i <- getIState
510 let opts = idris_options i
511 let opt' = opts { opt_repl = t }
512 putIState $ i { idris_options = opt' }
514setNoBanner :: Bool -> Idris ()
515setNoBanner n = do i <- getIState
516 let opts = idris_options i
517 let opt' = opts {opt_nobanner = n}
518 putIState $ i { idris_options = opt' }
520getNoBanner :: Idris Bool
521getNoBanner = do i <- getIState
522 let opts = idris_options i
523 return (opt_nobanner opts)
525setQuiet :: Bool -> Idris ()
526setQuiet q = do i <- getIState
527 let opts = idris_options i
528 let opt' = opts { opt_quiet = q }
529 putIState $ i { idris_options = opt' }
531getQuiet :: Idris Bool
532getQuiet = do i <- getIState
533 let opts = idris_options i
534 return (opt_quiet opts)
536setCodegen :: Codegen -> Idris ()
537setCodegen t = do i <- getIState
538 let opts = idris_options i
539 let opt' = opts { opt_codegen = t }
540 putIState $ i { idris_options = opt' }
542codegen :: Idris Codegen
543codegen = do i <- getIState
544 return (opt_codegen (idris_options i))
546setOutputTy :: OutputType -> Idris ()
547setOutputTy t = do i <- getIState
548 let opts = idris_options i
549 let opt' = opts { opt_outputTy = t }
550 putIState $ i { idris_options = opt' }
552outputTy :: Idris OutputType
553outputTy = do i <- getIState
554 return $ opt_outputTy $ idris_options i
556setIdeSlave :: Bool -> Idris ()
557setIdeSlave True = do i <- getIState
558 putIState $ i { idris_outputmode = (IdeSlave 0), idris_colourRepl = False }
559setIdeSlave False = return ()
561setTargetTriple :: String -> Idris ()
562setTargetTriple t = do i <- getIState
563 let opts = idris_options i
564 opt' = opts { opt_triple = t }
565 putIState $ i { idris_options = opt' }
567targetTriple :: Idris String
568targetTriple = do i <- getIState
569 return (opt_triple (idris_options i))
571setTargetCPU :: String -> Idris ()
572setTargetCPU t = do i <- getIState
573 let opts = idris_options i
574 opt' = opts { opt_cpu = t }
575 putIState $ i { idris_options = opt' }
577targetCPU :: Idris String
578targetCPU = do i <- getIState
579 return (opt_cpu (idris_options i))
581setOptLevel :: Word -> Idris ()
582setOptLevel t = do i <- getIState
583 let opts = idris_options i
584 opt' = opts { opt_optLevel = t }
585 putIState $ i { idris_options = opt' }
587optLevel :: Idris Word
588optLevel = do i <- getIState
589 return (opt_optLevel (idris_options i))
591verbose :: Idris Bool
592verbose = do i <- getIState
593 return (opt_verbose (idris_options i))
595setVerbose :: Bool -> Idris ()
596setVerbose t = do i <- getIState
597 let opts = idris_options i
598 let opt' = opts { opt_verbose = t }
599 putIState $ i { idris_options = opt' }
601typeInType :: Idris Bool
602typeInType = do i <- getIState
603 return (opt_typeintype (idris_options i))
605setTypeInType :: Bool -> Idris ()
606setTypeInType t = do i <- getIState
607 let opts = idris_options i
608 let opt' = opts { opt_typeintype = t }
609 putIState $ i { idris_options = opt' }
611coverage :: Idris Bool
612coverage = do i <- getIState
613 return (opt_coverage (idris_options i))
615setCoverage :: Bool -> Idris ()
616setCoverage t = do i <- getIState
617 let opts = idris_options i
618 let opt' = opts { opt_coverage = t }
619 putIState $ i { idris_options = opt' }
621setIBCSubDir :: FilePath -> Idris ()
622setIBCSubDir fp = do i <- getIState
623 let opts = idris_options i
624 let opt' = opts { opt_ibcsubdir = fp }
625 putIState $ i { idris_options = opt' }
627valIBCSubDir :: IState -> Idris FilePath
628valIBCSubDir i = return (opt_ibcsubdir (idris_options i))
630addImportDir :: FilePath -> Idris ()
631addImportDir fp = do i <- getIState
632 let opts = idris_options i
633 let opt' = opts { opt_importdirs = fp : opt_importdirs opts }
634 putIState $ i { idris_options = opt' }
636setImportDirs :: [FilePath] -> Idris ()
637setImportDirs fps = do i <- getIState
638 let opts = idris_options i
639 let opt' = opts { opt_importdirs = fps }
640 putIState $ i { idris_options = opt' }
642allImportDirs :: Idris [FilePath]
643allImportDirs = do i <- getIState
644 let optdirs = opt_importdirs (idris_options i)
645 return ("." : reverse optdirs)
647colourise :: Idris Bool
648colourise = do i <- getIState
649 return $ idris_colourRepl i
651setColourise :: Bool -> Idris ()
652setColourise b = do i <- getIState
653 putIState $ i { idris_colourRepl = b }
655setOutH :: Handle -> Idris ()
656setOutH h = do i <- getIState
657 putIState $ i { idris_outh = h }
659impShow :: Idris Bool
660impShow = do i <- getIState
661 return (opt_showimp (idris_options i))
663setImpShow :: Bool -> Idris ()
664setImpShow t = do i <- getIState
665 let opts = idris_options i
666 let opt' = opts { opt_showimp = t }
667 putIState $ i { idris_options = opt' }
669setColour :: ColourType -> IdrisColour -> Idris ()
670setColour ct c = do i <- getIState
671 let newTheme = setColour' ct c (idris_colourTheme i)
672 putIState $ i { idris_colourTheme = newTheme }
673 where setColour' KeywordColour c t = t { keywordColour = c }
674 setColour' BoundVarColour c t = t { boundVarColour = c }
675 setColour' ImplicitColour c t = t { implicitColour = c }
676 setColour' FunctionColour c t = t { functionColour = c }
677 setColour' TypeColour c t = t { typeColour = c }
678 setColour' DataColour c t = t { dataColour = c }
679 setColour' PromptColour c t = t { promptColour = c }
681logLvl :: Int -> String -> Idris ()
682logLvl l str = do i <- getIState
683 let lvl = opt_logLevel (idris_options i)
684 when (lvl >= l) $
685 case idris_outputmode i of
686 RawOutput -> do runIO $ putStrLn str
687 IdeSlave n ->
688 do let good = SexpList [IntegerAtom (toInteger l), toSExp str]
689 runIO $ putStrLn $ convSExp "log" good n
691cmdOptType :: Opt -> Idris Bool
692cmdOptType x = do i <- getIState
693 return $ x `elem` opt_cmdline (idris_options i)
695iLOG :: String -> Idris ()
696iLOG = logLvl 1
698noErrors :: Idris Bool
699noErrors = do i <- getIState
700 case errLine i of
701 Nothing -> return True
702 _ -> return False
704setTypeCase :: Bool -> Idris ()
705setTypeCase t = do i <- getIState
706 let opts = idris_options i
707 let opt' = opts { opt_typecase = t }
708 putIState $ i { idris_options = opt' }
711-- For inferring types of things
713bi = fileFC "builtin"
715inferTy = sMN 0 "__Infer"
716inferCon = sMN 0 "__infer"
717inferDecl = PDatadecl inferTy
718 PType
719 [("", inferCon, PPi impl (sMN 0 "iType") PType (
720 PPi expl (sMN 0 "ival") (PRef bi (sMN 0 "iType"))
721 (PRef bi inferTy)), bi, [])]
722inferOpts = []
724infTerm t = PApp bi (PRef bi inferCon) [pimp (sMN 0 "iType") Placeholder True, pexp t]
725infP = P (TCon 6 0) inferTy (TType (UVal 0))
727getInferTerm, getInferType :: Term -> Term
728getInferTerm (Bind n b sc) = Bind n b $ getInferTerm sc
729getInferTerm (App (App _ _) tm) = tm
730getInferTerm tm = tm -- error ("getInferTerm " ++ show tm)
732getInferType (Bind n b sc) = Bind n b $ getInferType sc
733getInferType (App (App _ ty) _) = ty
735-- Handy primitives: Unit, False, Pair, MkPair, =, mkForeign, Elim type class
737primNames = [unitTy, unitCon,
738 falseTy, pairTy, pairCon,
739 eqTy, eqCon, inferTy, inferCon]
741unitTy = sMN 0 "__Unit"
742unitCon = sMN 0 "__II"
743unitDecl = PDatadecl unitTy PType
744 [("", unitCon, PRef bi unitTy, bi, [])]
745unitOpts = [DefaultEliminator]
747falseTy = sMN 0 "__False"
748falseDecl = PDatadecl falseTy PType []
749falseOpts = []
751pairTy = sMN 0 "__Pair"
752pairCon = sMN 0 "__MkPair"
753pairDecl = PDatadecl pairTy (piBind [(n "A", PType), (n "B", PType)] PType)
754 [("", pairCon, PPi impl (n "A") PType (
755 PPi impl (n "B") PType (
756 PPi expl (n "a") (PRef bi (n "A")) (
757 PPi expl (n "b") (PRef bi (n "B"))
758 (PApp bi (PRef bi pairTy) [pexp (PRef bi (n "A")),
759 pexp (PRef bi (n "B"))])))), bi, [])]
760 where n a = sMN 0 a
761pairOpts = []
763eqTy = sUN "="
764eqCon = sUN "refl"
765eqDecl = PDatadecl eqTy (piBind [(n "A", PType), (n "B", PType),
766 (n "x", PRef bi (n "A")), (n "y", PRef bi (n "B"))]
767 PType)
768 [("", eqCon, PPi impl (n "A") PType (
769 PPi impl (n "x") (PRef bi (n "A"))
770 (PApp bi (PRef bi eqTy) [pimp (n "A") Placeholder False,
771 pimp (n "B") Placeholder False,
772 pexp (PRef bi (n "x")),
773 pexp (PRef bi (n "x"))])), bi, [])]
774 where n a = sMN 0 a
775eqOpts = []
777elimName = sUN "__Elim"
778elimMethElimTy = sUN "__elimTy"
779elimMethElim = sUN "elim"
780elimDecl = PClass "Type class for eliminators" defaultSyntax bi [] elimName [(sUN "scrutineeType", PType)]
781 [PTy "" defaultSyntax bi [TotalFn] elimMethElimTy PType,
782 PTy "" defaultSyntax bi [TotalFn] elimMethElim (PRef bi elimMethElimTy)]
784-- Defined in builtins.idr
785sigmaTy = sUN "Exists"
786existsCon = sUN "Ex_intro"
788piBind :: [(Name, PTerm)] -> PTerm -> PTerm
789piBind = piBindp expl
791piBindp :: Plicity -> [(Name, PTerm)] -> PTerm -> PTerm
792piBindp p [] t = t
793piBindp p ((n, ty):ns) t = PPi p n ty (piBindp p ns t)
795-- Dealing with parameters
797expandParams :: (Name -> Name) -> [(Name, PTerm)] ->
798 [Name] -> -- all names
799 [Name] -> -- names with no declaration
800 PTerm -> PTerm
801expandParams dec ps ns infs tm = en tm
802 where
803 -- if we shadow a name (say in a lambda binding) that is used in a call to
804 -- a lifted function, we need access to both names - once in the scope of the
805 -- binding and once to call the lifted functions. So we'll explicitly shadow
806 -- it. (Yes, it's a hack. The alternative would be to resolve names earlier
807 -- but we didn't...)
809 mkShadow (UN n) = MN 0 n
810 mkShadow (MN i n) = MN (i+1) n
811 mkShadow (NS x s) = NS (mkShadow x) s
813 en (PLam n t s)
814 | n `elem` (map fst ps ++ ns)
815 = let n' = mkShadow n in
816 PLam n' (en t) (en (shadow n n' s))
817 | otherwise = PLam n (en t) (en s)
818 en (PPi p n t s)
819 | n `elem` (map fst ps ++ ns)
820 = let n' = mkShadow n in
821 PPi p n' (en t) (en (shadow n n' s))
822 | otherwise = PPi p n (en t) (en s)
823 en (PLet n ty v s)
824 | n `elem` (map fst ps ++ ns)
825 = let n' = mkShadow n in
826 PLet n' (en ty) (en v) (en (shadow n n' s))
827 | otherwise = PLet n (en ty) (en v) (en s)
828 -- FIXME: Should only do this in a type signature!
829 en (PDPair f (PRef f' n) t r)
830 | n `elem` (map fst ps ++ ns) && t /= Placeholder
831 = let n' = mkShadow n in
832 PDPair f (PRef f' n') (en t) (en (shadow n n' r))
833 en (PEq f l r) = PEq f (en l) (en r)
834 en (PRewrite f l r g) = PRewrite f (en l) (en r) (fmap en g)
835 en (PTyped l r) = PTyped (en l) (en r)
836 en (PPair f l r) = PPair f (en l) (en r)
837 en (PDPair f l t r) = PDPair f (en l) (en t) (en r)
838 en (PAlternative a as) = PAlternative a (map en as)
839 en (PHidden t) = PHidden (en t)
840 en (PUnifyLog t) = PUnifyLog (en t)
841 en (PNoImplicits t) = PNoImplicits (en t)
842 en (PDoBlock ds) = PDoBlock (map (fmap en) ds)
843 en (PProof ts) = PProof (map (fmap en) ts)
844 en (PTactics ts) = PTactics (map (fmap en) ts)
846 en (PQuote (Var n))
847 | n `nselem` ns = PQuote (Var (dec n))
848 en (PApp fc (PInferRef fc' n) as)
849 | n `nselem` ns = PApp fc (PInferRef fc' (dec n))
850 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
851 en (PApp fc (PRef fc' n) as)
852 | n `elem` infs = PApp fc (PInferRef fc' (dec n))
853 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
854 | n `nselem` ns = PApp fc (PRef fc' (dec n))
855 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
856 en (PAppBind fc (PRef fc' n) as)
857 | n `elem` infs = PAppBind fc (PInferRef fc' (dec n))
858 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
859 | n `nselem` ns = PAppBind fc (PRef fc' (dec n))
860 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
861 en (PRef fc n)
862 | n `elem` infs = PApp fc (PInferRef fc (dec n))
863 (map (pexp . (PRef fc)) (map fst ps))
864 | n `nselem` ns = PApp fc (PRef fc (dec n))
865 (map (pexp . (PRef fc)) (map fst ps))
866 en (PInferRef fc n)
867 | n `nselem` ns = PApp fc (PInferRef fc (dec n))
868 (map (pexp . (PRef fc)) (map fst ps))
869 en (PApp fc f as) = PApp fc (en f) (map (fmap en) as)
870 en (PAppBind fc f as) = PAppBind fc (en f) (map (fmap en) as)
871 en (PCase fc c os) = PCase fc (en c) (map (pmap en) os)
872 en t = t
874 nselem x [] = False
875 nselem x (y : xs) | nseq x y = True
876 | otherwise = nselem x xs
878 nseq x y = nsroot x == nsroot y
880expandParamsD :: Bool -> -- True = RHS only
881 IState ->
882 (Name -> Name) -> [(Name, PTerm)] -> [Name] -> PDecl -> PDecl
883expandParamsD rhsonly ist dec ps ns (PTy doc syn fc o n ty)
884 = if n `elem` ns && (not rhsonly)
885 then -- trace (show (n, expandParams dec ps ns ty)) $
886 PTy doc syn fc o (dec n) (piBindp expl_param ps (expandParams dec ps ns [] ty))
887 else --trace (show (n, expandParams dec ps ns ty)) $
888 PTy doc syn fc o n (expandParams dec ps ns [] ty)
889expandParamsD rhsonly ist dec ps ns (PPostulate doc syn fc o n ty)
890 = if n `elem` ns && (not rhsonly)
891 then -- trace (show (n, expandParams dec ps ns ty)) $
892 PPostulate doc syn fc o (dec n) (piBind ps
893 (expandParams dec ps ns [] ty))
894 else --trace (show (n, expandParams dec ps ns ty)) $
895 PPostulate doc syn fc o n (expandParams dec ps ns [] ty)
896expandParamsD rhsonly ist dec ps ns (PClauses fc opts n cs)
897 = let n' = if n `elem` ns then dec n else n in
898 PClauses fc opts n' (map expandParamsC cs)
899 where
900 expandParamsC (PClause fc n lhs ws rhs ds)
901 = let -- ps' = updateps True (namesIn ist rhs) (zip ps [0..])
902 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
903 lhs' = if rhsonly then lhs else (expandParams dec ps'' ns [] lhs)
904 n' = if n `elem` ns then dec n else n
905 -- names bound on the lhs should not be expanded on the rhs
906 ns' = removeBound lhs ns in
907 PClause fc n' lhs'
908 (map (expandParams dec ps'' ns' []) ws)
909 (expandParams dec ps'' ns' [] rhs)
910 (map (expandParamsD True ist dec ps'' ns') ds)
911 expandParamsC (PWith fc n lhs ws wval ds)
912 = let -- ps' = updateps True (namesIn ist wval) (zip ps [0..])
913 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
914 lhs' = if rhsonly then lhs else (expandParams dec ps'' ns [] lhs)
915 n' = if n `elem` ns then dec n else n
916 ns' = removeBound lhs ns in
917 PWith fc n' lhs'
918 (map (expandParams dec ps'' ns' []) ws)
919 (expandParams dec ps'' ns' [] wval)
920 (map (expandParamsD rhsonly ist dec ps'' ns') ds)
921 updateps yn nm [] = []
922 updateps yn nm (((a, t), i):as)
923 | (a `elem` nm) == yn = (a, t) : updateps yn nm as
924 | otherwise = (sMN i (show n ++ "_u"), t) : updateps yn nm as
926 removeBound lhs ns = ns \\ nub (bnames lhs)
928 bnames (PRef _ n) = [n]
929 bnames (PApp _ _ args) = concatMap bnames (map getTm args)
930 bnames (PPair _ l r) = bnames l ++ bnames r
931 bnames (PDPair _ l Placeholder r) = bnames l ++ bnames r
932 bnames _ = []
934expandParamsD rhs ist dec ps ns (PData doc syn fc co pd)
935 = PData doc syn fc co (expandPData pd)
936 where
937 -- just do the type decl, leave constructors alone (parameters will be
938 -- added implicitly)
939 expandPData (PDatadecl n ty cons)
940 = if n `elem` ns
941 then PDatadecl (dec n) (piBind ps (expandParams dec ps ns [] ty))
942 (map econ cons)
943 else PDatadecl n (expandParams dec ps ns [] ty) (map econ cons)
944 econ (doc, n, t, fc, fs)
945 = (doc, dec n, piBindp expl ps (expandParams dec ps ns [] t), fc, fs)
946expandParamsD rhs ist dec ps ns (PParams f params pds)
947 = PParams f (ps ++ map (mapsnd (expandParams dec ps ns [])) params)
948 (map (expandParamsD True ist dec ps ns) pds)
949-- (map (expandParamsD ist dec ps ns) pds)
950expandParamsD rhs ist dec ps ns (PMutual f pds)
951 = PMutual f (map (expandParamsD rhs ist dec ps ns) pds)
952expandParamsD rhs ist dec ps ns (PClass doc info f cs n params decls)
953 = PClass doc info f
954 (map (expandParams dec ps ns []) cs)
955 n
956 (map (mapsnd (expandParams dec ps ns [])) params)
957 (map (expandParamsD rhs ist dec ps ns) decls)
958expandParamsD rhs ist dec ps ns (PInstance info f cs n params ty cn decls)
959 = PInstance info f
960 (map (expandParams dec ps ns []) cs)
961 n
962 (map (expandParams dec ps ns []) params)
963 (expandParams dec ps ns [] ty)
964 cn
965 (map (expandParamsD rhs ist dec ps ns) decls)
966expandParamsD rhs ist dec ps ns d = d
968mapsnd f (x, t) = (x, f t)
970-- Calculate a priority for a type, for deciding elaboration order
971-- * if it's just a type variable or concrete type, do it early (0)
972-- * if there's only type variables and injective constructors, do it next (1)
973-- * if there's a function type, next (2)
974-- * finally, everything else (3)
976getPriority :: IState -> PTerm -> Int
977getPriority i tm = 1 -- pri tm
978 where
979 pri (PRef _ n) =
980 case lookupP n (tt_ctxt i) of
981 ((P (DCon _ _) _ _):_) -> 1
982 ((P (TCon _ _) _ _):_) -> 1
983 ((P Ref _ _):_) -> 1
984 [] -> 0 -- must be locally bound, if it's not an error...
985 pri (PPi _ _ x y) = max 5 (max (pri x) (pri y))
986 pri (PTrue _) = 0
987 pri (PFalse _) = 0
988 pri (PRefl _ _) = 1
989 pri (PEq _ l r) = max 1 (max (pri l) (pri r))
990 pri (PRewrite _ l r _) = max 1 (max (pri l) (pri r))
991 pri (PApp _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.getTm) as)))
992 pri (PAppBind _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.getTm) as)))
993 pri (PCase _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.snd) as)))
994 pri (PTyped l r) = pri l
995 pri (PPair _ l r) = max 1 (max (pri l) (pri r))
996 pri (PDPair _ l t r) = max 1 (max (pri l) (max (pri t) (pri r)))
997 pri (PAlternative a as) = maximum (map pri as)
998 pri (PConstant _) = 0
999 pri Placeholder = 1
1000 pri _ = 3
1002addStatics :: Name -> Term -> PTerm -> Idris ()
1003addStatics n tm ptm =
1004 do let (statics, dynamics) = initStatics tm ptm
1005 let stnames = nub $ concatMap freeArgNames (map snd statics)
1006 let dnames = nub $ concatMap freeArgNames (map snd dynamics)
1007 -- also get the arguments which are 'uniquely inferrable' from
1008 -- statics (see sec 4.2 of "Scrapping Your Inefficient Engine")
1009 let statics' = nub $ map fst statics ++
1010 filter (\x -> not (elem x dnames)) stnames
1011 let stpos = staticList statics' tm
1012 i <- getIState
1013 when (not (null statics)) $
1014 logLvl 5 $ show n ++ " " ++ show statics' ++ "\n" ++ show dynamics
1015 ++ "\n" ++ show stnames ++ "\n" ++ show dnames
1016 putIState $ i { idris_statics = addDef n stpos (idris_statics i) }
1017 addIBC (IBCStatic n)
1018 where
1019 initStatics (Bind n (Pi ty) sc) (PPi p _ _ s)
1020 = let (static, dynamic) = initStatics (instantiate (P Bound n ty) sc) s in
1021 if pstatic p == Static then ((n, ty) : static, dynamic)
1022 else if (not (searchArg p))
1023 then (static, (n, ty) : dynamic)
1024 else (static, dynamic)
1025 initStatics t pt = ([], [])
1027 freeArgNames (Bind n (Pi ty) sc)
1028 = nub $ freeArgNames ty
1029 freeArgNames tm = let (_, args) = unApply tm in
1030 concatMap freeNames args
1032 -- if a name appears in a type class or tactic implicit index, it doesn't
1033 -- affect its 'uniquely inferrable' from a static status since these are
1034 -- resolved by searching.
1035 searchArg (Constraint _ _ _) = True
1036 searchArg (TacImp _ _ _ _) = True
1037 searchArg _ = False
1039 staticList sts (Bind n (Pi _) sc) = (n `elem` sts) : staticList sts sc
1040 staticList _ _ = []
1042-- Dealing with implicit arguments
1044-- Add constraint bindings from using block
1046addUsingConstraints :: SyntaxInfo -> FC -> PTerm -> Idris PTerm
1047addUsingConstraints syn fc t
1048 = do ist <- get
1049 let ns = namesIn [] ist t
1050 let cs = getConstraints t -- check declared constraints
1051 let addconsts = uconsts \\ cs
1052 -- if all names in the arguments of addconsts appear in ns,
1053 -- add the constraint implicitly
1054 return (doAdd addconsts ns t)
1055 where uconsts = filter uconst (using syn)
1056 uconst (UConstraint _ _) = True
1057 uconst _ = False
1059 doAdd [] _ t = t
1060 -- if all of args in ns, then add it
1061 doAdd (UConstraint c args : cs) ns t
1062 | all (\n -> elem n ns) args
1063 = PPi (Constraint False Dynamic "") (sMN 0 "cu")
1064 (mkConst c args) (doAdd cs ns t)
1065 | otherwise = doAdd cs ns t
1067 mkConst c args = PApp fc (PRef fc c)
1068 (map (\n -> PExp 0 False (PRef fc n) "") args)
1070 getConstraints (PPi (Constraint _ _ _) _ c sc)
1071 = getcapp c ++ getConstraints sc
1072 getConstraints (PPi _ _ c sc) = getConstraints sc
1073 getConstraints _ = []
1075 getcapp (PApp _ (PRef _ c) args)
1076 = do ns <- mapM getName args
1077 return (UConstraint c ns)
1078 getcapp _ = []
1080 getName (PExp _ _ (PRef _ n) _) = return n
1081 getName _ = []
1083-- Add implicit Pi bindings for any names in the term which appear in an
1084-- argument position.
1086-- This has become a right mess already. Better redo it some time...
1088implicit :: SyntaxInfo -> Name -> PTerm -> Idris PTerm
1089implicit syn n ptm = implicit' syn [] n ptm
1091implicit' :: SyntaxInfo -> [Name] -> Name -> PTerm -> Idris PTerm
1092implicit' syn ignore n ptm
1093 = do i <- getIState
1094 let (tm', impdata) = implicitise syn ignore i ptm
1095-- let (tm'', spos) = findStatics i tm'
1096 putIState $ i { idris_implicits = addDef n impdata (idris_implicits i) }
1097 addIBC (IBCImp n)
1098 logLvl 5 ("Implicit " ++ show n ++ " " ++ show impdata)
1099-- i <- get
1100-- putIState $ i { idris_statics = addDef n spos (idris_statics i) }
1101 return tm'
1103implicitise :: SyntaxInfo -> [Name] -> IState -> PTerm -> (PTerm, [PArg])
1104implicitise syn ignore ist tm = -- trace ("INCOMING " ++ showImp True tm) $
1105 let (declimps, ns') = execState (imps True [] tm) ([], [])
1106 ns = filter (\n -> implicitable n || elem n (map fst uvars)) $
1107 ns' \\ (map fst pvars ++ no_imp syn ++ ignore)
1108 nsOrder = filter (not . inUsing) ns ++ filter inUsing ns in
1109 if null ns
1110 then (tm, reverse declimps)
1111 else implicitise syn ignore ist (pibind uvars nsOrder tm)
1112 where
1113 uvars = map ipair (filter uimplicit (using syn))
1114 pvars = syn_params syn
1116 inUsing n = n `elem` map fst uvars
1118 ipair (UImplicit x y) = (x, y)
1119 uimplicit (UImplicit _ _) = True
1120 uimplicit _ = False
1122 dropAll (x:xs) ys | x `elem` ys = dropAll xs ys
1123 | otherwise = x : dropAll xs ys
1124 dropAll [] ys = []
1126 imps top env (PApp _ f as)
1127 = do (decls, ns) <- get
1128 let isn = concatMap (namesIn uvars ist) (map getTm as)
1129 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1130 imps top env (PPi (Imp l _ doc _) n ty sc)
1131 = do let isn = nub (namesIn uvars ist ty) `dropAll` [n]
1132 (decls , ns) <- get
1133 put (PImp (getPriority ist ty) True l n Placeholder doc : decls,
1134 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1135 imps True (n:env) sc
1136 imps top env (PPi (Exp l _ doc _) n ty sc)
1137 = do let isn = nub (namesIn uvars ist ty ++ case sc of
1138 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
1139 _ -> [])
1140 (decls, ns) <- get -- ignore decls in HO types
1141 put (PExp (getPriority ist ty) l Placeholder doc : decls,
1142 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1143 imps True (n:env) sc
1144 imps top env (PPi (Constraint l _ doc) n ty sc)
1145 = do let isn = nub (namesIn uvars ist ty ++ case sc of
1146 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
1147 _ -> [])
1148 (decls, ns) <- get -- ignore decls in HO types
1149 put (PConstraint 10 l Placeholder doc : decls,
1150 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1151 imps True (n:env) sc
1152 imps top env (PPi (TacImp l _ scr doc) n ty sc)
1153 = do let isn = nub (namesIn uvars ist ty ++ case sc of
1154 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
1155 _ -> [])
1156 (decls, ns) <- get -- ignore decls in HO types
1157 put (PTacImplicit 10 l n scr Placeholder doc : decls,
1158 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1159 imps True (n:env) sc
1160 imps top env (PEq _ l r)
1161 = do (decls, ns) <- get
1162 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1163 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1164 imps top env (PRewrite _ l r _)
1165 = do (decls, ns) <- get
1166 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1167 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1168 imps top env (PTyped l r)
1169 = imps top env l
1170 imps top env (PPair _ l r)
1171 = do (decls, ns) <- get
1172 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1173 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1174 imps top env (PDPair _ (PRef _ n) t r)
1175 = do (decls, ns) <- get
1176 let isn = nub (namesIn uvars ist t ++ namesIn uvars ist r) \\ [n]
1177 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
1178 imps top env (PDPair _ l t r)
1179 = do (decls, ns) <- get
1180 let isn = namesIn uvars ist l ++ namesIn uvars ist t ++
1181 namesIn uvars ist r
1182 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
1183 imps top env (PAlternative a as)
1184 = do (decls, ns) <- get
1185 let isn = concatMap (namesIn uvars ist) as
1186 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1187 imps top env (PLam n ty sc)
1188 = do imps False env ty
1189 imps False (n:env) sc
1190 imps top env (PHidden tm) = imps False env tm
1191 imps top env (PUnifyLog tm) = imps False env tm
1192 imps top env (PNoImplicits tm) = imps False env tm
1193 imps top env _ = return ()
1195 pibind using [] sc = sc
1196 pibind using (n:ns) sc
1197 = case lookup n using of
1198 Just ty -> PPi (Imp False Dynamic "" False) n ty (pibind using ns sc)
1199 Nothing -> PPi (Imp False Dynamic "" False) n Placeholder
1200 (pibind using ns sc)
1202-- Add implicit arguments in function calls
1203addImplPat :: IState -> PTerm -> PTerm
1204addImplPat = addImpl' True [] []
1206addImplBound :: IState -> [Name] -> PTerm -> PTerm
1207addImplBound ist ns = addImpl' False ns [] ist
1209addImplBoundInf :: IState -> [Name] -> [Name] -> PTerm -> PTerm
1210addImplBoundInf ist ns inf = addImpl' False ns inf ist
1212addImpl :: IState -> PTerm -> PTerm
1213addImpl = addImpl' False [] []
1215-- TODO: in patterns, don't add implicits to function names guarded by constructors
1216-- and *not* inside a PHidden
1218addImpl' :: Bool -> [Name] -> [Name] -> IState -> PTerm -> PTerm
1219addImpl' inpat env infns ist ptm
1220 = mkUniqueNames env (ai (zip env (repeat Nothing)) [] ptm)
1221 where
1222 ai env ds (PRef fc f)
1223 | f `elem` infns = PInferRef fc f
1224 | not (f `elem` map fst env) = handleErr $ aiFn inpat inpat ist fc f ds []
1225 ai env ds (PHidden (PRef fc f))
1226 | not (f `elem` map fst env) = handleErr $ aiFn inpat False ist fc f ds []
1227 ai env ds (PEq fc l r)
1228 = let l' = ai env ds l
1229 r' = ai env ds r in
1230 PEq fc l' r'
1231 ai env ds (PRewrite fc l r g)
1232 = let l' = ai env ds l
1233 r' = ai env ds r
1234 g' = fmap (ai env ds) g in
1235 PRewrite fc l' r' g'
1236 ai env ds (PTyped l r)
1237 = let l' = ai env ds l
1238 r' = ai env ds r in
1239 PTyped l' r'
1240 ai env ds (PPair fc l r)
1241 = let l' = ai env ds l
1242 r' = ai env ds r in
1243 PPair fc l' r'
1244 ai env ds (PDPair fc l t r)
1245 = let l' = ai env ds l
1246 t' = ai env ds t
1247 r' = ai env ds r in
1248 PDPair fc l' t' r'
1249 ai env ds (PAlternative a as)
1250 = let as' = map (ai env ds) as in
1251 PAlternative a as'
1252 ai env _ (PDisamb ds' as) = ai env ds' as
1253 ai env ds (PApp fc (PInferRef _ f) as)
1254 = let as' = map (fmap (ai env ds)) as in
1255 PApp fc (PInferRef fc f) as'
1256 ai env ds (PApp fc ftm@(PRef _ f) as)
1257 | f `elem` infns = ai env ds (PApp fc (PInferRef fc f) as)
1258 | not (f `elem` map fst env)
1259 = let as' = map (fmap (ai env ds)) as in
1260 handleErr $ aiFn inpat False ist fc f ds as'
1261 | Just (Just ty) <- lookup f env =
1262 let as' = map (fmap (ai env ds)) as
1263 arity = getPArity ty in
1264 mkPApp fc arity ftm as'
1265 ai env ds (PApp fc f as)
1266 = let f' = ai env ds f
1267 as' = map (fmap (ai env ds)) as in
1268 mkPApp fc 1 f' as'
1269 ai env ds (PCase fc c os)
1270 = let c' = ai env ds c
1271 os' = map (pmap (ai env ds)) os in
1272 PCase fc c' os'
1273 ai env ds (PLam n ty sc)
1274 = let ty' = ai env ds ty
1275 sc' = ai ((n, Just ty):env) ds sc in
1276 PLam n ty' sc'
1277 ai env ds (PLet n ty val sc)
1278 = let ty' = ai env ds ty
1279 val' = ai env ds val
1280 sc' = ai ((n, Just ty):env) ds sc in
1281 PLet n ty' val' sc'
1282 ai env ds (PPi p n ty sc)
1283 = let ty' = ai env ds ty
1284 sc' = ai ((n, Just ty):env) ds sc in
1285 PPi p n ty' sc'
1286 ai env ds (PGoal fc r n sc)
1287 = let r' = ai env ds r
1288 sc' = ai ((n, Nothing):env) ds sc in
1289 PGoal fc r' n sc'
1290 ai env ds (PHidden tm) = PHidden (ai env ds tm)
1291 ai env ds (PProof ts) = PProof (map (fmap (ai env ds)) ts)
1292 ai env ds (PTactics ts) = PTactics (map (fmap (ai env ds)) ts)
1293 ai env ds (PRefl fc tm) = PRefl fc (ai env ds tm)
1294 ai env ds (PUnifyLog tm) = PUnifyLog (ai env ds tm)
1295 ai env ds (PNoImplicits tm) = PNoImplicits (ai env ds tm)
1296 ai env ds tm = tm
1298 handleErr (Left err) = PElabError err
1299 handleErr (Right x) = x
1301-- if in a pattern, and there are no arguments, and there's no possible
1302-- names with zero explicit arguments, don't add implicits.
1304aiFn :: Bool -> Bool -> IState -> FC -> Name -> [[T.Text]] -> [PArg] -> Either Err PTerm
1305aiFn inpat True ist fc f ds []
1306 = case lookupDef f (tt_ctxt ist) of
1307 [] -> Right $ PPatvar fc f
1308 alts -> let ialts = lookupCtxtName f (idris_implicits ist) in
1309 -- trace (show f ++ " " ++ show (fc, any (all imp) ialts, ialts, any constructor alts)) $
1310 if (not (vname f) || tcname f
1311 || any (conCaf (tt_ctxt ist)) ialts)
1312-- any constructor alts || any allImp ialts))
1313 then aiFn inpat False ist fc f ds [] -- use it as a constructor
1314 else Right $ PPatvar fc f
1315 where imp (PExp _ _ _ _) = False
1316 imp _ = True
1317-- allImp [] = False
1318 allImp xs = all imp xs
1319 constructor (TyDecl (DCon _ _) _) = True
1320 constructor _ = False
1322 conCaf ctxt (n, cia) = isDConName n ctxt && allImp cia
1324 vname (UN n) = True -- non qualified
1325 vname _ = False
1327aiFn inpat expat ist fc f ds as
1328 | f `elem` primNames = Right $ PApp fc (PRef fc f) as
1329aiFn inpat expat ist fc f ds as
1330 -- This is where namespaces get resolved by adding PAlternative
1331 = do let ns = lookupCtxtName f (idris_implicits ist)
1332 let nh = filter (\(n, _) -> notHidden n) ns
1333 let ns' = case trimAlts ds nh of
1334 [] -> nh
1335 x -> x
1336 case ns' of
1337 [(f',ns)] -> Right $ mkPApp fc (length ns) (PRef fc f') (insertImpl ns as)
1338 [] -> if f `elem` (map fst (idris_metavars ist))
1339 then Right $ PApp fc (PRef fc f) as
1340 else Right $ mkPApp fc (length as) (PRef fc f) as
1341 alts -> Right $
1342 PAlternative True $
1343 map (\(f', ns) -> mkPApp fc (length ns) (PRef fc f')
1344 (insertImpl ns as)) alts
1345 where
1346 trimAlts [] alts = alts
1347 trimAlts ns alts
1348 = filter (\(x, _) -> any (\d -> d `isPrefixOf` nspace x) ns) alts
1350 nspace (NS _ s) = s
1351 nspace _ = []
1353 notHidden n = case getAccessibility n of
1354 Hidden -> False
1355 _ -> True
1357 getAccessibility n
1358 = case lookupDefAcc n False (tt_ctxt ist) of
1359 [(n,t)] -> t
1360 _ -> Public
1363 insertImpl :: [PArg] -> [PArg] -> [PArg]
1364 insertImpl (PExp p l ty _ : ps) (PExp _ _ tm d : given) =
1365 PExp p l tm d : insertImpl ps given
1366 insertImpl (PConstraint p l ty _ : ps) (PConstraint _ _ tm d : given) =
1367 PConstraint p l tm d : insertImpl ps given
1368 insertImpl (PConstraint p l ty d : ps) given =
1369 PConstraint p l (PResolveTC fc) d : insertImpl ps given
1370 insertImpl (PImp p _ l n ty d : ps) given =
1371 case find n given [] of
1372 Just (tm, given') -> PImp p False l n tm "" : insertImpl ps given'
1373 Nothing -> PImp p True l n Placeholder "" : insertImpl ps given
1374 insertImpl (PTacImplicit p l n sc' ty d : ps) given =
1375 let sc = addImpl ist sc' in
1376 case find n given [] of
1377 Just (tm, given') -> PTacImplicit p l n sc tm "" : insertImpl ps given'
1378 Nothing -> if inpat
1379 then PTacImplicit p l n sc Placeholder "" : insertImpl ps given
1380 else PTacImplicit p l n sc sc "" : insertImpl ps given
1381 insertImpl expected [] = []
1382 insertImpl _ given = given
1384 find n [] acc = Nothing
1385 find n (PImp _ _ _ n' t _ : gs) acc
1386 | n == n' = Just (t, reverse acc ++ gs)
1387 find n (PTacImplicit _ _ n' _ t _ : gs) acc
1388 | n == n' = Just (t, reverse acc ++ gs)
1389 find n (g : gs) acc = find n gs (g : acc)
1391-- replace non-linear occurrences with _
1392-- ASSUMPTION: This is called before adding 'alternatives' because otherwise
1393-- it is hard to get right!
1395stripLinear :: IState -> PTerm -> PTerm
1396stripLinear i tm = evalState (sl tm) [] where
1397 sl :: PTerm -> State [Name] PTerm
1398 sl (PRef fc f)
1399 | (_:_) <- lookupTy f (tt_ctxt i)
1400 = return $ PRef fc f
1401 | otherwise = do ns <- get
1402 if (f `elem` ns)
1403 then return Placeholder
1404 else do put (f : ns)
1405 return (PRef fc f)
1406 sl (PPatvar fc f)
1407 = do ns <- get
1408 if (f `elem` ns)
1409 then return Placeholder
1410 else do put (f : ns)
1411 return (PPatvar fc f)
1412 sl (PApp fc fn args) = do fn' <- sl fn
1413 args' <- mapM slA args
1414 return $ PApp fc fn' args'
1415 where slA (PImp p m l n t d) = do t' <- sl t
1416 return $ PImp p m l n t' d
1417 slA (PExp p l t d) = do t' <- sl t
1418 return $ PExp p l t' d
1419 slA (PConstraint p l t d)
1420 = do t' <- sl t
1421 return $ PConstraint p l t' d
1422 slA (PTacImplicit p l n sc t d)
1423 = do t' <- sl t
1424 return $ PTacImplicit p l n sc t' d
1425 sl x = return x
1427-- Remove functions which aren't applied to anything, which must then
1428-- be resolved by unification. Assume names resolved and alternatives
1429-- filled in (so no ambiguity).
1431stripUnmatchable :: IState -> PTerm -> PTerm
1432stripUnmatchable i (PApp fc fn args) = PApp fc fn (fmap (fmap su) args) where
1433 su :: PTerm -> PTerm
1434 su (PRef fc f)
1435 | (Bind n (Pi t) sc :_) <- lookupTy f (tt_ctxt i)
1436 = Placeholder
1437 su (PApp fc fn args)
1438 = PApp fc fn (fmap (fmap su) args)
1439 su (PAlternative b alts)
1440 = let alts' = filter (/= Placeholder) (map su alts) in
1441 if null alts' then Placeholder
1442 else PAlternative b alts'
1443 su (PPair fc l r) = PPair fc (su l) (su r)
1444 su (PDPair fc l t r) = PDPair fc (su l) (su t) (su r)
1445 su t = t
1446stripUnmatchable i tm = tm
1448mkPApp fc a f [] = f
1449mkPApp fc a f as = let rest = drop a as in
1450 appRest fc (PApp fc f (take a as)) rest
1451 where
1452 appRest fc f [] = f
1453 appRest fc f (a : as) = appRest fc (PApp fc f [a]) as
1455-- Find 'static' argument positions
1456-- (the declared ones, plus any names in argument position in the declared
1457-- statics)
1458-- FIXME: It's possible that this really has to happen after elaboration
1460findStatics :: IState -> PTerm -> (PTerm, [Bool])
1461findStatics ist tm = trace (showImp Nothing True False tm) $
1462 let (ns, ss) = fs tm in
1463 runState (pos ns ss tm) []
1464 where fs (PPi p n t sc)
1465 | Static <- pstatic p
1466 = let (ns, ss) = fs sc in
1467 (namesIn [] ist t : ns, n : ss)
1468 | otherwise = let (ns, ss) = fs sc in
1469 (ns, ss)
1470 fs _ = ([], [])
1472 inOne n ns = length (filter id (map (elem n) ns)) == 1
1474 pos ns ss (PPi p n t sc)
1475 | elem n ss = do sc' <- pos ns ss sc
1476 spos <- get
1477 put (True : spos)
1478 return (PPi (p { pstatic = Static }) n t sc')
1479 | otherwise = do sc' <- pos ns ss sc
1480 spos <- get
1481 put (False : spos)
1482 return (PPi p n t sc')
1483 pos ns ss t = return t
1485-- for 6.12/7 compatibility
1486data EitherErr a b = LeftErr a | RightOK b
1488instance Monad (EitherErr a) where
1489 return = RightOK
1491 (LeftErr e) >>= k = LeftErr e
1492 RightOK v >>= k = k v
1494toEither (LeftErr e) = Left e
1495toEither (RightOK ho) = Right ho
1497-- syntactic match of a against b, returning pair of variables in a
1498-- and what they match. Returns the pair that failed if not a match.
1500matchClause :: IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
1501matchClause = matchClause' False
1503matchClause' :: Bool -> IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
1504matchClause' names i x y = checkRpts $ match (fullApp x) (fullApp y) where
1505 matchArg x y = match (fullApp (getTm x)) (fullApp (getTm y))
1507 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
1508 fullApp x = x
1510 match' x y = match (fullApp x) (fullApp y)
1511 match (PApp _ (PRef _ (NS (UN fi) [b])) [_,_,x]) x'
1512 | fi == txt "fromInteger" && b == txt "builtins",
1513 PConstant (I _) <- getTm x = match (getTm x) x'
1514 match x' (PApp _ (PRef _ (NS (UN fi) [b])) [_,_,x])
1515 | fi == txt "fromInteger" && b == txt "builtins",
1516 PConstant (I _) <- getTm x = match (getTm x) x'
1517 match (PApp _ (PRef _ (UN l)) [_,x]) x' | l == txt "lazy" = match (getTm x) x'
1518 match x (PApp _ (PRef _ (UN l)) [_,x']) | l == txt "lazy" = match x (getTm x')
1519 match (PApp _ f args) (PApp _ f' args')
1520 | length args == length args'
1521 = do mf <- match' f f'
1522 ms <- zipWithM matchArg args args'
1523 return (mf ++ concat ms)
1524-- match (PRef _ n) (PRef _ n') | n == n' = return []
1525-- | otherwise = Nothing
1526 match (PRef f n) (PApp _ x []) = match (PRef f n) x
1527 match (PPatvar f n) xr = match (PRef f n) xr
1528 match xr (PPatvar f n) = match xr (PRef f n)
1529 match (PApp _ x []) (PRef f n) = match x (PRef f n)
1530 match (PRef _ n) tm@(PRef _ n')
1531 | n == n' && not names &&
1532 (not (isConName n (tt_ctxt i) || isFnName n (tt_ctxt i))
1533 || tm == Placeholder)
1534 = return [(n, tm)]
1535 | n == n' = return []
1536 match (PRef _ n) tm
1537 | not names && (not (isConName n (tt_ctxt i) ||
1538 isFnName n (tt_ctxt i)) || tm == Placeholder)
1539 = return [(n, tm)]
1540 match (PEq _ l r) (PEq _ l' r') = do ml <- match' l l'
1541 mr <- match' r r'
1542 return (ml ++ mr)
1543 match (PRewrite _ l r _) (PRewrite _ l' r' _)
1544 = do ml <- match' l l'
1545 mr <- match' r r'
1546 return (ml ++ mr)
1547 match (PTyped l r) (PTyped l' r') = do ml <- match l l'
1548 mr <- match r r'
1549 return (ml ++ mr)
1550 match (PTyped l r) x = match l x
1551 match x (PTyped l r) = match x l
1552 match (PPair _ l r) (PPair _ l' r') = do ml <- match' l l'
1553 mr <- match' r r'
1554 return (ml ++ mr)
1555 match (PDPair _ l t r) (PDPair _ l' t' r') = do ml <- match' l l'
1556 mt <- match' t t'
1557 mr <- match' r r'
1558 return (ml ++ mt ++ mr)
1559 match (PAlternative a as) (PAlternative a' as')
1560 = do ms <- zipWithM match' as as'
1561 return (concat ms)
1562 match a@(PAlternative _ as) b
1563 = do let ms = zipWith match' as (repeat b)
1564 case (rights (map toEither ms)) of
1565 (x: _) -> return x
1566 _ -> LeftErr (a, b)
1567 match (PCase _ _ _) _ = return [] -- lifted out
1568 match (PMetavar _) _ = return [] -- modified
1569 match (PInferRef _ _) _ = return [] -- modified
1570 match (PQuote _) _ = return []
1571 match (PProof _) _ = return []
1572 match (PTactics _) _ = return []
1573 match (PRefl _ _) (PRefl _ _) = return []
1574 match (PResolveTC _) (PResolveTC _) = return []
1575 match (PTrue _) (PTrue _) = return []
1576 match (PFalse _) (PFalse _) = return []
1577 match (PReturn _) (PReturn _) = return []
1578 match (PPi _ _ t s) (PPi _ _ t' s') = do mt <- match' t t'
1579 ms <- match' s s'
1580 return (mt ++ ms)
1581 match (PLam _ t s) (PLam _ t' s') = do mt <- match' t t'
1582 ms <- match' s s'
1583 return (mt ++ ms)
1584 match (PLet _ t ty s) (PLet _ t' ty' s') = do mt <- match' t t'
1585 mty <- match' ty ty'
1586 ms <- match' s s'
1587 return (mt ++ mty ++ ms)
1588 match (PHidden x) (PHidden y) = match' x y
1589 match (PUnifyLog x) y = match' x y
1590 match x (PUnifyLog y) = match' x y
1591 match (PNoImplicits x) y = match' x y
1592 match x (PNoImplicits y) = match' x y
1593 match Placeholder _ = return []
1594 match _ Placeholder = return []
1595 match (PResolveTC _) _ = return []
1596 match a b | a == b = return []
1597 | otherwise = LeftErr (a, b)
1599 checkRpts (RightOK ms) = check ms where
1600 check ((n,t):xs)
1601 | Just t' <- lookup n xs = if t/=t' && t/=Placeholder && t'/=Placeholder
1602 then Left (t, t')
1603 else check xs
1604 check (_:xs) = check xs
1605 check [] = Right ms
1606 checkRpts (LeftErr x) = Left x
1608substMatches :: [(Name, PTerm)] -> PTerm -> PTerm
1609substMatches ms = substMatchesShadow ms []
1611substMatchesShadow :: [(Name, PTerm)] -> [Name] -> PTerm -> PTerm
1612substMatchesShadow [] shs t = t
1613substMatchesShadow ((n,tm):ns) shs t
1614 = substMatchShadow n shs tm (substMatchesShadow ns shs t)
1616substMatch :: Name -> PTerm -> PTerm -> PTerm
1617substMatch n = substMatchShadow n []
1619substMatchShadow :: Name -> [Name] -> PTerm -> PTerm -> PTerm
1620substMatchShadow n shs tm t = sm shs t where
1621 sm xs (PRef _ n') | n == n' = tm
1622 sm xs (PLam x t sc) = PLam x (sm xs t) (sm xs sc)
1623 sm xs (PPi p x t sc)
1624 | x `elem` xs
1625 = let x' = nextName x in
1626 PPi p x' (sm (x':xs) (substMatch x (PRef emptyFC x') t))
1627 (sm (x':xs) (substMatch x (PRef emptyFC x') sc))
1628 | otherwise = PPi p x (sm xs t) (sm (x : xs) sc)
1629 sm xs (PApp f x as) = fullApp $ PApp f (sm xs x) (map (fmap (sm xs)) as)
1630 sm xs (PCase f x as) = PCase f (sm xs x) (map (pmap (sm xs)) as)
1631 sm xs (PEq f x y) = PEq f (sm xs x) (sm xs y)
1632 sm xs (PRewrite f x y tm) = PRewrite f (sm xs x) (sm xs y)
1633 (fmap (sm xs) tm)
1634 sm xs (PTyped x y) = PTyped (sm xs x) (sm xs y)
1635 sm xs (PPair f x y) = PPair f (sm xs x) (sm xs y)
1636 sm xs (PDPair f x t y) = PDPair f (sm xs x) (sm xs t) (sm xs y)
1637 sm xs (PAlternative a as) = PAlternative a (map (sm xs) as)
1638 sm xs (PHidden x) = PHidden (sm xs x)
1639 sm xs (PUnifyLog x) = PUnifyLog (sm xs x)
1640 sm xs (PNoImplicits x) = PNoImplicits (sm xs x)
1641 sm xs x = x
1643 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
1644 fullApp x = x
1646shadow :: Name -> Name -> PTerm -> PTerm
1647shadow n n' t = sm t where
1648 sm (PRef fc x) | n == x = PRef fc n'
1649 sm (PLam x t sc) | n /= x = PLam x (sm t) (sm sc)
1650 sm (PPi p x t sc) | n /=x = PPi p x (sm t) (sm sc)
1651 sm (PLet x t v sc) | n /= x = PLet x (sm t) (sm v) (sm sc)
1652 sm (PApp f x as) = PApp f (sm x) (map (fmap sm) as)
1653 sm (PAppBind f x as) = PAppBind f (sm x) (map (fmap sm) as)
1654 sm (PCase f x as) = PCase f (sm x) (map (pmap sm) as)
1655 sm (PEq f x y) = PEq f (sm x) (sm y)
1656 sm (PRewrite f x y tm) = PRewrite f (sm x) (sm y) (fmap sm tm)
1657 sm (PTyped x y) = PTyped (sm x) (sm y)
1658 sm (PPair f x y) = PPair f (sm x) (sm y)
1659 sm (PDPair f x t y) = PDPair f (sm x) (sm t) (sm y)
1660 sm (PAlternative a as) = PAlternative a (map sm as)
1661 sm (PTactics ts) = PTactics (map (fmap sm) ts)
1662 sm (PProof ts) = PProof (map (fmap sm) ts)
1663 sm (PHidden x) = PHidden (sm x)
1664 sm (PUnifyLog x) = PUnifyLog (sm x)
1665 sm (PNoImplicits x) = PNoImplicits (sm x)
1666 sm x = x
1668-- Rename any binders which are repeated (so that we don't have to mess
1669-- about with shadowing anywhere else).
1671mkUniqueNames :: [Name] -> PTerm -> PTerm
1672mkUniqueNames env tm = evalState (mkUniq tm) env where
1673 inScope = boundNamesIn tm
1675 mkUniqA arg = do t' <- mkUniq (getTm arg)
1676 return (arg { getTm = t' })
1678 -- FIXME: Probably ought to do this for completeness! It's fine as
1679 -- long as there are no bindings inside tactics though.
1680 mkUniqT tac = return tac
1682 mkUniq :: PTerm -> State [Name] PTerm
1683 mkUniq (PLam n ty sc)
1684 = do env <- get
1685 (n', sc') <-
1686 if n `elem` env
1687 then do let n' = uniqueName n (env ++ inScope)
1688 return (n', shadow n n' sc)
1689 else return (n, sc)
1690 put (n' : env)
1691 ty' <- mkUniq ty
1692 sc'' <- mkUniq sc'
1693 return $! PLam n' ty' sc''
1694 mkUniq (PPi p n ty sc)
1695 = do env <- get
1696 (n', sc') <-
1697 if n `elem` env
1698 then do let n' = uniqueName n (env ++ inScope)
1699 return (n', shadow n n' sc)
1700 else return (n, sc)
1701 put (n' : env)
1702 ty' <- mkUniq ty
1703 sc'' <- mkUniq sc'
1704 return $! PPi p n' ty' sc''
1705 mkUniq (PLet n ty val sc)
1706 = do env <- get
1707 (n', sc') <-
1708 if n `elem` env
1709 then do let n' = uniqueName n (env ++ inScope)
1710 return (n', shadow n n' sc)
1711 else return (n, sc)
1712 put (n' : env)
1713 ty' <- mkUniq ty; val' <- mkUniq val
1714 sc'' <- mkUniq sc'
1715 return $! PLet n' ty' val' sc''
1716 mkUniq (PApp fc t args)
1717 = do t' <- mkUniq t
1718 args' <- mapM mkUniqA args
1719 return $! PApp fc t' args'
1720 mkUniq (PAppBind fc t args)
1721 = do t' <- mkUniq t
1722 args' <- mapM mkUniqA args
1723 return $! PAppBind fc t' args'
1724 mkUniq (PCase fc t alts)
1725 = do t' <- mkUniq t
1726 alts' <- mapM (\(x,y)-> do x' <- mkUniq x; y' <- mkUniq y
1727 return (x', y')) alts
1728 return $! PCase fc t' alts'
1729 mkUniq (PPair fc l r)
1730 = do l' <- mkUniq l; r' <- mkUniq r
1731 return $! PPair fc l' r'
1732 mkUniq (PDPair fc l t r)
1733 = do l' <- mkUniq l; t' <- mkUniq t; r' <- mkUniq r
1734 return $! PDPair fc l' t' r'
1735 mkUniq (PAlternative b as)
1736 = liftM (PAlternative b) (mapM mkUniq as)
1737 mkUniq (PHidden t) = liftM PHidden (mkUniq t)
1738 mkUniq (PUnifyLog t) = liftM PUnifyLog (mkUniq t)
1739 mkUniq (PDisamb n t) = liftM (PDisamb n) (mkUniq t)
1740 mkUniq (PNoImplicits t) = liftM PNoImplicits (mkUniq t)
1741 mkUniq (PProof ts) = liftM PProof (mapM mkUniqT ts)
1742 mkUniq (PTactics ts) = liftM PTactics (mapM mkUniqT ts)
1743 mkUniq t = return t