on 3f04ad4 help sign in
Idris-dev/src/Idris/AbsSyntax.hs
2614 lines 111 kB history raw
1{-|
2Module : Idris.AbsSyntax
3Description : Provides Idris' core data definitions and utility code.
4Copyright :
5License : BSD3
6Maintainer : The Idris Community.
7-}
9{-# LANGUAGE DeriveFunctor, FlexibleContexts, PatternGuards #-}
11module Idris.AbsSyntax(
12 module Idris.AbsSyntax
13 , module Idris.AbsSyntaxTree
14 ) where
16import Idris.AbsSyntaxTree
17import Idris.Colours
18import Idris.Core.Evaluate
19import Idris.Core.TT
20import Idris.Docstrings
21import Idris.IdeMode hiding (Opt(..))
22import Idris.Options
23import IRTS.CodegenCommon
25import System.Directory (canonicalizePath, doesFileExist)
26import System.IO
28import Control.Applicative
29import Control.Monad.State
30import Prelude hiding (Applicative, Foldable, Traversable, (<$>))
32import Data.Either
33import Data.List hiding (insert, union)
34import qualified Data.Map as M
35import Data.Maybe
36import qualified Data.Set as S
37import qualified Data.Text as T
38import System.IO.Error (tryIOError)
40import Data.Generics.Uniplate.Data (descend, descendM)
42import Debug.Trace
43import Util.DynamicLinker
44import Util.Pretty
45import Util.System
47getContext :: Idris Context
48getContext = do i <- getIState; return (tt_ctxt i)
50forCodegen :: Codegen -> [(Codegen, a)] -> [a]
51forCodegen tgt xs = [x | (tgt', x) <- xs, eqLang tgt tgt']
52 where
53 eqLang (Via _ x) (Via _ y) = x == y
54 eqLang Bytecode Bytecode = True
55 eqLang _ _ = False
57getObjectFiles :: Codegen -> Idris [FilePath]
58getObjectFiles tgt = do i <- getIState; return (forCodegen tgt $ idris_objs i)
60addObjectFile :: Codegen -> FilePath -> Idris ()
61addObjectFile tgt f = do i <- getIState; putIState $ i { idris_objs = nub $ (tgt, f) : idris_objs i }
63getLibs :: Codegen -> Idris [String]
64getLibs tgt = do i <- getIState; return (forCodegen tgt $ idris_libs i)
66addLib :: Codegen -> String -> Idris ()
67addLib tgt f = do i <- getIState; putIState $ i { idris_libs = nub $ (tgt, f) : idris_libs i }
69getFlags :: Codegen -> Idris [String]
70getFlags tgt = do i <- getIState; return (forCodegen tgt $ idris_cgflags i)
72addFlag :: Codegen -> String -> Idris ()
73addFlag tgt f = do i <- getIState; putIState $ i { idris_cgflags = nub $ (tgt, f) : idris_cgflags i }
75addDyLib :: [String] -> Idris (Either DynamicLib String)
76addDyLib libs = do i <- getIState
77 let ls = idris_dynamic_libs i
78 let importdirs = opt_importdirs (idris_options i)
79 case mapMaybe (findDyLib ls) libs of
80 x:_ -> return (Left x)
81 [] -> do
82 handle <- lift . lift .
83 mapM (\l -> catchIO (tryLoadLib importdirs l)
84 (\_ -> return Nothing)) $ libs
85 case msum handle of
86 Nothing -> return (Right $ "Could not load dynamic alternatives \"" ++
87 intercalate "," libs ++ "\"")
88 Just x -> do putIState $ i { idris_dynamic_libs = x:ls }
89 return (Left x)
90 where findDyLib :: [DynamicLib] -> String -> Maybe DynamicLib
91 findDyLib [] _ = Nothing
92 findDyLib (lib:libs') l | l == lib_name lib = Just lib
93 | otherwise = findDyLib libs' l
95getAutoImports :: Idris [FilePath]
96getAutoImports = do i <- getIState
97 return (opt_autoImport (idris_options i))
99addAutoImport :: FilePath -> Idris ()
100addAutoImport fp = do i <- getIState
101 let opts = idris_options i
102 put (i { idris_options = opts { opt_autoImport =
103 fp : opt_autoImport opts } } )
105addDefinedName :: Name -> Idris ()
106addDefinedName n = do ist <- getIState
107 putIState $ ist { idris_inmodule = S.insert n (idris_inmodule ist) }
109getDefinedNames :: Idris [Name]
110getDefinedNames = do ist <- getIState
111 return (S.toList (idris_inmodule ist))
113addTT :: Term -> Idris (Maybe Term)
114addTT t = do ist <- getIState
115 case M.lookup t (idris_ttstats ist) of
116 Nothing -> do let tt' = M.insert t (1, t) (idris_ttstats ist)
117 putIState $ ist { idris_ttstats = tt' }
118 return Nothing
119 Just (i, t') -> do let tt' = M.insert t' (i + 1, t') (idris_ttstats ist)
120 putIState $ ist { idris_ttstats = tt' }
121 return (Just t')
123dumpTT :: Idris ()
124dumpTT = do ist <- get
125 let sts = sortBy count (M.toList (idris_ttstats ist))
126 mapM_ dump sts
127 return ()
128 where
129 count (_,x) (_,y) = compare y x
130 dump (tm, val) = runIO $ putStrLn (show val ++ ": " ++ show tm)
132addHdr :: Codegen -> String -> Idris ()
133addHdr tgt f = do i <- getIState; putIState $ i { idris_hdrs = nub $ (tgt, f) : idris_hdrs i }
135addImported :: Bool -> FilePath -> Idris ()
136addImported pub f
137 = do i <- getIState
138 putIState $ i { idris_imported = nub $ (f, pub) : idris_imported i }
140addLangExt :: LanguageExt -> Idris ()
141addLangExt e = do i <- getIState
142 putIState $ i {
143 idris_language_extensions = e : idris_language_extensions i
144 }
146-- | Transforms are organised by the function being applied on the lhs
147-- of the transform, to make looking up appropriate transforms quicker
148addTrans :: Name -> (Term, Term) -> Idris ()
149addTrans basefn t
150 = do i <- getIState
151 let t' = case lookupCtxtExact basefn (idris_transforms i) of
152 Just def -> (t : def)
153 Nothing -> [t]
154 putIState $ i { idris_transforms = addDef basefn t'
155 (idris_transforms i) }
157-- | Add transformation rules from a definition, which will reverse the
158-- definition for an error to make it more readable
159addErrRev :: (Term, Term) -> Idris ()
160addErrRev t = do i <- getIState
161 putIState $ i { idris_errRev = t : idris_errRev i }
163-- | Say that the name should always be reduced in error messages, to
164-- help readability/error reflection
165addErrReduce :: Name -> Idris ()
166addErrReduce t = do i <- getIState
167 putIState $ i { idris_errReduce = t : idris_errReduce i }
169addErasureUsage :: Name -> Int -> Idris ()
170addErasureUsage n i = do ist <- getIState
171 putIState $ ist { idris_erasureUsed = (n, i) : idris_erasureUsed ist }
173addExport :: Name -> Idris ()
174addExport n = do ist <- getIState
175 putIState $ ist { idris_exports = n : idris_exports ist }
177addUsedName :: FC -> Name -> Name -> Idris ()
178addUsedName fc n arg
179 = do ist <- getIState
180 case lookupTyName n (tt_ctxt ist) of
181 [(n', ty)] -> addUsage n' 0 ty
182 [] -> throwError (At fc (NoSuchVariable n))
183 xs -> throwError (At fc (CantResolveAlts (map fst xs)))
184 where addUsage n i (Bind x _ sc) | x == arg = do addIBC (IBCUsage (n, i))
185 addErasureUsage n i
186 | otherwise = addUsage n (i + 1) sc
187 addUsage _ _ _ = throwError (At fc (Msg ("No such argument name " ++ show arg)))
189getErasureUsage :: Idris [(Name, Int)]
190getErasureUsage = do ist <- getIState;
191 return (idris_erasureUsed ist)
193getExports :: Idris [Name]
194getExports = do ist <- getIState
195 return (idris_exports ist)
197totcheck :: (FC, Name) -> Idris ()
198totcheck n = do i <- getIState; putIState $ i { idris_totcheck = idris_totcheck i ++ [n] }
200defer_totcheck :: (FC, Name) -> Idris ()
201defer_totcheck n
202 = do i <- getIState;
203 putIState $ i { idris_defertotcheck = nub (idris_defertotcheck i ++ [n]) }
205clear_totcheck :: Idris ()
206clear_totcheck = do i <- getIState; putIState $ i { idris_totcheck = [] }
208setFlags :: Name -> [FnOpt] -> Idris ()
209setFlags n fs = do i <- getIState; putIState $ i { idris_flags = addDef n fs (idris_flags i) }
211addFnOpt :: Name -> FnOpt -> Idris ()
212addFnOpt n f = do i <- getIState
213 let fls = case lookupCtxtExact n (idris_flags i) of
214 Nothing -> []
215 Just x -> x
216 setFlags n (f : fls)
218setFnInfo :: Name -> FnInfo -> Idris ()
219setFnInfo n fs = do i <- getIState; putIState $ i { idris_fninfo = addDef n fs (idris_fninfo i) }
221setAccessibility :: Name -> Accessibility -> Idris ()
222setAccessibility n a
223 = do i <- getIState
224 let ctxt = setAccess n a (tt_ctxt i)
225 putIState $ i { tt_ctxt = ctxt }
227-- | get the accessibility of a name outside this module
228getFromHideList :: Name -> Idris (Maybe Accessibility)
229getFromHideList n = do i <- getIState
230 return $ lookupCtxtExact n (hide_list i)
232setTotality :: Name -> Totality -> Idris ()
233setTotality n a
234 = do i <- getIState
235 let ctxt = setTotal n a (tt_ctxt i)
236 putIState $ i { tt_ctxt = ctxt }
238setInjectivity :: Name -> Injectivity -> Idris ()
239setInjectivity n a
240 = do i <- getIState
241 let ctxt = setInjective n a (tt_ctxt i)
242 putIState $ i { tt_ctxt = ctxt }
244getTotality :: Name -> Idris Totality
245getTotality n
246 = do i <- getIState
247 case lookupTotal n (tt_ctxt i) of
248 [t] -> return t
249 _ -> return (Total [])
251-- Get coercions which might return the required type
252getCoercionsTo :: IState -> Type -> [Name]
253getCoercionsTo i ty =
254 let cs = idris_coercions i
255 (fn,_) = unApply (getRetTy ty) in
256 findCoercions fn cs
257 where findCoercions _ [] = []
258 findCoercions t (n : ns) =
259 let ps = case lookupTy n (tt_ctxt i) of
260 [ty'] -> case unApply (getRetTy (normalise (tt_ctxt i) [] ty')) of
261 (t', _) -> [n | t == t']
262 _ -> [] in
263 ps ++ findCoercions t ns
265addToCG :: Name -> CGInfo -> Idris ()
266addToCG n cg
267 = do i <- getIState
268 putIState $ i { idris_callgraph = addDef n cg (idris_callgraph i) }
270addCalls :: Name -> [Name] -> Idris ()
271addCalls n calls
272 = do i <- getIState
273 case lookupCtxtExact n (idris_callgraph i) of
274 Nothing -> addToCG n (CGInfo calls Nothing [] [])
275 Just (CGInfo cs ans scg used) ->
276 addToCG n (CGInfo (nub (calls ++ cs)) ans scg used)
278addTyInferred :: Name -> Idris ()
279addTyInferred n
280 = do i <- getIState
281 putIState $ i { idris_tyinfodata =
282 addDef n TIPartial (idris_tyinfodata i) }
284addTyInfConstraints :: FC -> [(Term, Term)] -> Idris ()
285addTyInfConstraints fc ts = do logLvl 2 $ "TI missing: " ++ show ts
286 mapM_ addConstraint ts
287 return ()
288 where addConstraint (x, y) = findMVApps x y
290 findMVApps x y
291 = do let (fx, argsx) = unApply x
292 let (fy, argsy) = unApply y
293 if (fx /= fy)
294 then do
295 tryAddMV fx y
296 tryAddMV fy x
297 else mapM_ addConstraint (zip argsx argsy)
299 tryAddMV (P _ mv _) y =
300 do ist <- get
301 case lookup mv (idris_metavars ist) of
302 Just _ -> addConstraintRule mv y
303 _ -> return ()
304 tryAddMV _ _ = return ()
306 addConstraintRule :: Name -> Term -> Idris ()
307 addConstraintRule n t
308 = do ist <- get
309 logLvl 1 $ "TI constraint: " ++ show (n, t)
310 case lookupCtxt n (idris_tyinfodata ist) of
311 [TISolution ts] ->
312 do mapM_ (checkConsistent t) ts
313 let ti' = addDef n (TISolution (t : ts))
314 (idris_tyinfodata ist)
315 put $ ist { idris_tyinfodata = ti' }
316 _ ->
317 do let ti' = addDef n (TISolution [t])
318 (idris_tyinfodata ist)
319 put $ ist { idris_tyinfodata = ti' }
321 -- Check a solution is consistent with previous solutions
322 -- Meaning: If heads are both data types, they had better be the
323 -- same.
324 checkConsistent :: Term -> Term -> Idris ()
325 checkConsistent x y =
326 do let (fx, _) = unApply x
327 let (fy, _) = unApply y
328 case (fx, fy) of
329 (P (TCon _ _) n _, P (TCon _ _) n' _) -> errWhen (n/=n')
330 (P (TCon _ _) n _, Constant _) -> errWhen True
331 (Constant _, P (TCon _ _) n' _) -> errWhen True
332 (P (DCon _ _ _) n _, P (DCon _ _ _) n' _) -> errWhen (n/=n')
333 _ -> return ()
335 where errWhen True
336 = throwError (At fc
337 (CantUnify False (x, Nothing) (y, Nothing) (Msg "") [] 0))
338 errWhen False = return ()
340isTyInferred :: Name -> Idris Bool
341isTyInferred n
342 = do i <- getIState
343 case lookupCtxt n (idris_tyinfodata i) of
344 [TIPartial] -> return True
345 _ -> return False
347-- | Adds error handlers for a particular function and argument. If
348-- names are ambiguous, all matching handlers are updated.
349addFunctionErrorHandlers :: Name -> Name -> [Name] -> Idris ()
350addFunctionErrorHandlers f arg hs =
351 do i <- getIState
352 let oldHandlers = idris_function_errorhandlers i
353 let newHandlers = flip (addDef f) oldHandlers $
354 case lookupCtxtExact f oldHandlers of
355 Nothing -> M.singleton arg (S.fromList hs)
356 Just (oldHandlers) -> M.insertWith S.union arg (S.fromList hs) oldHandlers
357 -- will always be one of those two, thus no extra case
358 putIState $ i { idris_function_errorhandlers = newHandlers }
360-- | Trace all the names in a call graph starting at the given name
361getAllNames :: Name -> Idris [Name]
362getAllNames n = do i <- getIState
363 case getCGAllNames i n of
364 Just ns -> return ns
365 Nothing -> do ns <- allNames [] n
366 addCGAllNames i n ns
367 return ns
369getCGAllNames :: IState -> Name -> Maybe [Name]
370getCGAllNames i n = case lookupCtxtExact n (idris_callgraph i) of
371 Just ci -> allCalls ci
372 _ -> Nothing
374addCGAllNames :: IState -> Name -> [Name] -> Idris ()
375addCGAllNames i n ns
376 = case lookupCtxtExact n (idris_callgraph i) of
377 Just ci -> addToCG n (ci { allCalls = Just ns })
378 _ -> addToCG n (CGInfo [] (Just ns) [] [])
380allNames :: [Name] -> Name -> Idris [Name]
381allNames ns n | n `elem` ns = return []
382allNames ns n = do i <- getIState
383 case getCGAllNames i n of
384 Just ns -> return ns
385 Nothing -> case lookupCtxtExact n (idris_callgraph i) of
386 Just ci ->
387 do more <- mapM (allNames (n:ns)) (calls ci)
388 let ns' = nub (n : concat more)
389 addCGAllNames i n ns'
390 return ns'
391 _ -> return [n]
393addCoercion :: Name -> Idris ()
394addCoercion n = do i <- getIState
395 putIState $ i { idris_coercions = nub $ n : idris_coercions i }
397addDocStr :: Name -> Docstring DocTerm -> [(Name, Docstring DocTerm)] -> Idris ()
398addDocStr n doc args
399 = do i <- getIState
400 putIState $ i { idris_docstrings = addDef n (doc, args) (idris_docstrings i) }
402addNameHint :: Name -> Name -> Idris ()
403addNameHint ty n
404 = do i <- getIState
405 ty' <- case lookupCtxtName ty (idris_implicits i) of
406 [(tyn, _)] -> return tyn
407 [] -> throwError (NoSuchVariable ty)
408 tyns -> throwError (CantResolveAlts (map fst tyns))
409 let ns' = case lookupCtxt ty' (idris_namehints i) of
410 [ns] -> ns ++ [n]
411 _ -> [n]
412 putIState $ i { idris_namehints = addDef ty' ns' (idris_namehints i) }
414getNameHints :: IState -> Name -> [Name]
415getNameHints _ (UN arr) | arr == txt "->" = [sUN "f",sUN "g"]
416getNameHints i n =
417 case lookupCtxt n (idris_namehints i) of
418 [ns] -> ns
419 _ -> []
421addDeprecated :: Name -> String -> Idris ()
422addDeprecated n reason = do
423 i <- getIState
424 putIState $ i { idris_deprecated = addDef n reason (idris_deprecated i) }
426getDeprecated :: Name -> Idris (Maybe String)
427getDeprecated n = do
428 i <- getIState
429 return $ lookupCtxtExact n (idris_deprecated i)
431addFragile :: Name -> String -> Idris ()
432addFragile n reason = do
433 i <- getIState
434 putIState $ i { idris_fragile = addDef n reason (idris_fragile i) }
436getFragile :: Name -> Idris (Maybe String)
437getFragile n = do
438 i <- getIState
439 return $ lookupCtxtExact n (idris_fragile i)
441push_estack :: Name -> Bool -> Idris ()
442push_estack n implementation
443 = do i <- getIState
444 putIState (i { elab_stack = (n, implementation) : elab_stack i })
446pop_estack :: Idris ()
447pop_estack = do i <- getIState
448 putIState (i { elab_stack = ptail (elab_stack i) })
449 where ptail [] = []
450 ptail (_ : xs) = xs
452-- | Add an interface implementation function.
453--
454-- Precondition: the implementation should have the correct type.
455--
456-- Dodgy hack 1: Put integer implementations first in the list so they are
457-- resolved by default.
458--
459-- Dodgy hack 2: put constraint chasers (ParentN) last
460addImplementation :: Bool -- ^ whether the name is an Integer implementation
461 -> Bool -- ^ whether to include the implementation in implementation search
462 -> Name -- ^ the name of the interface
463 -> Name -- ^ the name of the implementation
464 -> Idris ()
465addImplementation int res n i
466 = do ist <- getIState
467 case lookupCtxt n (idris_interfaces ist) of
468 [CI a b c d e f g ins fds] ->
469 do let cs = addDef n (CI a b c d e f g (addI i ins) fds) (idris_interfaces ist)
470 putIState $ ist { idris_interfaces = cs }
471 _ -> do let cs = addDef n (CI (sMN 0 "none") [] [] [] [] [] [] [(i, res)] []) (idris_interfaces ist)
472 putIState $ ist { idris_interfaces = cs }
473 where addI, insI :: Name -> [(Name, Bool)] -> [(Name, Bool)]
474 addI i ins | int = (i, res) : ins
475 | chaser n = ins ++ [(i, res)]
476 | otherwise = insI i ins
477 insI i [] = [(i, res)]
478 insI i (n : ns) | chaser (fst n) = (i, res) : n : ns
479 | otherwise = n : insI i ns
481 chaser (SN (ParentN _ _)) = True
482 chaser (NS n _) = chaser n
483 chaser _ = False
485-- | Add a privileged implementation - one which implementation search will
486-- happily resolve immediately if it is type correct This is used for
487-- naming parent implementations when defining an implementation with
488-- constraints. Returns the old list, so we can revert easily at the
489-- end of a block
490addOpenImpl :: [Name] -> Idris [Name]
491addOpenImpl ns = do ist <- getIState
492 ns' <- mapM (checkValid ist) ns
493 let open = idris_openimpls ist
494 putIState $ ist { idris_openimpls = nub (ns' ++ open) }
495 return open
496 where
497 checkValid ist n
498 = case lookupCtxtName n (idris_implicits ist) of
499 [(n', _)] -> return n'
500 [] -> throwError (NoSuchVariable n)
501 more -> throwError (CantResolveAlts (map fst more))
503setOpenImpl :: [Name] -> Idris ()
504setOpenImpl ns = do ist <- getIState
505 putIState $ ist { idris_openimpls = ns }
507getOpenImpl :: Idris [Name]
508getOpenImpl = do ist <- getIState
509 return (idris_openimpls ist)
511addInterface :: Name -> InterfaceInfo -> Idris ()
512addInterface n i
513 = do ist <- getIState
514 let i' = case lookupCtxt n (idris_interfaces ist) of
515 [c] -> i { interface_implementations = interface_implementations c ++
516 interface_implementations i }
517 _ -> i
518 putIState $ ist { idris_interfaces = addDef n i' (idris_interfaces ist) }
520updateIMethods :: Name -> [(Name, PTerm)] -> Idris ()
521updateIMethods n meths
522 = do ist <- getIState
523 let i = case lookupCtxtExact n (idris_interfaces ist) of
524 Just c -> c { interface_methods = update (interface_methods c) }
525 Nothing -> error "Can't happen updateIMethods"
526 putIState $ ist { idris_interfaces = addDef n i (idris_interfaces ist) }
527 where
528 update [] = []
529 update (m@(n, (b, opts, t)) : rest)
530 | Just ty <- lookup n meths
531 = (n, (b, opts, ty)) : update rest
532 | otherwise = m : update rest
534addRecord :: Name -> RecordInfo -> Idris ()
535addRecord n ri = do ist <- getIState
536 putIState $ ist { idris_records = addDef n ri (idris_records ist) }
538addAutoHint :: Name -> Name -> Idris ()
539addAutoHint n hint =
540 do ist <- getIState
541 case lookupCtxtExact n (idris_autohints ist) of
542 Nothing ->
543 do let hs = addDef n [hint] (idris_autohints ist)
544 putIState $ ist { idris_autohints = hs }
545 Just nhints ->
546 do let hs = addDef n (hint : nhints) (idris_autohints ist)
547 putIState $ ist { idris_autohints = hs }
549getAutoHints :: Name -> Idris [Name]
550getAutoHints n = do ist <- getIState
551 case lookupCtxtExact n (idris_autohints ist) of
552 Nothing -> return []
553 Just ns -> return ns
555addIBC :: IBCWrite -> Idris ()
556addIBC ibc@(IBCDef n)
557 = do i <- getIState
558 when (notDef (ibc_write i)) $
559 putIState $ i { ibc_write = ibc : ibc_write i }
560 where notDef [] = True
561 notDef (IBCDef n': _) | n == n' = False
562 notDef (_ : is) = notDef is
563addIBC ibc = do i <- getIState; putIState $ i { ibc_write = ibc : ibc_write i }
565clearIBC :: Idris ()
566clearIBC = do i <- getIState; putIState $ i { ibc_write = [],
567 idris_inmodule = S.empty }
569resetNameIdx :: Idris ()
570resetNameIdx = do i <- getIState
571 put (i { idris_nameIdx = (0, emptyContext) })
573-- | Used to preserve sharing of names
574addNameIdx :: Name -> Idris (Int, Name)
575addNameIdx n = do i <- getIState
576 let (i', x) = addNameIdx' i n
577 putIState i'
578 return x
580addNameIdx' :: IState -> Name -> (IState, (Int, Name))
581addNameIdx' i n
582 = let idxs = snd (idris_nameIdx i) in
583 case lookupCtxt n idxs of
584 [x] -> (i, x)
585 _ -> let i' = fst (idris_nameIdx i) + 1 in
586 (i { idris_nameIdx = (i', addDef n (i', n) idxs) }, (i', n))
588getSymbol :: Name -> Idris Name
589getSymbol n = do i <- getIState
590 case M.lookup n (idris_symbols i) of
591 Just n' -> return n'
592 Nothing -> do let sym' = M.insert n n (idris_symbols i)
593 put (i { idris_symbols = sym' })
594 return n
596getHdrs :: Codegen -> Idris [String]
597getHdrs tgt = do i <- getIState; return (forCodegen tgt $ idris_hdrs i)
599getImported :: Idris [(FilePath, Bool)]
600getImported = do i <- getIState; return (idris_imported i)
602setErrSpan :: FC -> Idris ()
603setErrSpan x = do i <- getIState;
604 case (errSpan i) of
605 Nothing -> putIState $ i { errSpan = Just x }
606 Just _ -> return ()
608clearErr :: Idris ()
609clearErr = do i <- getIState
610 putIState $ i { errSpan = Nothing }
612getSO :: Idris (Maybe String)
613getSO = do i <- getIState
614 return (compiled_so i)
616setSO :: Maybe String -> Idris ()
617setSO s = do i <- getIState
618 putIState (i { compiled_so = s })
620getIState :: Idris IState
621getIState = get
623putIState :: IState -> Idris ()
624putIState = put
626updateIState :: (IState -> IState) -> Idris ()
627updateIState f = do i <- getIState
628 putIState $ f i
630withContext :: (IState -> Ctxt a) -> Name -> b -> (a -> Idris b) -> Idris b
631withContext ctx name dflt action = do
632 ist <- getIState
633 case lookupCtxt name (ctx ist) of
634 [x] -> action x
635 _ -> return dflt
637withContext_ :: (IState -> Ctxt a) -> Name -> (a -> Idris ()) -> Idris ()
638withContext_ ctx name action = withContext ctx name () action
640-- | A version of liftIO that puts errors into the exception type of
641-- the Idris monad
642runIO :: IO a -> Idris a
643runIO x = liftIO (tryIOError x) >>= either (throwError . Msg . show) return
644-- TODO: create specific Idris exceptions for specific IO errors such as "openFile: does not exist"
645--
646-- Issue #1738 on the issue tracker.
647-- https://github.com/idris-lang/Idris-dev/issues/1738
649getName :: Idris Int
650getName = do i <- getIState;
651 let idx = idris_name i;
652 putIState (i { idris_name = idx + 1 })
653 return idx
655-- | InternalApp keeps track of the real function application for
656-- making case splits from, not the application the programmer wrote,
657-- which doesn't have the whole context in any case other than top
658-- level definitions
659addInternalApp :: FilePath -> Int -> PTerm -> Idris ()
660addInternalApp fp l t
661 = do i <- getIState
662 -- We canonicalise the path to make "./Test/Module.idr" equal
663 -- to "Test/Module.idr"
664 exists <- runIO $ doesFileExist fp
665 when exists $
666 do fp' <- runIO $ canonicalizePath fp
667 putIState (i { idris_lineapps = ((fp', l), t) : idris_lineapps i })
669getInternalApp :: FilePath -> Int -> Idris PTerm
670getInternalApp fp l = do i <- getIState
671 -- We canonicalise the path to make
672 -- "./Test/Module.idr" equal to
673 -- "Test/Module.idr"
674 exists <- runIO $ doesFileExist fp
675 if exists
676 then do fp' <- runIO $ canonicalizePath fp
677 case lookup (fp', l) (idris_lineapps i) of
678 Just n' -> return n'
679 Nothing -> return Placeholder
680 -- TODO: What if it's not there?
681 else return Placeholder
683-- | Pattern definitions are only used for coverage checking, so erase
684-- them when we're done
685clearOrigPats :: Idris ()
686clearOrigPats = do i <- get
687 let ps = idris_patdefs i
688 let ps' = mapCtxt (\ (_,miss) -> ([], miss)) ps
689 put (i { idris_patdefs = ps' })
691-- | Erase types from Ps in the context (basically ending up with
692-- what's in the .ibc, which is all we need after all the analysis is
693-- done)
694clearPTypes :: Idris ()
695clearPTypes = do i <- get
696 let ctxt = tt_ctxt i
697 put (i { tt_ctxt = mapDefCtxt pErase ctxt })
698 where pErase (CaseOp c t tys orig _ cds)
699 = CaseOp c t tys orig [] (pErase' cds)
700 pErase x = x
701 pErase' (CaseDefs (cs, c) rs)
702 = let c' = (cs, fmap pEraseType c) in
703 CaseDefs c' rs
705checkUndefined :: FC -> Name -> Idris ()
706checkUndefined fc n
707 = do i <- getContext
708 case lookupTy n i of
709 (_:_) -> throwError . Msg $ show fc ++ ":" ++
710 show n ++ " already defined"
711 _ -> return ()
713isUndefined :: FC -> Name -> Idris Bool
714isUndefined _ n
715 = do i <- getContext
716 case lookupTyExact n i of
717 Just _ -> return False
718 _ -> return True
720setContext :: Context -> Idris ()
721setContext ctxt = do i <- getIState; putIState (i { tt_ctxt = ctxt } )
723updateContext :: (Context -> Context) -> Idris ()
724updateContext f = do i <- getIState; putIState (i { tt_ctxt = f (tt_ctxt i) } )
726addConstraints :: FC -> (Int, [UConstraint]) -> Idris ()
727addConstraints fc (v, cs)
728 = do tit <- typeInType
729 when (not tit) $ do
730 i <- getIState
731 let ctxt = tt_ctxt i
732 let ctxt' = ctxt { next_tvar = v }
733 let ics = insertAll (zip cs (repeat fc)) (idris_constraints i)
734 putIState $ i { tt_ctxt = ctxt', idris_constraints = ics }
735 where
736 insertAll [] c = c
737 insertAll ((ULE (UVal 0) _, fc) : cs) ics = insertAll cs ics
738 insertAll ((ULE x y, fc) : cs) ics | x == y = insertAll cs ics
739 insertAll ((c, fc) : cs) ics
740 = insertAll cs $ S.insert (ConstraintFC c fc) ics
742addDeferred = addDeferred' Ref
743addDeferredTyCon = addDeferred' (TCon 0 0)
745-- | Save information about a name that is not yet defined
746addDeferred' :: NameType
747 -> [(Name, (Int, Maybe Name, Type, [Name], Bool, Bool))]
748 -- ^ The Name is the name being made into a metavar,
749 -- the Int is the number of vars that are part of a
750 -- putative proof context, the Maybe Name is the
751 -- top-level function containing the new metavariable,
752 -- the Type is its type, and the Bool is whether :p is
753 -- allowed
754 -> Idris ()
755addDeferred' nt ns
756 = do mapM_ (\(n, (i, _, t, _, _, _)) -> updateContext (addTyDecl n nt (tidyNames S.empty t))) ns
757 mapM_ (\(n, _) -> when (not (n `elem` primDefs)) $ addIBC (IBCMetavar n)) ns
758 i <- getIState
759 putIState $ i { idris_metavars = map (\(n, (i, top, _, ns, isTopLevel, isDefinable)) ->
760 (n, (top, i, ns, isTopLevel, isDefinable))) ns ++
761 idris_metavars i }
762 where
763 -- 'tidyNames' is to generate user accessible names in case they are
764 -- needed in tactic scripts
765 tidyNames used (Bind (MN i x) b sc)
766 = let n' = uniqueNameSet (UN x) used in
767 Bind n' b $ tidyNames (S.insert n' used) sc
768 tidyNames used (Bind n b sc)
769 = let n' = uniqueNameSet n used in
770 Bind n' b $ tidyNames (S.insert n' used) sc
771 tidyNames _ b = b
773solveDeferred :: FC -> Name -> Idris ()
774solveDeferred fc n
775 = do i <- getIState
776 case lookup n (idris_metavars i) of
777 Just (_, _, _, _, False) ->
778 throwError $ At fc $ Msg ("Can't define hole " ++ show n ++ " as it depends on other holes")
779 _ -> putIState $ i { idris_metavars =
780 filter (\(n', _) -> n/=n')
781 (idris_metavars i),
782 ibc_write =
783 filter (notMV n) (ibc_write i)
784 }
785 where notMV n (IBCMetavar n') = not (n == n')
786 notMV n _ = True
788getUndefined :: Idris [Name]
789getUndefined = do i <- getIState
790 return (map fst (idris_metavars i) \\ primDefs)
792isMetavarName :: Name -> IState -> Bool
793isMetavarName n ist
794 = case lookupNames n (tt_ctxt ist) of
795 (t:_) -> isJust $ lookup t (idris_metavars ist)
796 _ -> False
798getWidth :: Idris ConsoleWidth
799getWidth = fmap idris_consolewidth getIState
801setWidth :: ConsoleWidth -> Idris ()
802setWidth w = do ist <- getIState
803 put ist { idris_consolewidth = w }
805setDepth :: Maybe Int -> Idris ()
806setDepth d = do ist <- getIState
807 put ist { idris_options = (idris_options ist) { opt_printdepth = d } }
809typeDescription :: String
810typeDescription = "The type of types"
813type1Doc :: Doc OutputAnnotation
814type1Doc = (annotate (AnnType "Type" "The type of types, one level up") $ text "Type 1")
817isetPrompt :: String -> Idris ()
818isetPrompt p = do i <- getIState
819 case idris_outputmode i of
820 IdeMode n h -> runIO . hPutStrLn h $ convSExp "set-prompt" p n
822-- | Tell clients how much was parsed and loaded
823isetLoadedRegion :: Idris ()
824isetLoadedRegion = do i <- getIState
825 let span = idris_parsedSpan i
826 case span of
827 Just fc ->
828 case idris_outputmode i of
829 IdeMode n h ->
830 runIO . hPutStrLn h $
831 convSExp "set-loaded-region" fc n
832 Nothing -> return ()
834setLogLevel :: Int -> Idris ()
835setLogLevel l = do i <- getIState
836 let opts = idris_options i
837 let opt' = opts { opt_logLevel = l }
838 putIState $ i { idris_options = opt' }
840setLogCats :: [LogCat] -> Idris ()
841setLogCats cs = do
842 i <- getIState
843 let opts = idris_options i
844 let opt' = opts { opt_logcats = cs }
845 putIState $ i { idris_options = opt' }
847setCmdLine :: [Opt] -> Idris ()
848setCmdLine opts = do i <- getIState
849 let iopts = idris_options i
850 putIState $ i { idris_options = iopts { opt_cmdline = opts } }
852getCmdLine :: Idris [Opt]
853getCmdLine = do i <- getIState
854 return (opt_cmdline (idris_options i))
856getDumpHighlighting :: Idris Bool
857getDumpHighlighting = do ist <- getIState
858 return (findC (opt_cmdline (idris_options ist)))
859 where findC = elem DumpHighlights
861getDumpDefun :: Idris (Maybe FilePath)
862getDumpDefun = do i <- getIState
863 return $ findC (opt_cmdline (idris_options i))
864 where findC [] = Nothing
865 findC (DumpDefun x : _) = Just x
866 findC (_ : xs) = findC xs
868getDumpCases :: Idris (Maybe FilePath)
869getDumpCases = do i <- getIState
870 return $ findC (opt_cmdline (idris_options i))
871 where findC [] = Nothing
872 findC (DumpCases x : _) = Just x
873 findC (_ : xs) = findC xs
875logLevel :: Idris Int
876logLevel = do i <- getIState
877 return (opt_logLevel (idris_options i))
879setAutoImpls :: Bool -> Idris ()
880setAutoImpls b = do i <- getIState
881 let opts = idris_options i
882 let opt' = opts { opt_autoimpls = b }
883 putIState $ i { idris_options = opt' }
885getAutoImpls :: Idris Bool
886getAutoImpls = do i <- getIState
887 return (opt_autoimpls (idris_options i))
889setErrContext :: Bool -> Idris ()
890setErrContext t = do i <- getIState
891 let opts = idris_options i
892 let opts' = opts { opt_errContext = t }
893 putIState $ i { idris_options = opts' }
895errContext :: Idris Bool
896errContext = do i <- getIState
897 return (opt_errContext (idris_options i))
899getOptimise :: Idris [Optimisation]
900getOptimise = do i <- getIState
901 return (opt_optimise (idris_options i))
903setOptimise :: [Optimisation] -> Idris ()
904setOptimise newopts = do i <- getIState
905 let opts = idris_options i
906 let opts' = opts { opt_optimise = newopts }
907 putIState $ i { idris_options = opts' }
909addOptimise :: Optimisation -> Idris ()
910addOptimise opt = do opts <- getOptimise
911 setOptimise (nub (opt : opts))
913removeOptimise :: Optimisation -> Idris ()
914removeOptimise opt = do opts <- getOptimise
915 setOptimise ((nub opts) \\ [opt])
917-- | Set appropriate optimisation set for the given level. We only
918-- have one optimisation that is configurable at the moment, however!
919setOptLevel :: Int -> Idris ()
920setOptLevel n | n <= 0 = setOptimise []
921setOptLevel 1 = setOptimise []
922setOptLevel 2 = setOptimise [PETransform]
923setOptLevel n | n >= 3 = setOptimise [PETransform]
925useREPL :: Idris Bool
926useREPL = do i <- getIState
927 return (opt_repl (idris_options i))
929setREPL :: Bool -> Idris ()
930setREPL t = do i <- getIState
931 let opts = idris_options i
932 let opt' = opts { opt_repl = t }
933 putIState $ i { idris_options = opt' }
935showOrigErr :: Idris Bool
936showOrigErr = do i <- getIState
937 return (opt_origerr (idris_options i))
939setShowOrigErr :: Bool -> Idris ()
940setShowOrigErr b = do i <- getIState
941 let opts = idris_options i
942 let opt' = opts { opt_origerr = b }
943 putIState $ i { idris_options = opt' }
945setAutoSolve :: Bool -> Idris ()
946setAutoSolve b = do i <- getIState
947 let opts = idris_options i
948 let opt' = opts { opt_autoSolve = b }
949 putIState $ i { idris_options = opt' }
951setNoBanner :: Bool -> Idris ()
952setNoBanner n = do i <- getIState
953 let opts = idris_options i
954 let opt' = opts { opt_nobanner = n }
955 putIState $ i { idris_options = opt' }
957getNoBanner :: Idris Bool
958getNoBanner = do i <- getIState
959 let opts = idris_options i
960 return (opt_nobanner opts)
962setEvalTypes :: Bool -> Idris ()
963setEvalTypes n = do i <- getIState
964 let opts = idris_options i
965 let opt' = opts { opt_evaltypes = n }
966 putIState $ i { idris_options = opt' }
968getDesugarNats :: Idris Bool
969getDesugarNats = do i <- getIState
970 let opts = idris_options i
971 return (opt_desugarnats opts)
974setDesugarNats :: Bool -> Idris ()
975setDesugarNats n = do i <- getIState
976 let opts = idris_options i
977 let opt' = opts { opt_desugarnats = n }
978 putIState $ i { idris_options = opt' }
980setQuiet :: Bool -> Idris ()
981setQuiet q = do i <- getIState
982 let opts = idris_options i
983 let opt' = opts { opt_quiet = q }
984 putIState $ i { idris_options = opt' }
986getQuiet :: Idris Bool
987getQuiet = do i <- getIState
988 let opts = idris_options i
989 return (opt_quiet opts)
991setCodegen :: Codegen -> Idris ()
992setCodegen t = do i <- getIState
993 let opts = idris_options i
994 let opt' = opts { opt_codegen = t }
995 putIState $ i { idris_options = opt' }
997codegen :: Idris Codegen
998codegen = do i <- getIState
999 return (opt_codegen (idris_options i))
1002setOutputTy :: OutputType -> Idris ()
1003setOutputTy t = do i <- getIState
1004 let opts = idris_options i
1005 let opt' = opts { opt_outputTy = t }
1006 putIState $ i { idris_options = opt' }
1008outputTy :: Idris OutputType
1009outputTy = do i <- getIState
1010 return $ opt_outputTy $ idris_options i
1012setIdeMode :: Bool -> Handle -> Idris ()
1013setIdeMode True h = do i <- getIState
1014 putIState $ i { idris_outputmode = IdeMode 0 h
1015 , idris_colourRepl = False
1017setIdeMode False _ = return ()
1019setTargetTriple :: String -> Idris ()
1020setTargetTriple t = do i <- getIState
1021 let opts = idris_options i
1022 opt' = opts { opt_triple = t }
1023 putIState $ i { idris_options = opt' }
1025targetTriple :: Idris String
1026targetTriple = do i <- getIState
1027 return (opt_triple (idris_options i))
1029setTargetCPU :: String -> Idris ()
1030setTargetCPU t = do i <- getIState
1031 let opts = idris_options i
1032 opt' = opts { opt_cpu = t }
1033 putIState $ i { idris_options = opt' }
1035targetCPU :: Idris String
1036targetCPU = do i <- getIState
1037 return (opt_cpu (idris_options i))
1039verbose :: Idris Int
1040verbose = do
1041 i <- getIState
1042 -- Quietness overrides verbosity
1043 let quiet = opt_quiet $ idris_options i
1044 if quiet
1045 then return $ 0
1046 else return $ (opt_verbose $ idris_options i)
1048setVerbose :: Int -> Idris ()
1049setVerbose t = do
1050 i <- getIState
1051 let opts = idris_options i
1052 let opt' = opts { opt_verbose = t }
1053 putIState $ i { idris_options = opt' }
1055iReport :: Int -> String -> Idris ()
1056iReport level msg = do
1057 verbosity <- verbose
1058 i <- getIState
1059 when (level <= verbosity) $
1060 case idris_outputmode i of
1061 RawOutput h -> runIO $ hPutStrLn h msg
1062 IdeMode n h -> runIO . hPutStrLn h $ convSExp "write-string" msg n
1063 return ()
1065typeInType :: Idris Bool
1066typeInType = do i <- getIState
1067 return (opt_typeintype (idris_options i))
1069setTypeInType :: Bool -> Idris ()
1070setTypeInType t = do i <- getIState
1071 let opts = idris_options i
1072 let opt' = opts { opt_typeintype = t }
1073 putIState $ i { idris_options = opt' }
1075coverage :: Idris Bool
1076coverage = do i <- getIState
1077 return (opt_coverage (idris_options i))
1079setCoverage :: Bool -> Idris ()
1080setCoverage t = do i <- getIState
1081 let opts = idris_options i
1082 let opt' = opts { opt_coverage = t }
1083 putIState $ i { idris_options = opt' }
1085setIBCSubDir :: FilePath -> Idris ()
1086setIBCSubDir fp = do i <- getIState
1087 let opts = idris_options i
1088 let opt' = opts { opt_ibcsubdir = fp }
1089 putIState $ i { idris_options = opt' }
1091valIBCSubDir :: IState -> Idris FilePath
1092valIBCSubDir i = return (opt_ibcsubdir (idris_options i))
1094addImportDir :: FilePath -> Idris ()
1095addImportDir fp = do i <- getIState
1096 let opts = idris_options i
1097 let opt' = opts { opt_importdirs = nub $ fp : opt_importdirs opts }
1098 putIState $ i { idris_options = opt' }
1100setImportDirs :: [FilePath] -> Idris ()
1101setImportDirs fps = do i <- getIState
1102 let opts = idris_options i
1103 let opt' = opts { opt_importdirs = fps }
1104 putIState $ i { idris_options = opt' }
1106allImportDirs :: Idris [FilePath]
1107allImportDirs = do i <- getIState
1108 let optdirs = opt_importdirs (idris_options i)
1109 return ("." : reverse optdirs)
1111-- Like allImportDirs but the dirs that are a prefix of
1112-- the files path first. This makes it look in the current
1113-- package first.
1114rankedImportDirs :: FilePath -> Idris [FilePath]
1115rankedImportDirs fp = do ids <- allImportDirs
1116 let (prefixes, rest) = partition (`isPrefixOf`fp) ids
1117 return $ prefixes ++ rest
1119addSourceDir :: FilePath -> Idris ()
1120addSourceDir fp = do i <- getIState
1121 let opts = idris_options i
1122 let opts' = opts { opt_sourcedirs = nub $ fp : opt_sourcedirs opts }
1123 putIState $ i { idris_options = opts' }
1125setSourceDirs :: [FilePath] -> Idris ()
1126setSourceDirs fps = do i <- getIState
1127 let opts = idris_options i
1128 let opts' = opts { opt_sourcedirs = nub $ fps }
1129 putIState $ i { idris_options = opts' }
1131allSourceDirs :: Idris [FilePath]
1132allSourceDirs = do i <- getIState
1133 let optdirs = opt_sourcedirs (idris_options i)
1134 return ("." : reverse optdirs)
1136colourise :: Idris Bool
1137colourise = do i <- getIState
1138 return $ idris_colourRepl i
1140setColourise :: Bool -> Idris ()
1141setColourise b = do i <- getIState
1142 putIState $ i { idris_colourRepl = b }
1144impShow :: Idris Bool
1145impShow = do i <- getIState
1146 return (opt_showimp (idris_options i))
1148setImpShow :: Bool -> Idris ()
1149setImpShow t = do i <- getIState
1150 let opts = idris_options i
1151 let opt' = opts { opt_showimp = t }
1152 putIState $ i { idris_options = opt' }
1154setColour :: ColourType -> IdrisColour -> Idris ()
1155setColour ct c = do i <- getIState
1156 let newTheme = setColour' ct c (idris_colourTheme i)
1157 putIState $ i { idris_colourTheme = newTheme }
1158 where setColour' KeywordColour c t = t { keywordColour = c }
1159 setColour' BoundVarColour c t = t { boundVarColour = c }
1160 setColour' ImplicitColour c t = t { implicitColour = c }
1161 setColour' FunctionColour c t = t { functionColour = c }
1162 setColour' TypeColour c t = t { typeColour = c }
1163 setColour' DataColour c t = t { dataColour = c }
1164 setColour' PromptColour c t = t { promptColour = c }
1165 setColour' PostulateColour c t = t { postulateColour = c }
1167logLvl :: Int -> String -> Idris ()
1168logLvl = logLvlCats []
1170logCoverage :: Int -> String -> Idris ()
1171logCoverage = logLvlCats [ICoverage]
1173logErasure :: Int -> String -> Idris ()
1174logErasure = logLvlCats [IErasure]
1176-- | Log an action of the parser
1177logParser :: Int -> String -> Idris ()
1178logParser = logLvlCats parserCats
1180-- | Log an action of the elaborator.
1181logElab :: Int -> String -> Idris ()
1182logElab = logLvlCats elabCats
1184-- | Log an action of the compiler.
1185logCodeGen :: Int -> String -> Idris ()
1186logCodeGen = logLvlCats codegenCats
1188logIBC :: Int -> String -> Idris ()
1189logIBC = logLvlCats [IIBC]
1191-- | Log aspect of Idris execution
1193-- An empty set of logging levels is used to denote all categories.
1195-- @TODO update IDE protocol
1196logLvlCats :: [LogCat] -- ^ The categories that the message should appear under.
1197 -> Int -- ^ The Logging level the message should appear.
1198 -> String -- ^ The message to show the developer.
1199 -> Idris ()
1200logLvlCats cs l msg = do
1201 i <- getIState
1202 let lvl = opt_logLevel (idris_options i)
1203 let cats = opt_logcats (idris_options i)
1204 when (lvl >= l) $
1205 when (inCat cs cats || null cats) $
1206 case idris_outputmode i of
1207 RawOutput h -> do
1208 runIO $ hPutStrLn h msg
1209 IdeMode n h -> do
1210 let good = SexpList [IntegerAtom (toInteger l), toSExp msg]
1211 runIO . hPutStrLn h $ convSExp "log" good n
1212 where
1213 inCat :: [LogCat] -> [LogCat] -> Bool
1214 inCat cs cats = any (`elem` cats) cs
1216cmdOptType :: Opt -> Idris Bool
1217cmdOptType x = do i <- getIState
1218 return $ x `elem` opt_cmdline (idris_options i)
1220noErrors :: Idris Bool
1221noErrors = do i <- getIState
1222 case errSpan i of
1223 Nothing -> return True
1224 _ -> return False
1226setTypeCase :: Bool -> Idris ()
1227setTypeCase t = do i <- getIState
1228 let opts = idris_options i
1229 let opt' = opts { opt_typecase = t }
1230 putIState $ i { idris_options = opt' }
1232getIndentWith :: Idris Int
1233getIndentWith = do
1234 i <- getIState
1235 return $ interactiveOpts_indentWith (idris_interactiveOpts i)
1237setIndentWith :: Int -> Idris ()
1238setIndentWith indentWith = do
1239 i <- getIState
1240 let opts = idris_interactiveOpts i
1241 let opts' = opts { interactiveOpts_indentWith = indentWith }
1242 putIState $ i { idris_interactiveOpts = opts' }
1244getIndentClause :: Idris Int
1245getIndentClause = do
1246 i <- getIState
1247 return $ interactiveOpts_indentClause (idris_interactiveOpts i)
1249setIndentClause :: Int -> Idris ()
1250setIndentClause indentClause = do
1251 i <- getIState
1252 let opts = idris_interactiveOpts i
1253 let opts' = opts { interactiveOpts_indentClause = indentClause }
1254 putIState $ i { idris_interactiveOpts = opts' }
1256-- Dealing with parameters
1258expandParams :: (Name -> Name) -> [(Name, PTerm)] ->
1259 [Name] -> -- all names
1260 [Name] -> -- names with no declaration
1261 PTerm -> PTerm
1262expandParams dec ps ns infs tm = en 0 tm
1263 where
1264 -- if we shadow a name (say in a lambda binding) that is used in a call to
1265 -- a lifted function, we need access to both names - once in the scope of the
1266 -- binding and once to call the lifted functions. So we'll explicitly shadow
1267 -- it. (Yes, it's a hack. The alternative would be to resolve names earlier
1268 -- but we didn't...)
1270 mkShadow (UN n) = MN 0 n
1271 mkShadow (MN i n) = MN (i+1) n
1272 mkShadow (NS x s) = NS (mkShadow x) s
1274 en :: Int -- ^ The quotation level - only transform terms that are used, not terms
1275 -- that are merely mentioned.
1276 -> PTerm -> PTerm
1277 en 0 (PLam fc n nfc t s)
1278 | n `elem` (map fst ps ++ ns)
1279 = let n' = mkShadow n in
1280 PLam fc n' nfc (en 0 t) (en 0 (shadow n n' s))
1281 | otherwise = PLam fc n nfc (en 0 t) (en 0 s)
1282 en 0 (PPi p n nfc t s)
1283 | n `elem` (map fst ps ++ ns)
1284 = let n' = mkShadow n in -- TODO THINK SHADOWING TacImp?
1285 PPi (enTacImp 0 p) n' nfc (en 0 t) (en 0 (shadow n n' s))
1286 | otherwise = PPi (enTacImp 0 p) n nfc (en 0 t) (en 0 s)
1287 en 0 (PLet fc n nfc ty v s)
1288 | n `elem` (map fst ps ++ ns)
1289 = let n' = mkShadow n in
1290 PLet fc n' nfc (en 0 ty) (en 0 v) (en 0 (shadow n n' s))
1291 | otherwise = PLet fc n nfc (en 0 ty) (en 0 v) (en 0 s)
1292 -- FIXME: Should only do this in a type signature!
1293 en 0 (PDPair f hls p (PRef f' fcs n) t r)
1294 | n `elem` (map fst ps ++ ns) && t /= Placeholder
1295 = let n' = mkShadow n in
1296 PDPair f hls p (PRef f' fcs n') (en 0 t) (en 0 (shadow n n' r))
1297 en 0 (PRewrite f by l r g) = PRewrite f by (en 0 l) (en 0 r) (fmap (en 0) g)
1298 en 0 (PTyped l r) = PTyped (en 0 l) (en 0 r)
1299 en 0 (PPair f hls p l r) = PPair f hls p (en 0 l) (en 0 r)
1300 en 0 (PDPair f hls p l t r) = PDPair f hls p (en 0 l) (en 0 t) (en 0 r)
1301 en 0 (PAlternative ns a as) = PAlternative ns a (map (en 0) as)
1302 en 0 (PHidden t) = PHidden (en 0 t)
1303 en 0 (PUnifyLog t) = PUnifyLog (en 0 t)
1304 en 0 (PDisamb ds t) = PDisamb ds (en 0 t)
1305 en 0 (PNoImplicits t) = PNoImplicits (en 0 t)
1306 en 0 (PDoBlock ds) = PDoBlock (map (fmap (en 0)) ds)
1307 en 0 (PProof ts) = PProof (map (fmap (en 0)) ts)
1308 en 0 (PTactics ts) = PTactics (map (fmap (en 0)) ts)
1310 en 0 (PQuote (Var n))
1311 | n `nselem` ns = PQuote (Var (dec n))
1312 en 0 (PApp fc (PInferRef fc' hl n) as)
1313 | n `nselem` ns = PApp fc (PInferRef fc' hl (dec n))
1314 (map ((pexp . (PRef fc hl)) . fst) ps ++ (map (fmap (en 0)) as))
1315 en 0 (PApp fc (PRef fc' hl n) as)
1316 | n `elem` infs = PApp fc (PInferRef fc' hl (dec n))
1317 (map ((pexp . (PRef fc hl)) . fst) ps ++ (map (fmap (en 0)) as))
1318 | n `nselem` ns = PApp fc (PRef fc' hl (dec n))
1319 (map ((pexp . (PRef fc hl)) . fst) ps ++ (map (fmap (en 0)) as))
1320 en 0 (PAppBind fc (PRef fc' hl n) as)
1321 | n `elem` infs = PAppBind fc (PInferRef fc' hl (dec n))
1322 (map ((pexp . (PRef fc hl)) . fst) ps ++ (map (fmap (en 0)) as))
1323 | n `nselem` ns = PAppBind fc (PRef fc' hl (dec n))
1324 (map ((pexp . (PRef fc hl)) . fst) ps ++ (map (fmap (en 0)) as))
1325 en 0 (PRef fc hl n)
1326 | n `elem` infs = PApp fc (PInferRef fc hl (dec n))
1327 (map ((pexp . (PRef fc hl)) . fst) ps)
1328 | n `nselem` ns = PApp fc (PRef fc hl (dec n))
1329 (map ((pexp . (PRef fc hl)) . fst) ps)
1330 en 0 (PInferRef fc hl n)
1331 | n `nselem` ns = PApp fc (PInferRef fc hl (dec n))
1332 (map ((pexp . (PRef fc hl)) . fst) ps)
1333 en 0 (PApp fc f as) = PApp fc (en 0 f) (map (fmap (en 0)) as)
1334 en 0 (PAppBind fc f as) = PAppBind fc (en 0 f) (map (fmap (en 0)) as)
1335 en 0 (PCase fc c os) = PCase fc (en 0 c) (map (pmap (en 0)) os)
1336 en 0 (PIfThenElse fc c t f) = PIfThenElse fc (en 0 c) (en 0 t) (en 0 f)
1337 en 0 (PRunElab fc tm ns) = PRunElab fc (en 0 tm) ns
1338 en 0 (PConstSugar fc tm) = PConstSugar fc (en 0 tm)
1340 en ql (PQuasiquote tm ty) = PQuasiquote (en (ql + 1) tm) (fmap (en ql) ty)
1341 en ql (PUnquote tm) = PUnquote (en (ql - 1) tm)
1343 en ql t = descend (en ql) t
1345 nselem x [] = False
1346 nselem x (y : xs) | nseq x y = True
1347 | otherwise = nselem x xs
1349 nseq x y = nsroot x == nsroot y
1351 enTacImp ql (TacImp aos st scr rig) = TacImp aos st (en ql scr) rig
1352 enTacImp ql other = other
1354expandParamsD :: Bool -> -- True = RHS only
1355 IState ->
1356 (Name -> Name) -> [(Name, PTerm)] -> [Name] -> PDecl -> PDecl
1357expandParamsD rhsonly ist dec ps ns (PTy doc argdocs syn fc o n nfc ty)
1358 = if n `elem` ns && (not rhsonly)
1359 then -- trace (show (n, expandParams dec ps ns ty)) $
1360 PTy doc argdocs syn fc o (dec n) nfc (piBindp expl_param ps (expandParams dec ps ns [] ty))
1361 else --trace (show (n, expandParams dec ps ns ty)) $
1362 PTy doc argdocs syn fc o n nfc (expandParams dec ps ns [] ty)
1363expandParamsD rhsonly ist dec ps ns (PPostulate e doc syn fc nfc o n ty)
1364 = if n `elem` ns && (not rhsonly)
1365 then -- trace (show (n, expandParams dec ps ns ty)) $
1366 PPostulate e doc syn fc nfc o (dec n)
1367 (piBind ps (expandParams dec ps ns [] ty))
1368 else --trace (show (n, expandParams dec ps ns ty)) $
1369 PPostulate e doc syn fc nfc o n (expandParams dec ps ns [] ty)
1370expandParamsD rhsonly ist dec ps ns (PClauses fc opts n cs)
1371 = let n' = if n `elem` ns then dec n else n in
1372 PClauses fc opts n' (map expandParamsC cs)
1373 where
1374 expandParamsC (PClause fc n lhs ws rhs ds)
1375 = let -- ps' = updateps True (namesIn ist rhs) (zip ps [0..])
1376 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
1377 lhs' = if rhsonly then lhs else (expandParams dec ps'' ns [] lhs)
1378 n' = if n `elem` ns then dec n else n
1379 -- names bound on the lhs should not be expanded on the rhs
1380 ns' = removeBound lhs ns in
1381 PClause fc n' lhs'
1382 (map (expandParams dec ps'' ns' []) ws)
1383 (expandParams dec ps'' ns' [] rhs)
1384 (map (expandParamsD True ist dec ps'' ns') ds)
1385 expandParamsC (PWith fc n lhs ws wval pn ds)
1386 = let -- ps' = updateps True (namesIn ist wval) (zip ps [0..])
1387 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
1388 lhs' = if rhsonly then lhs else (expandParams dec ps'' ns [] lhs)
1389 n' = if n `elem` ns then dec n else n
1390 ns' = removeBound lhs ns in
1391 PWith fc n' lhs'
1392 (map (expandParams dec ps'' ns' []) ws)
1393 (expandParams dec ps'' ns' [] wval)
1394 pn
1395 (map (expandParamsD rhsonly ist dec ps'' ns') ds)
1396 updateps yn nm [] = []
1397 updateps yn nm (((a, t), i):as)
1398 | (a `elem` nm) == yn = (a, t) : updateps yn nm as
1399 | otherwise = (sMN i (show a ++ "_shadow"), t) : updateps yn nm as
1401 removeBound lhs ns = ns \\ nub (bnames lhs)
1403 bnames (PRef _ _ n) = [n]
1404 bnames (PApp _ _ args) = concatMap (bnames . getTm) args
1405 bnames (PPair _ _ _ l r) = bnames l ++ bnames r
1406 bnames (PDPair _ _ _ l Placeholder r) = bnames l ++ bnames r
1407 bnames _ = []
1409-- | Expands parameters defined in parameter and where blocks inside of declarations
1410expandParamsD rhs ist dec ps ns (PData doc argDocs syn fc co pd)
1411 = PData doc argDocs syn fc co (expandPData pd)
1412 where
1413 -- just do the type decl, leave constructors alone (parameters will be
1414 -- added implicitly)
1415 expandPData (PDatadecl n nfc ty cons)
1416 = if n `elem` ns
1417 then PDatadecl (dec n) nfc (piBind ps (expandParams dec ps ns [] ty))
1418 (map econ cons)
1419 else PDatadecl n nfc (expandParams dec ps ns [] ty) (map econ cons)
1420 econ (doc, argDocs, n, nfc, t, fc, fs)
1421 = (doc, argDocs, dec n, nfc, piBindp expl ps (expandParams dec ps ns [] t), fc, fs)
1422expandParamsD rhs ist dec ps ns d@(PRecord doc rsyn fc opts name nfc prs pdocs fls cn cdoc csyn)
1423 = d
1424expandParamsD rhs ist dec ps ns (PParams f params pds)
1425 = PParams f (ps ++ map (mapsnd (expandParams dec ps ns [])) params)
1426 (map (expandParamsD True ist dec ps ns) pds)
1427-- (map (expandParamsD ist dec ps ns) pds)
1428expandParamsD rhs ist dec ps ns (PMutual f pds)
1429 = PMutual f (map (expandParamsD rhs ist dec ps ns) pds)
1430expandParamsD rhs ist dec ps ns (PInterface doc info f cs n nfc params pDocs fds decls cn cd)
1431 = PInterface doc info f
1432 (map (\ (n, t) -> (n, expandParams dec ps ns [] t)) cs)
1433 n nfc
1434 (map (\(n, fc, t) -> (n, fc, expandParams dec ps ns [] t)) params)
1435 pDocs
1436 fds
1437 (map (expandParamsD rhs ist dec ps ns) decls)
1438 cn
1439 cd
1440expandParamsD rhs ist dec ps ns (PImplementation doc argDocs info f cs pnames acc opts n nfc params pextra ty cn decls)
1441 = let cn' = case cn of
1442 Just n -> if n `elem` ns then Just (dec n) else Just n
1443 Nothing -> Nothing in
1444 PImplementation doc argDocs info f
1445 (map (\ (n, t) -> (n, expandParams dec ps ns [] t)) cs)
1446 pnames acc opts n
1447 nfc
1448 (map (expandParams dec ps ns []) params)
1449 (map (\ (n, t) -> (n, expandParams dec ps ns [] t)) pextra)
1450 (expandParams dec ps ns [] ty)
1451 cn'
1452 (map (expandParamsD True ist dec ps ns) decls)
1453expandParamsD rhs ist dec ps ns d = d
1455mapsnd f (x, t) = (x, f t)
1457expandImplementationScope ist dec ps ns (PImplementation doc argDocs info f cs pnames acc opts n nfc params pextra ty cn decls)
1458 = PImplementation doc argDocs info f cs pnames acc opts n nfc params (ps ++ pextra)
1459 ty cn decls
1460expandImplementationScope ist dec ps ns d = d
1462-- | Calculate a priority for a type, for deciding elaboration order
1463-- * if it's just a type variable or concrete type, do it early (0)
1464-- * if there's only type variables and injective constructors, do it next (1)
1465-- * if there's a function type, next (2)
1466-- * finally, everything else (3)
1467getPriority :: IState -> PTerm -> Int
1468getPriority i tm = 1 -- pri tm
1469 where
1470 pri (PRef _ _ n) =
1471 case lookupP n (tt_ctxt i) of
1472 ((P (DCon _ _ _) _ _):_) -> 1
1473 ((P (TCon _ _) _ _):_) -> 1
1474 ((P Ref _ _):_) -> 1
1475 [] -> 0 -- must be locally bound, if it's not an error...
1476 pri (PPi _ _ _ x y) = max 5 (max (pri x) (pri y))
1477 pri (PTrue _ _) = 0
1478 pri (PRewrite _ _ l r _) = max 1 (max (pri l) (pri r))
1479 pri (PApp _ f as) = max 1 (max (pri f) (foldr (max . pri . getTm) 0 as))
1480 pri (PAppBind _ f as) = max 1 (max (pri f) (foldr (max . pri . getTm) 0 as))
1481 pri (PCase _ f as) = max 1 (max (pri f) (foldr (max . pri . snd) 0 as))
1482 pri (PTyped l r) = pri l
1483 pri (PPair _ _ _ l r) = max 1 (max (pri l) (pri r))
1484 pri (PDPair _ _ _ l t r) = max 1 (max (pri l) (max (pri t) (pri r)))
1485 pri (PAlternative _ a as) = maximum (map pri as)
1486 pri (PConstant _ _) = 0
1487 pri Placeholder = 1
1488 pri _ = 3
1491addStatics :: Name -> Term -> PTerm -> Idris ()
1492addStatics n tm ptm =
1493 do let (statics, dynamics) = initStatics tm ptm
1494 ist <- getIState
1495 let paramnames
1496 = nub $ case lookupCtxtExact n (idris_fninfo ist) of
1497 Just p -> getNamesFrom 0 (fn_params p) tm ++
1498 concatMap (getParamNames ist . snd) statics
1499 _ -> concatMap (getParamNames ist . snd) statics
1501 let stnames = nub $ concatMap (freeArgNames . snd) statics
1502 let dnames = (nub $ concatMap (freeArgNames . snd) dynamics)
1503 \\ paramnames
1504 -- also get the arguments which are 'uniquely inferrable' from
1505 -- statics (see sec 4.2 of "Scrapping Your Inefficient Engine")
1506 -- or parameters to the type of a static
1507 let statics' = nub $ map fst statics ++
1508 filter (\x -> not (elem x dnames)) stnames
1509 let stpos = staticList statics' tm
1510 i <- getIState
1511 unless (null statics) $
1512 logLvl 3 $ "Statics for " ++ show n ++ " " ++ show tm ++ "\n"
1513 ++ showTmImpls ptm ++ "\n"
1514 ++ show statics ++ "\n" ++ show dynamics
1515 ++ "\n" ++ show paramnames
1516 ++ "\n" ++ show stpos
1517 putIState $ i { idris_statics = addDef n stpos (idris_statics i) }
1518 addIBC (IBCStatic n)
1519 where
1520 initStatics (Bind n (Pi _ _ ty _) sc) (PPi p n' fc t s)
1521 | n /= n' = let (static, dynamic) = initStatics sc (PPi p n' fc t s) in
1522 (static, (n, ty) : dynamic)
1523 initStatics (Bind n (Pi _ _ ty _) sc) (PPi p n' fc _ s)
1524 = let (static, dynamic) = initStatics (instantiate (P Bound n ty) sc) s in
1525 if pstatic p == Static then ((n, ty) : static, dynamic)
1526 else if (not (searchArg p))
1527 then (static, (n, ty) : dynamic)
1528 else (static, dynamic)
1529 initStatics t pt = ([], [])
1531 getParamNames ist tm | (P _ n _ , args) <- unApply tm
1532 = case lookupCtxtExact n (idris_datatypes ist) of
1533 Just ti -> getNamePos 0 (param_pos ti) args
1534 Nothing -> []
1535 where getNamePos i ps [] = []
1536 getNamePos i ps (P _ n _ : as)
1537 | i `elem` ps = n : getNamePos (i + 1) ps as
1538 getNamePos i ps (_ : as) = getNamePos (i + 1) ps as
1539 getParamNames ist (Bind t (Pi _ _ (P _ n _) _) sc)
1540 = n : getParamNames ist sc
1541 getParamNames ist _ = []
1543 getNamesFrom i ps (Bind n (Pi _ _ _ _) sc)
1544 | i `elem` ps = n : getNamesFrom (i + 1) ps sc
1545 | otherwise = getNamesFrom (i + 1) ps sc
1546 getNamesFrom i ps sc = []
1548 freeArgNames (Bind n (Pi _ _ ty _) sc)
1549 = nub $ freeNames ty ++ freeNames sc -- treat '->' as fn here
1550 freeArgNames tm = let (_, args) = unApply tm in
1551 concatMap freeNames args
1553 -- if a name appears in an interface or tactic implicit index, it doesn't
1554 -- affect its 'uniquely inferrable' from a static status since these are
1555 -- resolved by searching.
1556 searchArg (Constraint _ _ _) = True
1557 searchArg (TacImp _ _ _ _) = True
1558 searchArg _ = False
1560 staticList sts (Bind n (Pi _ _ _ _) sc) = (n `elem` sts) : staticList sts sc
1561 staticList _ _ = []
1563-- Dealing with implicit arguments
1565-- Add some bound implicits to the using block if they aren't there already
1567addToUsing :: [Using] -> [(Name, PTerm)] -> [Using]
1568addToUsing us [] = us
1569addToUsing us ((n, t) : ns)
1570 | n `notElem` mapMaybe impName us = addToUsing (us ++ [UImplicit n t]) ns
1571 | otherwise = addToUsing us ns
1572 where impName (UImplicit n _) = Just n
1573 impName _ = Nothing
1575-- Add constraint bindings from using block
1577addUsingConstraints :: SyntaxInfo -> FC -> PTerm -> Idris PTerm
1578addUsingConstraints syn fc t
1579 = do ist <- get
1580 let ns = namesIn [] ist t
1581 let cs = getConstraints t -- check declared constraints
1582 let addconsts = uconsts \\ cs
1583 return (doAdd addconsts ns t)
1584 where uconsts = filter uconst (using syn)
1585 uconst (UConstraint _ _) = True
1586 uconst _ = False
1588 doAdd [] _ t = t
1589 -- if all of args in ns, then add it
1590 doAdd (UConstraint c args : cs) ns t
1591 | all (\n -> elem n ns) args
1592 = PPi (Constraint [] Dynamic RigW) (sMN 0 "cu") NoFC
1593 (mkConst c args) (doAdd cs ns t)
1594 | otherwise = doAdd cs ns t
1596 mkConst c args = PApp fc (PRef fc [] c)
1597 (map (PExp 0 [] (sMN 0 "carg") . PRef fc []) args)
1599 getConstraints (PPi (Constraint _ _ _) _ _ c sc)
1600 = getcapp c ++ getConstraints sc
1601 getConstraints (PPi _ _ _ c sc) = getConstraints sc
1602 getConstraints _ = []
1604 getcapp (PApp _ (PRef _ _ c) args)
1605 = do ns <- mapM getName args
1606 return (UConstraint c ns)
1607 getcapp _ = []
1609 getName (PExp _ _ _ (PRef _ _ n)) = return n
1610 getName _ = []
1612-- | Add implicit bindings from using block, and bind any missing names
1613addUsingImpls :: SyntaxInfo -> Name -> FC -> PTerm -> Idris PTerm
1614addUsingImpls syn n fc t
1615 = do ist <- getIState
1616 autoimpl <- getAutoImpls
1617 let ns_in = implicitNamesIn (map iname uimpls) ist t
1618 let ns = if autoimpl then ns_in
1619 else filter (\n -> n `elem` (map iname uimpls)) ns_in
1621 let badnames = filter (\n -> not (implicitable n) &&
1622 n `notElem` (map iname uimpls)) ns
1623 unless (null badnames) $
1624 throwError (At fc (Elaborating "type of " n Nothing
1625 (NoSuchVariable (head badnames))))
1626 let cs = getArgnames t -- get already bound names
1627 let addimpls = filter (\n -> iname n `notElem` cs) uimpls
1628 -- if all names in the arguments of addconsts appear in ns,
1629 -- add the constraint implicitly
1630 return (bindFree ns (doAdd addimpls ns t))
1631 where uimpls = filter uimpl (using syn)
1632 uimpl (UImplicit _ _) = True
1633 uimpl _ = False
1635 iname (UImplicit n _) = n
1636 iname (UConstraint _ _) = error "Can't happen addUsingImpls"
1638 doAdd [] _ t = t
1639 -- if all of args in ns, then add it
1640 doAdd (UImplicit n ty : cs) ns t
1641 | elem n ns
1642 = PPi impl_gen n NoFC ty (doAdd cs ns t)
1643 | otherwise = doAdd cs ns t
1645 -- bind the free names which weren't in the using block
1646 bindFree [] tm = tm
1647 bindFree (n:ns) tm
1648 | elem n (map iname uimpls) = bindFree ns tm
1649 | otherwise
1650 = PPi (impl_gen { pargopts = [InaccessibleArg] }) n NoFC Placeholder (bindFree ns tm)
1652 getArgnames (PPi _ n _ c sc)
1653 = n : getArgnames sc
1654 getArgnames _ = []
1656-- Given the original type and the elaborated type, return the implicitness
1657-- status of each pi-bound argument, and whether it's inaccessible (True) or not.
1659getUnboundImplicits :: IState -> Type -> PTerm -> [(Bool, PArg)]
1660getUnboundImplicits i t tm = getImps t (collectImps tm)
1661 where collectImps (PPi p n _ t sc)
1662 = (n, (p, t)) : collectImps sc
1663 collectImps _ = []
1665 scopedimpl (Just i) = not (toplevel_imp i)
1666 scopedimpl _ = False
1668 getImps (Bind n (Pi _ i _ _) sc) imps
1669 | scopedimpl i = getImps sc imps
1670 getImps (Bind n (Pi _ _ t _) sc) imps
1671 | Just (p, t') <- lookup n imps = argInfo n p t' : getImps sc imps
1672 where
1673 argInfo n (Imp opt _ _ _ _ _) Placeholder
1674 = (True, PImp 0 True opt n Placeholder)
1675 argInfo n (Imp opt _ _ _ _ _) t'
1676 = (False, PImp (getPriority i t') True opt n t')
1677 argInfo n (Exp opt _ _ _) t'
1678 = (InaccessibleArg `elem` opt,
1679 PExp (getPriority i t') opt n t')
1680 argInfo n (Constraint opt _ _) t'
1681 = (InaccessibleArg `elem` opt,
1682 PConstraint 10 opt n t')
1683 argInfo n (TacImp opt _ scr _) t'
1684 = (InaccessibleArg `elem` opt,
1685 PTacImplicit 10 opt n scr t')
1686 getImps (Bind n (Pi _ _ t _) sc) imps = impBind n t : getImps sc imps
1687 where impBind n t = (True, PImp 1 True [] n Placeholder)
1688 getImps sc tm = []
1690-- Add implicit Pi bindings for any names in the term which appear in an
1691-- argument position.
1693-- This has become a right mess already. Better redo it some time...
1694-- TODO: This is obsoleted by the new way of elaborating types, (which
1695-- calls addUsingImpls) but there's still a couple of places which use
1696-- it. Clean them up!
1698-- Issue 1739 in the issue tracker
1699-- https://github.com/idris-lang/Idris-dev/issues/1739
1700implicit :: ElabInfo -> SyntaxInfo -> Name -> PTerm -> Idris PTerm
1701implicit info syn n ptm = implicit' info syn [] n ptm
1703implicit' :: ElabInfo -> SyntaxInfo -> [Name] -> Name -> PTerm -> Idris PTerm
1704implicit' info syn ignore n ptm
1705 = do i <- getIState
1706 auto <- getAutoImpls
1707 let (tm', impdata) = implicitise auto syn ignore i ptm
1708 defaultArgCheck (eInfoNames info ++ M.keys (idris_implicits i)) impdata
1709-- let (tm'', spos) = findStatics i tm'
1710 putIState $ i { idris_implicits = addDef n impdata (idris_implicits i) }
1711 addIBC (IBCImp n)
1712 logLvl 5 ("Implicit " ++ show n ++ " " ++ show impdata)
1713-- i <- get
1714-- putIState $ i { idris_statics = addDef n spos (idris_statics i) }
1715 return tm'
1716 where
1717 -- Detect unknown names in default arguments and throw error if found.
1718 defaultArgCheck :: [Name] -> [PArg] -> Idris ()
1719 defaultArgCheck knowns params = foldM_ notFoundInDefault knowns params
1721 notFoundInDefault :: [Name] -> PArg -> Idris [Name]
1722 notFoundInDefault kns (PTacImplicit _ _ n script _)
1723 = do i <- getIState
1724 case notFound kns (namesIn [] i script) of
1725 Nothing -> return (n:kns)
1726 Just name -> throwError (NoSuchVariable name)
1727 notFoundInDefault kns p = return ((pname p):kns)
1729 notFound :: [Name] -> [Name] -> Maybe Name
1730 notFound kns [] = Nothing
1731 notFound kns (SN (WhereN _ _ _) : ns) = notFound kns ns -- Known already
1732 notFound kns (n:ns) = if elem n kns then notFound kns ns else Just n
1734-- | Even if auto_implicits is off, we need to call this so we record
1735-- which arguments are implicit
1736implicitise :: Bool -> SyntaxInfo -> [Name] -> IState -> PTerm -> (PTerm, [PArg])
1737implicitise auto syn ignore ist tm = -- trace ("INCOMING " ++ showImp True tm) $
1738 let (declimps, ns') = execState (imps True [] tm) ([], [])
1739 ns = filter (\n -> auto && implicitable n || elem n (map fst uvars)) $
1740 ns' \\ (map fst pvars ++ no_imp syn ++ ignore)
1741 nsOrder = filter (not . inUsing) ns ++ filter inUsing ns in
1742 if null ns
1743 then (tm, reverse declimps)
1744 else implicitise auto syn ignore ist (pibind uvars nsOrder tm)
1745 where
1746 uvars = map ipair (filter uimplicit (using syn))
1747 pvars = syn_params syn
1749 inUsing n = n `elem` map fst uvars
1751 ipair (UImplicit x y) = (x, y)
1752 uimplicit (UImplicit _ _) = True
1753 uimplicit _ = False
1755 dropAll (x:xs) ys | x `elem` ys = dropAll xs ys
1756 | otherwise = x : dropAll xs ys
1757 dropAll [] ys = []
1759 -- Find names in argument position in a type, suitable for implicit
1760 -- binding
1761 -- Not the function position, but do everything else...
1762 implNamesIn uv (PApp fc f args) = concatMap (implNamesIn uv . getTm) args
1763 implNamesIn uv t = implicitNamesIn (map fst uv) ist t
1765 imps top env ty@(PApp _ f as)
1766 = do (decls, ns) <- get
1767 let isn = nub (implNamesIn uvars ty)
1768 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1769 imps top env (PPi (Imp l _ _ _ _ _) n _ ty sc)
1770 = do let isn = nub (implNamesIn uvars ty) `dropAll` [n]
1771 (decls , ns) <- get
1772 put (PImp (getPriority ist ty) True l n Placeholder : decls,
1773 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1774 imps True (n:env) sc
1775 imps top env (PPi (Exp l _ _ _) n _ ty sc)
1776 = do let isn = nub (implNamesIn uvars ty ++ case sc of
1777 (PRef _ _ x) -> namesIn uvars ist sc `dropAll` [n]
1778 _ -> [])
1779 (decls, ns) <- get -- ignore decls in HO types
1780 put (PExp (getPriority ist ty) l n Placeholder : decls,
1781 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1782 imps True (n:env) sc
1783 imps top env (PPi (Constraint l _ _) n _ ty sc)
1784 = do let isn = nub (implNamesIn uvars ty ++ case sc of
1785 (PRef _ _ x) -> namesIn uvars ist sc `dropAll` [n]
1786 _ -> [])
1787 (decls, ns) <- get -- ignore decls in HO types
1788 put (PConstraint 10 l n Placeholder : decls,
1789 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1790 imps True (n:env) sc
1791 imps top env (PPi (TacImp l _ scr _) n _ ty sc)
1792 = do let isn = nub (implNamesIn uvars ty ++ case sc of
1793 (PRef _ _ x) -> namesIn uvars ist sc `dropAll` [n]
1794 _ -> [])
1795 (decls, ns) <- get -- ignore decls in HO types
1796 put (PTacImplicit 10 l n scr Placeholder : decls,
1797 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1798 imps True (n:env) sc
1799 imps top env (PRewrite _ _ l r _)
1800 = do (decls, ns) <- get
1801 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1802 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1803 imps top env (PTyped l r)
1804 = imps top env l
1805 imps top env (PPair _ _ _ l r)
1806 = do (decls, ns) <- get
1807 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1808 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1809 imps top env (PDPair _ _ _ (PRef _ _ n) t r)
1810 = do (decls, ns) <- get
1811 let isn = nub (namesIn uvars ist t ++ namesIn uvars ist r) \\ [n]
1812 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
1813 imps top env (PDPair _ _ _ l t r)
1814 = do (decls, ns) <- get
1815 let isn = namesIn uvars ist l ++ namesIn uvars ist t ++
1816 namesIn uvars ist r
1817 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
1818 imps top env (PAlternative ms a as)
1819 = do (decls, ns) <- get
1820 let isn = concatMap (namesIn uvars ist) as
1821 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1822 imps top env (PLam fc n _ ty sc)
1823 = do imps False env ty
1824 imps False (n:env) sc
1825 imps top env (PHidden tm) = imps False env tm
1826 imps top env (PUnifyLog tm) = imps False env tm
1827 imps top env (PNoImplicits tm) = imps False env tm
1828 imps top env (PRunElab fc tm ns) = imps False env tm
1829 imps top env (PConstSugar fc tm) = imps top env tm -- ignore PConstSugar - it's for highlighting only!
1830 imps top env _ = return ()
1832 pibind using [] sc = sc
1833 pibind using (n:ns) sc
1834 = case lookup n using of
1835 Just ty -> PPi impl_gen
1836 n NoFC ty (pibind using ns sc)
1837 Nothing -> PPi (impl_gen { pargopts = [InaccessibleArg] })
1838 n NoFC Placeholder (pibind using ns sc)
1840-- | Add implicit arguments in function calls
1841addImplPat :: IState -> PTerm -> PTerm
1842addImplPat = addImpl' True [] [] []
1844addImplBound :: IState -> [Name] -> PTerm -> PTerm
1845addImplBound ist ns = addImpl' False ns [] [] ist
1847addImplBoundInf :: IState -> [Name] -> [Name] -> PTerm -> PTerm
1848addImplBoundInf ist ns inf = addImpl' False ns inf [] ist
1850-- | Add the implicit arguments to applications in the term [Name]
1851-- gives the names to always expend, even when under a binder of that
1852-- name (this is to expand methods with implicit arguments in
1853-- dependent interfaces).
1854addImpl :: [Name] -> IState -> PTerm -> PTerm
1855addImpl = addImpl' False [] []
1857-- TODO: in patterns, don't add implicits to function names guarded by constructors
1858-- and *not* inside a PHidden
1860addImpl' :: Bool -> [Name] -> [Name] -> [Name] -> IState -> PTerm -> PTerm
1861addImpl' inpat env infns imp_meths ist ptm
1862 = ai inpat False (zip env (repeat Nothing)) [] (mkUniqueNames env [] ptm)
1863 where
1864 topname = case ptm of
1865 PRef _ _ n -> n
1866 PApp _ (PRef _ _ n) _ -> n
1867 _ -> sUN "" -- doesn't matter then
1869 ai :: Bool -> Bool -> [(Name, Maybe PTerm)] -> [[T.Text]] -> PTerm -> PTerm
1870 ai inpat qq env ds (PRef fc fcs f)
1871 | f `elem` infns = PInferRef fc fcs f
1872 | not (f `elem` map fst env) = handleErr $ aiFn topname inpat inpat qq imp_meths ist fc f fc ds []
1873 ai inpat qq env ds (PHidden (PRef fc hl f))
1874 | not (f `elem` map fst env) = PHidden (handleErr $ aiFn topname inpat False qq imp_meths ist fc f fc ds [])
1875 ai inpat qq env ds (PRewrite fc by l r g)
1876 = let l' = ai inpat qq env ds l
1877 r' = ai inpat qq env ds r
1878 g' = fmap (ai inpat qq env ds) g in
1879 PRewrite fc by l' r' g'
1880 ai inpat qq env ds (PTyped l r)
1881 = let l' = ai inpat qq env ds l
1882 r' = ai inpat qq env ds r in
1883 PTyped l' r'
1884 ai inpat qq env ds (PPair fc hls p l r)
1885 = let l' = ai inpat qq env ds l
1886 r' = ai inpat qq env ds r in
1887 PPair fc hls p l' r'
1888 ai inpat qq env ds (PDPair fc hls p l t r)
1889 = let l' = ai inpat qq env ds l
1890 t' = ai inpat qq env ds t
1891 r' = ai inpat qq env ds r in
1892 PDPair fc hls p l' t' r'
1893 ai inpat qq env ds (PAlternative ms a as)
1894 = let as' = map (ai inpat qq env ds) as in
1895 PAlternative ms a as'
1896 ai inpat qq env _ (PDisamb ds' as) = ai inpat qq env ds' as
1897 ai inpat qq env ds (PApp fc (PInferRef ffc hl f) as)
1898 = let as' = map (fmap (ai inpat qq env ds)) as in
1899 PApp fc (PInferRef ffc hl f) as'
1900 ai inpat qq env ds (PApp fc ftm@(PRef ffc hl f) as)
1901 | f `elem` infns = ai inpat qq env ds (PApp fc (PInferRef ffc hl f) as)
1902 | not (f `elem` map fst env)
1903 = let as' = map (fmap (ai inpat qq env ds)) as in
1904 handleErr $ aiFn topname inpat False qq imp_meths ist fc f ffc ds as'
1905 | Just (Just ty) <- lookup f env =
1906 let as' = map (fmap (ai inpat qq env ds)) as
1907 arity = getPArity ty in
1908 mkPApp fc arity ftm as'
1909 ai inpat qq env ds (PApp fc f as)
1910 = let f' = ai inpat qq env ds f
1911 as' = map (fmap (ai inpat qq env ds)) as in
1912 mkPApp fc 1 f' as'
1913 ai inpat qq env ds (PWithApp fc f a)
1914 = PWithApp fc (ai inpat qq env ds f) (ai inpat qq env ds a)
1915 ai inpat qq env ds (PCase fc c os)
1916 = let c' = ai inpat qq env ds c in
1917 -- leave lhs alone, because they get lifted into a new pattern match
1918 -- definition which is passed through addImpl again
1919 PCase fc c' (map aiCase os)
1920 where
1921 aiCase (lhs, rhs)
1922 = (lhs, ai inpat qq (env ++ patnames lhs) ds rhs)
1924 -- Anything beginning with a lower case letter, not applied,
1925 -- and no namespace is a pattern variable
1926 patnames (PApp _ (PRef _ _ f) [])
1927 | implicitable f = [(f, Nothing)]
1928 patnames (PRef _ _ f)
1929 | implicitable f = [(f, Nothing)]
1930 patnames (PApp _ (PRef _ _ _) args)
1931 = concatMap patnames (map getTm args)
1932 patnames (PPair _ _ _ l r) = patnames l ++ patnames r
1933 patnames (PDPair _ _ _ l t r) = patnames l ++ patnames t ++ patnames r
1934 patnames (PAs _ _ t) = patnames t
1935 patnames (PAlternative _ _ ts) = concatMap patnames ts
1936 patnames _ = []
1939 ai inpat qq env ds (PIfThenElse fc c t f) = PIfThenElse fc (ai inpat qq env ds c)
1940 (ai inpat qq env ds t)
1941 (ai inpat qq env ds f)
1943 -- If the name in a lambda is an unapplied data constructor name, do this
1944 -- as a 'case' instead because we'll expect to match on it
1945 ai inpat qq env ds (PLam fc n nfc ty sc)
1946 = if canBeDConName n (tt_ctxt ist)
1947 then ai inpat qq env ds (PLam fc (sMN 0 "lamp") NoFC ty
1948 (PCase fc (PRef fc [] (sMN 0 "lamp") )
1949 [(PRef fc [] n, sc)]))
1950 else let ty' = ai inpat qq env ds ty
1951 sc' = ai inpat qq ((n, Just ty):env) ds sc in
1952 PLam fc n nfc ty' sc'
1953 ai inpat qq env ds (PLet fc n nfc ty val sc)
1954 = if canBeDConName n (tt_ctxt ist)
1955 then ai inpat qq env ds (PCase fc val [(PRef fc [] n, sc)])
1956 else let ty' = ai inpat qq env ds ty
1957 val' = ai inpat qq env ds val
1958 sc' = ai inpat qq ((n, Just ty):env) ds sc in
1959 PLet fc n nfc ty' val' sc'
1960 ai inpat qq env ds (PPi p n nfc ty sc)
1961 = let ty' = ai inpat qq env ds ty
1962 env' = if n `elem` imp_meths then env
1963 else
1964 ((n, Just ty) : env)
1965 sc' = ai inpat qq env' ds sc in
1966 PPi p n nfc ty' sc'
1967 ai inpat qq env ds (PGoal fc r n sc)
1968 = let r' = ai inpat qq env ds r
1969 sc' = ai inpat qq ((n, Nothing):env) ds sc in
1970 PGoal fc r' n sc'
1971 ai inpat qq env ds (PHidden tm) = PHidden (ai inpat qq env ds tm)
1972 -- Don't do PProof or PTactics since implicits get added when scope is
1973 -- properly known in ElabTerm.runTac
1974 ai inpat qq env ds (PUnifyLog tm) = PUnifyLog (ai inpat qq env ds tm)
1975 ai inpat qq env ds (PNoImplicits tm) = PNoImplicits (ai inpat qq env ds tm)
1976 ai inpat qq env ds (PQuasiquote tm g) = PQuasiquote (ai inpat True env ds tm)
1977 (fmap (ai inpat True env ds) g)
1978 ai inpat qq env ds (PUnquote tm) = PUnquote (ai inpat False env ds tm)
1979 ai inpat qq env ds (PRunElab fc tm ns) = PRunElab fc (ai inpat False env ds tm) ns
1980 ai inpat qq env ds (PConstSugar fc tm) = PConstSugar fc (ai inpat qq env ds tm)
1981 ai inpat qq env ds tm = tm
1983 handleErr (Left err) = PElabError err
1984 handleErr (Right x) = x
1986-- if in a pattern, and there are no arguments, and there's no possible
1987-- names with zero explicit arguments, don't add implicits.
1989aiFn :: Name -> Bool -> Bool -> Bool
1990 -> [Name]
1991 -> IState -> FC
1992 -> Name -- ^ function being applied
1993 -> FC -> [[T.Text]]
1994 -> [PArg] -- ^ initial arguments (if in a pattern)
1995 -> Either Err PTerm
1996aiFn topname inpat True qq imp_meths ist fc f ffc ds []
1997 | inpat && implicitable f && unqualified f = Right $ PPatvar ffc f
1998 | otherwise
1999 = case lookupDef f (tt_ctxt ist) of
2000 [] -> Right $ PPatvar ffc f
2001 alts -> let ialts = lookupCtxtName f (idris_implicits ist) in
2002 -- trace (show f ++ " " ++ show (fc, any (all imp) ialts, ialts, any constructor alts)) $
2003 if (not (vname f) || tcname f
2004 || any (conCaf (tt_ctxt ist)) ialts)
2005-- any constructor alts || any allImp ialts))
2006 then aiFn topname inpat False qq imp_meths ist fc f ffc ds [] -- use it as a constructor
2007 else Right $ PPatvar ffc f
2008 where imp (PExp _ _ _ _) = False
2009 imp _ = True
2010-- allImp [] = False
2011 allImp xs = all imp xs
2013 unqualified (NS _ _) = False
2014 unqualified _ = True
2016 constructor (TyDecl (DCon _ _ _) _) = True
2017 constructor _ = False
2019 conCaf ctxt (n, cia) = (isDConName n ctxt || (qq && isTConName n ctxt)) && allImp cia
2021 vname (UN n) = True -- non qualified
2022 vname _ = False
2024aiFn topname inpat expat qq imp_meths ist fc f ffc ds as
2025 | f `elem` primNames = Right $ PApp fc (PRef ffc [ffc] f) as
2026aiFn topname inpat expat qq imp_meths ist fc f ffc ds as
2027 -- This is where namespaces get resolved by adding PAlternative
2028 = do let ns = lookupCtxtName f (idris_implicits ist)
2029 let nh = filter (\(n, _) -> notHidden n) ns
2030 let ns' = case trimAlts ds nh of
2031 [] -> nh
2032 x -> x
2033 case ns' of
2034 [(f',ns)] -> Right $ mkPApp fc (length ns) (PRef ffc [ffc] (isImpName f f'))
2035 (insertImpl ns as)
2036 [] -> case metaVar f (map fst (idris_metavars ist)) of
2037 Just f' -> Right $ PApp fc (PRef ffc [ffc] f') as
2038 Nothing -> Right $ mkPApp fc (length as) (PRef ffc [ffc] f) as
2039 alts -> Right $
2040 PAlternative [] (ExactlyOne True) $
2041 map (\(f', ns) -> mkPApp fc (length ns) (PRef ffc [ffc] (isImpName f f'))
2042 (insertImpl ns as)) alts
2043 where
2044 -- if the name is in imp_meths, we should actually refer to the bound
2045 -- name rather than the global one after expanding implicits
2046 isImpName f f' | f `elem` imp_meths = f
2047 | otherwise = f'
2049 -- If it's a metavariable name, try to qualify it from the list of
2050 -- unsolved metavariables
2051 metaVar f (mvn : ns) | f == nsroot mvn = Just mvn
2052 metaVar f (_ : ns) = metaVar f ns
2053 metaVar f [] = Nothing
2055 trimAlts [] alts = alts
2056 trimAlts ns alts
2057 = filter (\(x, _) -> any (\d -> d `isPrefixOf` nspace x) ns) alts
2059 nspace (NS _ s) = s
2060 nspace _ = []
2062 notHidden n = case getAccessibility n of
2063 Hidden -> False
2064 Private -> False
2065 _ -> True
2067 getAccessibility n
2068 = case lookupDefAccExact n False (tt_ctxt ist) of
2069 Just (n,t) -> t
2070 _ -> Public
2072 insertImpl :: [PArg] -- ^ expected argument types (from idris_implicits)
2073 -> [PArg] -- ^ given arguments
2074 -> [PArg]
2075 insertImpl ps as
2076 = let (as', badimpls) = partition (impIn ps) as in
2077 map addUnknownImp badimpls ++
2078 insImpAcc M.empty ps (filter expArg as') (filter (not . expArg) as')
2080 insImpAcc :: M.Map Name PTerm -- accumulated param names & arg terms
2081 -> [PArg] -- parameters
2082 -> [PArg] -- explicit arguments
2083 -> [PArg] -- implicits given
2084 -> [PArg]
2085 insImpAcc pnas (PExp p l n ty : ps) (PExp _ _ _ tm : given) imps =
2086 PExp p l n tm : insImpAcc (M.insert n tm pnas) ps given imps
2087 insImpAcc pnas (PConstraint p l n ty : ps) (PConstraint _ _ _ tm : given) imps =
2088 PConstraint p l n tm : insImpAcc (M.insert n tm pnas) ps given imps
2089 insImpAcc pnas (PConstraint p l n ty : ps) given imps =
2090 let rtc = PResolveTC fc in
2091 PConstraint p l n rtc : insImpAcc (M.insert n rtc pnas) ps given imps
2092 insImpAcc pnas (PImp p _ l n ty : ps) given imps =
2093 case find n imps [] of
2094 Just (tm, imps') ->
2095 PImp p False l n tm : insImpAcc (M.insert n tm pnas) ps given imps'
2096 Nothing ->
2097 PImp p True l n Placeholder :
2098 insImpAcc (M.insert n Placeholder pnas) ps given imps
2099 insImpAcc pnas (PTacImplicit p l n sc' ty : ps) given imps =
2100 let sc = addImpl imp_meths ist (substMatches (M.toList pnas) sc') in
2101 case find n imps [] of
2102 Just (tm, imps') ->
2103 PTacImplicit p l n sc tm :
2104 insImpAcc (M.insert n tm pnas) ps given imps'
2105 Nothing ->
2106 if inpat
2107 then PTacImplicit p l n sc Placeholder :
2108 insImpAcc (M.insert n Placeholder pnas) ps given imps
2109 else PTacImplicit p l n sc sc :
2110 insImpAcc (M.insert n sc pnas) ps given imps
2111 insImpAcc _ expected [] imps = map addUnknownImp imps -- so that unused implicits give error
2112 insImpAcc _ _ given imps = given ++ imps
2114 addUnknownImp arg = arg { argopts = UnknownImp : argopts arg }
2116 find n [] acc = Nothing
2117 find n (PImp _ _ _ n' t : gs) acc
2118 | n == n' = Just (t, reverse acc ++ gs)
2119 find n (PTacImplicit _ _ n' _ t : gs) acc
2120 | n == n' = Just (t, reverse acc ++ gs)
2121 find n (g : gs) acc = find n gs (g : acc)
2123-- | return True if the second argument is an implicit argument which
2124-- is expected in the implicits, or if it's not an implicit
2125impIn :: [PArg] -> PArg -> Bool
2126impIn ps (PExp _ _ _ _) = True
2127impIn ps (PConstraint _ _ _ _) = True
2128impIn ps arg = any (\p -> not (expArg arg) && pname arg == pname p) ps
2130expArg (PExp _ _ _ _) = True
2131expArg (PConstraint _ _ _ _) = True
2132expArg _ = False
2134-- replace non-linear occurrences with _
2136stripLinear :: IState -> PTerm -> PTerm
2137stripLinear i tm = evalState (sl tm) [] where
2138 sl :: PTerm -> State [Name] PTerm
2139 sl (PRef fc hl f)
2140 | (_:_) <- lookupTy f (tt_ctxt i)
2141 = return $ PRef fc hl f
2142 | otherwise = do ns <- get
2143 if (f `elem` ns)
2144 then return $ PHidden (PRef fc hl f) -- Placeholder
2145 else do put (f : ns)
2146 return (PRef fc hl f)
2147 sl (PPatvar fc f)
2148 = do ns <- get
2149 if (f `elem` ns)
2150 then return $ PHidden (PPatvar fc f) -- Placeholder
2151 else do put (f : ns)
2152 return (PPatvar fc f)
2153 -- Assumption is that variables are all the same in each alternative
2154 sl t@(PAlternative ms b as) = do ns <- get
2155 as' <- slAlts ns as
2156 return (PAlternative ms b as')
2157 where slAlts ns (a : as) = do put ns
2158 a' <- sl a
2159 as' <- slAlts ns as
2160 return (a' : as')
2161 slAlts ns [] = return []
2162 sl (PPair fc hls p l r) = do l' <- sl l; r' <- sl r; return (PPair fc hls p l' r')
2163 sl (PDPair fc hls p l t r) = do l' <- sl l
2164 t' <- sl t
2165 r' <- sl r
2166 return (PDPair fc hls p l' t' r')
2167 sl (PApp fc fn args) = do fn' <- case fn of
2168 -- Just the args, fn isn't matchable as a var
2169 PRef _ _ _ -> return fn
2170 t -> sl t
2171 args' <- mapM slA args
2172 return $ PApp fc fn' args'
2173 where slA (PImp p m l n t) = do t' <- sl t
2174 return $ PImp p m l n t'
2175 slA (PExp p l n t) = do t' <- sl t
2176 return $ PExp p l n t'
2177 slA (PConstraint p l n t)
2178 = do t' <- sl t
2179 return $ PConstraint p l n t'
2180 slA (PTacImplicit p l n sc t)
2181 = do t' <- sl t
2182 return $ PTacImplicit p l n sc t'
2183 sl x = return x
2185-- | Remove functions which aren't applied to anything, which must then
2186-- be resolved by unification. Assume names resolved and alternatives
2187-- filled in (so no ambiguity).
2188stripUnmatchable :: IState -> PTerm -> PTerm
2189stripUnmatchable i (PApp fc fn args) = PApp fc fn (fmap (fmap su) args) where
2190 su :: PTerm -> PTerm
2191 su tm@(PRef fc hl f)
2192 | (Bind n (Pi _ _ t _) sc :_) <- lookupTy f (tt_ctxt i)
2193 = Placeholder
2194 | (TType _ : _) <- lookupTy f (tt_ctxt i),
2195 not (implicitable f)
2196 = PHidden tm
2197 | (UType _ : _) <- lookupTy f (tt_ctxt i),
2198 not (implicitable f)
2199 = PHidden tm
2200 su (PApp fc f@(PRef _ _ fn) args)
2201 -- here we use canBeDConName because the impossible pattern
2202 -- check will not necessarily fully resolve constructor names,
2203 -- and these bare names will otherwise get in the way of
2204 -- impossbility checking.
2205 | -- Just fn <- getFn f,
2206 canBeDConName fn ctxt
2207 = PApp fc f (fmap (fmap su) args)
2208 where getFn (PRef _ _ fn) = Just fn
2209 getFn (PApp _ f args) = getFn f
2210 getFn _ = Nothing
2211 su (PApp fc f args)
2212 = PHidden (PApp fc f args)
2213 su (PAlternative ms b alts)
2214 = let alts' = filter (/= Placeholder) (map su alts) in
2215 if null alts' then Placeholder
2216 else liftHidden $ PAlternative ms b alts'
2217 su (PPair fc hls p l r) = PPair fc hls p (su l) (su r)
2218 su (PDPair fc hls p l t r) = PDPair fc hls p (su l) (su t) (su r)
2219 su t@(PLam fc _ _ _ _) = PHidden t
2220 su t@(PPi _ _ _ _ _) = PHidden t
2221 su t@(PConstant _ c) | isTypeConst c = PHidden t
2222 su t = t
2224 ctxt = tt_ctxt i
2226 -- If the ambiguous terms are all hidden, the PHidden needs to be outside
2227 -- because elaboration of PHidden gets delayed, and we need the elaboration
2228 -- to resolve the ambiguity.
2229 liftHidden tm@(PAlternative ms b as)
2230 | allHidden as = PHidden (PAlternative ms b (map unHide as))
2231 | otherwise = tm
2233 allHidden [] = True
2234 allHidden (PHidden _ : xs) = allHidden xs
2235 allHidden (x : xs) = False
2237 unHide (PHidden t) = t
2238 unHide t = t
2240stripUnmatchable i tm = tm
2242mkPApp fc a f [] = f
2243mkPApp fc a f as = let rest = drop a as in
2244 if a == 0 then appRest fc f rest
2245 else appRest fc (PApp fc f (take a as)) rest
2246 where
2247 appRest fc f [] = f
2248 appRest fc f (a : as) = appRest fc (PApp fc f [a]) as
2252-- | Find 'static' argument positions
2253-- (the declared ones, plus any names in argument position in the declared
2254-- statics)
2255-- FIXME: It's possible that this really has to happen after elaboration
2256findStatics :: IState -> PTerm -> (PTerm, [Bool])
2257findStatics ist tm = let (ns, ss) = fs tm
2258 in runState (pos ns ss tm) []
2259 where fs (PPi p n fc t sc)
2260 | Static <- pstatic p
2261 = let (ns, ss) = fs sc in
2262 (namesIn [] ist t : ns, n : ss)
2263 | otherwise = let (ns, ss) = fs sc in
2264 (ns, ss)
2265 fs _ = ([], [])
2267 inOne n ns = length (filter id (map (elem n) ns)) == 1
2269 pos ns ss (PPi p n fc t sc)
2270 | elem n ss = do sc' <- pos ns ss sc
2271 spos <- get
2272 put (True : spos)
2273 return (PPi (p { pstatic = Static }) n fc t sc')
2274 | otherwise = do sc' <- pos ns ss sc
2275 spos <- get
2276 put (False : spos)
2277 return (PPi p n fc t sc')
2278 pos ns ss t = return t
2280-- for 6.12/7 compatibility
2281data EitherErr a b = LeftErr a | RightOK b deriving ( Functor )
2283instance Applicative (EitherErr a) where
2284 pure = return
2285 (<*>) = ap
2287instance Monad (EitherErr a) where
2288 return = RightOK
2290 (LeftErr e) >>= _ = LeftErr e
2291 RightOK v >>= k = k v
2293toEither :: EitherErr a b -> Either a b
2294toEither (LeftErr e) = Left e
2295toEither (RightOK ho) = Right ho
2297-- | Syntactic match of a against b, returning pair of variables in a
2298-- and what they match. Returns the pair that failed if not a match.
2299matchClause :: IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
2300matchClause = matchClause' False
2302matchClause' :: Bool -> IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
2303matchClause' names i x y = checkRpts $ match (fullApp x) (fullApp y) where
2304 matchArg x y = match (fullApp (getTm x)) (fullApp (getTm y))
2306 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
2307 fullApp x = x
2309 match' x y = match (fullApp x) (fullApp y)
2310 match (PApp _ (PRef _ _ (NS (UN fi) [b])) [_,_,x]) x'
2311 | fi == txt "fromInteger" && b == txt "builtins",
2312 PConstant _ (I _) <- getTm x = match (getTm x) x'
2313 match x' (PApp _ (PRef _ _ (NS (UN fi) [b])) [_,_,x])
2314 | fi == txt "fromInteger" && b == txt "builtins",
2315 PConstant _ (I _) <- getTm x = match (getTm x) x'
2316 match (PApp _ (PRef _ _ (UN l)) [_,x]) x' | l == txt "lazy" = match (getTm x) x'
2317 match x (PApp _ (PRef _ _ (UN l)) [_,x']) | l == txt "lazy" = match x (getTm x')
2318 match (PApp _ f args) (PApp _ f' args')
2319 | length args == length args'
2320 = do mf <- match' f f'
2321 ms <- zipWithM matchArg args args'
2322 return (mf ++ concat ms)
2323 match (PRef f hl n) (PApp _ x []) = match (PRef f hl n) x
2324 match (PPatvar f n) xr = match (PRef f [f] n) xr
2325 match xr (PPatvar f n) = match xr (PRef f [f] n)
2326 match (PApp _ x []) (PRef f hl n) = match x (PRef f hl n)
2327 match (PRef _ _ n) tm@(PRef _ _ n')
2328 | n == n' && not names &&
2329 (not (isConName n (tt_ctxt i) || isFnName n (tt_ctxt i))
2330 || tm == Placeholder)
2331 = return [(n, tm)]
2332 -- if one namespace is missing, drop the other
2333 | n == n' || n == dropNS n' || dropNS n == n' = return []
2334 where dropNS (NS n _) = n
2335 dropNS n = n
2336 match (PRef _ _ n) tm
2337 | not names && (not (isConName n (tt_ctxt i) ||
2338 isFnName n (tt_ctxt i)) || tm == Placeholder)
2339 = return [(n, tm)]
2340 match (PRewrite _ by l r _) (PRewrite _ by' l' r' _) | by == by'
2341 = do ml <- match' l l'
2342 mr <- match' r r'
2343 return (ml ++ mr)
2344 match (PTyped l r) (PTyped l' r') = do ml <- match l l'
2345 mr <- match r r'
2346 return (ml ++ mr)
2347 match (PTyped l r) x = match l x
2348 match x (PTyped l r) = match x l
2349 match (PPair _ _ _ l r) (PPair _ _ _ l' r') = do ml <- match' l l'
2350 mr <- match' r r'
2351 return (ml ++ mr)
2352 match (PDPair _ _ _ l t r) (PDPair _ _ _ l' t' r') = do ml <- match' l l'
2353 mt <- match' t t'
2354 mr <- match' r r'
2355 return (ml ++ mt ++ mr)
2356 match (PAlternative _ a as) (PAlternative _ a' as')
2357 = do ms <- zipWithM match' as as'
2358 return (concat ms)
2359 match a@(PAlternative _ _ as) b
2360 = do let ms = zipWith match' as (repeat b)
2361 case (rights (map toEither ms)) of
2362 (x: _) -> return x
2363 _ -> LeftErr (a, b)
2364 match (PCase _ _ _) _ = return [] -- lifted out
2365 match (PMetavar _ _) _ = return [] -- modified
2366 match (PInferRef _ _ _) _ = return [] -- modified
2367 match (PQuote _) _ = return []
2368 match (PProof _) _ = return []
2369 match (PTactics _) _ = return []
2370 match (PResolveTC _) (PResolveTC _) = return []
2371 match (PTrue _ _) (PTrue _ _) = return []
2372 match (PPi _ _ _ t s) (PPi _ _ _ t' s') = do mt <- match' t t'
2373 ms <- match' s s'
2374 return (mt ++ ms)
2375 match (PLam _ _ _ t s) (PLam _ _ _ t' s') = do mt <- match' t t'
2376 ms <- match' s s'
2377 return (mt ++ ms)
2378 match (PLet _ _ _ t ty s) (PLet _ _ _ t' ty' s') = do mt <- match' t t'
2379 mty <- match' ty ty'
2380 ms <- match' s s'
2381 return (mt ++ mty ++ ms)
2382 match (PHidden x) (PHidden y)
2383 | RightOK xs <- match x y = return xs -- to collect variables
2384 | otherwise = return [] -- Otherwise hidden things are unmatchable
2385 match (PHidden x) y
2386 | RightOK xs <- match x y = return xs
2387 | otherwise = return []
2388 match x (PHidden y)
2389 | RightOK xs <- match x y = return xs
2390 | otherwise = return []
2391 match (PUnifyLog x) y = match' x y
2392 match x (PUnifyLog y) = match' x y
2393 match (PNoImplicits x) y = match' x y
2394 match x (PNoImplicits y) = match' x y
2395 match Placeholder _ = return []
2396 match _ Placeholder = return []
2397 match (PResolveTC _) _ = return []
2398 match a b | a == b = return []
2399 | otherwise = LeftErr (a, b)
2401 checkRpts (RightOK ms) = check ms where
2402 check ((n,t):xs)
2403 | Just t' <- lookup n xs = if t/=t' && t/=Placeholder && t'/=Placeholder
2404 then Left (t, t')
2405 else check xs
2406 check (_:xs) = check xs
2407 check [] = Right ms
2408 checkRpts (LeftErr x) = Left x
2410substMatches :: [(Name, PTerm)] -> PTerm -> PTerm
2411substMatches ms = substMatchesShadow ms []
2413-- substMatchesShadow :: [(Name, PTerm)] -> [Name] -> PTerm -> PTerm
2414-- substMatchesShadow [] shs t = t
2415-- substMatchesShadow ((n,tm):ns) shs t
2416-- = substMatchShadow n shs tm (substMatchesShadow ns shs t)
2418substMatch :: Name -> PTerm -> PTerm -> PTerm
2419substMatch n = substMatchShadow n []
2421substMatchShadow :: Name -> [Name] -> PTerm -> PTerm -> PTerm
2422substMatchShadow n shs tm t = substMatchesShadow [(n, tm)] shs t
2424substMatchesShadow :: [(Name, PTerm)] -> [Name] -> PTerm -> PTerm
2425substMatchesShadow nmap shs t = sm shs t where
2426 sm xs (PRef _ _ n) | Just tm <- lookup n nmap = tm
2427 sm xs (PLam fc x xfc t sc) = PLam fc x xfc (sm xs t) (sm xs sc)
2428 sm xs (PPi p x fc t sc)
2429 | x `elem` xs
2430 = let x' = nextName x in
2431 PPi p x' fc (sm (x':xs) (substMatch x (PRef emptyFC [] x') t))
2432 (sm (x':xs) (substMatch x (PRef emptyFC [] x') sc))
2433 | otherwise = PPi p x fc (sm xs t) (sm (x : xs) sc)
2434 sm xs (PLet fc x xfc val t sc)
2435 = PLet fc x xfc (sm xs val) (sm xs t) (sm xs sc)
2436 sm xs (PApp f x as) = fullApp $ PApp f (sm xs x) (map (fmap (sm xs)) as)
2437 sm xs (PCase f x as) = PCase f (sm xs x) (map (pmap (sm xs)) as)
2438 sm xs (PIfThenElse fc c t f) = PIfThenElse fc (sm xs c) (sm xs t) (sm xs f)
2439 sm xs (PRewrite f by x y tm) = PRewrite f by (sm xs x) (sm xs y)
2440 (fmap (sm xs) tm)
2441 sm xs (PTyped x y) = PTyped (sm xs x) (sm xs y)
2442 sm xs (PPair f hls p x y) = PPair f hls p (sm xs x) (sm xs y)
2443 sm xs (PDPair f hls p x t y) = PDPair f hls p (sm xs x) (sm xs t) (sm xs y)
2444 sm xs (PAlternative ms a as) = PAlternative ms a (map (sm xs) as)
2445 sm xs (PHidden x) = PHidden (sm xs x)
2446 sm xs (PUnifyLog x) = PUnifyLog (sm xs x)
2447 sm xs (PNoImplicits x) = PNoImplicits (sm xs x)
2448 sm xs (PRunElab fc script ns) = PRunElab fc (sm xs script) ns
2449 sm xs (PConstSugar fc tm) = PConstSugar fc (sm xs tm)
2450 sm xs x = x
2452 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
2453 fullApp x = x
2455shadow :: Name -> Name -> PTerm -> PTerm
2456shadow n n' t = sm 0 t where
2457 sm 0 (PRef fc hl x) | n == x = PRef fc hl n'
2458 sm 0 (PLam fc x xfc t sc) | n /= x = PLam fc x xfc (sm 0 t) (sm 0 sc)
2459 | otherwise = PLam fc x xfc (sm 0 t) sc
2460 sm 0 (PPi p x fc t sc) | n /= x = PPi p x fc (sm 0 t) (sm 0 sc)
2461 | otherwise = PPi p x fc (sm 0 t) sc
2462 sm 0 (PLet fc x xfc t v sc) | n /= x = PLet fc x xfc (sm 0 t) (sm 0 v) (sm 0 sc)
2463 | otherwise = PLet fc x xfc (sm 0 t) (sm 0 v) sc
2464 sm 0 (PApp f x as) = PApp f (sm 0 x) (map (fmap (sm 0)) as)
2465 sm 0 (PAppBind f x as) = PAppBind f (sm 0 x) (map (fmap (sm 0)) as)
2466 sm 0 (PCase f x as) = PCase f (sm 0 x) (map (pmap (sm 0)) as)
2467 sm 0 (PIfThenElse fc c t f) = PIfThenElse fc (sm 0 c) (sm 0 t) (sm 0 f)
2468 sm 0 (PRewrite f by x y tm) = PRewrite f by (sm 0 x) (sm 0 y) (fmap (sm 0) tm)
2469 sm 0 (PTyped x y) = PTyped (sm 0 x) (sm 0 y)
2470 sm 0 (PPair f hls p x y) = PPair f hls p (sm 0 x) (sm 0 y)
2471 sm 0 (PDPair f hls p x t y) = PDPair f hls p (sm 0 x) (sm 0 t) (sm 0 y)
2472 sm 0 (PAlternative ms a as)
2473 = PAlternative (map shadowAlt ms) a (map (sm 0) as)
2474 sm 0 (PTactics ts) = PTactics (map (fmap (sm 0)) ts)
2475 sm 0 (PProof ts) = PProof (map (fmap (sm 0)) ts)
2476 sm 0 (PHidden x) = PHidden (sm 0 x)
2477 sm 0 (PUnifyLog x) = PUnifyLog (sm 0 x)
2478 sm 0 (PNoImplicits x) = PNoImplicits (sm 0 x)
2479 sm 0 (PCoerced t) = PCoerced (sm 0 t)
2480 sm ql (PQuasiquote tm ty) = PQuasiquote (sm (ql + 1) tm) (fmap (sm ql) ty)
2481 sm ql (PUnquote tm) = PUnquote (sm (ql - 1) tm)
2482 sm ql x = descend (sm ql) x
2484 shadowAlt p@(x, oldn) = (update x, update oldn)
2485 update oldn | n == oldn = n'
2486 | otherwise = oldn
2488-- | Rename any binders which are repeated (so that we don't have to
2489-- mess about with shadowing anywhere else).
2490mkUniqueNames :: [Name] -> [(Name, Name)] -> PTerm -> PTerm
2491mkUniqueNames env shadows tm
2492 = evalState (mkUniq 0 initMap tm) (S.fromList env) where
2494 initMap = M.fromList shadows
2496 inScope :: S.Set Name
2497 inScope = S.fromList $ boundNamesIn tm
2499 mkUniqA ql nmap arg = do t' <- mkUniq ql nmap (getTm arg)
2500 return (arg { getTm = t' })
2502 -- Initialise the unique name with the environment length (so we're not
2503 -- looking for too long...)
2504 initN (UN n) l = UN $ txt (str n ++ show l)
2505 initN (MN i s) l = MN (i+l) s
2506 initN n _ = n
2508 -- FIXME: Probably ought to do this for completeness! It's fine as
2509 -- long as there are no bindings inside tactics though.
2510 mkUniqT _ nmap tac = return tac
2512 mkUniq :: Int -- ^ The number of quotations that we're under
2513 -> M.Map Name Name -> PTerm -> State (S.Set Name) PTerm
2514 mkUniq 0 nmap (PLam fc n nfc ty sc)
2515 = do env <- get
2516 (n', sc') <-
2517 if n `S.member` env
2518 then do let n' = uniqueNameSet (initN n (S.size env))
2519 (S.union env inScope)
2520 return (n', sc) -- shadow n n' sc)
2521 else return (n, sc)
2522 put (S.insert n' env)
2523 let nmap' = M.insert n n' nmap
2524 ty' <- mkUniq 0 nmap ty
2525 sc'' <- mkUniq 0 nmap' sc'
2526 return $! PLam fc n' nfc ty' sc''
2527 mkUniq 0 nmap (PPi p n fc ty sc)
2528 = do env <- get
2529 (n', sc') <-
2530 if n `S.member` env
2531 then do let n' = uniqueNameSet (initN n (S.size env))
2532 (S.union env inScope)
2533 return (n', sc) -- shadow n n' sc)
2534 else return (n, sc)
2535 put (S.insert n' env)
2536 let nmap' = M.insert n n' nmap
2537 ty' <- mkUniq 0 nmap ty
2538 sc'' <- mkUniq 0 nmap' sc'
2539 return $! PPi p n' fc ty' sc''
2540 mkUniq 0 nmap (PLet fc n nfc ty val sc)
2541 = do env <- get
2542 (n', sc') <-
2543 if n `S.member` env
2544 then do let n' = uniqueNameSet (initN n (S.size env))
2545 (S.union env inScope)
2546 return (n', sc) -- shadow n n' sc)
2547 else return (n, sc)
2548 put (S.insert n' env)
2549 let nmap' = M.insert n n' nmap
2550 ty' <- mkUniq 0 nmap ty; val' <- mkUniq 0 nmap val
2551 sc'' <- mkUniq 0 nmap' sc'
2552 return $! PLet fc n' nfc ty' val' sc''
2553 mkUniq 0 nmap (PApp fc t args)
2554 = do t' <- mkUniq 0 nmap t
2555 args' <- mapM (mkUniqA 0 nmap) args
2556 return $! PApp fc t' args'
2557 mkUniq 0 nmap (PAppBind fc t args)
2558 = do t' <- mkUniq 0 nmap t
2559 args' <- mapM (mkUniqA 0 nmap) args
2560 return $! PAppBind fc t' args'
2561 mkUniq 0 nmap (PCase fc t alts)
2562 = do t' <- mkUniq 0 nmap t
2563 alts' <- mapM (\(x,y)-> do x' <- mkUniq 0 nmap x; y' <- mkUniq 0 nmap y
2564 return (x', y')) alts
2565 return $! PCase fc t' alts'
2566 mkUniq 0 nmap (PIfThenElse fc c t f)
2567 = liftM3 (PIfThenElse fc) (mkUniq 0 nmap c) (mkUniq 0 nmap t) (mkUniq 0 nmap f)
2568 mkUniq 0 nmap (PPair fc hls p l r)
2569 = do l' <- mkUniq 0 nmap l; r' <- mkUniq 0 nmap r
2570 return $! PPair fc hls p l' r'
2571 mkUniq 0 nmap (PDPair fc hls p (PRef fc' hls' n) t sc)
2572 | t /= Placeholder
2573 = do env <- get
2574 (n', sc') <- if n `S.member` env
2575 then do let n' = uniqueNameSet n (S.union env inScope)
2576 return (n', sc) -- shadow n n' sc)
2577 else return (n, sc)
2578 put (S.insert n' env)
2579 let nmap' = M.insert n n' nmap
2580 t' <- mkUniq 0 nmap t
2581 sc'' <- mkUniq 0 nmap' sc'
2582 return $! PDPair fc hls p (PRef fc' hls' n') t' sc''
2583 mkUniq 0 nmap (PDPair fc hls p l t r)
2584 = do l' <- mkUniq 0 nmap l; t' <- mkUniq 0 nmap t; r' <- mkUniq 0 nmap r
2585 return $! PDPair fc hls p l' t' r'
2586 mkUniq 0 nmap (PAlternative ns b as)
2587 -- store the nmap and defer the rest until we've pruned the set
2588 -- during elaboration
2589 = return $ PAlternative (ns ++ M.toList nmap) b as
2590 mkUniq 0 nmap (PHidden t) = liftM PHidden (mkUniq 0 nmap t)
2591 mkUniq 0 nmap (PUnifyLog t) = liftM PUnifyLog (mkUniq 0 nmap t)
2592 mkUniq 0 nmap (PDisamb n t) = liftM (PDisamb n) (mkUniq 0 nmap t)
2593 mkUniq 0 nmap (PNoImplicits t) = liftM PNoImplicits (mkUniq 0 nmap t)
2594 mkUniq 0 nmap (PProof ts) = liftM PProof (mapM (mkUniqT 0 nmap) ts)
2595 mkUniq 0 nmap (PTactics ts) = liftM PTactics (mapM (mkUniqT 0 nmap) ts)
2596 mkUniq 0 nmap (PRunElab fc ts ns) = liftM (\tm -> PRunElab fc tm ns) (mkUniq 0 nmap ts)
2597 mkUniq 0 nmap (PConstSugar fc tm) = liftM (PConstSugar fc) (mkUniq 0 nmap tm)
2598 mkUniq 0 nmap (PCoerced tm) = liftM PCoerced (mkUniq 0 nmap tm)
2599 mkUniq 0 nmap t = return $ shadowAll (M.toList nmap) t
2600 where
2601 shadowAll [] t = t
2602 shadowAll ((n, n') : ns) t = shadow n n' (shadowAll ns t)
2604 mkUniq ql nmap (PQuasiquote tm ty) =
2605 do tm' <- mkUniq (ql + 1) nmap tm
2606 ty' <- case ty of
2607 Nothing -> return Nothing
2608 Just t -> fmap Just $ mkUniq ql nmap t
2609 return $! PQuasiquote tm' ty'
2610 mkUniq ql nmap (PUnquote tm) = fmap PUnquote (mkUniq (ql - 1) nmap tm)
2612 mkUniq ql nmap tm = descendM (mkUniq ql nmap) tm