on 787832b help sign in
Idris-dev/src/Idris/AbsSyntax.hs
1425 lines 59 kB history raw
1{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, DeriveFunctor,
2 TypeSynonymInstances, PatternGuards #-}
4module Idris.AbsSyntax(module Idris.AbsSyntax, module Idris.AbsSyntaxTree) where
6import Core.TT
7import Core.Evaluate
8import Core.Elaborate hiding (Tactic(..))
9import Core.Typecheck
10import Idris.AbsSyntaxTree
11import Idris.IdeSlave
12import Idris.Colours
13import IRTS.CodegenCommon
14import Util.DynamicLinker
16import Paths_idris
18import System.Console.Haskeline
20import Control.Monad.State
22import Data.List
23import Data.Char
24import Data.Either
25import Data.Maybe
27import Debug.Trace
29import Util.Pretty
30import Util.System
32getContext :: Idris Context
33getContext = do i <- getIState; return (tt_ctxt i)
35forCodegen :: Codegen -> [(Codegen, a)] -> [a]
36forCodegen tgt xs = [x | (tgt', x) <- xs, tgt == tgt']
38getObjectFiles :: Codegen -> Idris [FilePath]
39getObjectFiles tgt = do i <- getIState; return (forCodegen tgt $ idris_objs i)
41addObjectFile :: Codegen -> FilePath -> Idris ()
42addObjectFile tgt f = do i <- getIState; putIState $ i { idris_objs = nub $ (tgt, f) : idris_objs i }
44getLibs :: Codegen -> Idris [String]
45getLibs tgt = do i <- getIState; return (forCodegen tgt $ idris_libs i)
47addLib :: Codegen -> String -> Idris ()
48addLib tgt f = do i <- getIState; putIState $ i { idris_libs = nub $ (tgt, f) : idris_libs i }
50getFlags :: Codegen -> Idris [String]
51getFlags tgt = do i <- getIState; return (forCodegen tgt $ idris_cgflags i)
53addFlag :: Codegen -> String -> Idris ()
54addFlag tgt f = do i <- getIState; putIState $ i { idris_cgflags = nub $ (tgt, f) : idris_cgflags i }
56addDyLib :: [String] -> Idris (Either DynamicLib String)
57addDyLib libs = do i <- getIState
58 let ls = idris_dynamic_libs i
59 case mapMaybe (findDyLib ls) libs of
60 x:_ -> return (Left x)
61 [] -> do
62 handle <- lift $ mapM (\l -> catchIO (tryLoadLib l) (\_ -> return Nothing)) $ libs
63 case msum handle of
64 Nothing -> return (Right $ "Could not load dynamic alternatives \"" ++
65 concat (intersperse "," libs) ++ "\"")
66 Just x -> do putIState $ i { idris_dynamic_libs = x:ls }
67 return (Left x)
68 where findDyLib :: [DynamicLib] -> String -> Maybe DynamicLib
69 findDyLib [] l = Nothing
70 findDyLib (lib:libs) l | l == lib_name lib = Just lib
71 | otherwise = findDyLib libs l
74addHdr :: Codegen -> String -> Idris ()
75addHdr tgt f = do i <- getIState; putIState $ i { idris_hdrs = nub $ (tgt, f) : idris_hdrs i }
77addLangExt :: LanguageExt -> Idris ()
78addLangExt TypeProviders = do i <- getIState ; putIState $ i { idris_language_extensions = [TypeProviders] }
80addTrans :: (Term, Term) -> Idris ()
81addTrans t = do i <- getIState
82 putIState $ i { idris_transforms = t : idris_transforms i }
84totcheck :: (FC, Name) -> Idris ()
85totcheck n = do i <- getIState; putIState $ i { idris_totcheck = idris_totcheck i ++ [n] }
87setFlags :: Name -> [FnOpt] -> Idris ()
88setFlags n fs = do i <- getIState; putIState $ i { idris_flags = addDef n fs (idris_flags i) }
90setAccessibility :: Name -> Accessibility -> Idris ()
91setAccessibility n a
92 = do i <- getIState
93 let ctxt = setAccess n a (tt_ctxt i)
94 putIState $ i { tt_ctxt = ctxt }
96setTotality :: Name -> Totality -> Idris ()
97setTotality n a
98 = do i <- getIState
99 let ctxt = setTotal n a (tt_ctxt i)
100 putIState $ i { tt_ctxt = ctxt }
102getTotality :: Name -> Idris Totality
103getTotality n
104 = do i <- getIState
105 case lookupTotal n (tt_ctxt i) of
106 [t] -> return t
107 _ -> return (Total [])
109-- Get coercions which might return the required type
110getCoercionsTo :: IState -> Type -> [Name]
111getCoercionsTo i ty =
112 let cs = idris_coercions i
113 (fn,_) = unApply (getRetTy ty) in
114 findCoercions fn cs
115 where findCoercions t [] = []
116 findCoercions t (n : ns) =
117 let ps = case lookupTy n (tt_ctxt i) of
118 [ty] -> case unApply (getRetTy ty) of
119 (t', _) ->
120 if t == t' then [n] else []
121 _ -> [] in
122 ps ++ findCoercions t ns
124addToCG :: Name -> CGInfo -> Idris ()
125addToCG n cg
126 = do i <- getIState
127 putIState $ i { idris_callgraph = addDef n cg (idris_callgraph i) }
129addCoercion :: Name -> Idris ()
130addCoercion n = do i <- getIState
131 putIState $ i { idris_coercions = nub $ n : idris_coercions i }
133addDocStr :: Name -> String -> Idris ()
134addDocStr n doc
135 = do i <- getIState
136 putIState $ i { idris_docstrings = addDef n doc (idris_docstrings i) }
138addToCalledG :: Name -> [Name] -> Idris ()
139addToCalledG n ns = return () -- TODO
141-- Add a class instance function. Dodgy hack: Put integer instances first in the
142-- list so they are resolved by default.
143-- Dodgy hack 2: put constraint chasers (@@) last
145addInstance :: Bool -> Name -> Name -> Idris ()
146addInstance int n i
147 = do ist <- getIState
148 case lookupCtxt n (idris_classes ist) of
149 [CI a b c d ins] ->
150 do let cs = addDef n (CI a b c d (addI i ins)) (idris_classes ist)
151 putIState $ ist { idris_classes = cs }
152 _ -> do let cs = addDef n (CI (MN 0 "none") [] [] [] [i]) (idris_classes ist)
153 putIState $ ist { idris_classes = cs }
154 where addI i ins | int = i : ins
155 | chaser n = ins ++ [i]
156 | otherwise = insI i ins
157 insI i [] = [i]
158 insI i (n : ns) | chaser n = i : n : ns
159 | otherwise = n : insI i ns
161 chaser (UN ('@':'@':_)) = True
162 chaser (NS n _) = chaser n
163 chaser _ = False
165addClass :: Name -> ClassInfo -> Idris ()
166addClass n i
167 = do ist <- getIState
168 let i' = case lookupCtxt n (idris_classes ist) of
169 [c] -> c { class_instances = class_instances i }
170 _ -> i
171 putIState $ ist { idris_classes = addDef n i' (idris_classes ist) }
173addIBC :: IBCWrite -> Idris ()
174addIBC ibc@(IBCDef n)
175 = do i <- getIState
176 when (notDef (ibc_write i)) $
177 putIState $ i { ibc_write = ibc : ibc_write i }
178 where notDef [] = True
179 notDef (IBCDef n': is) | n == n' = False
180 notDef (_ : is) = notDef is
181addIBC ibc = do i <- getIState; putIState $ i { ibc_write = ibc : ibc_write i }
183clearIBC :: Idris ()
184clearIBC = do i <- getIState; putIState $ i { ibc_write = [] }
186getHdrs :: Codegen -> Idris [String]
187getHdrs tgt = do i <- getIState; return (forCodegen tgt $ idris_hdrs i)
189setErrLine :: Int -> Idris ()
190setErrLine x = do i <- getIState;
191 case (errLine i) of
192 Nothing -> putIState $ i { errLine = Just x }
193 Just _ -> return ()
195clearErr :: Idris ()
196clearErr = do i <- getIState
197 putIState $ i { errLine = Nothing }
199getSO :: Idris (Maybe String)
200getSO = do i <- getIState
201 return (compiled_so i)
203setSO :: Maybe String -> Idris ()
204setSO s = do i <- getIState
205 putIState $ (i { compiled_so = s })
207getIState :: Idris IState
208getIState = get
210putIState :: IState -> Idris ()
211putIState = put
213getName :: Idris Int
214getName = do i <- getIState;
215 let idx = idris_name i;
216 putIState $ (i { idris_name = idx + 1 })
217 return idx
219checkUndefined :: FC -> Name -> Idris ()
220checkUndefined fc n
221 = do i <- getContext
222 case lookupTy n i of
223 (_:_) -> fail $ show fc ++ ":" ++
224 show n ++ " already defined"
225 _ -> return ()
227isUndefined :: FC -> Name -> Idris Bool
228isUndefined fc n
229 = do i <- getContext
230 case lookupTy n i of
231 (_:_) -> return False
232 _ -> return True
234setContext :: Context -> Idris ()
235setContext ctxt = do i <- getIState; putIState $ (i { tt_ctxt = ctxt } )
237updateContext :: (Context -> Context) -> Idris ()
238updateContext f = do i <- getIState; putIState $ (i { tt_ctxt = f (tt_ctxt i) } )
240addConstraints :: FC -> (Int, [UConstraint]) -> Idris ()
241addConstraints fc (v, cs)
242 = do i <- getIState
243 let ctxt = tt_ctxt i
244 let ctxt' = ctxt { uconstraints = cs ++ uconstraints ctxt,
245 next_tvar = v }
246 let ics = zip cs (repeat fc) ++ idris_constraints i
247 putIState $ i { tt_ctxt = ctxt', idris_constraints = ics }
249addDeferred = addDeferred' Ref
250addDeferredTyCon = addDeferred' (TCon 0 0)
252addDeferred' :: NameType -> [(Name, Type)] -> Idris ()
253addDeferred' nt ns
254 = do mapM_ (\(n, t) -> updateContext (addTyDecl n nt (tidyNames [] t))) ns
255 i <- getIState
256 putIState $ i { idris_metavars = map fst ns ++ idris_metavars i }
257 where tidyNames used (Bind (MN i x) b sc)
258 = let n' = uniqueName (UN x) used in
259 Bind n' b $ tidyNames (n':used) sc
260 tidyNames used (Bind n b sc)
261 = let n' = uniqueName n used in
262 Bind n' b $ tidyNames (n':used) sc
263 tidyNames used b = b
265solveDeferred :: Name -> Idris ()
266solveDeferred n = do i <- getIState
267 putIState $ i { idris_metavars = idris_metavars i \\ [n] }
269iResult :: String -> Idris ()
270iResult s = do i <- getIState
271 case idris_outputmode i of
272 RawOutput -> case s of
273 "" -> return ()
274 s -> liftIO $ putStrLn s
275 IdeSlave n ->
276 let good = SexpList [SymbolAtom "ok", toSExp s] in
277 liftIO $ putStrLn $ convSExp "return" good n
279iFail :: String -> Idris ()
280iFail s = do i <- getIState
281 case idris_outputmode i of
282 RawOutput -> case s of
283 "" -> return ()
284 s -> liftIO $ putStrLn s
285 IdeSlave n ->
286 let good = SexpList [SymbolAtom "error", toSExp s] in
287 liftIO . putStrLn $ convSExp "return" good n
289iputStrLn :: String -> Idris ()
290iputStrLn s = do i <- getIState
291 case idris_outputmode i of
292 RawOutput -> liftIO $ putStrLn s
293 IdeSlave n ->
294 case span (/=':') s of
295 (fn, ':':rest) -> case span isDigit rest of
296 ([], ':':msg) -> write
297 ([], msg) -> write
298 (num, ':':msg) -> iWarn (FC fn (read num)) msg
299 _ -> write
300 where write = liftIO . putStrLn $ convSExp "write-string" s n
302ideslavePutSExp :: SExpable a => String -> a -> Idris ()
303ideslavePutSExp cmd info = do i <- getIState
304 case idris_outputmode i of
305 IdeSlave n -> liftIO . putStrLn $ convSExp cmd info n
306 _ -> return ()
308-- this needs some typing magic and more structured output towards emacs
309iputGoal :: String -> Idris ()
310iputGoal s = do i <- getIState
311 case idris_outputmode i of
312 RawOutput -> liftIO $ putStrLn s
313 IdeSlave n -> liftIO . putStrLn $ convSExp "write-goal" s n
315isetPrompt :: String -> Idris ()
316isetPrompt p = do i <- getIState
317 case idris_outputmode i of
318 IdeSlave n -> liftIO . putStrLn $ convSExp "set-prompt" p n
320iWarn :: FC -> String -> Idris ()
321iWarn fc err = do i <- getIState
322 case idris_outputmode i of
323 RawOutput -> liftIO $ putStrLn (show fc ++ ":" ++ err)
324 IdeSlave n -> liftIO . putStrLn $ convSExp "warning" (fc_fname fc, fc_line fc, err) n
326setLogLevel :: Int -> Idris ()
327setLogLevel l = do i <- getIState
328 let opts = idris_options i
329 let opt' = opts { opt_logLevel = l }
330 putIState $ i { idris_options = opt' }
332setCmdLine :: [Opt] -> Idris ()
333setCmdLine opts = do i <- getIState
334 let iopts = idris_options i
335 putIState $ i { idris_options = iopts { opt_cmdline = opts } }
337getCmdLine :: Idris [Opt]
338getCmdLine = do i <- getIState
339 return (opt_cmdline (idris_options i))
341getDumpDefun :: Idris (Maybe FilePath)
342getDumpDefun = do i <- getIState
343 return $ findC (opt_cmdline (idris_options i))
344 where findC [] = Nothing
345 findC (DumpDefun x : _) = Just x
346 findC (_ : xs) = findC xs
348getDumpCases :: Idris (Maybe FilePath)
349getDumpCases = do i <- getIState
350 return $ findC (opt_cmdline (idris_options i))
351 where findC [] = Nothing
352 findC (DumpCases x : _) = Just x
353 findC (_ : xs) = findC xs
355logLevel :: Idris Int
356logLevel = do i <- getIState
357 return (opt_logLevel (idris_options i))
359setErrContext :: Bool -> Idris ()
360setErrContext t = do i <- getIState
361 let opts = idris_options i
362 let opt' = opts { opt_errContext = t }
363 putIState $ i { idris_options = opt' }
365errContext :: Idris Bool
366errContext = do i <- getIState
367 return (opt_errContext (idris_options i))
369useREPL :: Idris Bool
370useREPL = do i <- getIState
371 return (opt_repl (idris_options i))
373setREPL :: Bool -> Idris ()
374setREPL t = do i <- getIState
375 let opts = idris_options i
376 let opt' = opts { opt_repl = t }
377 putIState $ i { idris_options = opt' }
379setQuiet :: Bool -> Idris ()
380setQuiet q = do i <- getIState
381 let opts = idris_options i
382 let opt' = opts { opt_quiet = q }
383 putIState $ i { idris_options = opt' }
385getQuiet :: Idris Bool
386getQuiet = do i <- getIState
387 let opts = idris_options i
388 return (opt_quiet opts)
390setCodegen :: Codegen -> Idris ()
391setCodegen t = do i <- getIState
392 let opts = idris_options i
393 let opt' = opts { opt_codegen = t }
394 putIState $ i { idris_options = opt' }
396codegen :: Idris Codegen
397codegen = do i <- getIState
398 return (opt_codegen (idris_options i))
400setOutputTy :: OutputType -> Idris ()
401setOutputTy t = do i <- getIState
402 let opts = idris_options i
403 let opt' = opts { opt_outputTy = t }
404 putIState $ i { idris_options = opt' }
406outputTy :: Idris OutputType
407outputTy = do i <- getIState
408 return $ opt_outputTy $ idris_options i
410setIdeSlave :: Bool -> Idris ()
411setIdeSlave True = do i <- getIState
412 putIState $ i { idris_outputmode = (IdeSlave 0) }
413setIdeSlave False = return ()
415setTargetTriple :: String -> Idris ()
416setTargetTriple t = do i <- getIState
417 let opts = idris_options i
418 opt' = opts { opt_triple = t }
419 putIState $ i { idris_options = opt' }
421targetTriple :: Idris String
422targetTriple = do i <- getIState
423 return (opt_triple (idris_options i))
425setTargetCPU :: String -> Idris ()
426setTargetCPU t = do i <- getIState
427 let opts = idris_options i
428 opt' = opts { opt_cpu = t }
429 putIState $ i { idris_options = opt' }
431targetCPU :: Idris String
432targetCPU = do i <- getIState
433 return (opt_cpu (idris_options i))
435setOptLevel :: Int -> Idris ()
436setOptLevel t = do i <- getIState
437 let opts = idris_options i
438 opt' = opts { opt_optLevel = t }
439 putIState $ i { idris_options = opt' }
441optLevel :: Idris Int
442optLevel = do i <- getIState
443 return (opt_optLevel (idris_options i))
445verbose :: Idris Bool
446verbose = do i <- getIState
447 return (opt_verbose (idris_options i))
449setVerbose :: Bool -> Idris ()
450setVerbose t = do i <- getIState
451 let opts = idris_options i
452 let opt' = opts { opt_verbose = t }
453 putIState $ i { idris_options = opt' }
455typeInType :: Idris Bool
456typeInType = do i <- getIState
457 return (opt_typeintype (idris_options i))
459setTypeInType :: Bool -> Idris ()
460setTypeInType t = do i <- getIState
461 let opts = idris_options i
462 let opt' = opts { opt_typeintype = t }
463 putIState $ i { idris_options = opt' }
465coverage :: Idris Bool
466coverage = do i <- getIState
467 return (opt_coverage (idris_options i))
469setCoverage :: Bool -> Idris ()
470setCoverage t = do i <- getIState
471 let opts = idris_options i
472 let opt' = opts { opt_coverage = t }
473 putIState $ i { idris_options = opt' }
475setIBCSubDir :: FilePath -> Idris ()
476setIBCSubDir fp = do i <- getIState
477 let opts = idris_options i
478 let opt' = opts { opt_ibcsubdir = fp }
479 putIState $ i { idris_options = opt' }
481valIBCSubDir :: IState -> Idris FilePath
482valIBCSubDir i = return (opt_ibcsubdir (idris_options i))
484addImportDir :: FilePath -> Idris ()
485addImportDir fp = do i <- getIState
486 let opts = idris_options i
487 let opt' = opts { opt_importdirs = fp : opt_importdirs opts }
488 putIState $ i { idris_options = opt' }
490setImportDirs :: [FilePath] -> Idris ()
491setImportDirs fps = do i <- getIState
492 let opts = idris_options i
493 let opt' = opts { opt_importdirs = fps }
494 putIState $ i { idris_options = opt' }
496allImportDirs :: Idris [FilePath]
497allImportDirs = do i <- getIState
498 let optdirs = opt_importdirs (idris_options i)
499 return ("." : reverse optdirs)
501colourise :: Idris Bool
502colourise = do i <- getIState
503 return $ idris_colourRepl i
505setColourise :: Bool -> Idris ()
506setColourise b = do i <- getIState
507 putIState $ i { idris_colourRepl = b }
509impShow :: Idris Bool
510impShow = do i <- getIState
511 return (opt_showimp (idris_options i))
513setImpShow :: Bool -> Idris ()
514setImpShow t = do i <- getIState
515 let opts = idris_options i
516 let opt' = opts { opt_showimp = t }
517 putIState $ i { idris_options = opt' }
519setColour :: ColourType -> IdrisColour -> Idris ()
520setColour ct c = do i <- getIState
521 let newTheme = setColour' ct c (idris_colourTheme i)
522 putIState $ i { idris_colourTheme = newTheme }
523 where setColour' KeywordColour c t = t { keywordColour = c }
524 setColour' BoundVarColour c t = t { boundVarColour = c }
525 setColour' ImplicitColour c t = t { implicitColour = c }
526 setColour' FunctionColour c t = t { functionColour = c }
527 setColour' TypeColour c t = t { typeColour = c }
528 setColour' DataColour c t = t { dataColour = c }
529 setColour' PromptColour c t = t { promptColour = c }
531logLvl :: Int -> String -> Idris ()
532logLvl l str = do i <- getIState
533 let lvl = opt_logLevel (idris_options i)
534 when (lvl >= l)
535 $ do liftIO (putStrLn str)
536 putIState $ i { idris_log = idris_log i ++ str ++ "\n" }
538cmdOptType :: Opt -> Idris Bool
539cmdOptType x = do i <- getIState
540 return $ x `elem` opt_cmdline (idris_options i)
542iLOG :: String -> Idris ()
543iLOG = logLvl 1
545noErrors :: Idris Bool
546noErrors = do i <- getIState
547 case errLine i of
548 Nothing -> return True
549 _ -> return False
551setTypeCase :: Bool -> Idris ()
552setTypeCase t = do i <- getIState
553 let opts = idris_options i
554 let opt' = opts { opt_typecase = t }
555 putIState $ i { idris_options = opt' }
558-- For inferring types of things
560bi = FC "builtin" 0
562inferTy = MN 0 "__Infer"
563inferCon = MN 0 "__infer"
564inferDecl = PDatadecl inferTy
565 PType
566 [("", inferCon, PPi impl (MN 0 "A") PType (
567 PPi expl (MN 0 "a") (PRef bi (MN 0 "A"))
568 (PRef bi inferTy)), bi)]
570infTerm t = PApp bi (PRef bi inferCon) [pimp (MN 0 "A") Placeholder, pexp t]
571infP = P (TCon 6 0) inferTy (TType (UVal 0))
573getInferTerm, getInferType :: Term -> Term
574getInferTerm (Bind n b sc) = Bind n b $ getInferTerm sc
575getInferTerm (App (App _ _) tm) = tm
576getInferTerm tm = tm -- error ("getInferTerm " ++ show tm)
578getInferType (Bind n b sc) = Bind n b $ getInferType sc
579getInferType (App (App _ ty) _) = ty
581-- Handy primitives: Unit, False, Pair, MkPair, =, mkForeign
583primNames = [unitTy, unitCon,
584 falseTy, pairTy, pairCon,
585 eqTy, eqCon, inferTy, inferCon]
587unitTy = MN 0 "__Unit"
588unitCon = MN 0 "__II"
589unitDecl = PDatadecl unitTy PType
590 [("", unitCon, PRef bi unitTy, bi)]
592falseTy = MN 0 "__False"
593falseDecl = PDatadecl falseTy PType []
595pairTy = MN 0 "__Pair"
596pairCon = MN 0 "__MkPair"
597pairDecl = PDatadecl pairTy (piBind [(n "A", PType), (n "B", PType)] PType)
598 [("", pairCon, PPi impl (n "A") PType (
599 PPi impl (n "B") PType (
600 PPi expl (n "a") (PRef bi (n "A")) (
601 PPi expl (n "b") (PRef bi (n "B"))
602 (PApp bi (PRef bi pairTy) [pexp (PRef bi (n "A")),
603 pexp (PRef bi (n "B"))])))), bi)]
604 where n a = MN 0 a
606eqTy = UN "="
607eqCon = UN "refl"
608eqDecl = PDatadecl eqTy (piBind [(n "a", PType), (n "b", PType),
609 (n "x", PRef bi (n "a")), (n "y", PRef bi (n "b"))]
610 PType)
611 [("", eqCon, PPi impl (n "a") PType (
612 PPi impl (n "x") (PRef bi (n "a"))
613 (PApp bi (PRef bi eqTy) [pimp (n "a") Placeholder,
614 pimp (n "b") Placeholder,
615 pexp (PRef bi (n "x")),
616 pexp (PRef bi (n "x"))])), bi)]
617 where n a = MN 0 a
619-- Defined in builtins.idr
620sigmaTy = UN "Exists"
621existsCon = UN "Ex_intro"
623piBind :: [(Name, PTerm)] -> PTerm -> PTerm
624piBind = piBindp expl
626piBindp :: Plicity -> [(Name, PTerm)] -> PTerm -> PTerm
627piBindp p [] t = t
628piBindp p ((n, ty):ns) t = PPi p n ty (piBind ns t)
630-- Dealing with parameters
632expandParams :: (Name -> Name) -> [(Name, PTerm)] ->
633 [Name] -> -- all names
634 [Name] -> -- names with no declaration
635 PTerm -> PTerm
636expandParams dec ps ns infs tm = en tm
637 where
638 -- if we shadow a name (say in a lambda binding) that is used in a call to
639 -- a lifted function, we need access to both names - once in the scope of the
640 -- binding and once to call the lifted functions. So we'll explicitly shadow
641 -- it. (Yes, it's a hack. The alternative would be to resolve names earlier
642 -- but we didn't...)
644 mkShadow (UN n) = MN 0 n
645 mkShadow (MN i n) = MN (i+1) n
646 mkShadow (NS x s) = NS (mkShadow x) s
648 en (PLam n t s)
649 | n `elem` (map fst ps ++ ns)
650 = let n' = mkShadow n in
651 PLam n' (en t) (en (shadow n n' s))
652 | otherwise = PLam n (en t) (en s)
653 en (PPi p n t s)
654 | n `elem` (map fst ps ++ ns)
655 = let n' = mkShadow n in
656 PPi p n' (en t) (en (shadow n n' s))
657 | otherwise = PPi p n (en t) (en s)
658 en (PLet n ty v s)
659 | n `elem` (map fst ps ++ ns)
660 = let n' = mkShadow n in
661 PLet n' (en ty) (en v) (en (shadow n n' s))
662 | otherwise = PLet n (en ty) (en v) (en s)
663 -- FIXME: Should only do this in a type signature!
664 en (PDPair f (PRef f' n) t r)
665 | n `elem` (map fst ps ++ ns) && t /= Placeholder
666 = let n' = mkShadow n in
667 PDPair f (PRef f' n') (en t) (en (shadow n n' r))
668 en (PEq f l r) = PEq f (en l) (en r)
669 en (PRewrite f l r g) = PRewrite f (en l) (en r) (fmap en g)
670 en (PTyped l r) = PTyped (en l) (en r)
671 en (PPair f l r) = PPair f (en l) (en r)
672 en (PDPair f l t r) = PDPair f (en l) (en t) (en r)
673 en (PAlternative a as) = PAlternative a (map en as)
674 en (PHidden t) = PHidden (en t)
675 en (PUnifyLog t) = PUnifyLog (en t)
676 en (PDoBlock ds) = PDoBlock (map (fmap en) ds)
677 en (PProof ts) = PProof (map (fmap en) ts)
678 en (PTactics ts) = PTactics (map (fmap en) ts)
680 en (PQuote (Var n))
681 | n `nselem` ns = PQuote (Var (dec n))
682 en (PApp fc (PInferRef fc' n) as)
683 | n `nselem` ns = PApp fc (PInferRef fc' (dec n))
684 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
685 en (PApp fc (PRef fc' n) as)
686 | n `elem` infs = PApp fc (PInferRef fc' (dec n))
687 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
688 | n `nselem` ns = PApp fc (PRef fc' (dec n))
689 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
690 en (PRef fc n)
691 | n `elem` infs = PApp fc (PInferRef fc (dec n))
692 (map (pexp . (PRef fc)) (map fst ps))
693 | n `nselem` ns = PApp fc (PRef fc (dec n))
694 (map (pexp . (PRef fc)) (map fst ps))
695 en (PInferRef fc n)
696 | n `nselem` ns = PApp fc (PInferRef fc (dec n))
697 (map (pexp . (PRef fc)) (map fst ps))
698 en (PApp fc f as) = PApp fc (en f) (map (fmap en) as)
699 en (PCase fc c os) = PCase fc (en c) (map (pmap en) os)
700 en t = t
702 nselem x [] = False
703 nselem x (y : xs) | nseq x y = True
704 | otherwise = nselem x xs
706 nseq x y = nsroot x == nsroot y
708expandParamsD :: Bool -> -- True = RHS only
709 IState ->
710 (Name -> Name) -> [(Name, PTerm)] -> [Name] -> PDecl -> PDecl
711expandParamsD rhsonly ist dec ps ns (PTy doc syn fc o n ty)
712 = if n `elem` ns && (not rhsonly)
713 then -- trace (show (n, expandParams dec ps ns ty)) $
714 PTy doc syn fc o (dec n) (piBind ps (expandParams dec ps ns [] ty))
715 else --trace (show (n, expandParams dec ps ns ty)) $
716 PTy doc syn fc o n (expandParams dec ps ns [] ty)
717expandParamsD rhsonly ist dec ps ns (PPostulate doc syn fc o n ty)
718 = if n `elem` ns && (not rhsonly)
719 then -- trace (show (n, expandParams dec ps ns ty)) $
720 PPostulate doc syn fc o (dec n) (piBind ps
721 (expandParams dec ps ns [] ty))
722 else --trace (show (n, expandParams dec ps ns ty)) $
723 PPostulate doc syn fc o n (expandParams dec ps ns [] ty)
724expandParamsD rhsonly ist dec ps ns (PClauses fc opts n cs)
725 = let n' = if n `elem` ns then dec n else n in
726 PClauses fc opts n' (map expandParamsC cs)
727 where
728 expandParamsC (PClause fc n lhs ws rhs ds)
729 = let -- ps' = updateps True (namesIn ist rhs) (zip ps [0..])
730 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
731 lhs' = if rhsonly then lhs else (expandParams dec ps'' ns [] lhs)
732 n' = if n `elem` ns then dec n else n
733 -- names bound on the lhs should not be expanded on the rhs
734 ns' = removeBound lhs ns in
735 PClause fc n' lhs'
736 (map (expandParams dec ps'' ns' []) ws)
737 (expandParams dec ps'' ns' [] rhs)
738 (map (expandParamsD True ist dec ps'' ns') ds)
739 expandParamsC (PWith fc n lhs ws wval ds)
740 = let -- ps' = updateps True (namesIn ist wval) (zip ps [0..])
741 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
742 lhs' = if rhsonly then lhs else (expandParams dec ps'' ns [] lhs)
743 n' = if n `elem` ns then dec n else n
744 ns' = removeBound lhs ns in
745 PWith fc n' lhs'
746 (map (expandParams dec ps'' ns' []) ws)
747 (expandParams dec ps'' ns' [] wval)
748 (map (expandParamsD rhsonly ist dec ps'' ns') ds)
749 updateps yn nm [] = []
750 updateps yn nm (((a, t), i):as)
751 | (a `elem` nm) == yn = (a, t) : updateps yn nm as
752 | otherwise = (MN i (show n ++ "_u"), t) : updateps yn nm as
754 removeBound lhs ns = ns \\ nub (bnames lhs)
756 bnames (PRef _ n) = [n]
757 bnames (PApp _ _ args) = concatMap bnames (map getTm args)
758 bnames (PPair _ l r) = bnames l ++ bnames r
759 bnames (PDPair _ l Placeholder r) = bnames l ++ bnames r
760 bnames _ = []
762expandParamsD rhs ist dec ps ns (PData doc syn fc co pd)
763 = PData doc syn fc co (expandPData pd)
764 where
765 -- just do the type decl, leave constructors alone (parameters will be
766 -- added implicitly)
767 expandPData (PDatadecl n ty cons)
768 = if n `elem` ns
769 then PDatadecl (dec n) (piBind ps (expandParams dec ps ns [] ty))
770 (map econ cons)
771 else PDatadecl n (expandParams dec ps ns [] ty) (map econ cons)
772 econ (doc, n, t, fc)
773 = (doc, dec n, piBindp expl ps (expandParams dec ps ns [] t), fc)
774expandParamsD rhs ist dec ps ns (PParams f params pds)
775 = PParams f (ps ++ map (mapsnd (expandParams dec ps ns [])) params)
776 (map (expandParamsD True ist dec ps ns) pds)
777-- (map (expandParamsD ist dec ps ns) pds)
778expandParamsD rhs ist dec ps ns (PMutual f pds)
779 = PMutual f (map (expandParamsD rhs ist dec ps ns) pds)
780expandParamsD rhs ist dec ps ns (PClass doc info f cs n params decls)
781 = PClass doc info f
782 (map (expandParams dec ps ns []) cs)
783 n
784 (map (mapsnd (expandParams dec ps ns [])) params)
785 (map (expandParamsD rhs ist dec ps ns) decls)
786expandParamsD rhs ist dec ps ns (PInstance info f cs n params ty cn decls)
787 = PInstance info f
788 (map (expandParams dec ps ns []) cs)
789 n
790 (map (expandParams dec ps ns []) params)
791 (expandParams dec ps ns [] ty)
792 cn
793 (map (expandParamsD rhs ist dec ps ns) decls)
794expandParamsD rhs ist dec ps ns d = d
796mapsnd f (x, t) = (x, f t)
798-- Calculate a priority for a type, for deciding elaboration order
799-- * if it's just a type variable or concrete type, do it early (0)
800-- * if there's only type variables and injective constructors, do it next (1)
801-- * if there's a function type, next (2)
802-- * finally, everything else (3)
804getPriority :: IState -> PTerm -> Int
805getPriority i tm = 1 -- pri tm
806 where
807 pri (PRef _ n) =
808 case lookupP n (tt_ctxt i) of
809 ((P (DCon _ _) _ _):_) -> 1
810 ((P (TCon _ _) _ _):_) -> 1
811 ((P Ref _ _):_) -> 1
812 [] -> 0 -- must be locally bound, if it's not an error...
813 pri (PPi _ _ x y) = max 5 (max (pri x) (pri y))
814 pri (PTrue _) = 0
815 pri (PFalse _) = 0
816 pri (PRefl _ _) = 1
817 pri (PEq _ l r) = max 1 (max (pri l) (pri r))
818 pri (PRewrite _ l r _) = max 1 (max (pri l) (pri r))
819 pri (PApp _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.getTm) as)))
820 pri (PCase _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.snd) as)))
821 pri (PTyped l r) = pri l
822 pri (PPair _ l r) = max 1 (max (pri l) (pri r))
823 pri (PDPair _ l t r) = max 1 (max (pri l) (max (pri t) (pri r)))
824 pri (PAlternative a as) = maximum (map pri as)
825 pri (PConstant _) = 0
826 pri Placeholder = 1
827 pri _ = 3
829addStatics :: Name -> Term -> PTerm -> Idris ()
830addStatics n tm ptm =
831 do let (statics, dynamics) = initStatics tm ptm
832 let stnames = nub $ concatMap freeNames (map snd statics)
833 let dnames = nub $ concatMap freeNames (map snd dynamics)
834 when (not (null statics)) $
835 logLvl 7 $ show n ++ " " ++ show statics ++ "\n" ++ show dynamics
836 ++ "\n" ++ show stnames ++ "\n" ++ show dnames
837 let statics' = nub $ map fst statics ++
838 filter (\x -> not (elem x dnames)) stnames
839 let stpos = staticList statics' tm
840 i <- getIState
841 putIState $ i { idris_statics = addDef n stpos (idris_statics i) }
842 addIBC (IBCStatic n)
843 where
844 initStatics (Bind n (Pi ty) sc) (PPi p _ _ s)
845 = let (static, dynamic) = initStatics (instantiate (P Bound n ty) sc) s in
846 if pstatic p == Static then ((n, ty) : static, dynamic)
847 else (static, (n, ty) : dynamic)
848 initStatics t pt = ([], [])
850 staticList sts (Bind n (Pi _) sc) = (n `elem` sts) : staticList sts sc
851 staticList _ _ = []
853-- Dealing with implicit arguments
855-- Add constraint bindings from using block
857addUsingConstraints :: SyntaxInfo -> FC -> PTerm -> Idris PTerm
858addUsingConstraints syn fc t
859 = do ist <- get
860 let ns = namesIn [] ist t
861 let cs = getConstraints t -- check declared constraints
862 let addconsts = uconsts \\ cs
863 -- if all names in the arguments of addconsts appear in ns,
864 -- add the constraint implicitly
865 return (doAdd addconsts ns t)
866 where uconsts = filter uconst (using syn)
867 uconst (UConstraint _ _) = True
868 uconst _ = False
870 doAdd [] _ t = t
871 -- if all of args in ns, then add it
872 doAdd (UConstraint c args : cs) ns t
873 | all (\n -> elem n ns) args
874 = PPi (Constraint False Dynamic "") (MN 0 "cu")
875 (mkConst c args) (doAdd cs ns t)
876 | otherwise = doAdd cs ns t
878 mkConst c args = PApp fc (PRef fc c)
879 (map (\n -> PExp 0 False (PRef fc n) "") args)
881 getConstraints (PPi (Constraint _ _ _) _ c sc)
882 = getcapp c ++ getConstraints sc
883 getConstraints (PPi _ _ c sc) = getConstraints sc
884 getConstraints _ = []
886 getcapp (PApp _ (PRef _ c) args)
887 = do ns <- mapM getName args
888 return (UConstraint c ns)
889 getcapp _ = []
891 getName (PExp _ _ (PRef _ n) _) = return n
892 getName _ = []
894-- Add implicit Pi bindings for any names in the term which appear in an
895-- argument position.
897-- This has become a right mess already. Better redo it some time...
899implicit :: SyntaxInfo -> Name -> PTerm -> Idris PTerm
900implicit syn n ptm = implicit' syn [] n ptm
902implicit' :: SyntaxInfo -> [Name] -> Name -> PTerm -> Idris PTerm
903implicit' syn ignore n ptm
904 = do i <- getIState
905 let (tm', impdata) = implicitise syn ignore i ptm
906-- let (tm'', spos) = findStatics i tm'
907 putIState $ i { idris_implicits = addDef n impdata (idris_implicits i) }
908 addIBC (IBCImp n)
909 logLvl 5 ("Implicit " ++ show n ++ " " ++ show impdata)
910-- i <- get
911-- putIState $ i { idris_statics = addDef n spos (idris_statics i) }
912 return tm'
914implicitise :: SyntaxInfo -> [Name] -> IState -> PTerm -> (PTerm, [PArg])
915implicitise syn ignore ist tm = -- trace ("INCOMING " ++ showImp True tm) $
916 let (declimps, ns') = execState (imps True [] tm) ([], [])
917 ns = filter (\n -> implicitable n || elem n (map fst uvars)) $
918 ns' \\ (map fst pvars ++ no_imp syn ++ ignore)
919 nsOrder = filter (not . inUsing) ns ++ filter inUsing ns in
920 if null ns
921 then (tm, reverse declimps)
922 else implicitise syn ignore ist (pibind uvars nsOrder tm)
923 where
924 uvars = map ipair (filter uimplicit (using syn))
925 pvars = syn_params syn
927 inUsing n = n `elem` map fst uvars
929 ipair (UImplicit x y) = (x, y)
930 uimplicit (UImplicit _ _) = True
931 uimplicit _ = False
933 dropAll (x:xs) ys | x `elem` ys = dropAll xs ys
934 | otherwise = x : dropAll xs ys
935 dropAll [] ys = []
937 imps top env (PApp _ f as)
938 = do (decls, ns) <- get
939 let isn = concatMap (namesIn uvars ist) (map getTm as)
940 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
941 imps top env (PPi (Imp l _ doc) n ty sc)
942 = do let isn = nub (namesIn uvars ist ty) `dropAll` [n]
943 (decls , ns) <- get
944 put (PImp (getPriority ist ty) l n ty doc : decls,
945 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
946 imps True (n:env) sc
947 imps top env (PPi (Exp l _ doc) n ty sc)
948 = do let isn = nub (namesIn uvars ist ty ++ case sc of
949 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
950 _ -> [])
951 (decls, ns) <- get -- ignore decls in HO types
952 put (PExp (getPriority ist ty) l ty doc : decls,
953 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
954 imps True (n:env) sc
955 imps top env (PPi (Constraint l _ doc) n ty sc)
956 = do let isn = nub (namesIn uvars ist ty ++ case sc of
957 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
958 _ -> [])
959 (decls, ns) <- get -- ignore decls in HO types
960 put (PConstraint 10 l ty doc : decls,
961 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
962 imps True (n:env) sc
963 imps top env (PPi (TacImp l _ scr doc) n ty sc)
964 = do let isn = nub (namesIn uvars ist ty ++ case sc of
965 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
966 _ -> [])
967 (decls, ns) <- get -- ignore decls in HO types
968 put (PTacImplicit 10 l n scr ty doc : decls,
969 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
970 imps True (n:env) sc
971 imps top env (PEq _ l r)
972 = do (decls, ns) <- get
973 let isn = namesIn uvars ist l ++ namesIn uvars ist r
974 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
975 imps top env (PRewrite _ l r _)
976 = do (decls, ns) <- get
977 let isn = namesIn uvars ist l ++ namesIn uvars ist r
978 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
979 imps top env (PTyped l r)
980 = imps top env l
981 imps top env (PPair _ l r)
982 = do (decls, ns) <- get
983 let isn = namesIn uvars ist l ++ namesIn uvars ist r
984 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
985 imps top env (PDPair _ (PRef _ n) t r)
986 = do (decls, ns) <- get
987 let isn = nub (namesIn uvars ist t ++ namesIn uvars ist r) \\ [n]
988 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
989 imps top env (PDPair _ l t r)
990 = do (decls, ns) <- get
991 let isn = namesIn uvars ist l ++ namesIn uvars ist t ++
992 namesIn uvars ist r
993 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
994 imps top env (PAlternative a as)
995 = do (decls, ns) <- get
996 let isn = concatMap (namesIn uvars ist) as
997 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
998 imps top env (PLam n ty sc)
999 = do imps False env ty
1000 imps False (n:env) sc
1001 imps top env (PHidden tm) = imps False env tm
1002 imps top env (PUnifyLog tm) = imps False env tm
1003 imps top env _ = return ()
1005 pibind using [] sc = sc
1006 pibind using (n:ns) sc
1007 = case lookup n using of
1008 Just ty -> PPi (Imp False Dynamic "") n ty (pibind using ns sc)
1009 Nothing -> PPi (Imp False Dynamic "") n Placeholder
1010 (pibind using ns sc)
1012-- Add implicit arguments in function calls
1013addImplPat :: IState -> PTerm -> PTerm
1014addImplPat = addImpl' True [] []
1016addImplBound :: IState -> [Name] -> PTerm -> PTerm
1017addImplBound ist ns = addImpl' False ns [] ist
1019addImplBoundInf :: IState -> [Name] -> [Name] -> PTerm -> PTerm
1020addImplBoundInf ist ns inf = addImpl' False ns inf ist
1022addImpl :: IState -> PTerm -> PTerm
1023addImpl = addImpl' False [] []
1025-- TODO: in patterns, don't add implicits to function names guarded by constructors
1026-- and *not* inside a PHidden
1028addImpl' :: Bool -> [Name] -> [Name] -> IState -> PTerm -> PTerm
1029addImpl' inpat env infns ist ptm = ai (zip env (repeat Nothing)) ptm
1030 where
1031 ai env (PRef fc f)
1032 | f `elem` infns = PInferRef fc f
1033 | not (f `elem` map fst env) = handleErr $ aiFn inpat inpat ist fc f []
1034 ai env (PHidden (PRef fc f))
1035 | not (f `elem` map fst env) = handleErr $ aiFn inpat False ist fc f []
1036 ai env (PEq fc l r) = let l' = ai env l
1037 r' = ai env r in
1038 PEq fc l' r'
1039 ai env (PRewrite fc l r g) = let l' = ai env l
1040 r' = ai env r
1041 g' = fmap (ai env) g in
1042 PRewrite fc l' r' g'
1043 ai env (PTyped l r) = let l' = ai env l
1044 r' = ai env r in
1045 PTyped l' r'
1046 ai env (PPair fc l r) = let l' = ai env l
1047 r' = ai env r in
1048 PPair fc l' r'
1049 ai env (PDPair fc l t r) = let l' = ai env l
1050 t' = ai env t
1051 r' = ai env r in
1052 PDPair fc l' t' r'
1053 ai env (PAlternative a as) = let as' = map (ai env) as in
1054 PAlternative a as'
1055 ai env (PApp fc (PInferRef _ f) as)
1056 = let as' = map (fmap (ai env)) as in
1057 PApp fc (PInferRef fc f) as'
1058 ai env (PApp fc ftm@(PRef _ f) as)
1059 | f `elem` infns = ai env (PApp fc (PInferRef fc f) as)
1060 | not (f `elem` map fst env)
1061 = let as' = map (fmap (ai env)) as in
1062 handleErr $ aiFn inpat False ist fc f as'
1063 | Just (Just ty) <- lookup f env
1064 = let as' = map (fmap (ai env)) as
1065 arity = getPArity ty in
1066 mkPApp fc arity ftm as'
1067 ai env (PApp fc f as) = let f' = ai env f
1068 as' = map (fmap (ai env)) as in
1069 mkPApp fc 1 f' as'
1070 ai env (PCase fc c os) = let c' = ai env c
1071 os' = map (pmap (ai env)) os in
1072 PCase fc c' os'
1073 ai env (PLam n ty sc) = let ty' = ai env ty
1074 sc' = ai ((n, Just ty):env) sc in
1075 PLam n ty' sc'
1076 ai env (PLet n ty val sc)
1077 = let ty' = ai env ty
1078 val' = ai env val
1079 sc' = ai ((n, Just ty):env) sc in
1080 PLet n ty' val' sc'
1081 ai env (PPi p n ty sc) = let ty' = ai env ty
1082 sc' = ai ((n, Just ty):env) sc in
1083 PPi p n ty' sc'
1084 ai env (PGoal fc r n sc) = let r' = ai env r
1085 sc' = ai ((n, Nothing):env) sc in
1086 PGoal fc r' n sc'
1087 ai env (PHidden tm) = PHidden (ai env tm)
1088 ai env (PProof ts) = PProof (map (fmap (ai env)) ts)
1089 ai env (PTactics ts) = PTactics (map (fmap (ai env)) ts)
1090 ai env (PRefl fc tm) = PRefl fc (ai env tm)
1091 ai env (PUnifyLog tm) = PUnifyLog (ai env tm)
1092 ai env tm = tm
1094 handleErr (Left err) = PElabError err
1095 handleErr (Right x) = x
1097-- if in a pattern, and there are no arguments, and there's no possible
1098-- names with zero explicit arguments, don't add implicits.
1100aiFn :: Bool -> Bool -> IState -> FC -> Name -> [PArg] -> Either Err PTerm
1101aiFn inpat True ist fc f []
1102 = case lookupDef f (tt_ctxt ist) of
1103 [] -> Right $ PPatvar fc f
1104 alts -> let ialts = lookupCtxt f (idris_implicits ist) in
1105 -- trace (show f ++ " " ++ show (fc, any (all imp) ialts, ialts, any constructor alts)) $
1106 if (not (vname f) || tcname f
1107 || any constructor alts || any allImp ialts)
1108 then aiFn inpat False ist fc f [] -- use it as a constructor
1109 else Right $ PPatvar fc f
1110 where imp (PExp _ _ _ _) = False
1111 imp _ = True
1112 allImp [] = False
1113 allImp xs = all imp xs
1114 constructor (TyDecl (DCon _ _) _) = True
1115 constructor _ = False
1117 vname (UN n) = True -- non qualified
1118 vname _ = False
1120aiFn inpat expat ist fc f as
1121 | f `elem` primNames = Right $ PApp fc (PRef fc f) as
1122aiFn inpat expat ist fc f as
1123 -- This is where namespaces get resolved by adding PAlternative
1124 = case lookupCtxtName f (idris_implicits ist) of
1125 [(f',ns)] -> Right $ mkPApp fc (length ns) (PRef fc f') (insertImpl ns as)
1126 [] -> if f `elem` idris_metavars ist
1127 then Right $ PApp fc (PRef fc f) as
1128 else Right $ mkPApp fc (length as) (PRef fc f) as
1129 alts -> Right $
1130 PAlternative True $
1131 map (\(f', ns) -> mkPApp fc (length ns) (PRef fc f')
1132 (insertImpl ns as)) alts
1133 where
1134 insertImpl :: [PArg] -> [PArg] -> [PArg]
1135 insertImpl (PExp p l ty _ : ps) (PExp _ _ tm d : given) =
1136 PExp p l tm d : insertImpl ps given
1137 insertImpl (PConstraint p l ty _ : ps) (PConstraint _ _ tm d : given) =
1138 PConstraint p l tm d : insertImpl ps given
1139 insertImpl (PConstraint p l ty d : ps) given =
1140 PConstraint p l (PResolveTC fc) d : insertImpl ps given
1141 insertImpl (PImp p l n ty d : ps) given =
1142 case find n given [] of
1143 Just (tm, given') -> PImp p l n tm "" : insertImpl ps given'
1144 Nothing -> PImp p l n Placeholder "" : insertImpl ps given
1145 insertImpl (PTacImplicit p l n sc ty d : ps) given =
1146 case find n given [] of
1147 Just (tm, given') -> PTacImplicit p l n sc tm "" : insertImpl ps given'
1148 Nothing -> if inpat
1149 then PTacImplicit p l n sc Placeholder "" : insertImpl ps given
1150 else PTacImplicit p l n sc sc "" : insertImpl ps given
1151 insertImpl expected [] = []
1152 insertImpl _ given = given
1154 find n [] acc = Nothing
1155 find n (PImp _ _ n' t _ : gs) acc
1156 | n == n' = Just (t, reverse acc ++ gs)
1157 find n (PTacImplicit _ _ n' _ t _ : gs) acc
1158 | n == n' = Just (t, reverse acc ++ gs)
1159 find n (g : gs) acc = find n gs (g : acc)
1161-- replace non-linear occurrences with _
1162-- ASSUMPTION: This is called before adding 'alternatives' because otherwise
1163-- it is hard to get right!
1165stripLinear :: IState -> PTerm -> PTerm
1166stripLinear i tm = evalState (sl tm) [] where
1167 sl :: PTerm -> State [Name] PTerm
1168 sl (PRef fc f)
1169 | (_:_) <- lookupTy f (tt_ctxt i)
1170 = return $ PRef fc f
1171 | otherwise = do ns <- get
1172 if (f `elem` ns)
1173 then return Placeholder
1174 else do put (f : ns)
1175 return (PRef fc f)
1176 sl (PPatvar fc f)
1177 = do ns <- get
1178 if (f `elem` ns)
1179 then return Placeholder
1180 else do put (f : ns)
1181 return (PPatvar fc f)
1182 sl (PApp fc fn args) = do fn' <- sl fn
1183 args' <- mapM slA args
1184 return $ PApp fc fn' args'
1185 where slA (PImp p l n t d) = do t' <- sl t
1186 return $ PImp p l n t' d
1187 slA (PExp p l t d) = do t' <- sl t
1188 return $ PExp p l t' d
1189 slA (PConstraint p l t d)
1190 = do t' <- sl t
1191 return $ PConstraint p l t' d
1192 slA (PTacImplicit p l n sc t d)
1193 = do t' <- sl t
1194 return $ PTacImplicit p l n sc t' d
1195 sl x = return x
1197mkPApp fc a f [] = f
1198mkPApp fc a f as = let rest = drop a as in
1199 appRest fc (PApp fc f (take a as)) rest
1200 where
1201 appRest fc f [] = f
1202 appRest fc f (a : as) = appRest fc (PApp fc f [a]) as
1204-- Find 'static' argument positions
1205-- (the declared ones, plus any names in argument position in the declared
1206-- statics)
1207-- FIXME: It's possible that this really has to happen after elaboration
1209findStatics :: IState -> PTerm -> (PTerm, [Bool])
1210findStatics ist tm = trace (showImp Nothing True False tm) $
1211 let (ns, ss) = fs tm in
1212 runState (pos ns ss tm) []
1213 where fs (PPi p n t sc)
1214 | Static <- pstatic p
1215 = let (ns, ss) = fs sc in
1216 (namesIn [] ist t : ns, n : ss)
1217 | otherwise = let (ns, ss) = fs sc in
1218 (ns, ss)
1219 fs _ = ([], [])
1221 inOne n ns = length (filter id (map (elem n) ns)) == 1
1223 pos ns ss (PPi p n t sc)
1224 | elem n ss = do sc' <- pos ns ss sc
1225 spos <- get
1226 put (True : spos)
1227 return (PPi (p { pstatic = Static }) n t sc')
1228 | otherwise = do sc' <- pos ns ss sc
1229 spos <- get
1230 put (False : spos)
1231 return (PPi p n t sc')
1232 pos ns ss t = return t
1234-- Debugging/logging stuff
1236dumpDecls :: [PDecl] -> String
1237dumpDecls [] = ""
1238dumpDecls (d:ds) = dumpDecl d ++ "\n" ++ dumpDecls ds
1240dumpDecl (PFix _ f ops) = show f ++ " " ++ showSep ", " ops
1241dumpDecl (PTy _ _ _ _ n t) = "tydecl " ++ show n ++ " : " ++ showImp Nothing True False t
1242dumpDecl (PClauses _ _ n cs) = "pat " ++ show n ++ "\t" ++ showSep "\n\t" (map (showCImp True) cs)
1243dumpDecl (PData _ _ _ _ d) = showDImp True d
1244dumpDecl (PParams _ ns ps) = "params {" ++ show ns ++ "\n" ++ dumpDecls ps ++ "}\n"
1245dumpDecl (PNamespace n ps) = "namespace {" ++ n ++ "\n" ++ dumpDecls ps ++ "}\n"
1246dumpDecl (PSyntax _ syn) = "syntax " ++ show syn
1247dumpDecl (PClass _ _ _ cs n ps ds)
1248 = "class " ++ show cs ++ " " ++ show n ++ " " ++ show ps ++ "\n" ++ dumpDecls ds
1249dumpDecl (PInstance _ _ cs n _ t _ ds)
1250 = "instance " ++ show cs ++ " " ++ show n ++ " " ++ show t ++ "\n" ++ dumpDecls ds
1251dumpDecl _ = "..."
1252-- dumpDecl (PImport i) = "import " ++ i
1254-- for 6.12/7 compatibility
1255data EitherErr a b = LeftErr a | RightOK b
1257instance Monad (EitherErr a) where
1258 return = RightOK
1260 (LeftErr e) >>= k = LeftErr e
1261 RightOK v >>= k = k v
1263toEither (LeftErr e) = Left e
1264toEither (RightOK ho) = Right ho
1266-- syntactic match of a against b, returning pair of variables in a
1267-- and what they match. Returns the pair that failed if not a match.
1269matchClause :: IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
1270matchClause = matchClause' False
1272matchClause' :: Bool -> IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
1273matchClause' names i x y = checkRpts $ match (fullApp x) (fullApp y) where
1274 matchArg x y = match (fullApp (getTm x)) (fullApp (getTm y))
1276 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
1277 fullApp x = x
1279 match' x y = match (fullApp x) (fullApp y)
1280 match (PApp _ (PRef _ (NS (UN "fromInteger") ["builtins"])) [_,_,x]) x'
1281 | PConstant (I _) <- getTm x = match (getTm x) x'
1282 match x' (PApp _ (PRef _ (NS (UN "fromInteger") ["builtins"])) [_,_,x])
1283 | PConstant (I _) <- getTm x = match (getTm x) x'
1284 match (PApp _ (PRef _ (UN "lazy")) [_,x]) x' = match (getTm x) x'
1285 match x (PApp _ (PRef _ (UN "lazy")) [_,x']) = match x (getTm x')
1286 match (PApp _ f args) (PApp _ f' args')
1287 | length args == length args'
1288 = do mf <- match' f f'
1289 ms <- zipWithM matchArg args args'
1290 return (mf ++ concat ms)
1291-- match (PRef _ n) (PRef _ n') | n == n' = return []
1292-- | otherwise = Nothing
1293 match (PRef f n) (PApp _ x []) = match (PRef f n) x
1294 match (PPatvar f n) xr = match (PRef f n) xr
1295 match xr (PPatvar f n) = match xr (PRef f n)
1296 match (PApp _ x []) (PRef f n) = match x (PRef f n)
1297 match (PRef _ n) tm@(PRef _ n')
1298 | n == n' && not names &&
1299 (not (isConName n (tt_ctxt i)) || tm == Placeholder)
1300 = return [(n, tm)]
1301 | n == n' = return []
1302 match (PRef _ n) tm
1303 | not names && (not (isConName n (tt_ctxt i)) || tm == Placeholder)
1304 = return [(n, tm)]
1305 match (PEq _ l r) (PEq _ l' r') = do ml <- match' l l'
1306 mr <- match' r r'
1307 return (ml ++ mr)
1308 match (PRewrite _ l r _) (PRewrite _ l' r' _)
1309 = do ml <- match' l l'
1310 mr <- match' r r'
1311 return (ml ++ mr)
1312 match (PTyped l r) (PTyped l' r') = do ml <- match l l'
1313 mr <- match r r'
1314 return (ml ++ mr)
1315 match (PTyped l r) x = match l x
1316 match x (PTyped l r) = match x l
1317 match (PPair _ l r) (PPair _ l' r') = do ml <- match' l l'
1318 mr <- match' r r'
1319 return (ml ++ mr)
1320 match (PDPair _ l t r) (PDPair _ l' t' r') = do ml <- match' l l'
1321 mt <- match' t t'
1322 mr <- match' r r'
1323 return (ml ++ mt ++ mr)
1324 match (PAlternative a as) (PAlternative a' as')
1325 = do ms <- zipWithM match' as as'
1326 return (concat ms)
1327 match a@(PAlternative _ as) b
1328 = do let ms = zipWith match' as (repeat b)
1329 case (rights (map toEither ms)) of
1330 (x: _) -> return x
1331 _ -> LeftErr (a, b)
1332 match (PCase _ _ _) _ = return [] -- lifted out
1333 match (PMetavar _) _ = return [] -- modified
1334 match (PInferRef _ _) _ = return [] -- modified
1335 match (PQuote _) _ = return []
1336 match (PProof _) _ = return []
1337 match (PTactics _) _ = return []
1338 match (PRefl _ _) (PRefl _ _) = return []
1339 match (PResolveTC _) (PResolveTC _) = return []
1340 match (PTrue _) (PTrue _) = return []
1341 match (PFalse _) (PFalse _) = return []
1342 match (PReturn _) (PReturn _) = return []
1343 match (PPi _ _ t s) (PPi _ _ t' s') = do mt <- match' t t'
1344 ms <- match' s s'
1345 return (mt ++ ms)
1346 match (PLam _ t s) (PLam _ t' s') = do mt <- match' t t'
1347 ms <- match' s s'
1348 return (mt ++ ms)
1349 match (PLet _ t ty s) (PLet _ t' ty' s') = do mt <- match' t t'
1350 mty <- match' ty ty'
1351 ms <- match' s s'
1352 return (mt ++ mty ++ ms)
1353 match (PHidden x) (PHidden y) = match' x y
1354 match (PUnifyLog x) y = match' x y
1355 match x (PUnifyLog y) = match' x y
1356 match Placeholder _ = return []
1357 match _ Placeholder = return []
1358 match (PResolveTC _) _ = return []
1359 match a b | a == b = return []
1360 | otherwise = LeftErr (a, b)
1362 checkRpts (RightOK ms) = check ms where
1363 check ((n,t):xs)
1364 | Just t' <- lookup n xs = if t/=t' && t/=Placeholder && t'/=Placeholder
1365 then Left (t, t')
1366 else check xs
1367 check (_:xs) = check xs
1368 check [] = Right ms
1369 checkRpts (LeftErr x) = Left x
1371substMatches :: [(Name, PTerm)] -> PTerm -> PTerm
1372substMatches ms = substMatchesShadow ms []
1374substMatchesShadow :: [(Name, PTerm)] -> [Name] -> PTerm -> PTerm
1375substMatchesShadow [] shs t = t
1376substMatchesShadow ((n,tm):ns) shs t
1377 = substMatchShadow n shs tm (substMatchesShadow ns shs t)
1379substMatch :: Name -> PTerm -> PTerm -> PTerm
1380substMatch n = substMatchShadow n []
1382substMatchShadow :: Name -> [Name] -> PTerm -> PTerm -> PTerm
1383substMatchShadow n shs tm t = sm shs t where
1384 sm xs (PRef _ n') | n == n' = tm
1385 sm xs (PLam x t sc) = PLam x (sm xs t) (sm xs sc)
1386 sm xs (PPi p x t sc)
1387 | x `elem` xs
1388 = let x' = nextName x in
1389 PPi p x' (sm (x':xs) (substMatch x (PRef (FC "" 0) x') t))
1390 (sm (x':xs) (substMatch x (PRef (FC "" 0) x') sc))
1391 | otherwise = PPi p x (sm xs t) (sm (x : xs) sc)
1392 sm xs (PApp f x as) = fullApp $ PApp f (sm xs x) (map (fmap (sm xs)) as)
1393 sm xs (PCase f x as) = PCase f (sm xs x) (map (pmap (sm xs)) as)
1394 sm xs (PEq f x y) = PEq f (sm xs x) (sm xs y)
1395 sm xs (PRewrite f x y tm) = PRewrite f (sm xs x) (sm xs y)
1396 (fmap (sm xs) tm)
1397 sm xs (PTyped x y) = PTyped (sm xs x) (sm xs y)
1398 sm xs (PPair f x y) = PPair f (sm xs x) (sm xs y)
1399 sm xs (PDPair f x t y) = PDPair f (sm xs x) (sm xs t) (sm xs y)
1400 sm xs (PAlternative a as) = PAlternative a (map (sm xs) as)
1401 sm xs (PHidden x) = PHidden (sm xs x)
1402 sm xs (PUnifyLog x) = PUnifyLog (sm xs x)
1403 sm xs x = x
1405 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
1406 fullApp x = x
1408shadow :: Name -> Name -> PTerm -> PTerm
1409shadow n n' t = sm t where
1410 sm (PRef fc x) | n == x = PRef fc n'
1411 sm (PLam x t sc) = PLam x (sm t) (sm sc)
1412 sm (PPi p x t sc) = PPi p x (sm t) (sm sc)
1413 sm (PApp f x as) = PApp f (sm x) (map (fmap sm) as)
1414 sm (PCase f x as) = PCase f (sm x) (map (pmap sm) as)
1415 sm (PEq f x y) = PEq f (sm x) (sm y)
1416 sm (PRewrite f x y tm) = PRewrite f (sm x) (sm y) (fmap sm tm)
1417 sm (PTyped x y) = PTyped (sm x) (sm y)
1418 sm (PPair f x y) = PPair f (sm x) (sm y)
1419 sm (PDPair f x t y) = PDPair f (sm x) (sm t) (sm y)
1420 sm (PAlternative a as) = PAlternative a (map sm as)
1421 sm (PHidden x) = PHidden (sm x)
1422 sm (PUnifyLog x) = PUnifyLog (sm x)
1423 sm x = x