1{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, DeriveFunctor,
2 TypeSynonymInstances, PatternGuards #-}
4module Idris.AbsSyntax where
8import Core.Elaborate hiding (Tactic(..))
13import System.Console.Haskeline
15import Control.Monad.State
23import qualified Epic.Epic as E
27data IOption = IOption { opt_logLevel :: Int,
29 opt_typeintype :: Bool,
34 opt_ibcsubdir :: FilePath,
35 opt_importdirs :: [FilePath]
39defaultOpts = IOption 0 False False True False True True "" []
41-- TODO: Add 'module data' to IState, which can be saved out and reloaded quickly (i.e
42-- without typechecking).
43-- This will include all the functions and data declarations, plus fixity declarations
46data IState = IState { tt_ctxt :: Context,
47 idris_constraints :: [(UConstraint, FC)],
48 idris_infixes :: [FixDecl],
49 idris_implicits :: Ctxt [PArg],
50 idris_statics :: Ctxt [Bool],
51 idris_classes :: Ctxt ClassInfo,
52 idris_dsls :: Ctxt DSL,
53 idris_optimisation :: Ctxt OptInfo,
54 idris_datatypes :: Ctxt TypeInfo,
55 idris_patdefs :: Ctxt [([Name], Term, Term)], -- not exported
56 idris_flags :: Ctxt [FnOpt],
57 idris_callgraph :: Ctxt [Name],
58 idris_totcheck :: [(FC, Name)],
60 idris_options :: IOption,
62 idris_metavars :: [Name],
63 syntax_rules :: [Syntax],
64 syntax_keywords :: [String],
65 imported :: [FilePath],
66 idris_prims :: [(Name, ([E.Name], E.Term))],
67 idris_objs :: [FilePath],
68 idris_libs :: [String],
69 idris_hdrs :: [String],
70 last_proof :: Maybe (Name, [String]),
72 lastParse :: Maybe Name,
73 indent_stack :: [Int],
74 brace_stack :: [Maybe Int],
75 hide_list :: [(Name, Maybe Accessibility)],
76 default_access :: Accessibility,
77 ibc_write :: [IBCWrite],
78 compiled_so :: Maybe String
81-- information that needs writing for the current module's .ibc file
82data IBCWrite = IBCFix FixDecl
86 | IBCInstance Bool Name Name
96 | IBCAccess Name Accessibility
97 | IBCTotal Name Totality
98 | IBCFlags Name [FnOpt]
100 | IBCDef Name -- i.e. main context
103idrisInit = IState initContext [] [] emptyContext emptyContext emptyContext
104 emptyContext emptyContext emptyContext emptyContext
105 emptyContext emptyContext
106 [] "" defaultOpts 6 [] [] [] [] [] [] [] []
107 Nothing Nothing Nothing [] [] [] Hidden [] Nothing
109-- The monad for the main REPL - reading and processing files and updating
110-- global state (hence the IO inner monad).
111type Idris = StateT IState (InputT IO)
113getContext :: Idris Context
114getContext = do i <- get; return (tt_ctxt i)
116getObjectFiles :: Idris [FilePath]
117getObjectFiles = do i <- get; return (idris_objs i)
119addObjectFile :: FilePath -> Idris ()
120addObjectFile f = do i <- get; put (i { idris_objs = f : idris_objs i })
122getLibs :: Idris [String]
123getLibs = do i <- get; return (idris_libs i)
125addLib :: String -> Idris ()
126addLib f = do i <- get; put (i { idris_libs = f : idris_libs i })
128addHdr :: String -> Idris ()
129addHdr f = do i <- get; put (i { idris_hdrs = f : idris_hdrs i })
131totcheck :: (FC, Name) -> Idris ()
132totcheck n = do i <- get; put (i { idris_totcheck = n : idris_totcheck i })
134setFlags :: Name -> [FnOpt] -> Idris ()
135setFlags n fs = do i <- get; put (i { idris_flags = addDef n fs (idris_flags i) })
137setAccessibility :: Name -> Accessibility -> Idris ()
140 let ctxt = setAccess n a (tt_ctxt i)
141 put (i { tt_ctxt = ctxt })
143setTotality :: Name -> Totality -> Idris ()
146 let ctxt = setTotal n a (tt_ctxt i)
147 put (i { tt_ctxt = ctxt })
149getTotality :: Name -> Idris Totality
152 case lookupTotal n (tt_ctxt i) of
154 _ -> return (Total [])
156addToCG :: Name -> [Name] -> Idris ()
157addToCG n ns = do i <- get
158 put (i { idris_callgraph = addDef n ns (idris_callgraph i) })
160-- Add a class instance function. Dodgy hack: Put integer instances first in the
161-- list so they are resolved by default.
163addInstance :: Bool -> Name -> Name -> Idris ()
166 case lookupCtxt Nothing n (idris_classes ist) of
168 do let cs = addDef n (CI a b c d (addI i ins)) (idris_classes ist)
169 put (ist { idris_classes = cs })
170 _ -> do let cs = addDef n (CI (MN 0 "none") [] [] [] [i]) (idris_classes ist)
171 put (ist { idris_classes = cs })
172 where addI i ins | int = i : ins
173 | otherwise = ins ++ [i]
175addClass :: Name -> ClassInfo -> Idris ()
178 let i' = case lookupCtxt Nothing n (idris_classes ist) of
179 [c] -> c { class_instances = class_instances i }
181 put (ist { idris_classes = addDef n i' (idris_classes ist) })
183addIBC :: IBCWrite -> Idris ()
186 when (notDef (ibc_write i)) $
187 put (i { ibc_write = ibc : ibc_write i })
188 where notDef [] = True
189 notDef (IBCDef n': is) | n == n' = False
190 notDef (_ : is) = notDef is
191addIBC ibc = do i <- get; put (i { ibc_write = ibc : ibc_write i })
194clearIBC = do i <- get; put (i { ibc_write = [] })
196getHdrs :: Idris [String]
197getHdrs = do i <- get; return (idris_hdrs i)
199setErrLine :: Int -> Idris ()
200setErrLine x = do i <- get;
202 Nothing -> put (i { errLine = Just x })
206clearErr = do i <- get
207 put (i { errLine = Nothing })
209getSO :: Idris (Maybe String)
211 return (compiled_so i)
213setSO :: Maybe String -> Idris ()
215 put (i { compiled_so = s })
217getIState :: Idris IState
220putIState :: IState -> Idris ()
224getName = do i <- get;
225 let idx = idris_name i;
226 put (i { idris_name = idx + 1 })
229checkUndefined :: FC -> Name -> Idris ()
232 case lookupTy Nothing n i of
233 (_:_) -> fail $ show fc ++ ":" ++
234 show n ++ " already defined"
237setContext :: Context -> Idris ()
238setContext ctxt = do i <- get; put (i { tt_ctxt = ctxt } )
240updateContext :: (Context -> Context) -> Idris ()
241updateContext f = do i <- get; put (i { tt_ctxt = f (tt_ctxt i) } )
243addConstraints :: FC -> (Int, [UConstraint]) -> Idris ()
244addConstraints fc (v, cs)
247 let ctxt' = ctxt { uconstraints = cs ++ uconstraints ctxt,
249 let ics = zip cs (repeat fc) ++ idris_constraints i
250 put (i { tt_ctxt = ctxt', idris_constraints = ics })
252addDeferred :: [(Name, Type)] -> Idris ()
253addDeferred ns = do mapM_ (\(n, t) -> updateContext (addTyDecl n (tidyNames [] t))) ns
255 put (i { idris_metavars = map fst ns ++ idris_metavars i })
256 where tidyNames used (Bind (MN i x) b sc)
257 = let n' = uniqueName (UN x) used in
258 Bind n' b $ tidyNames (n':used) sc
259 tidyNames used (Bind n b sc)
260 = let n' = uniqueName n used in
261 Bind n' b $ tidyNames (n':used) sc
264solveDeferred :: Name -> Idris ()
265solveDeferred n = do i <- get
266 put (i { idris_metavars = idris_metavars i \\ [n] })
268iputStrLn :: String -> Idris ()
269iputStrLn = liftIO . putStrLn
271iWarn :: FC -> String -> Idris ()
272iWarn fc err = liftIO $ putStrLn (show fc ++ ":" ++ err)
274setLogLevel :: Int -> Idris ()
275setLogLevel l = do i <- get
276 let opts = idris_options i
277 let opt' = opts { opt_logLevel = l }
278 put (i { idris_options = opt' } )
281logLevel = do i <- get
282 return (opt_logLevel (idris_options i))
286 return (opt_repl (idris_options i))
288setREPL :: Bool -> Idris ()
289setREPL t = do i <- get
290 let opts = idris_options i
291 let opt' = opts { opt_repl = t }
292 put (i { idris_options = opt' })
296 return (opt_verbose (idris_options i))
298setVerbose :: Bool -> Idris ()
299setVerbose t = do i <- get
300 let opts = idris_options i
301 let opt' = opts { opt_verbose = t }
302 put (i { idris_options = opt' })
304typeInType :: Idris Bool
305typeInType = do i <- get
306 return (opt_typeintype (idris_options i))
308setTypeInType :: Bool -> Idris ()
309setTypeInType t = do i <- get
310 let opts = idris_options i
311 let opt' = opts { opt_typeintype = t }
312 put (i { idris_options = opt' })
314coverage :: Idris Bool
315coverage = do i <- get
316 return (opt_coverage (idris_options i))
318setCoverage :: Bool -> Idris ()
319setCoverage t = do i <- get
320 let opts = idris_options i
321 let opt' = opts { opt_coverage = t }
322 put (i { idris_options = opt' })
324setIBCSubDir :: FilePath -> Idris ()
325setIBCSubDir fp = do i <- get
326 let opts = idris_options i
327 let opt' = opts { opt_ibcsubdir = fp }
328 put (i { idris_options = opt' })
330valIBCSubDir :: IState -> Idris FilePath
331valIBCSubDir i = return (opt_ibcsubdir (idris_options i))
333setImportDirs :: [FilePath] -> Idris ()
334setImportDirs fps = do i <- get
335 let opts = idris_options i
336 let opt' = opts { opt_importdirs = fps }
337 put (i { idris_options = opt' })
339allImportDirs :: IState -> Idris [FilePath]
340allImportDirs i = do datadir <- liftIO $ getDataDir
341 let optdirs = opt_importdirs (idris_options i)
342 return ("." : (optdirs ++ [datadir]))
346 return (opt_showimp (idris_options i))
348setImpShow :: Bool -> Idris ()
349setImpShow t = do i <- get
350 let opts = idris_options i
351 let opt' = opts { opt_showimp = t }
352 put (i { idris_options = opt' })
354logLvl :: Int -> String -> Idris ()
355logLvl l str = do i <- get
356 let lvl = opt_logLevel (idris_options i)
358 $ do liftIO (putStrLn str)
359 put (i { idris_log = idris_log i ++ str ++ "\n" } )
361iLOG :: String -> Idris ()
364noErrors :: Idris Bool
365noErrors = do i <- get
367 Nothing -> return True
370setTypeCase :: Bool -> Idris ()
371setTypeCase t = do i <- get
372 let opts = idris_options i
373 let opt' = opts { opt_typecase = t }
374 put (i { idris_options = opt' })
376-- Commands in the REPL
378data Command = Quit | Help | Eval PTerm | Check PTerm | TotCheck Name
380 | Compile String | Execute | ExecVal PTerm
381 | Metavars | Prove Name | AddProof | Universes
383 | LogLvl Int | Spec PTerm | HNF PTerm | Defn Name
384 | Info Name | DebugInfo Name
388-- Parsed declarations
390data Fixity = Infixl { prec :: Int }
391 | Infixr { prec :: Int }
392 | InfixN { prec :: Int }
393 | PrefixN { prec :: Int }
396deriving instance Binary Fixity
399instance Show Fixity where
400 show (Infixl i) = "infixl " ++ show i
401 show (Infixr i) = "infixr " ++ show i
402 show (InfixN i) = "infix " ++ show i
403 show (PrefixN i) = "prefix " ++ show i
405data FixDecl = Fix Fixity String
408deriving instance Binary FixDecl
411instance Ord FixDecl where
412 compare (Fix x _) (Fix y _) = compare (prec x) (prec y)
415data Static = Static | Dynamic
418deriving instance Binary Static
421-- Mark bindings with their explicitness, and laziness
422data Plicity = Imp { plazy :: Bool,
424 | Exp { plazy :: Bool,
426 | Constraint { plazy :: Bool,
428 | TacImp { plazy :: Bool,
434deriving instance Binary Plicity
437impl = Imp False Dynamic
438expl = Exp False Dynamic
439constraint = Constraint False Dynamic
440tacimpl = TacImp False Dynamic
442data FnOpt = Inlinable | TotalFn | AssertTotal | TCGen
443 | Specialise [Name] -- specialise it, freeze these names
446deriving instance Binary FnOpt
451inlinable :: FnOpts -> Bool
452inlinable = elem Inlinable
454data PDecl' t = PFix FC Fixity [String] -- fixity declaration
455 | PTy SyntaxInfo FC FnOpts Name t -- type declaration
456 | PClauses FC FnOpts Name [PClause' t] -- pattern clause
457 | PData SyntaxInfo FC (PData' t) -- data declaration
458 | PParams FC [(Name, t)] [PDecl' t] -- params block
459 | PNamespace String [PDecl' t] -- new namespace
460 | PRecord SyntaxInfo FC Name t Name t -- record declaration
461 | PClass SyntaxInfo FC
464 [(Name, t)] -- parameters
465 [PDecl' t] -- declarations
466 | PInstance SyntaxInfo FC [t] -- constraints
469 t -- full instance type
473 | PDirective (Idris ())
476deriving instance Binary PDecl'
479data PClause' t = PClause FC Name t [t] t [PDecl' t]
480 | PWith FC Name t [t] t [PDecl' t]
481 | PClauseR FC [t] t [PDecl' t]
482 | PWithR FC [t] t [PDecl' t]
485deriving instance Binary PClause'
488data PData' t = PDatadecl { d_name :: Name,
490 d_cons :: [(Name, t, FC)] }
493deriving instance Binary PData'
496-- Handy to get a free function for applying PTerm -> PTerm functions
497-- across a program, by deriving Functor
499type PDecl = PDecl' PTerm
500type PData = PData' PTerm
501type PClause = PClause' PTerm
503-- get all the names declared in a decl
505declared :: PDecl -> [Name]
506declared (PFix _ _ _) = []
507declared (PTy _ _ _ n t) = [n]
508declared (PClauses _ _ n _) = [] -- not a declaration
509declared (PData _ _ (PDatadecl n _ ts)) = n : map fstt ts
510 where fstt (a, _, _) = a
511declared (PParams _ _ ds) = concatMap declared ds
512declared (PNamespace _ ds) = concatMap declared ds
513-- declared (PImport _) = []
515defined :: PDecl -> [Name]
516defined (PFix _ _ _) = []
517defined (PTy _ _ _ n t) = []
518defined (PClauses _ _ n _) = [n] -- not a declaration
519defined (PData _ _ (PDatadecl n _ ts)) = n : map fstt ts
520 where fstt (a, _, _) = a
521defined (PParams _ _ ds) = concatMap defined ds
522defined (PNamespace _ ds) = concatMap defined ds
523-- declared (PImport _) = []
525updateN :: [(Name, Name)] -> Name -> Name
526updateN ns n | Just n' <- lookup n ns = n'
529updateNs :: [(Name, Name)] -> PTerm -> PTerm
531updateNs ns t = mapPT updateRef t
532 where updateRef (PRef fc f) = PRef fc (updateN ns f)
535-- updateDNs :: [(Name, Name)] -> PDecl -> PDecl
537-- updateDNs ns (PTy s f n t) | Just n' <- lookup n ns = PTy s f n' t
538-- updateDNs ns (PClauses f n c) | Just n' <- lookup n ns = PClauses f n' (map updateCNs c)
539-- where updateCNs ns (PClause n l ts r ds)
540-- = PClause (updateN ns n) (fmap (updateNs ns) l)
541-- (map (fmap (updateNs ns)) ts)
542-- (fmap (updateNs ns) r)
543-- (map (updateDNs ns) ds)
546-- High level language terms
548data PTerm = PQuote Raw
550 | PLam Name PTerm PTerm
551 | PPi Plicity Name PTerm PTerm
552 | PLet Name PTerm PTerm PTerm
553 | PTyped PTerm PTerm -- term with explicit type
554 | PApp FC PTerm [PArg]
555 | PCase FC PTerm [(PTerm, PTerm)]
561 | PPair FC PTerm PTerm
562 | PDPair FC PTerm PTerm PTerm
563 | PAlternative Bool [PTerm] -- True if only one may work
564 | PHidden PTerm -- irrelevant or hidden pattern
573 | PTactics [PTactic] -- as PProof, but no auto solving
574 | PElabError Err -- error to report on elaboration
575 | PImpossible -- special case for declaring when an LHS can't typecheck
578deriving instance Binary PTerm
581mapPT :: (PTerm -> PTerm) -> PTerm -> PTerm
582mapPT f t = f (mpt t) where
583 mpt (PLam n t s) = PLam n (mapPT f t) (mapPT f s)
584 mpt (PPi p n t s) = PPi p n (mapPT f t) (mapPT f s)
585 mpt (PLet n ty v s) = PLet n (mapPT f ty) (mapPT f v) (mapPT f s)
586 mpt (PApp fc t as) = PApp fc (mapPT f t) (map (fmap (mapPT f)) as)
587 mpt (PCase fc c os) = PCase fc (mapPT f c) (map (pmap (mapPT f)) os)
588 mpt (PEq fc l r) = PEq fc (mapPT f l) (mapPT f r)
589 mpt (PTyped l r) = PTyped (mapPT f l) (mapPT f r)
590 mpt (PPair fc l r) = PPair fc (mapPT f l) (mapPT f r)
591 mpt (PDPair fc l t r) = PDPair fc (mapPT f l) (mapPT f t) (mapPT f r)
592 mpt (PAlternative a as) = PAlternative a (map (mapPT f) as)
593 mpt (PHidden t) = PHidden (mapPT f t)
594 mpt (PDoBlock ds) = PDoBlock (map (fmap (mapPT f)) ds)
595 mpt (PProof ts) = PProof (map (fmap (mapPT f)) ts)
596 mpt (PTactics ts) = PTactics (map (fmap (mapPT f)) ts)
600data PTactic' t = Intro [Name] | Intros | Focus Name
601 | Refine Name [Bool] | Rewrite t | LetTac Name t
602 | Exact t | Compute | Trivial
605 | ProofState | ProofTerm | Undo
606 | Try (PTactic' t) (PTactic' t)
607 | TSeq (PTactic' t) (PTactic' t)
609 deriving (Show, Eq, Functor)
611deriving instance Binary PTactic'
614instance Sized a => Sized (PTactic' a) where
615 size (Intro nms) = 1 + size nms
617 size (Focus nm) = 1 + size nm
618 size (Refine nm bs) = 1 + size nm + length bs
619 size (Rewrite t) = 1 + size t
620 size (LetTac nm t) = 1 + size nm + size t
621 size (Exact t) = 1 + size t
629 size (Try l r) = 1 + size l + size r
630 size (TSeq l r) = 1 + size l + size r
634type PTactic = PTactic' PTerm
636data PDo' t = DoExp FC t
641 deriving (Eq, Functor)
643deriving instance Binary PDo'
646instance Sized a => Sized (PDo' a) where
647 size (DoExp fc t) = 1 + size fc + size t
648 size (DoBind fc nm t) = 1 + size fc + size nm + size t
649 size (DoBindP fc l r) = 1 + size fc + size l + size r
650 size (DoLet fc nm l r) = 1 + size fc + size nm + size l + size r
651 size (DoLetP fc l r) = 1 + size fc + size l + size r
655-- The priority gives a hint as to elaboration order. Best to elaborate
656-- things early which will help give a more concrete type to other
657-- variables, e.g. a before (interpTy a).
659data PArg' t = PImp { priority :: Int,
660 lazyarg :: Bool, pname :: Name, getTm :: t }
661 | PExp { priority :: Int,
662 lazyarg :: Bool, getTm :: t }
663 | PConstraint { priority :: Int,
664 lazyarg :: Bool, getTm :: t }
665 | PTacImplicit { priority :: Int,
666 lazyarg :: Bool, pname :: Name,
669 deriving (Show, Eq, Functor)
671instance Sized a => Sized (PArg' a) where
672 size (PImp p l nm trm) = 1 + size nm + size trm
673 size (PExp p l trm) = 1 + size trm
674 size (PConstraint p l trm) = 1 + size trm
675 size (PTacImplicit p l nm scr trm) = 1 + size nm + size scr + size trm
678deriving instance Binary PArg'
683pconst = PConstraint 0 False
684ptacimp = PTacImplicit 0 True
686type PArg = PArg' PTerm
690data ClassInfo = CI { instanceName :: Name,
691 class_methods :: [(Name, (FnOpts, PTerm))],
692 class_defaults :: [(Name, (Name, PDecl))], -- method name -> default impl
693 class_params :: [Name],
694 class_instances :: [Name] }
697deriving instance Binary ClassInfo
700data OptInfo = Optimise { collapsible :: Bool,
701 forceable :: [Int], -- argument positions
705deriving instance Binary OptInfo
709data TypeInfo = TI { con_names :: [Name] }
712deriving instance Binary TypeInfo
715-- Syntactic sugar info
717data DSL' t = DSL { dsl_bind :: t,
722 index_first :: Maybe t,
723 index_next :: Maybe t,
724 dsl_lambda :: Maybe t,
727 deriving (Show, Functor)
729deriving instance Binary DSL'
734data SynContext = PatternSyntax | TermSyntax | AnySyntax
737deriving instance Binary SynContext
740data Syntax = Rule [SSymbol] PTerm SynContext
743deriving instance Binary Syntax
746data SSymbol = Keyword Name
752deriving instance Binary SSymbol
755initDSL = DSL (PRef f (UN ">>="))
756 (PRef f (UN "return"))
764 where f = FC "(builtin)" 0
766data SyntaxInfo = Syn { using :: [(Name, PTerm)],
767 syn_params :: [(Name, PTerm)],
768 syn_namespace :: [String],
770 decoration :: Name -> Name,
775deriving instance Binary SyntaxInfo
778defaultSyntax = Syn [] [] [] [] id False initDSL
780expandNS :: SyntaxInfo -> Name -> Name
781expandNS syn n@(NS _ _) = n
782expandNS syn n = case syn_namespace syn of
787--- Pretty printing declarations and terms
789instance Show PTerm where
790 show tm = showImp False tm
792instance Pretty PTerm where
793 pretty = prettyImp False
795instance Show PDecl where
796 show d = showDeclImp False d
798instance Show PClause where
799 show c = showCImp True c
801instance Show PData where
802 show d = showDImp False d
804showDeclImp _ (PFix _ f ops) = show f ++ " " ++ showSep ", " ops
805showDeclImp t (PTy _ _ _ n ty) = show n ++ " : " ++ showImp t ty
806showDeclImp _ (PClauses _ _ n c) = showSep "\n" (map show c)
807showDeclImp _ (PData _ _ d) = show d
809showCImp :: Bool -> PClause -> String
810showCImp impl (PClause _ n l ws r w)
811 = showImp impl l ++ showWs ws ++ " = " ++ showImp impl r
812 ++ " where " ++ show w
815 showWs (x : xs) = " | " ++ showImp impl x ++ showWs xs
816showCImp impl (PWith _ n l ws r w)
817 = showImp impl l ++ showWs ws ++ " with " ++ showImp impl r
818 ++ " { " ++ show w ++ " } "
821 showWs (x : xs) = " | " ++ showImp impl x ++ showWs xs
824showDImp :: Bool -> PData -> String
825showDImp impl (PDatadecl n ty cons)
826 = "data " ++ show n ++ " : " ++ showImp impl ty ++ " where\n\t"
828 (map (\ (n, t, _) -> show n ++ " : " ++ showImp impl t) cons)
830getImps :: [PArg] -> [(Name, PTerm)]
832getImps (PImp _ _ n tm : xs) = (n, tm) : getImps xs
833getImps (_ : xs) = getImps xs
835getExps :: [PArg] -> [PTerm]
837getExps (PExp _ _ tm : xs) = tm : getExps xs
838getExps (_ : xs) = getExps xs
840getConsts :: [PArg] -> [PTerm]
842getConsts (PConstraint _ _ tm : xs) = tm : getConsts xs
843getConsts (_ : xs) = getConsts xs
845getAll :: [PArg] -> [PTerm]
848prettyImp :: Bool -> PTerm -> Doc
849prettyImp impl = prettySe 10
851 prettySe p (PQuote r) =
852 if size r > breakingSize then
853 text "![" $$ pretty r <> text "]"
855 text "![" <> pretty r <> text "]"
856 prettySe p (PRef fc n) =
862 prettyBasic n@(UN _) = pretty n
863 prettyBasic (MN _ s) = text s
864 prettyBasic (NS n s) = (foldr (<>) empty (intersperse (text ".") (map text $ reverse s))) <> prettyBasic n
865 prettySe p (PLam n ty sc) =
867 if size sc > breakingSize then
868 text "λ" <> pretty n <+> text "=>" $+$ pretty sc
870 text "λ" <> pretty n <+> text "=>" <+> pretty sc
871 prettySe p (PLet n ty v sc) =
873 if size sc > breakingSize then
874 text "let" <+> pretty n <+> text "=" <+> prettySe 10 v <+> text "in" $+$
875 nest nestingSize (prettySe 10 sc)
877 text "let" <+> pretty n <+> text "=" <+> prettySe 10 v <+> text "in" <+>
879 prettySe p (PPi (Exp l s) n ty sc)
880 | n `elem` allNamesIn sc || impl =
881 let open = if l then text "|" <> lparen else lparen in
883 if size sc > breakingSize then
884 open <> pretty n <+> colon <+> prettySe 10 ty <> rparen <+>
885 st <+> text "->" $+$ prettySe 10 sc
887 open <> pretty n <+> colon <+> prettySe 10 ty <> rparen <+>
888 st <+> text "->" <+> prettySe 10 sc
891 if size sc > breakingSize then
892 prettySe 0 ty <+> st <+> text "->" $+$ prettySe 10 sc
894 prettySe 0 ty <+> st <+> text "->" <+> prettySe 10 sc
898 Static -> text "[static]"
900 prettySe p (PPi (Imp l s) n ty sc)
902 let open = if l then text "|" <> lbrace else lbrace in
904 if size sc > breakingSize then
905 open <> pretty n <+> colon <+> prettySe 10 ty <> rbrace <+>
906 st <+> text "->" <+> prettySe 10 sc
908 open <> pretty n <+> colon <+> prettySe 10 ty <> rbrace <+>
909 st <+> text "->" <+> prettySe 10 sc
910 | otherwise = prettySe 10 sc
914 Static -> text $ "[static]"
916 prettySe p (PPi (Constraint _ _) n ty sc) =
918 if size sc > breakingSize then
919 prettySe 10 ty <+> text "=>" <+> prettySe 10 sc
921 prettySe 10 ty <+> text "=>" $+$ prettySe 10 sc
922 prettySe p (PPi (TacImp _ _ s) n ty sc) =
924 if size sc > breakingSize then
925 lbrace <> text "tacimp" <+> pretty n <+> colon <+> prettySe 10 ty <>
926 rbrace <+> text "->" $+$ prettySe 10 sc
928 lbrace <> text "tacimp" <+> pretty n <+> colon <+> prettySe 10 ty <>
929 rbrace <+> text "->" <+> prettySe 10 sc
930 prettySe p (PApp _ (PRef _ f) [])
931 | not impl = pretty f
932 prettySe p (PApp _ (PRef _ op@(UN (f:_))) args)
933 | length (getExps args) == 2 && (not impl) && (not $ isAlpha f) =
934 let [l, r] = getExps args in
936 if size r > breakingSize then
937 prettySe 1 l <+> pretty op $+$ prettySe 0 r
939 prettySe 1 l <+> pretty op <+> prettySe 0 r
940 prettySe p (PApp _ f as) =
941 let args = getExps as in
946 -- foldr (<+>) empty $ map prettyArgS as
949 -- foldr (<+>) empty $ map prettyArgSe args
952 if size r > breakingSize then
953 l $+$ nest nestingSize (prettyArgS r)
958 if size r > breakingSize then
959 l $+$ nest nestingSize (prettyArgSe r)
962 prettySe p (PCase _ scr opts) =
963 text "case" <+> prettySe 10 scr <+> text "of" $+$ nest nestingSize prettyBody
965 prettyBody = foldr ($$) empty $ intersperse (text "|") $ map sc opts
967 sc (l, r) = prettySe 10 l <+> text "=>" <+> prettySe 10 r
968 prettySe p (PHidden tm) = text "." <> prettySe 0 tm
969 prettySe p (PRefl _) = text "refl"
970 prettySe p (PResolveTC _) = text "resolvetc"
971 prettySe p (PTrue _) = text "()"
972 prettySe p (PFalse _) = text "_|_"
973 prettySe p (PEq _ l r) =
975 if size r > breakingSize then
976 prettySe 10 l <+> text "=" $$ nest nestingSize (prettySe 10 r)
978 prettySe 10 l <+> text "=" <+> prettySe 10 r
979 prettySe p (PTyped l r) =
980 lparen <> prettySe 10 l <+> colon <+> prettySe 10 r <> rparen
981 prettySe p (PPair _ l r) =
982 if size r > breakingSize then
983 lparen <> prettySe 10 l <> text "," $+$
984 prettySe 10 r <> rparen
986 lparen <> prettySe 10 l <> text "," <+> prettySe 10 r <> rparen
987 prettySe p (PDPair _ l t r) =
988 if size r > breakingSize then
989 lparen <> prettySe 10 l <+> text "**" $+$
990 prettySe 10 r <> rparen
992 lparen <> prettySe 10 l <+> text "**" <+> prettySe 10 r <> rparen
993 prettySe p (PAlternative a as) =
994 lparen <> text "|" <> prettyAs <> text "|" <> rparen
997 foldr (\l -> \r -> l <+> text "," <+> r) empty $ map (prettySe 10) as
998 prettySe p PSet = text "Set"
999 prettySe p (PConstant c) = pretty c
1000 -- XXX: add pretty for tactics
1001 prettySe p (PProof ts) =
1002 text "proof" <+> lbrace $+$ nest nestingSize (text . show $ ts) $+$ rbrace
1003 prettySe p (PTactics ts) =
1004 text "tactics" <+> lbrace $+$ nest nestingSize (text . show $ ts) $+$ rbrace
1005 prettySe p (PMetavar n) = text "?" <> pretty n
1006 prettySe p (PReturn f) = text "return"
1007 prettySe p PImpossible = text "impossible"
1008 prettySe p Placeholder = text "_"
1009 prettySe p (PDoBlock _) = text "do block pretty not implemented"
1010 prettySe p (PElabError s) = pretty s
1012 prettySe p _ = text "test"
1014 prettyArgS (PImp _ _ n tm) = prettyArgSi (n, tm)
1015 prettyArgS (PExp _ _ tm) = prettyArgSe tm
1016 prettyArgS (PConstraint _ _ tm) = prettyArgSc tm
1017 prettyArgS (PTacImplicit _ _ n _ tm) = prettyArgSti (n, tm)
1019 prettyArgSe arg = prettySe 0 arg
1020 prettyArgSi (n, val) = lbrace <> pretty n <+> text "=" <+> prettySe 10 val <> rbrace
1021 prettyArgSc val = lbrace <> lbrace <> prettySe 10 val <> rbrace <> rbrace
1022 prettyArgSti (n, val) = lbrace <> text "auto" <+> pretty n <+> text "=" <+> prettySe 10 val <> rbrace
1024 bracket outer inner doc
1025 | inner > outer = lparen <> doc <> rparen
1028showImp :: Bool -> PTerm -> String
1029showImp impl tm = se 10 tm where
1030 se p (PQuote r) = "![" ++ show r ++ "]"
1031 se p (PRef fc n) = if impl then show n -- ++ "[" ++ show fc ++ "]"
1033 where showbasic n@(UN _) = show n
1034 showbasic (MN _ s) = s
1035 showbasic (NS n s) = showSep "." (reverse s) ++ "." ++ showbasic n
1036 se p (PLam n ty sc) = bracket p 2 $ "\\ " ++ show n ++
1037 (if impl then " : " ++ se 10 ty else "") ++ " => "
1039 se p (PLet n ty v sc) = bracket p 2 $ "let " ++ show n ++ " = " ++ se 10 v ++
1041 se p (PPi (Exp l s) n ty sc)
1042 | n `elem` allNamesIn sc || impl
1044 if l then "|(" else "(" ++
1045 show n ++ " : " ++ se 10 ty ++
1048 | otherwise = bracket p 2 $ se 0 ty ++ " " ++ st ++ "-> " ++ se 10 sc
1049 where st = case s of
1050 Static -> "[static] "
1052 se p (PPi (Imp l s) n ty sc)
1053 | impl = bracket p 2 $ if l then "|{" else "{" ++
1054 show n ++ " : " ++ se 10 ty ++
1055 "} " ++ st ++ "-> " ++ se 10 sc
1056 | otherwise = se 10 sc
1057 where st = case s of
1058 Static -> "[static] "
1060 se p (PPi (Constraint _ _) n ty sc)
1061 = bracket p 2 $ se 10 ty ++ " => " ++ se 10 sc
1062 se p (PPi (TacImp _ _ s) n ty sc)
1063 = bracket p 2 $ "{tacimp " ++ show n ++ " : " ++ se 10 ty ++ "} -> " ++ se 10 sc
1064 se p (PApp _ (PRef _ f) [])
1066 se p (PApp _ (PRef _ op@(UN (f:_))) args)
1067 | length (getExps args) == 2 && not impl && not (isAlpha f)
1068 = let [l, r] = getExps args in
1069 bracket p 1 $ se 1 l ++ " " ++ show op ++ " " ++ se 0 r
1071 = let args = getExps as in
1072 bracket p 1 $ se 1 f ++ if impl then concatMap sArg as
1073 else concatMap seArg args
1074 se p (PCase _ scr opts) = "case " ++ se 10 scr ++ " of " ++ showSep " | " (map sc opts)
1075 where sc (l, r) = se 10 l ++ " => " ++ se 10 r
1076 se p (PHidden tm) = "." ++ se 0 tm
1077 se p (PRefl _) = "refl"
1078 se p (PResolveTC _) = "resolvetc"
1079 se p (PTrue _) = "()"
1080 se p (PFalse _) = "_|_"
1081 se p (PEq _ l r) = bracket p 2 $ se 10 l ++ " = " ++ se 10 r
1082 se p (PTyped l r) = "(" ++ se 10 l ++ " : " ++ se 10 r ++ ")"
1083 se p (PPair _ l r) = "(" ++ se 10 l ++ ", " ++ se 10 r ++ ")"
1084 se p (PDPair _ l t r) = "(" ++ se 10 l ++ " ** " ++ se 10 r ++ ")"
1085 se p (PAlternative a as) = "(|" ++ showSep " , " (map (se 10) as) ++ "|)"
1087 se p (PConstant c) = show c
1088 se p (PProof ts) = "proof { " ++ show ts ++ "}"
1089 se p (PTactics ts) = "tactics { " ++ show ts ++ "}"
1090 se p (PMetavar n) = "?" ++ show n
1091 se p (PReturn f) = "return"
1092 se p PImpossible = "impossible"
1093 se p Placeholder = "_"
1094 se p (PDoBlock _) = "do block show not implemented"
1095 se p (PElabError s) = show s
1096-- se p x = "Not implemented"
1098 sArg (PImp _ _ n tm) = siArg (n, tm)
1099 sArg (PExp _ _ tm) = seArg tm
1100 sArg (PConstraint _ _ tm) = scArg tm
1101 sArg (PTacImplicit _ _ n _ tm) = stiArg (n, tm)
1103 seArg arg = " " ++ se 0 arg
1104 siArg (n, val) = " {" ++ show n ++ " = " ++ se 10 val ++ "}"
1105 scArg val = " {{" ++ se 10 val ++ "}}"
1106 stiArg (n, val) = " {auto " ++ show n ++ " = " ++ se 10 val ++ "}"
1108 bracket outer inner str | inner > outer = "(" ++ str ++ ")"
1114 | PLam Name PTerm PTerm
1115 | PPi Plicity Name PTerm PTerm
1116 | PLet Name PTerm PTerm PTerm
1117 | PTyped PTerm PTerm -- term with explicit type
1118 | PApp FC PTerm [PArg]
1119 | PCase FC PTerm [(PTerm, PTerm)]
1124 | PEq FC PTerm PTerm
1125 | PPair FC PTerm PTerm
1126 | PDPair FC PTerm PTerm PTerm
1127 | PAlternative [PTerm]
1128 | PHidden PTerm -- irrelevant or hidden pattern
1137 | PTactics [PTactic] -- as PProof, but no auto solving
1138 | PElabError Err -- error to report on elaboration
1139 | PImpossible -- special case for declaring when an LHS can't typecheck
1142instance Sized PTerm where
1143 size (PQuote rawTerm) = size rawTerm
1144 size (PRef fc name) = size name
1145 size (PLam name ty bdy) = 1 + size ty + size bdy
1146 size (PPi plicity name ty bdy) = 1 + size ty + size bdy
1147 size (PLet name ty def bdy) = 1 + size ty + size def + size bdy
1148 size (PTyped trm ty) = 1 + size trm + size ty
1149 size (PApp fc name args) = 1 + size args
1150 size (PCase fc trm bdy) = 1 + size trm + size bdy
1152 size (PFalse fc) = 1
1154 size (PResolveTC fc) = 1
1155 size (PEq fc left right) = 1 + size left + size right
1156 size (PPair fc left right) = 1 + size left + size right
1157 size (PDPair fs left ty right) = 1 + size left + size ty + size right
1158 size (PAlternative a alts) = 1 + size alts
1159 size (PHidden hidden) = size hidden
1161 size (PConstant const) = 1 + size const
1162 size Placeholder = 1
1163 size (PDoBlock dos) = 1 + size dos
1164 size (PIdiom fc term) = 1 + size term
1165 size (PReturn fc) = 1
1166 size (PMetavar name) = 1
1167 size (PProof tactics) = size tactics
1168 size (PElabError err) = size err
1169 size PImpossible = 1
1171allNamesIn :: PTerm -> [Name]
1172allNamesIn tm = nub $ ni [] tm
1175 | not (n `elem` env) = [n]
1176 ni env (PApp _ f as) = ni env f ++ concatMap (ni env) (map getTm as)
1177 ni env (PCase _ c os) = ni env c ++ concatMap (ni env) (map snd os)
1178 ni env (PLam n ty sc) = ni env ty ++ ni (n:env) sc
1179 ni env (PPi _ n ty sc) = ni env ty ++ ni (n:env) sc
1180 ni env (PHidden tm) = ni env tm
1181 ni env (PEq _ l r) = ni env l ++ ni env r
1182 ni env (PTyped l r) = ni env l ++ ni env r
1183 ni env (PPair _ l r) = ni env l ++ ni env r
1184 ni env (PDPair _ (PRef _ n) t r) = ni env t ++ ni (n:env) r
1185 ni env (PDPair _ l t r) = ni env l ++ ni env t ++ ni env r
1186 ni env (PAlternative a ls) = concatMap (ni env) ls
1189namesIn :: [(Name, PTerm)] -> IState -> PTerm -> [Name]
1190namesIn uvars ist tm = nub $ ni [] tm
1193 | not (n `elem` env)
1194 = case lookupTy Nothing n (tt_ctxt ist) of
1196 _ -> if n `elem` (map fst uvars) then [n] else []
1197 ni env (PApp _ f as) = ni env f ++ concatMap (ni env) (map getTm as)
1198 ni env (PCase _ c os) = ni env c ++ concatMap (ni env) (map snd os)
1199 ni env (PLam n ty sc) = ni env ty ++ ni (n:env) sc
1200 ni env (PPi _ n ty sc) = ni env ty ++ ni (n:env) sc
1201 ni env (PEq _ l r) = ni env l ++ ni env r
1202 ni env (PTyped l r) = ni env l ++ ni env r
1203 ni env (PPair _ l r) = ni env l ++ ni env r
1204 ni env (PDPair _ (PRef _ n) t r) = ni env t ++ ni (n:env) r
1205 ni env (PDPair _ l t r) = ni env l ++ ni env t ++ ni env r
1206 ni env (PAlternative a as) = concatMap (ni env) as
1207 ni env (PHidden tm) = ni env tm
1210-- For inferring types of things
1214inferTy = MN 0 "__Infer"
1215inferCon = MN 0 "__infer"
1216inferDecl = PDatadecl inferTy
1218 [(inferCon, PPi impl (MN 0 "A") PSet (
1219 PPi expl (MN 0 "a") (PRef bi (MN 0 "A"))
1220 (PRef bi inferTy)), bi)]
1222infTerm t = PApp bi (PRef bi inferCon) [pimp (MN 0 "A") Placeholder, pexp t]
1223infP = P (TCon 6 0) inferTy (Set (UVal 0))
1225getInferTerm, getInferType :: Term -> Term
1226getInferTerm (Bind n b sc) = Bind n b $ getInferTerm sc
1227getInferTerm (App (App _ _) tm) = tm
1228getInferTerm tm = error ("getInferTerm " ++ show tm)
1230getInferType (Bind n b sc) = Bind n b $ getInferType sc
1231getInferType (App (App _ ty) _) = ty
1233-- Handy primitives: Unit, False, Pair, MkPair, =, mkForeign
1235primNames = [unitTy, unitCon,
1236 falseTy, pairTy, pairCon,
1237 eqTy, eqCon, inferTy, inferCon]
1239unitTy = MN 0 "__Unit"
1240unitCon = MN 0 "__II"
1241unitDecl = PDatadecl unitTy PSet
1242 [(unitCon, PRef bi unitTy, bi)]
1244falseTy = MN 0 "__False"
1245falseDecl = PDatadecl falseTy PSet []
1247pairTy = MN 0 "__Pair"
1248pairCon = MN 0 "__MkPair"
1249pairDecl = PDatadecl pairTy (piBind [(n "A", PSet), (n "B", PSet)] PSet)
1250 [(pairCon, PPi impl (n "A") PSet (
1251 PPi impl (n "B") PSet (
1252 PPi expl (n "a") (PRef bi (n "A")) (
1253 PPi expl (n "b") (PRef bi (n "B"))
1254 (PApp bi (PRef bi pairTy) [pexp (PRef bi (n "A")),
1255 pexp (PRef bi (n "B"))])))), bi)]
1260eqDecl = PDatadecl eqTy (piBind [(n "a", PSet), (n "b", PSet),
1261 (n "x", PRef bi (n "a")), (n "y", PRef bi (n "b"))]
1263 [(eqCon, PPi impl (n "a") PSet (
1264 PPi impl (n "x") (PRef bi (n "a"))
1265 (PApp bi (PRef bi eqTy) [pimp (n "a") Placeholder,
1266 pimp (n "b") Placeholder,
1267 pexp (PRef bi (n "x")),
1268 pexp (PRef bi (n "x"))])), bi)]
1271-- Defined in builtins.idr
1272sigmaTy = UN "Exists"
1273existsCon = UN "Ex_intro"
1275piBind :: [(Name, PTerm)] -> PTerm -> PTerm
1277piBind ((n, ty):ns) t = PPi expl n ty (piBind ns t)
1279tcname (UN ('@':_)) = True
1280tcname (NS n _) = tcname n
1283-- Dealing with parameters
1285expandParams :: (Name -> Name) -> [(Name, PTerm)] -> [Name] -> PTerm -> PTerm
1286expandParams dec ps ns tm = en tm
1288 -- if we shadow a name (say in a lambda binding) that is used in a call to
1289 -- a lifted function, we need access to both names - once in the scope of the
1290 -- binding and once to call the lifted functions. So we'll explicitly shadow
1291 -- it. (Yes, it's a hack. The alternative would be to resolve names earlier
1292 -- but we didn't...)
1294 mkShadow (UN n) = MN 0 n
1295 mkShadow (MN i n) = MN (i+1) n
1296 mkShadow (NS x s) = NS (mkShadow x) s
1299 | n `elem` map fst ps
1300 = let n' = mkShadow n in
1301 PLam n' (en t) (en (shadow n n' s))
1302 | otherwise = PLam n (en t) (en s)
1304 | n `elem` map fst ps
1305 = let n' = mkShadow n in
1306 PPi p n' (en t) (en (shadow n n' s))
1307 | otherwise = PPi p n (en t) (en s)
1309 | n `elem` map fst ps
1310 = let n' = mkShadow n in
1311 PLet n' (en ty) (en v) (en (shadow n n' s))
1312 | otherwise = PLet n (en ty) (en v) (en s)
1313 en (PEq f l r) = PEq f (en l) (en r)
1314 en (PTyped l r) = PTyped (en l) (en r)
1315 en (PPair f l r) = PPair f (en l) (en r)
1316 en (PDPair f l t r) = PDPair f (en l) (en t) (en r)
1317 en (PAlternative a as) = PAlternative a (map en as)
1318 en (PHidden t) = PHidden (en t)
1319 en (PDoBlock ds) = PDoBlock (map (fmap en) ds)
1320 en (PProof ts) = PProof (map (fmap en) ts)
1321 en (PTactics ts) = PTactics (map (fmap en) ts)
1324 | n `elem` ns = PQuote (Var (dec n))
1325 en (PApp fc (PRef fc' n) as)
1326 | n `elem` ns = PApp fc (PRef fc' (dec n))
1327 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
1329 | n `elem` ns = PApp fc (PRef fc (dec n))
1330 (map (pexp . (PRef fc)) (map fst ps))
1331 en (PApp fc f as) = PApp fc (en f) (map (fmap en) as)
1332 en (PCase fc c os) = PCase fc (en c) (map (pmap en) os)
1335expandParamsD :: IState ->
1336 (Name -> Name) -> [(Name, PTerm)] -> [Name] -> PDecl -> PDecl
1337expandParamsD ist dec ps ns (PTy syn fc o n ty)
1339 then PTy syn fc o (dec n) (piBind ps (expandParams dec ps ns ty))
1340 else PTy syn fc o n (expandParams dec ps ns ty)
1341expandParamsD ist dec ps ns (PClauses fc opts n cs)
1342 = let n' = if n `elem` ns then dec n else n in
1343 PClauses fc opts n' (map expandParamsC cs)
1345 expandParamsC (PClause fc n lhs ws rhs ds)
1346 = let -- ps' = updateps True (namesIn ist rhs) (zip ps [0..])
1347 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
1348 n' = if n `elem` ns then dec n else n in
1349 PClause fc n' (expandParams dec ps'' ns lhs)
1350 (map (expandParams dec ps'' ns) ws)
1351 (expandParams dec ps'' ns rhs)
1352 (map (expandParamsD ist dec ps'' ns) ds)
1353 expandParamsC (PWith fc n lhs ws wval ds)
1354 = let -- ps' = updateps True (namesIn ist wval) (zip ps [0..])
1355 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
1356 n' = if n `elem` ns then dec n else n in
1357 PWith fc n' (expandParams dec ps'' ns lhs)
1358 (map (expandParams dec ps'' ns) ws)
1359 (expandParams dec ps'' ns wval)
1360 (map (expandParamsD ist dec ps'' ns) ds)
1361 updateps yn nm [] = []
1362 updateps yn nm (((a, t), i):as)
1363 | (a `elem` nm) == yn = (a, t) : updateps yn nm as
1364 | otherwise = (MN i (show n ++ "_u"), t) : updateps yn nm as
1366expandParamsD ist dec ps ns d = d
1368-- Calculate a priority for a type, for deciding elaboration order
1369-- * if it's just a type variable or concrete type, do it early (0)
1370-- * if there's only type variables and injective constructors, do it next (1)
1371-- * if there's a function type, next (2)
1372-- * finally, everything else (3)
1374getPriority :: IState -> PTerm -> Int
1375getPriority i tm = pri tm
1378 case lookupP Nothing n (tt_ctxt i) of
1379 ((P (DCon _ _) _ _):_) -> 1
1380 ((P (TCon _ _) _ _):_) -> 1
1381 ((P Ref _ _):_) -> 4
1382 [] -> 0 -- must be locally bound, if it's not an error...
1383 pri (PPi _ _ x y) = max 5 (max (pri x) (pri y))
1387 pri (PEq _ l r) = max 1 (max (pri l) (pri r))
1388 pri (PApp _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.getTm) as)))
1389 pri (PCase _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.snd) as)))
1390 pri (PTyped l r) = pri l
1391 pri (PPair _ l r) = max 1 (max (pri l) (pri r))
1392 pri (PDPair _ l t r) = max 1 (max (pri l) (max (pri t) (pri r)))
1393 pri (PAlternative a as) = maximum (map pri as)
1394 pri (PConstant _) = 0
1398addStatics :: Name -> Term -> PTerm -> Idris ()
1399addStatics n tm ptm =
1400 do let (statics, dynamics) = initStatics tm ptm
1401 let stnames = nub $ concatMap freeNames (map snd statics)
1402 let dnames = nub $ concatMap freeNames (map snd dynamics)
1403 when (not (null statics)) $
1404 logLvl 7 $ show n ++ " " ++ show statics ++ "\n" ++ show dynamics
1405 ++ "\n" ++ show stnames ++ "\n" ++ show dnames
1406 let statics' = nub $ map fst statics ++
1407 filter (\x -> not (elem x dnames)) stnames
1408 let stpos = staticList statics' tm
1410 put (i { idris_statics = addDef n stpos (idris_statics i) })
1411 addIBC (IBCStatic n)
1413 initStatics (Bind n (Pi ty) sc) (PPi p _ _ s)
1414 = let (static, dynamic) = initStatics (instantiate (P Bound n ty) sc) s in
1415 if pstatic p == Static then ((n, ty) : static, dynamic)
1416 else (static, (n, ty) : dynamic)
1417 initStatics t pt = ([], [])
1419 staticList sts (Bind n (Pi _) sc) = (n `elem` sts) : staticList sts sc
1422-- Dealing with implicit arguments
1424-- Add implicit Pi bindings for any names in the term which appear in an
1425-- argument position.
1427-- This has become a right mess already. Better redo it some time...
1429implicit :: SyntaxInfo -> Name -> PTerm -> Idris PTerm
1432 let (tm', impdata) = implicitise syn i ptm
1433-- let (tm'', spos) = findStatics i tm'
1434 put (i { idris_implicits = addDef n impdata (idris_implicits i) })
1436 logLvl 5 ("Implicit " ++ show n ++ " " ++ show impdata)
1438-- put (i { idris_statics = addDef n spos (idris_statics i) })
1441implicitise :: SyntaxInfo -> IState -> PTerm -> (PTerm, [PArg])
1442implicitise syn ist tm
1443 = let (declimps, ns') = execState (imps True [] tm) ([], [])
1444 ns = ns' \\ (map fst pvars ++ no_imp syn) in
1446 then (tm, reverse declimps)
1447 else implicitise syn ist (pibind uvars ns tm)
1450 pvars = syn_params syn
1452 dropAll (x:xs) ys | x `elem` ys = dropAll xs ys
1453 | otherwise = x : dropAll xs ys
1456 imps top env (PApp _ f as)
1457 = do (decls, ns) <- get
1458 let isn = concatMap (namesIn uvars ist) (map getTm as)
1459 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1460 imps top env (PPi (Imp l _) n ty sc)
1461 = do let isn = nub (namesIn uvars ist ty) `dropAll` [n]
1463 put (PImp (getPriority ist ty) l n ty : decls,
1464 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1465 imps True (n:env) sc
1466 imps top env (PPi (Exp l _) n ty sc)
1467 = do let isn = nub (namesIn uvars ist ty ++ case sc of
1468 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
1470 (decls, ns) <- get -- ignore decls in HO types
1471 put (PExp (getPriority ist ty) l ty : decls,
1472 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1473 imps True (n:env) sc
1474 imps top env (PPi (Constraint l _) n ty sc)
1475 = do let isn = nub (namesIn uvars ist ty ++ case sc of
1476 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
1478 (decls, ns) <- get -- ignore decls in HO types
1479 put (PConstraint 10 l ty : decls,
1480 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1481 imps True (n:env) sc
1482 imps top env (PPi (TacImp l _ scr) n ty sc)
1483 = do let isn = nub (namesIn uvars ist ty ++ case sc of
1484 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
1486 (decls, ns) <- get -- ignore decls in HO types
1487 put (PTacImplicit 10 l n scr ty : decls,
1488 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1489 imps True (n:env) sc
1490 imps top env (PEq _ l r)
1491 = do (decls, ns) <- get
1492 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1493 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1494 imps top env (PTyped l r)
1496 imps top env (PPair _ l r)
1497 = do (decls, ns) <- get
1498 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1499 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1500 imps top env (PDPair _ (PRef _ n) t r)
1501 = do (decls, ns) <- get
1502 let isn = nub (namesIn uvars ist t ++ namesIn uvars ist r) \\ [n]
1503 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
1504 imps top env (PDPair _ l t r)
1505 = do (decls, ns) <- get
1506 let isn = namesIn uvars ist l ++ namesIn uvars ist t ++
1508 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
1509 imps top env (PAlternative a as)
1510 = do (decls, ns) <- get
1511 let isn = concatMap (namesIn uvars ist) as
1512 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1513 imps top env (PLam n ty sc)
1514 = do imps False env ty
1515 imps False (n:env) sc
1516 imps top env (PHidden tm) = imps False env tm
1517 imps top env _ = return ()
1519 pibind using [] sc = sc
1520 pibind using (n:ns) sc
1521 = case lookup n using of
1522 Just ty -> PPi (Imp False Dynamic) n ty (pibind using ns sc)
1523 Nothing -> PPi (Imp False Dynamic) n Placeholder (pibind using ns sc)
1525-- Add implicit arguments in function calls
1526addImplPat :: IState -> PTerm -> PTerm
1527addImplPat = addImpl' True []
1529addImplBound :: IState -> [Name] -> PTerm -> PTerm
1530addImplBound ist ns = addImpl' False ns ist
1532addImpl :: IState -> PTerm -> PTerm
1533addImpl = addImpl' False []
1535-- TODO: in patterns, don't add implicits to function names guarded by constructors
1536-- and *not* inside a PHidden
1538addImpl' :: Bool -> [Name] -> IState -> PTerm -> PTerm
1539addImpl' inpat env ist ptm = ai env ptm
1542 | not (f `elem` env) = handleErr $ aiFn inpat ist fc f []
1543 ai env (PHidden (PRef fc f))
1544 | not (f `elem` env) = handleErr $ aiFn False ist fc f []
1545 ai env (PEq fc l r) = let l' = ai env l
1548 ai env (PTyped l r) = let l' = ai env l
1551 ai env (PPair fc l r) = let l' = ai env l
1554 ai env (PDPair fc l t r) = let l' = ai env l
1558 ai env (PAlternative a as) = let as' = map (ai env) as in
1560 ai env (PApp fc (PRef _ f) as)
1561 | not (f `elem` env)
1562 = let as' = map (fmap (ai env)) as in
1563 handleErr $ aiFn False ist fc f as'
1564 ai env (PApp fc f as) = let f' = ai env f
1565 as' = map (fmap (ai env)) as in
1567 ai env (PCase fc c os) = let c' = ai env c
1568 os' = map (pmap (ai env)) os in
1570 ai env (PLam n ty sc) = let ty' = ai env ty
1571 sc' = ai (n:env) sc in
1573 ai env (PLet n ty val sc)
1574 = let ty' = ai env ty
1576 sc' = ai (n:env) sc in
1578 ai env (PPi p n ty sc) = let ty' = ai env ty
1579 sc' = ai (n:env) sc in
1581 ai env (PHidden tm) = PHidden (ai env tm)
1582 ai env (PProof ts) = PProof (map (fmap (ai env)) ts)
1583 ai env (PTactics ts) = PTactics (map (fmap (ai env)) ts)
1586 handleErr (Left err) = PElabError err
1587 handleErr (Right x) = x
1589-- if in a pattern, and there are no arguments, and there's no possible
1590-- names with zero explicit arguments, don't add implicits.
1592aiFn :: Bool -> IState -> FC -> Name -> [PArg] -> Either Err PTerm
1593aiFn True ist fc f []
1594 = case lookupCtxt Nothing f (idris_implicits ist) of
1595 [] -> Right $ PRef fc f
1596 alts -> if (any (all imp) alts)
1597 then aiFn False ist fc f [] -- use it as a constructor
1598 else Right $ PRef fc f
1599 where imp (PExp _ _ _) = False
1601aiFn inpat ist fc f as
1602 | f `elem` primNames = Right $ PApp fc (PRef fc f) as
1603aiFn inpat ist fc f as
1604 -- This is where namespaces get resolved by adding PAlternative
1605 = case lookupCtxtName Nothing f (idris_implicits ist) of
1606 [(f',ns)] -> Right $ mkPApp fc (length ns) (PRef fc f') (insertImpl ns as)
1607 [] -> if f `elem` idris_metavars ist
1608 then Right $ PApp fc (PRef fc f) as
1609 else Right $ mkPApp fc (length as) (PRef fc f) as
1612 map (\(f', ns) -> mkPApp fc (length ns) (PRef fc f')
1613 (insertImpl ns as)) alts
1615 insertImpl :: [PArg] -> [PArg] -> [PArg]
1616 insertImpl (PExp p l ty : ps) (PExp _ _ tm : given) =
1617 PExp p l tm : insertImpl ps given
1618 insertImpl (PConstraint p l ty : ps) (PConstraint _ _ tm : given) =
1619 PConstraint p l tm : insertImpl ps given
1620 insertImpl (PConstraint p l ty : ps) given =
1621 PConstraint p l (PResolveTC fc) : insertImpl ps given
1622 insertImpl (PImp p l n ty : ps) given =
1623 case find n given [] of
1624 Just (tm, given') -> PImp p l n tm : insertImpl ps given'
1625 Nothing -> PImp p l n Placeholder : insertImpl ps given
1626 insertImpl (PTacImplicit p l n sc ty : ps) given =
1627 case find n given [] of
1628 Just (tm, given') -> PTacImplicit p l n sc tm : insertImpl ps given'
1629 Nothing -> PTacImplicit p l n sc sc
1630 : insertImpl ps given
1631 insertImpl expected [] = []
1632 insertImpl _ given = given
1634 find n [] acc = Nothing
1635 find n (PImp _ _ n' t : gs) acc
1636 | n == n' = Just (t, reverse acc ++ gs)
1637 find n (g : gs) acc = find n gs (g : acc)
1640mkPApp fc a f as = let rest = drop a as in
1641 appRest fc (PApp fc f (take a as)) rest
1644 appRest fc f (a : as) = appRest fc (PApp fc f [a]) as
1646-- Find 'static' argument positions
1647-- (the declared ones, plus any names in argument position in the declared
1649-- FIXME: It's possible that this really has to happen after elaboration
1651findStatics :: IState -> PTerm -> (PTerm, [Bool])
1652findStatics ist tm = trace (showImp True tm) $
1653 let (ns, ss) = fs tm in
1654 runState (pos ns ss tm) []
1655 where fs (PPi p n t sc)
1656 | Static <- pstatic p
1657 = let (ns, ss) = fs sc in
1658 (namesIn [] ist t : ns, n : ss)
1659 | otherwise = let (ns, ss) = fs sc in
1663 inOne n ns = length (filter id (map (elem n) ns)) == 1
1665 pos ns ss (PPi p n t sc)
1666 | elem n ss = do sc' <- pos ns ss sc
1669 return (PPi (p { pstatic = Static }) n t sc')
1670 | otherwise = do sc' <- pos ns ss sc
1673 return (PPi p n t sc')
1674 pos ns ss t = return t
1676-- Debugging/logging stuff
1678dumpDecls :: [PDecl] -> String
1680dumpDecls (d:ds) = dumpDecl d ++ "\n" ++ dumpDecls ds
1682dumpDecl (PFix _ f ops) = show f ++ " " ++ showSep ", " ops
1683dumpDecl (PTy _ _ _ n t) = "tydecl " ++ show n ++ " : " ++ showImp True t
1684dumpDecl (PClauses _ _ n cs) = "pat " ++ show n ++ "\t" ++ showSep "\n\t" (map (showCImp True) cs)
1685dumpDecl (PData _ _ d) = showDImp True d
1686dumpDecl (PParams _ ns ps) = "params {" ++ show ns ++ "\n" ++ dumpDecls ps ++ "}\n"
1687dumpDecl (PNamespace n ps) = "namespace {" ++ n ++ "\n" ++ dumpDecls ps ++ "}\n"
1688dumpDecl (PSyntax _ syn) = "syntax " ++ show syn
1689dumpDecl (PClass _ _ cs n ps ds)
1690 = "class " ++ show cs ++ " " ++ show n ++ " " ++ show ps ++ "\n" ++ dumpDecls ds
1691dumpDecl (PInstance _ _ cs n _ t ds)
1692 = "instance " ++ show cs ++ " " ++ show n ++ " " ++ show t ++ "\n" ++ dumpDecls ds
1694-- dumpDecl (PImport i) = "import " ++ i
1696-- for 6.12/7 compatibility
1697data EitherErr a b = LeftErr a | RightOK b
1699instance Monad (EitherErr a) where
1702 (LeftErr e) >>= k = LeftErr e
1703 RightOK v >>= k = k v
1705toEither (LeftErr e) = Left e
1706toEither (RightOK ho) = Right ho
1708-- syntactic match of a against b, returning pair of variables in a
1709-- and what they match. Returns the pair that failed if not a match.
1711matchClause :: IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
1712matchClause = matchClause' False
1714matchClause' :: Bool -> IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
1715matchClause' names i x y = checkRpts $ match (fullApp x) (fullApp y) where
1716 matchArg x y = match (fullApp (getTm x)) (fullApp (getTm y))
1718 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
1721 match' x y = match (fullApp x) (fullApp y)
1722 match (PApp _ (PRef _ (NS (UN "fromInteger") ["builtins"])) [_,_,x]) x'
1723 | PConstant (I _) <- getTm x = match (getTm x) x'
1724 match x' (PApp _ (PRef _ (NS (UN "fromInteger") ["builtins"])) [_,_,x])
1725 | PConstant (I _) <- getTm x = match (getTm x) x'
1726 match (PApp _ (PRef _ (UN "lazy")) [_,x]) x' = match (getTm x) x'
1727 match x (PApp _ (PRef _ (UN "lazy")) [_,x']) = match x (getTm x')
1728 match (PApp _ f args) (PApp _ f' args')
1729 | length args == length args'
1730 = do mf <- match' f f'
1731 ms <- zipWithM matchArg args args'
1732 return (mf ++ concat ms)
1733-- match (PRef _ n) (PRef _ n') | n == n' = return []
1734-- | otherwise = Nothing
1735 match (PRef f n) (PApp _ x []) = match (PRef f n) x
1736 match (PApp _ x []) (PRef f n) = match x (PRef f n)
1737 match (PRef _ n) (PRef _ n') | n == n' = return []
1739 | not names && (not (isConName Nothing n (tt_ctxt i)) || tm == Placeholder)
1741 match (PEq _ l r) (PEq _ l' r') = do ml <- match' l l'
1744 match (PTyped l r) (PTyped l' r') = do ml <- match l l'
1747 match (PTyped l r) x = match l x
1748 match x (PTyped l r) = match x l
1749 match (PPair _ l r) (PPair _ l' r') = do ml <- match' l l'
1752 match (PDPair _ l t r) (PDPair _ l' t' r') = do ml <- match' l l'
1755 return (ml ++ mt ++ mr)
1756 match (PAlternative a as) (PAlternative a' as')
1757 = do ms <- zipWithM match' as as'
1759 match a@(PAlternative _ as) b
1760 = do let ms = zipWith match' as (repeat b)
1761 case (rights (map toEither ms)) of
1764 match (PCase _ _ _) _ = return [] -- lifted out
1765 match (PMetavar _) _ = return [] -- modified
1766 match (PQuote _) _ = return []
1767 match (PProof _) _ = return []
1768 match (PTactics _) _ = return []
1769 match (PRefl _) (PRefl _) = return []
1770 match (PResolveTC _) (PResolveTC _) = return []
1771 match (PTrue _) (PTrue _) = return []
1772 match (PFalse _) (PFalse _) = return []
1773 match (PReturn _) (PReturn _) = return []
1774 match (PPi _ _ t s) (PPi _ _ t' s') = do mt <- match' t t'
1777 match (PLam _ t s) (PLam _ t' s') = do mt <- match' t t'
1780 match (PLet _ t ty s) (PLet _ t' ty' s') = do mt <- match' t t'
1781 mty <- match' ty ty'
1783 return (mt ++ mty ++ ms)
1784 match (PHidden x) (PHidden y) = match' x y
1785 match Placeholder _ = return []
1786-- match _ Placeholder = return []
1787 match (PResolveTC _) _ = return []
1788 match a b | a == b = return []
1789 | otherwise = LeftErr (a, b)
1791 checkRpts (RightOK ms) = check ms where
1793 | Just t' <- lookup n xs = if t/=t' && t/=Placeholder && t'/=Placeholder
1796 check (_:xs) = check xs
1798 checkRpts (LeftErr x) = Left x
1800substMatches :: [(Name, PTerm)] -> PTerm -> PTerm
1801substMatches [] t = t
1802substMatches ((n,tm):ns) t = substMatch n tm (substMatches ns t)
1804substMatch :: Name -> PTerm -> PTerm -> PTerm
1805substMatch n tm t = sm t where
1806 sm (PRef _ n') | n == n' = tm
1807 sm (PLam x t sc) = PLam x (sm t) (sm sc)
1808 sm (PPi p x t sc) = PPi p x (sm t) (sm sc)
1809 sm (PApp f x as) = PApp f (sm x) (map (fmap sm) as)
1810 sm (PCase f x as) = PCase f (sm x) (map (pmap sm) as)
1811 sm (PEq f x y) = PEq f (sm x) (sm y)
1812 sm (PTyped x y) = PTyped (sm x) (sm y)
1813 sm (PPair f x y) = PPair f (sm x) (sm y)
1814 sm (PDPair f x t y) = PDPair f (sm x) (sm t) (sm y)
1815 sm (PAlternative a as) = PAlternative a (map sm as)
1816 sm (PHidden x) = PHidden (sm x)
1819shadow :: Name -> Name -> PTerm -> PTerm
1820shadow n n' t = sm t where
1821 sm (PRef fc x) | n == x = PRef fc n'
1822 sm (PLam x t sc) = PLam x (sm t) (sm sc)
1823 sm (PPi p x t sc) = PPi p x (sm t) (sm sc)
1824 sm (PApp f x as) = PApp f (sm x) (map (fmap sm) as)
1825 sm (PCase f x as) = PCase f (sm x) (map (pmap sm) as)
1826 sm (PEq f x y) = PEq f (sm x) (sm y)
1827 sm (PTyped x y) = PTyped (sm x) (sm y)
1828 sm (PPair f x y) = PPair f (sm x) (sm y)
1829 sm (PDPair f x t y) = PDPair f (sm x) (sm t) (sm y)
1830 sm (PAlternative a as) = PAlternative a (map sm as)
1831 sm (PHidden x) = PHidden (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