1{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, DeriveFunctor,
2 TypeSynonymInstances, PatternGuards #-}
4module Idris.AbsSyntax(module Idris.AbsSyntax, module Idris.AbsSyntaxTree) where
8import Core.Elaborate hiding (Tactic(..))
10import Idris.AbsSyntaxTree
13import IRTS.CodegenCommon
14import Util.DynamicLinker
18import System.Console.Haskeline
20import Control.Monad.State
26import Data.Word (Word)
33getContext :: Idris Context
34getContext = do i <- getIState; return (tt_ctxt i)
36forCodegen :: Codegen -> [(Codegen, a)] -> [a]
37forCodegen tgt xs = [x | (tgt', x) <- xs, tgt == tgt']
39getObjectFiles :: Codegen -> Idris [FilePath]
40getObjectFiles tgt = do i <- getIState; return (forCodegen tgt $ idris_objs i)
42addObjectFile :: Codegen -> FilePath -> Idris ()
43addObjectFile tgt f = do i <- getIState; putIState $ i { idris_objs = nub $ (tgt, f) : idris_objs i }
45getLibs :: Codegen -> Idris [String]
46getLibs tgt = do i <- getIState; return (forCodegen tgt $ idris_libs i)
48addLib :: Codegen -> String -> Idris ()
49addLib tgt f = do i <- getIState; putIState $ i { idris_libs = nub $ (tgt, f) : idris_libs i }
51getFlags :: Codegen -> Idris [String]
52getFlags tgt = do i <- getIState; return (forCodegen tgt $ idris_cgflags i)
54addFlag :: Codegen -> String -> Idris ()
55addFlag tgt f = do i <- getIState; putIState $ i { idris_cgflags = nub $ (tgt, f) : idris_cgflags i }
57addDyLib :: [String] -> Idris (Either DynamicLib String)
58addDyLib libs = do i <- getIState
59 let ls = idris_dynamic_libs i
60 case mapMaybe (findDyLib ls) libs of
61 x:_ -> return (Left x)
63 handle <- lift $ mapM (\l -> catchIO (tryLoadLib l) (\_ -> return Nothing)) $ libs
65 Nothing -> return (Right $ "Could not load dynamic alternatives \"" ++
66 concat (intersperse "," libs) ++ "\"")
67 Just x -> do putIState $ i { idris_dynamic_libs = x:ls }
69 where findDyLib :: [DynamicLib] -> String -> Maybe DynamicLib
70 findDyLib [] l = Nothing
71 findDyLib (lib:libs) l | l == lib_name lib = Just lib
72 | otherwise = findDyLib libs l
75addHdr :: Codegen -> String -> Idris ()
76addHdr tgt f = do i <- getIState; putIState $ i { idris_hdrs = nub $ (tgt, f) : idris_hdrs i }
78addLangExt :: LanguageExt -> Idris ()
79addLangExt TypeProviders = do i <- getIState ; putIState $ i { idris_language_extensions = [TypeProviders] }
81addTrans :: (Term, Term) -> Idris ()
82addTrans t = do i <- getIState
83 putIState $ i { idris_transforms = t : idris_transforms i }
85totcheck :: (FC, Name) -> Idris ()
86totcheck n = do i <- getIState; putIState $ i { idris_totcheck = idris_totcheck i ++ [n] }
88clear_totcheck :: Idris ()
89clear_totcheck = do i <- getIState; putIState $ i { idris_totcheck = [] }
91setFlags :: Name -> [FnOpt] -> Idris ()
92setFlags n fs = do i <- getIState; putIState $ i { idris_flags = addDef n fs (idris_flags i) }
94setAccessibility :: Name -> Accessibility -> Idris ()
97 let ctxt = setAccess n a (tt_ctxt i)
98 putIState $ i { tt_ctxt = ctxt }
100setTotality :: Name -> Totality -> Idris ()
103 let ctxt = setTotal n a (tt_ctxt i)
104 putIState $ i { tt_ctxt = ctxt }
106getTotality :: Name -> Idris Totality
109 case lookupTotal n (tt_ctxt i) of
111 _ -> return (Total [])
113-- Get coercions which might return the required type
114getCoercionsTo :: IState -> Type -> [Name]
116 let cs = idris_coercions i
117 (fn,_) = unApply (getRetTy ty) in
119 where findCoercions t [] = []
120 findCoercions t (n : ns) =
121 let ps = case lookupTy n (tt_ctxt i) of
122 [ty] -> case unApply (getRetTy ty) of
124 if t == t' then [n] else []
126 ps ++ findCoercions t ns
128addToCG :: Name -> CGInfo -> Idris ()
131 putIState $ i { idris_callgraph = addDef n cg (idris_callgraph i) }
133addCoercion :: Name -> Idris ()
134addCoercion n = do i <- getIState
135 putIState $ i { idris_coercions = nub $ n : idris_coercions i }
137addDocStr :: Name -> String -> Idris ()
140 putIState $ i { idris_docstrings = addDef n doc (idris_docstrings i) }
142addToCalledG :: Name -> [Name] -> Idris ()
143addToCalledG n ns = return () -- TODO
145-- Add a class instance function. Dodgy hack: Put integer instances first in the
146-- list so they are resolved by default.
147-- Dodgy hack 2: put constraint chasers (@@) last
149addInstance :: Bool -> Name -> Name -> Idris ()
151 = do ist <- getIState
152 case lookupCtxt n (idris_classes ist) of
154 do let cs = addDef n (CI a b c d (addI i ins)) (idris_classes ist)
155 putIState $ ist { idris_classes = cs }
156 _ -> do let cs = addDef n (CI (MN 0 "none") [] [] [] [i]) (idris_classes ist)
157 putIState $ ist { idris_classes = cs }
158 where addI i ins | int = i : ins
159 | chaser n = ins ++ [i]
160 | otherwise = insI i ins
162 insI i (n : ns) | chaser n = i : n : ns
163 | otherwise = n : insI i ns
165 chaser (UN ('@':'@':_)) = True
166 chaser (NS n _) = chaser n
169addClass :: Name -> ClassInfo -> Idris ()
171 = do ist <- getIState
172 let i' = case lookupCtxt n (idris_classes ist) of
173 [c] -> c { class_instances = class_instances i }
175 putIState $ ist { idris_classes = addDef n i' (idris_classes ist) }
177addIBC :: IBCWrite -> Idris ()
180 when (notDef (ibc_write i)) $
181 putIState $ i { ibc_write = ibc : ibc_write i }
182 where notDef [] = True
183 notDef (IBCDef n': is) | n == n' = False
184 notDef (_ : is) = notDef is
185addIBC ibc = do i <- getIState; putIState $ i { ibc_write = ibc : ibc_write i }
188clearIBC = do i <- getIState; putIState $ i { ibc_write = [] }
190getHdrs :: Codegen -> Idris [String]
191getHdrs tgt = do i <- getIState; return (forCodegen tgt $ idris_hdrs i)
193setErrLine :: Int -> Idris ()
194setErrLine x = do i <- getIState;
196 Nothing -> putIState $ i { errLine = Just x }
200clearErr = do i <- getIState
201 putIState $ i { errLine = Nothing }
203getSO :: Idris (Maybe String)
204getSO = do i <- getIState
205 return (compiled_so i)
207setSO :: Maybe String -> Idris ()
208setSO s = do i <- getIState
209 putIState $ (i { compiled_so = s })
211getIState :: Idris IState
214putIState :: IState -> Idris ()
218getName = do i <- getIState;
219 let idx = idris_name i;
220 putIState $ (i { idris_name = idx + 1 })
223checkUndefined :: FC -> Name -> Idris ()
227 (_:_) -> fail $ show fc ++ ":" ++
228 show n ++ " already defined"
231isUndefined :: FC -> Name -> Idris Bool
235 (_:_) -> return False
238setContext :: Context -> Idris ()
239setContext ctxt = do i <- getIState; putIState $ (i { tt_ctxt = ctxt } )
241updateContext :: (Context -> Context) -> Idris ()
242updateContext f = do i <- getIState; putIState $ (i { tt_ctxt = f (tt_ctxt i) } )
244addConstraints :: FC -> (Int, [UConstraint]) -> Idris ()
245addConstraints fc (v, cs)
248 let ctxt' = ctxt { uconstraints = cs ++ uconstraints ctxt,
250 let ics = zip cs (repeat fc) ++ idris_constraints i
251 putIState $ i { tt_ctxt = ctxt', idris_constraints = ics }
253addDeferred = addDeferred' Ref
254addDeferredTyCon = addDeferred' (TCon 0 0)
256addDeferred' :: NameType -> [(Name, Type)] -> Idris ()
258 = do mapM_ (\(n, t) -> updateContext (addTyDecl n nt (tidyNames [] t))) ns
260 putIState $ i { idris_metavars = map fst ns ++ idris_metavars i }
261 where tidyNames used (Bind (MN i x) b sc)
262 = let n' = uniqueName (UN x) used in
263 Bind n' b $ tidyNames (n':used) sc
264 tidyNames used (Bind n b sc)
265 = let n' = uniqueName n used in
266 Bind n' b $ tidyNames (n':used) sc
269solveDeferred :: Name -> Idris ()
270solveDeferred n = do i <- getIState
271 putIState $ i { idris_metavars = idris_metavars i \\ [n] }
273iResult :: String -> Idris ()
274iResult s = do i <- getIState
275 case idris_outputmode i of
276 RawOutput -> case s of
278 s -> liftIO $ putStrLn s
280 let good = SexpList [SymbolAtom "ok", toSExp s] in
281 liftIO $ putStrLn $ convSExp "return" good n
283iFail :: String -> Idris ()
284iFail s = do i <- getIState
285 case idris_outputmode i of
286 RawOutput -> case s of
288 s -> liftIO $ putStrLn s
290 let good = SexpList [SymbolAtom "error", toSExp s] in
291 liftIO . putStrLn $ convSExp "return" good n
293iputStrLn :: String -> Idris ()
294iputStrLn s = do i <- getIState
295 case idris_outputmode i of
296 RawOutput -> liftIO $ putStrLn s
298 case span (/=':') s of
299 (fn, ':':rest) -> case span isDigit rest of
300 ([], ':':msg) -> write
302 (num, ':':msg) -> iWarn (FC fn (read num)) msg
304 where write = liftIO . putStrLn $ convSExp "write-string" s n
306ideslavePutSExp :: SExpable a => String -> a -> Idris ()
307ideslavePutSExp cmd info = do i <- getIState
308 case idris_outputmode i of
309 IdeSlave n -> liftIO . putStrLn $ convSExp cmd info n
312-- this needs some typing magic and more structured output towards emacs
313iputGoal :: String -> Idris ()
314iputGoal s = do i <- getIState
315 case idris_outputmode i of
316 RawOutput -> liftIO $ putStrLn s
317 IdeSlave n -> liftIO . putStrLn $ convSExp "write-goal" s n
319isetPrompt :: String -> Idris ()
320isetPrompt p = do i <- getIState
321 case idris_outputmode i of
322 IdeSlave n -> liftIO . putStrLn $ convSExp "set-prompt" p n
324iWarn :: FC -> String -> Idris ()
325iWarn fc err = do i <- getIState
326 case idris_outputmode i of
327 RawOutput -> liftIO $ putStrLn (show fc ++ ":" ++ err)
328 IdeSlave n -> liftIO . putStrLn $ convSExp "warning" (fc_fname fc, fc_line fc, err) n
330setLogLevel :: Int -> Idris ()
331setLogLevel l = do i <- getIState
332 let opts = idris_options i
333 let opt' = opts { opt_logLevel = l }
334 putIState $ i { idris_options = opt' }
336setCmdLine :: [Opt] -> Idris ()
337setCmdLine opts = do i <- getIState
338 let iopts = idris_options i
339 putIState $ i { idris_options = iopts { opt_cmdline = opts } }
341getCmdLine :: Idris [Opt]
342getCmdLine = do i <- getIState
343 return (opt_cmdline (idris_options i))
345getDumpDefun :: Idris (Maybe FilePath)
346getDumpDefun = do i <- getIState
347 return $ findC (opt_cmdline (idris_options i))
348 where findC [] = Nothing
349 findC (DumpDefun x : _) = Just x
350 findC (_ : xs) = findC xs
352getDumpCases :: Idris (Maybe FilePath)
353getDumpCases = do i <- getIState
354 return $ findC (opt_cmdline (idris_options i))
355 where findC [] = Nothing
356 findC (DumpCases x : _) = Just x
357 findC (_ : xs) = findC xs
360logLevel = do i <- getIState
361 return (opt_logLevel (idris_options i))
363setErrContext :: Bool -> Idris ()
364setErrContext t = do i <- getIState
365 let opts = idris_options i
366 let opt' = opts { opt_errContext = t }
367 putIState $ i { idris_options = opt' }
369errContext :: Idris Bool
370errContext = do i <- getIState
371 return (opt_errContext (idris_options i))
374useREPL = do i <- getIState
375 return (opt_repl (idris_options i))
377setREPL :: Bool -> Idris ()
378setREPL t = do i <- getIState
379 let opts = idris_options i
380 let opt' = opts { opt_repl = t }
381 putIState $ i { idris_options = opt' }
383setQuiet :: Bool -> Idris ()
384setQuiet q = do i <- getIState
385 let opts = idris_options i
386 let opt' = opts { opt_quiet = q }
387 putIState $ i { idris_options = opt' }
389getQuiet :: Idris Bool
390getQuiet = do i <- getIState
391 let opts = idris_options i
392 return (opt_quiet opts)
394setCodegen :: Codegen -> Idris ()
395setCodegen t = do i <- getIState
396 let opts = idris_options i
397 let opt' = opts { opt_codegen = t }
398 putIState $ i { idris_options = opt' }
400codegen :: Idris Codegen
401codegen = do i <- getIState
402 return (opt_codegen (idris_options i))
404setOutputTy :: OutputType -> Idris ()
405setOutputTy t = do i <- getIState
406 let opts = idris_options i
407 let opt' = opts { opt_outputTy = t }
408 putIState $ i { idris_options = opt' }
410outputTy :: Idris OutputType
411outputTy = do i <- getIState
412 return $ opt_outputTy $ idris_options i
414setIdeSlave :: Bool -> Idris ()
415setIdeSlave True = do i <- getIState
416 putIState $ i { idris_outputmode = (IdeSlave 0) }
417setIdeSlave False = return ()
419setTargetTriple :: String -> Idris ()
420setTargetTriple t = do i <- getIState
421 let opts = idris_options i
422 opt' = opts { opt_triple = t }
423 putIState $ i { idris_options = opt' }
425targetTriple :: Idris String
426targetTriple = do i <- getIState
427 return (opt_triple (idris_options i))
429setTargetCPU :: String -> Idris ()
430setTargetCPU t = do i <- getIState
431 let opts = idris_options i
432 opt' = opts { opt_cpu = t }
433 putIState $ i { idris_options = opt' }
435targetCPU :: Idris String
436targetCPU = do i <- getIState
437 return (opt_cpu (idris_options i))
439setOptLevel :: Word -> Idris ()
440setOptLevel t = do i <- getIState
441 let opts = idris_options i
442 opt' = opts { opt_optLevel = t }
443 putIState $ i { idris_options = opt' }
445optLevel :: Idris Word
446optLevel = do i <- getIState
447 return (opt_optLevel (idris_options i))
450verbose = do i <- getIState
451 return (opt_verbose (idris_options i))
453setVerbose :: Bool -> Idris ()
454setVerbose t = do i <- getIState
455 let opts = idris_options i
456 let opt' = opts { opt_verbose = t }
457 putIState $ i { idris_options = opt' }
459typeInType :: Idris Bool
460typeInType = do i <- getIState
461 return (opt_typeintype (idris_options i))
463setTypeInType :: Bool -> Idris ()
464setTypeInType t = do i <- getIState
465 let opts = idris_options i
466 let opt' = opts { opt_typeintype = t }
467 putIState $ i { idris_options = opt' }
469coverage :: Idris Bool
470coverage = do i <- getIState
471 return (opt_coverage (idris_options i))
473setCoverage :: Bool -> Idris ()
474setCoverage t = do i <- getIState
475 let opts = idris_options i
476 let opt' = opts { opt_coverage = t }
477 putIState $ i { idris_options = opt' }
479setIBCSubDir :: FilePath -> Idris ()
480setIBCSubDir fp = do i <- getIState
481 let opts = idris_options i
482 let opt' = opts { opt_ibcsubdir = fp }
483 putIState $ i { idris_options = opt' }
485valIBCSubDir :: IState -> Idris FilePath
486valIBCSubDir i = return (opt_ibcsubdir (idris_options i))
488addImportDir :: FilePath -> Idris ()
489addImportDir fp = do i <- getIState
490 let opts = idris_options i
491 let opt' = opts { opt_importdirs = fp : opt_importdirs opts }
492 putIState $ i { idris_options = opt' }
494setImportDirs :: [FilePath] -> Idris ()
495setImportDirs fps = do i <- getIState
496 let opts = idris_options i
497 let opt' = opts { opt_importdirs = fps }
498 putIState $ i { idris_options = opt' }
500allImportDirs :: Idris [FilePath]
501allImportDirs = do i <- getIState
502 let optdirs = opt_importdirs (idris_options i)
503 return ("." : reverse optdirs)
505colourise :: Idris Bool
506colourise = do i <- getIState
507 return $ idris_colourRepl i
509setColourise :: Bool -> Idris ()
510setColourise b = do i <- getIState
511 putIState $ i { idris_colourRepl = b }
514impShow = do i <- getIState
515 return (opt_showimp (idris_options i))
517setImpShow :: Bool -> Idris ()
518setImpShow t = do i <- getIState
519 let opts = idris_options i
520 let opt' = opts { opt_showimp = t }
521 putIState $ i { idris_options = opt' }
523setColour :: ColourType -> IdrisColour -> Idris ()
524setColour ct c = do i <- getIState
525 let newTheme = setColour' ct c (idris_colourTheme i)
526 putIState $ i { idris_colourTheme = newTheme }
527 where setColour' KeywordColour c t = t { keywordColour = c }
528 setColour' BoundVarColour c t = t { boundVarColour = c }
529 setColour' ImplicitColour c t = t { implicitColour = c }
530 setColour' FunctionColour c t = t { functionColour = c }
531 setColour' TypeColour c t = t { typeColour = c }
532 setColour' DataColour c t = t { dataColour = c }
533 setColour' PromptColour c t = t { promptColour = c }
535logLvl :: Int -> String -> Idris ()
536logLvl l str = do i <- getIState
537 let lvl = opt_logLevel (idris_options i)
539 $ do liftIO (putStrLn str)
540 putIState $ i { idris_log = idris_log i ++ str ++ "\n" }
542cmdOptType :: Opt -> Idris Bool
543cmdOptType x = do i <- getIState
544 return $ x `elem` opt_cmdline (idris_options i)
546iLOG :: String -> Idris ()
549noErrors :: Idris Bool
550noErrors = do i <- getIState
552 Nothing -> return True
555setTypeCase :: Bool -> Idris ()
556setTypeCase t = do i <- getIState
557 let opts = idris_options i
558 let opt' = opts { opt_typecase = t }
559 putIState $ i { idris_options = opt' }
562-- For inferring types of things
566inferTy = MN 0 "__Infer"
567inferCon = MN 0 "__infer"
568inferDecl = PDatadecl inferTy
570 [("", inferCon, PPi impl (MN 0 "A") PType (
571 PPi expl (MN 0 "a") (PRef bi (MN 0 "A"))
572 (PRef bi inferTy)), bi)]
574infTerm t = PApp bi (PRef bi inferCon) [pimp (MN 0 "A") Placeholder, pexp t]
575infP = P (TCon 6 0) inferTy (TType (UVal 0))
577getInferTerm, getInferType :: Term -> Term
578getInferTerm (Bind n b sc) = Bind n b $ getInferTerm sc
579getInferTerm (App (App _ _) tm) = tm
580getInferTerm tm = tm -- error ("getInferTerm " ++ show tm)
582getInferType (Bind n b sc) = Bind n b $ getInferType sc
583getInferType (App (App _ ty) _) = ty
585-- Handy primitives: Unit, False, Pair, MkPair, =, mkForeign
587primNames = [unitTy, unitCon,
588 falseTy, pairTy, pairCon,
589 eqTy, eqCon, inferTy, inferCon]
591unitTy = MN 0 "__Unit"
593unitDecl = PDatadecl unitTy PType
594 [("", unitCon, PRef bi unitTy, bi)]
596falseTy = MN 0 "__False"
597falseDecl = PDatadecl falseTy PType []
599pairTy = MN 0 "__Pair"
600pairCon = MN 0 "__MkPair"
601pairDecl = PDatadecl pairTy (piBind [(n "A", PType), (n "B", PType)] PType)
602 [("", pairCon, PPi impl (n "A") PType (
603 PPi impl (n "B") PType (
604 PPi expl (n "a") (PRef bi (n "A")) (
605 PPi expl (n "b") (PRef bi (n "B"))
606 (PApp bi (PRef bi pairTy) [pexp (PRef bi (n "A")),
607 pexp (PRef bi (n "B"))])))), bi)]
612eqDecl = PDatadecl eqTy (piBind [(n "a", PType), (n "b", PType),
613 (n "x", PRef bi (n "a")), (n "y", PRef bi (n "b"))]
615 [("", eqCon, PPi impl (n "a") PType (
616 PPi impl (n "x") (PRef bi (n "a"))
617 (PApp bi (PRef bi eqTy) [pimp (n "a") Placeholder,
618 pimp (n "b") Placeholder,
619 pexp (PRef bi (n "x")),
620 pexp (PRef bi (n "x"))])), bi)]
623-- Defined in builtins.idr
625existsCon = UN "Ex_intro"
627piBind :: [(Name, PTerm)] -> PTerm -> PTerm
630piBindp :: Plicity -> [(Name, PTerm)] -> PTerm -> PTerm
632piBindp p ((n, ty):ns) t = PPi p n ty (piBind ns t)
634-- Dealing with parameters
636expandParams :: (Name -> Name) -> [(Name, PTerm)] ->
637 [Name] -> -- all names
638 [Name] -> -- names with no declaration
640expandParams dec ps ns infs tm = en tm
642 -- if we shadow a name (say in a lambda binding) that is used in a call to
643 -- a lifted function, we need access to both names - once in the scope of the
644 -- binding and once to call the lifted functions. So we'll explicitly shadow
645 -- it. (Yes, it's a hack. The alternative would be to resolve names earlier
648 mkShadow (UN n) = MN 0 n
649 mkShadow (MN i n) = MN (i+1) n
650 mkShadow (NS x s) = NS (mkShadow x) s
653 | n `elem` (map fst ps ++ ns)
654 = let n' = mkShadow n in
655 PLam n' (en t) (en (shadow n n' s))
656 | otherwise = PLam n (en t) (en s)
658 | n `elem` (map fst ps ++ ns)
659 = let n' = mkShadow n in
660 PPi p n' (en t) (en (shadow n n' s))
661 | otherwise = PPi p n (en t) (en s)
663 | n `elem` (map fst ps ++ ns)
664 = let n' = mkShadow n in
665 PLet n' (en ty) (en v) (en (shadow n n' s))
666 | otherwise = PLet n (en ty) (en v) (en s)
667 -- FIXME: Should only do this in a type signature!
668 en (PDPair f (PRef f' n) t r)
669 | n `elem` (map fst ps ++ ns) && t /= Placeholder
670 = let n' = mkShadow n in
671 PDPair f (PRef f' n') (en t) (en (shadow n n' r))
672 en (PEq f l r) = PEq f (en l) (en r)
673 en (PRewrite f l r g) = PRewrite f (en l) (en r) (fmap en g)
674 en (PTyped l r) = PTyped (en l) (en r)
675 en (PPair f l r) = PPair f (en l) (en r)
676 en (PDPair f l t r) = PDPair f (en l) (en t) (en r)
677 en (PAlternative a as) = PAlternative a (map en as)
678 en (PHidden t) = PHidden (en t)
679 en (PUnifyLog t) = PUnifyLog (en t)
680 en (PDoBlock ds) = PDoBlock (map (fmap en) ds)
681 en (PProof ts) = PProof (map (fmap en) ts)
682 en (PTactics ts) = PTactics (map (fmap en) ts)
685 | n `nselem` ns = PQuote (Var (dec n))
686 en (PApp fc (PInferRef fc' n) as)
687 | n `nselem` ns = PApp fc (PInferRef fc' (dec n))
688 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
689 en (PApp fc (PRef fc' n) as)
690 | n `elem` infs = PApp fc (PInferRef fc' (dec n))
691 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
692 | n `nselem` ns = PApp fc (PRef fc' (dec n))
693 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
695 | n `elem` infs = PApp fc (PInferRef fc (dec n))
696 (map (pexp . (PRef fc)) (map fst ps))
697 | n `nselem` ns = PApp fc (PRef fc (dec n))
698 (map (pexp . (PRef fc)) (map fst ps))
700 | n `nselem` ns = PApp fc (PInferRef fc (dec n))
701 (map (pexp . (PRef fc)) (map fst ps))
702 en (PApp fc f as) = PApp fc (en f) (map (fmap en) as)
703 en (PCase fc c os) = PCase fc (en c) (map (pmap en) os)
707 nselem x (y : xs) | nseq x y = True
708 | otherwise = nselem x xs
710 nseq x y = nsroot x == nsroot y
712expandParamsD :: Bool -> -- True = RHS only
714 (Name -> Name) -> [(Name, PTerm)] -> [Name] -> PDecl -> PDecl
715expandParamsD rhsonly ist dec ps ns (PTy doc syn fc o n ty)
716 = if n `elem` ns && (not rhsonly)
717 then -- trace (show (n, expandParams dec ps ns ty)) $
718 PTy doc syn fc o (dec n) (piBind ps (expandParams dec ps ns [] ty))
719 else --trace (show (n, expandParams dec ps ns ty)) $
720 PTy doc syn fc o n (expandParams dec ps ns [] ty)
721expandParamsD rhsonly ist dec ps ns (PPostulate doc syn fc o n ty)
722 = if n `elem` ns && (not rhsonly)
723 then -- trace (show (n, expandParams dec ps ns ty)) $
724 PPostulate doc syn fc o (dec n) (piBind ps
725 (expandParams dec ps ns [] ty))
726 else --trace (show (n, expandParams dec ps ns ty)) $
727 PPostulate doc syn fc o n (expandParams dec ps ns [] ty)
728expandParamsD rhsonly ist dec ps ns (PClauses fc opts n cs)
729 = let n' = if n `elem` ns then dec n else n in
730 PClauses fc opts n' (map expandParamsC cs)
732 expandParamsC (PClause fc n lhs ws rhs ds)
733 = let -- ps' = updateps True (namesIn ist rhs) (zip ps [0..])
734 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
735 lhs' = if rhsonly then lhs else (expandParams dec ps'' ns [] lhs)
736 n' = if n `elem` ns then dec n else n
737 -- names bound on the lhs should not be expanded on the rhs
738 ns' = removeBound lhs ns in
740 (map (expandParams dec ps'' ns' []) ws)
741 (expandParams dec ps'' ns' [] rhs)
742 (map (expandParamsD True ist dec ps'' ns') ds)
743 expandParamsC (PWith fc n lhs ws wval ds)
744 = let -- ps' = updateps True (namesIn ist wval) (zip ps [0..])
745 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
746 lhs' = if rhsonly then lhs else (expandParams dec ps'' ns [] lhs)
747 n' = if n `elem` ns then dec n else n
748 ns' = removeBound lhs ns in
750 (map (expandParams dec ps'' ns' []) ws)
751 (expandParams dec ps'' ns' [] wval)
752 (map (expandParamsD rhsonly ist dec ps'' ns') ds)
753 updateps yn nm [] = []
754 updateps yn nm (((a, t), i):as)
755 | (a `elem` nm) == yn = (a, t) : updateps yn nm as
756 | otherwise = (MN i (show n ++ "_u"), t) : updateps yn nm as
758 removeBound lhs ns = ns \\ nub (bnames lhs)
760 bnames (PRef _ n) = [n]
761 bnames (PApp _ _ args) = concatMap bnames (map getTm args)
762 bnames (PPair _ l r) = bnames l ++ bnames r
763 bnames (PDPair _ l Placeholder r) = bnames l ++ bnames r
766expandParamsD rhs ist dec ps ns (PData doc syn fc co pd)
767 = PData doc syn fc co (expandPData pd)
769 -- just do the type decl, leave constructors alone (parameters will be
771 expandPData (PDatadecl n ty cons)
773 then PDatadecl (dec n) (piBind ps (expandParams dec ps ns [] ty))
775 else PDatadecl n (expandParams dec ps ns [] ty) (map econ cons)
777 = (doc, dec n, piBindp expl ps (expandParams dec ps ns [] t), fc)
778expandParamsD rhs ist dec ps ns (PParams f params pds)
779 = PParams f (ps ++ map (mapsnd (expandParams dec ps ns [])) params)
780 (map (expandParamsD True ist dec ps ns) pds)
781-- (map (expandParamsD ist dec ps ns) pds)
782expandParamsD rhs ist dec ps ns (PMutual f pds)
783 = PMutual f (map (expandParamsD rhs ist dec ps ns) pds)
784expandParamsD rhs ist dec ps ns (PClass doc info f cs n params decls)
786 (map (expandParams dec ps ns []) cs)
788 (map (mapsnd (expandParams dec ps ns [])) params)
789 (map (expandParamsD rhs ist dec ps ns) decls)
790expandParamsD rhs ist dec ps ns (PInstance info f cs n params ty cn decls)
792 (map (expandParams dec ps ns []) cs)
794 (map (expandParams dec ps ns []) params)
795 (expandParams dec ps ns [] ty)
797 (map (expandParamsD rhs ist dec ps ns) decls)
798expandParamsD rhs ist dec ps ns d = d
800mapsnd f (x, t) = (x, f t)
802-- Calculate a priority for a type, for deciding elaboration order
803-- * if it's just a type variable or concrete type, do it early (0)
804-- * if there's only type variables and injective constructors, do it next (1)
805-- * if there's a function type, next (2)
806-- * finally, everything else (3)
808getPriority :: IState -> PTerm -> Int
809getPriority i tm = 1 -- pri tm
812 case lookupP n (tt_ctxt i) of
813 ((P (DCon _ _) _ _):_) -> 1
814 ((P (TCon _ _) _ _):_) -> 1
816 [] -> 0 -- must be locally bound, if it's not an error...
817 pri (PPi _ _ x y) = max 5 (max (pri x) (pri y))
821 pri (PEq _ l r) = max 1 (max (pri l) (pri r))
822 pri (PRewrite _ l r _) = max 1 (max (pri l) (pri r))
823 pri (PApp _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.getTm) as)))
824 pri (PCase _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.snd) as)))
825 pri (PTyped l r) = pri l
826 pri (PPair _ l r) = max 1 (max (pri l) (pri r))
827 pri (PDPair _ l t r) = max 1 (max (pri l) (max (pri t) (pri r)))
828 pri (PAlternative a as) = maximum (map pri as)
829 pri (PConstant _) = 0
833addStatics :: Name -> Term -> PTerm -> Idris ()
835 do let (statics, dynamics) = initStatics tm ptm
836 let stnames = nub $ concatMap freeNames (map snd statics)
837 let dnames = nub $ concatMap freeNames (map snd dynamics)
838 when (not (null statics)) $
839 logLvl 7 $ show n ++ " " ++ show statics ++ "\n" ++ show dynamics
840 ++ "\n" ++ show stnames ++ "\n" ++ show dnames
841 let statics' = nub $ map fst statics ++
842 filter (\x -> not (elem x dnames)) stnames
843 let stpos = staticList statics' tm
845 putIState $ i { idris_statics = addDef n stpos (idris_statics i) }
848 initStatics (Bind n (Pi ty) sc) (PPi p _ _ s)
849 = let (static, dynamic) = initStatics (instantiate (P Bound n ty) sc) s in
850 if pstatic p == Static then ((n, ty) : static, dynamic)
851 else (static, (n, ty) : dynamic)
852 initStatics t pt = ([], [])
854 staticList sts (Bind n (Pi _) sc) = (n `elem` sts) : staticList sts sc
857-- Dealing with implicit arguments
859-- Add constraint bindings from using block
861addUsingConstraints :: SyntaxInfo -> FC -> PTerm -> Idris PTerm
862addUsingConstraints syn fc t
864 let ns = namesIn [] ist t
865 let cs = getConstraints t -- check declared constraints
866 let addconsts = uconsts \\ cs
867 -- if all names in the arguments of addconsts appear in ns,
868 -- add the constraint implicitly
869 return (doAdd addconsts ns t)
870 where uconsts = filter uconst (using syn)
871 uconst (UConstraint _ _) = True
875 -- if all of args in ns, then add it
876 doAdd (UConstraint c args : cs) ns t
877 | all (\n -> elem n ns) args
878 = PPi (Constraint False Dynamic "") (MN 0 "cu")
879 (mkConst c args) (doAdd cs ns t)
880 | otherwise = doAdd cs ns t
882 mkConst c args = PApp fc (PRef fc c)
883 (map (\n -> PExp 0 False (PRef fc n) "") args)
885 getConstraints (PPi (Constraint _ _ _) _ c sc)
886 = getcapp c ++ getConstraints sc
887 getConstraints (PPi _ _ c sc) = getConstraints sc
888 getConstraints _ = []
890 getcapp (PApp _ (PRef _ c) args)
891 = do ns <- mapM getName args
892 return (UConstraint c ns)
895 getName (PExp _ _ (PRef _ n) _) = return n
898-- Add implicit Pi bindings for any names in the term which appear in an
901-- This has become a right mess already. Better redo it some time...
903implicit :: SyntaxInfo -> Name -> PTerm -> Idris PTerm
904implicit syn n ptm = implicit' syn [] n ptm
906implicit' :: SyntaxInfo -> [Name] -> Name -> PTerm -> Idris PTerm
907implicit' syn ignore n ptm
909 let (tm', impdata) = implicitise syn ignore i ptm
910-- let (tm'', spos) = findStatics i tm'
911 putIState $ i { idris_implicits = addDef n impdata (idris_implicits i) }
913 logLvl 5 ("Implicit " ++ show n ++ " " ++ show impdata)
915-- putIState $ i { idris_statics = addDef n spos (idris_statics i) }
918implicitise :: SyntaxInfo -> [Name] -> IState -> PTerm -> (PTerm, [PArg])
919implicitise syn ignore ist tm = -- trace ("INCOMING " ++ showImp True tm) $
920 let (declimps, ns') = execState (imps True [] tm) ([], [])
921 ns = filter (\n -> implicitable n || elem n (map fst uvars)) $
922 ns' \\ (map fst pvars ++ no_imp syn ++ ignore)
923 nsOrder = filter (not . inUsing) ns ++ filter inUsing ns in
925 then (tm, reverse declimps)
926 else implicitise syn ignore ist (pibind uvars nsOrder tm)
928 uvars = map ipair (filter uimplicit (using syn))
929 pvars = syn_params syn
931 inUsing n = n `elem` map fst uvars
933 ipair (UImplicit x y) = (x, y)
934 uimplicit (UImplicit _ _) = True
937 dropAll (x:xs) ys | x `elem` ys = dropAll xs ys
938 | otherwise = x : dropAll xs ys
941 imps top env (PApp _ f as)
942 = do (decls, ns) <- get
943 let isn = concatMap (namesIn uvars ist) (map getTm as)
944 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
945 imps top env (PPi (Imp l _ doc) n ty sc)
946 = do let isn = nub (namesIn uvars ist ty) `dropAll` [n]
948 put (PImp (getPriority ist ty) l n ty doc : decls,
949 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
951 imps top env (PPi (Exp l _ doc) n ty sc)
952 = do let isn = nub (namesIn uvars ist ty ++ case sc of
953 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
955 (decls, ns) <- get -- ignore decls in HO types
956 put (PExp (getPriority ist ty) l ty doc : decls,
957 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
959 imps top env (PPi (Constraint l _ doc) n ty sc)
960 = do let isn = nub (namesIn uvars ist ty ++ case sc of
961 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
963 (decls, ns) <- get -- ignore decls in HO types
964 put (PConstraint 10 l ty doc : decls,
965 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
967 imps top env (PPi (TacImp l _ scr doc) n ty sc)
968 = do let isn = nub (namesIn uvars ist ty ++ case sc of
969 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
971 (decls, ns) <- get -- ignore decls in HO types
972 put (PTacImplicit 10 l n scr ty doc : decls,
973 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
975 imps top env (PEq _ 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 (PRewrite _ l r _)
980 = do (decls, ns) <- get
981 let isn = namesIn uvars ist l ++ namesIn uvars ist r
982 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
983 imps top env (PTyped l r)
985 imps top env (PPair _ l r)
986 = do (decls, ns) <- get
987 let isn = namesIn uvars ist l ++ namesIn uvars ist r
988 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
989 imps top env (PDPair _ (PRef _ n) t r)
990 = do (decls, ns) <- get
991 let isn = nub (namesIn uvars ist t ++ namesIn uvars ist r) \\ [n]
992 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
993 imps top env (PDPair _ l t r)
994 = do (decls, ns) <- get
995 let isn = namesIn uvars ist l ++ namesIn uvars ist t ++
997 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
998 imps top env (PAlternative a as)
999 = do (decls, ns) <- get
1000 let isn = concatMap (namesIn uvars ist) as
1001 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1002 imps top env (PLam n ty sc)
1003 = do imps False env ty
1004 imps False (n:env) sc
1005 imps top env (PHidden tm) = imps False env tm
1006 imps top env (PUnifyLog tm) = imps False env tm
1007 imps top env _ = return ()
1009 pibind using [] sc = sc
1010 pibind using (n:ns) sc
1011 = case lookup n using of
1012 Just ty -> PPi (Imp False Dynamic "") n ty (pibind using ns sc)
1013 Nothing -> PPi (Imp False Dynamic "") n Placeholder
1014 (pibind using ns sc)
1016-- Add implicit arguments in function calls
1017addImplPat :: IState -> PTerm -> PTerm
1018addImplPat = addImpl' True [] []
1020addImplBound :: IState -> [Name] -> PTerm -> PTerm
1021addImplBound ist ns = addImpl' False ns [] ist
1023addImplBoundInf :: IState -> [Name] -> [Name] -> PTerm -> PTerm
1024addImplBoundInf ist ns inf = addImpl' False ns inf ist
1026addImpl :: IState -> PTerm -> PTerm
1027addImpl = addImpl' False [] []
1029-- TODO: in patterns, don't add implicits to function names guarded by constructors
1030-- and *not* inside a PHidden
1032addImpl' :: Bool -> [Name] -> [Name] -> IState -> PTerm -> PTerm
1033addImpl' inpat env infns ist ptm = ai (zip env (repeat Nothing)) ptm
1036 | f `elem` infns = PInferRef fc f
1037 | not (f `elem` map fst env) = handleErr $ aiFn inpat inpat ist fc f []
1038 ai env (PHidden (PRef fc f))
1039 | not (f `elem` map fst env) = handleErr $ aiFn inpat False ist fc f []
1040 ai env (PEq fc l r) = let l' = ai env l
1043 ai env (PRewrite fc l r g) = let l' = ai env l
1045 g' = fmap (ai env) g in
1046 PRewrite fc l' r' g'
1047 ai env (PTyped l r) = let l' = ai env l
1050 ai env (PPair fc l r) = let l' = ai env l
1053 ai env (PDPair fc l t r) = let l' = ai env l
1057 ai env (PAlternative a as) = let as' = map (ai env) as in
1059 ai env (PApp fc (PInferRef _ f) as)
1060 = let as' = map (fmap (ai env)) as in
1061 PApp fc (PInferRef fc f) as'
1062 ai env (PApp fc ftm@(PRef _ f) as)
1063 | f `elem` infns = ai env (PApp fc (PInferRef fc f) as)
1064 | not (f `elem` map fst env)
1065 = let as' = map (fmap (ai env)) as in
1066 handleErr $ aiFn inpat False ist fc f as'
1067 | Just (Just ty) <- lookup f env
1068 = let as' = map (fmap (ai env)) as
1069 arity = getPArity ty in
1070 mkPApp fc arity ftm as'
1071 ai env (PApp fc f as) = let f' = ai env f
1072 as' = map (fmap (ai env)) as in
1074 ai env (PCase fc c os) = let c' = ai env c
1075 os' = map (pmap (ai env)) os in
1077 ai env (PLam n ty sc) = let ty' = ai env ty
1078 sc' = ai ((n, Just ty):env) sc in
1080 ai env (PLet n ty val sc)
1081 = let ty' = ai env ty
1083 sc' = ai ((n, Just ty):env) sc in
1085 ai env (PPi p n ty sc) = let ty' = ai env ty
1086 sc' = ai ((n, Just ty):env) sc in
1088 ai env (PGoal fc r n sc) = let r' = ai env r
1089 sc' = ai ((n, Nothing):env) sc in
1091 ai env (PHidden tm) = PHidden (ai env tm)
1092 ai env (PProof ts) = PProof (map (fmap (ai env)) ts)
1093 ai env (PTactics ts) = PTactics (map (fmap (ai env)) ts)
1094 ai env (PRefl fc tm) = PRefl fc (ai env tm)
1095 ai env (PUnifyLog tm) = PUnifyLog (ai env tm)
1098 handleErr (Left err) = PElabError err
1099 handleErr (Right x) = x
1101-- if in a pattern, and there are no arguments, and there's no possible
1102-- names with zero explicit arguments, don't add implicits.
1104aiFn :: Bool -> Bool -> IState -> FC -> Name -> [PArg] -> Either Err PTerm
1105aiFn inpat True ist fc f []
1106 = case lookupDef f (tt_ctxt ist) of
1107 [] -> Right $ PPatvar fc f
1108 alts -> let ialts = lookupCtxt f (idris_implicits ist) in
1109 -- trace (show f ++ " " ++ show (fc, any (all imp) ialts, ialts, any constructor alts)) $
1110 if (not (vname f) || tcname f
1111 || any constructor alts || any allImp ialts)
1112 then aiFn inpat False ist fc f [] -- use it as a constructor
1113 else Right $ PPatvar fc f
1114 where imp (PExp _ _ _ _) = False
1117 allImp xs = all imp xs
1118 constructor (TyDecl (DCon _ _) _) = True
1119 constructor _ = False
1121 vname (UN n) = True -- non qualified
1124aiFn inpat expat ist fc f as
1125 | f `elem` primNames = Right $ PApp fc (PRef fc f) as
1126aiFn inpat expat ist fc f as
1127 -- This is where namespaces get resolved by adding PAlternative
1128 = case lookupCtxtName f (idris_implicits ist) of
1129 [(f',ns)] -> Right $ mkPApp fc (length ns) (PRef fc f') (insertImpl ns as)
1130 [] -> if f `elem` idris_metavars ist
1131 then Right $ PApp fc (PRef fc f) as
1132 else Right $ mkPApp fc (length as) (PRef fc f) as
1135 map (\(f', ns) -> mkPApp fc (length ns) (PRef fc f')
1136 (insertImpl ns as)) alts
1138 insertImpl :: [PArg] -> [PArg] -> [PArg]
1139 insertImpl (PExp p l ty _ : ps) (PExp _ _ tm d : given) =
1140 PExp p l tm d : insertImpl ps given
1141 insertImpl (PConstraint p l ty _ : ps) (PConstraint _ _ tm d : given) =
1142 PConstraint p l tm d : insertImpl ps given
1143 insertImpl (PConstraint p l ty d : ps) given =
1144 PConstraint p l (PResolveTC fc) d : insertImpl ps given
1145 insertImpl (PImp p l n ty d : ps) given =
1146 case find n given [] of
1147 Just (tm, given') -> PImp p l n tm "" : insertImpl ps given'
1148 Nothing -> PImp p l n Placeholder "" : insertImpl ps given
1149 insertImpl (PTacImplicit p l n sc ty d : ps) given =
1150 case find n given [] of
1151 Just (tm, given') -> PTacImplicit p l n sc tm "" : insertImpl ps given'
1153 then PTacImplicit p l n sc Placeholder "" : insertImpl ps given
1154 else PTacImplicit p l n sc sc "" : insertImpl ps given
1155 insertImpl expected [] = []
1156 insertImpl _ given = given
1158 find n [] acc = Nothing
1159 find n (PImp _ _ n' t _ : gs) acc
1160 | n == n' = Just (t, reverse acc ++ gs)
1161 find n (PTacImplicit _ _ n' _ t _ : gs) acc
1162 | n == n' = Just (t, reverse acc ++ gs)
1163 find n (g : gs) acc = find n gs (g : acc)
1165-- replace non-linear occurrences with _
1166-- ASSUMPTION: This is called before adding 'alternatives' because otherwise
1167-- it is hard to get right!
1169stripLinear :: IState -> PTerm -> PTerm
1170stripLinear i tm = evalState (sl tm) [] where
1171 sl :: PTerm -> State [Name] PTerm
1173 | (_:_) <- lookupTy f (tt_ctxt i)
1174 = return $ PRef fc f
1175 | otherwise = do ns <- get
1177 then return Placeholder
1178 else do put (f : ns)
1183 then return Placeholder
1184 else do put (f : ns)
1185 return (PPatvar fc f)
1186 sl (PApp fc fn args) = do fn' <- sl fn
1187 args' <- mapM slA args
1188 return $ PApp fc fn' args'
1189 where slA (PImp p l n t d) = do t' <- sl t
1190 return $ PImp p l n t' d
1191 slA (PExp p l t d) = do t' <- sl t
1192 return $ PExp p l t' d
1193 slA (PConstraint p l t d)
1195 return $ PConstraint p l t' d
1196 slA (PTacImplicit p l n sc t d)
1198 return $ PTacImplicit p l n sc t' d
1202mkPApp fc a f as = let rest = drop a as in
1203 appRest fc (PApp fc f (take a as)) rest
1206 appRest fc f (a : as) = appRest fc (PApp fc f [a]) as
1208-- Find 'static' argument positions
1209-- (the declared ones, plus any names in argument position in the declared
1211-- FIXME: It's possible that this really has to happen after elaboration
1213findStatics :: IState -> PTerm -> (PTerm, [Bool])
1214findStatics ist tm = trace (showImp Nothing True False tm) $
1215 let (ns, ss) = fs tm in
1216 runState (pos ns ss tm) []
1217 where fs (PPi p n t sc)
1218 | Static <- pstatic p
1219 = let (ns, ss) = fs sc in
1220 (namesIn [] ist t : ns, n : ss)
1221 | otherwise = let (ns, ss) = fs sc in
1225 inOne n ns = length (filter id (map (elem n) ns)) == 1
1227 pos ns ss (PPi p n t sc)
1228 | elem n ss = do sc' <- pos ns ss sc
1231 return (PPi (p { pstatic = Static }) n t sc')
1232 | otherwise = do sc' <- pos ns ss sc
1235 return (PPi p n t sc')
1236 pos ns ss t = return t
1238-- Debugging/logging stuff
1240dumpDecls :: [PDecl] -> String
1242dumpDecls (d:ds) = dumpDecl d ++ "\n" ++ dumpDecls ds
1244dumpDecl (PFix _ f ops) = show f ++ " " ++ showSep ", " ops
1245dumpDecl (PTy _ _ _ _ n t) = "tydecl " ++ show n ++ " : " ++ showImp Nothing True False t
1246dumpDecl (PClauses _ _ n cs) = "pat " ++ show n ++ "\t" ++ showSep "\n\t" (map (showCImp True) cs)
1247dumpDecl (PData _ _ _ _ d) = showDImp True d
1248dumpDecl (PParams _ ns ps) = "params {" ++ show ns ++ "\n" ++ dumpDecls ps ++ "}\n"
1249dumpDecl (PNamespace n ps) = "namespace {" ++ n ++ "\n" ++ dumpDecls ps ++ "}\n"
1250dumpDecl (PSyntax _ syn) = "syntax " ++ show syn
1251dumpDecl (PClass _ _ _ cs n ps ds)
1252 = "class " ++ show cs ++ " " ++ show n ++ " " ++ show ps ++ "\n" ++ dumpDecls ds
1253dumpDecl (PInstance _ _ cs n _ t _ ds)
1254 = "instance " ++ show cs ++ " " ++ show n ++ " " ++ show t ++ "\n" ++ dumpDecls ds
1256-- dumpDecl (PImport i) = "import " ++ i
1258-- for 6.12/7 compatibility
1259data EitherErr a b = LeftErr a | RightOK b
1261instance Monad (EitherErr a) where
1264 (LeftErr e) >>= k = LeftErr e
1265 RightOK v >>= k = k v
1267toEither (LeftErr e) = Left e
1268toEither (RightOK ho) = Right ho
1270-- syntactic match of a against b, returning pair of variables in a
1271-- and what they match. Returns the pair that failed if not a match.
1273matchClause :: IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
1274matchClause = matchClause' False
1276matchClause' :: Bool -> IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
1277matchClause' names i x y = checkRpts $ match (fullApp x) (fullApp y) where
1278 matchArg x y = match (fullApp (getTm x)) (fullApp (getTm y))
1280 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
1283 match' x y = match (fullApp x) (fullApp y)
1284 match (PApp _ (PRef _ (NS (UN "fromInteger") ["builtins"])) [_,_,x]) x'
1285 | PConstant (I _) <- getTm x = match (getTm x) x'
1286 match x' (PApp _ (PRef _ (NS (UN "fromInteger") ["builtins"])) [_,_,x])
1287 | PConstant (I _) <- getTm x = match (getTm x) x'
1288 match (PApp _ (PRef _ (UN "lazy")) [_,x]) x' = match (getTm x) x'
1289 match x (PApp _ (PRef _ (UN "lazy")) [_,x']) = match x (getTm x')
1290 match (PApp _ f args) (PApp _ f' args')
1291 | length args == length args'
1292 = do mf <- match' f f'
1293 ms <- zipWithM matchArg args args'
1294 return (mf ++ concat ms)
1295-- match (PRef _ n) (PRef _ n') | n == n' = return []
1296-- | otherwise = Nothing
1297 match (PRef f n) (PApp _ x []) = match (PRef f n) x
1298 match (PPatvar f n) xr = match (PRef f n) xr
1299 match xr (PPatvar f n) = match xr (PRef f n)
1300 match (PApp _ x []) (PRef f n) = match x (PRef f n)
1301 match (PRef _ n) tm@(PRef _ n')
1302 | n == n' && not names &&
1303 (not (isConName n (tt_ctxt i)) || tm == Placeholder)
1305 | n == n' = return []
1307 | not names && (not (isConName n (tt_ctxt i)) || tm == Placeholder)
1309 match (PEq _ l r) (PEq _ l' r') = do ml <- match' l l'
1312 match (PRewrite _ l r _) (PRewrite _ l' r' _)
1313 = do ml <- match' l l'
1316 match (PTyped l r) (PTyped l' r') = do ml <- match l l'
1319 match (PTyped l r) x = match l x
1320 match x (PTyped l r) = match x l
1321 match (PPair _ l r) (PPair _ l' r') = do ml <- match' l l'
1324 match (PDPair _ l t r) (PDPair _ l' t' r') = do ml <- match' l l'
1327 return (ml ++ mt ++ mr)
1328 match (PAlternative a as) (PAlternative a' as')
1329 = do ms <- zipWithM match' as as'
1331 match a@(PAlternative _ as) b
1332 = do let ms = zipWith match' as (repeat b)
1333 case (rights (map toEither ms)) of
1336 match (PCase _ _ _) _ = return [] -- lifted out
1337 match (PMetavar _) _ = return [] -- modified
1338 match (PInferRef _ _) _ = return [] -- modified
1339 match (PQuote _) _ = return []
1340 match (PProof _) _ = return []
1341 match (PTactics _) _ = return []
1342 match (PRefl _ _) (PRefl _ _) = return []
1343 match (PResolveTC _) (PResolveTC _) = return []
1344 match (PTrue _) (PTrue _) = return []
1345 match (PFalse _) (PFalse _) = return []
1346 match (PReturn _) (PReturn _) = return []
1347 match (PPi _ _ t s) (PPi _ _ t' s') = do mt <- match' t t'
1350 match (PLam _ t s) (PLam _ t' s') = do mt <- match' t t'
1353 match (PLet _ t ty s) (PLet _ t' ty' s') = do mt <- match' t t'
1354 mty <- match' ty ty'
1356 return (mt ++ mty ++ ms)
1357 match (PHidden x) (PHidden y) = match' x y
1358 match (PUnifyLog x) y = match' x y
1359 match x (PUnifyLog y) = match' x y
1360 match Placeholder _ = return []
1361 match _ Placeholder = return []
1362 match (PResolveTC _) _ = return []
1363 match a b | a == b = return []
1364 | otherwise = LeftErr (a, b)
1366 checkRpts (RightOK ms) = check ms where
1368 | Just t' <- lookup n xs = if t/=t' && t/=Placeholder && t'/=Placeholder
1371 check (_:xs) = check xs
1373 checkRpts (LeftErr x) = Left x
1375substMatches :: [(Name, PTerm)] -> PTerm -> PTerm
1376substMatches ms = substMatchesShadow ms []
1378substMatchesShadow :: [(Name, PTerm)] -> [Name] -> PTerm -> PTerm
1379substMatchesShadow [] shs t = t
1380substMatchesShadow ((n,tm):ns) shs t
1381 = substMatchShadow n shs tm (substMatchesShadow ns shs t)
1383substMatch :: Name -> PTerm -> PTerm -> PTerm
1384substMatch n = substMatchShadow n []
1386substMatchShadow :: Name -> [Name] -> PTerm -> PTerm -> PTerm
1387substMatchShadow n shs tm t = sm shs t where
1388 sm xs (PRef _ n') | n == n' = tm
1389 sm xs (PLam x t sc) = PLam x (sm xs t) (sm xs sc)
1390 sm xs (PPi p x t sc)
1392 = let x' = nextName x in
1393 PPi p x' (sm (x':xs) (substMatch x (PRef (FC "" 0) x') t))
1394 (sm (x':xs) (substMatch x (PRef (FC "" 0) x') sc))
1395 | otherwise = PPi p x (sm xs t) (sm (x : xs) sc)
1396 sm xs (PApp f x as) = fullApp $ PApp f (sm xs x) (map (fmap (sm xs)) as)
1397 sm xs (PCase f x as) = PCase f (sm xs x) (map (pmap (sm xs)) as)
1398 sm xs (PEq f x y) = PEq f (sm xs x) (sm xs y)
1399 sm xs (PRewrite f x y tm) = PRewrite f (sm xs x) (sm xs y)
1401 sm xs (PTyped x y) = PTyped (sm xs x) (sm xs y)
1402 sm xs (PPair f x y) = PPair f (sm xs x) (sm xs y)
1403 sm xs (PDPair f x t y) = PDPair f (sm xs x) (sm xs t) (sm xs y)
1404 sm xs (PAlternative a as) = PAlternative a (map (sm xs) as)
1405 sm xs (PHidden x) = PHidden (sm xs x)
1406 sm xs (PUnifyLog x) = PUnifyLog (sm xs x)
1409 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
1412shadow :: Name -> Name -> PTerm -> PTerm
1413shadow n n' t = sm t where
1414 sm (PRef fc x) | n == x = PRef fc n'
1415 sm (PLam x t sc) = PLam x (sm t) (sm sc)
1416 sm (PPi p x t sc) = PPi p x (sm t) (sm sc)
1417 sm (PApp f x as) = PApp f (sm x) (map (fmap sm) as)
1418 sm (PCase f x as) = PCase f (sm x) (map (pmap sm) as)
1419 sm (PEq f x y) = PEq f (sm x) (sm y)
1420 sm (PRewrite f x y tm) = PRewrite f (sm x) (sm y) (fmap sm tm)
1421 sm (PTyped x y) = PTyped (sm x) (sm y)
1422 sm (PPair f x y) = PPair f (sm x) (sm y)
1423 sm (PDPair f x t y) = PDPair f (sm x) (sm t) (sm y)
1424 sm (PAlternative a as) = PAlternative a (map sm as)
1425 sm (PHidden x) = PHidden (sm x)
1426 sm (PUnifyLog x) = PUnifyLog (sm x)
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list