1{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, DeriveFunctor,
2 TypeSynonymInstances, PatternGuards #-}
4module Idris.AbsSyntax where
8import Core.Elaborate hiding (Tactic(..))
11import System.Console.Haskeline
13import Control.Monad.State
21import qualified Epic.Epic as E
25data IOption = IOption { opt_logLevel :: Int,
27 opt_typeintype :: Bool,
35defaultOpts = IOption 0 False False True False True True
37-- TODO: Add 'module data' to IState, which can be saved out and reloaded quickly (i.e
38-- without typechecking).
39-- This will include all the functions and data declarations, plus fixity declarations
42data IState = IState { tt_ctxt :: Context,
43 idris_constraints :: [(UConstraint, FC)],
44 idris_infixes :: [FixDecl],
45 idris_implicits :: Ctxt [PArg],
46 idris_statics :: Ctxt [Bool],
47 idris_classes :: Ctxt ClassInfo,
48 idris_dsls :: Ctxt DSL,
49 idris_optimisation :: Ctxt OptInfo,
50 idris_datatypes :: Ctxt TypeInfo,
51 idris_patdefs :: Ctxt [(Term, Term)], -- not exported
52 idris_flags :: Ctxt [FnOpt],
53 idris_callgraph :: Ctxt [Name],
54 idris_totcheck :: [(FC, Name)],
56 idris_options :: IOption,
58 idris_metavars :: [Name],
59 syntax_rules :: [Syntax],
60 syntax_keywords :: [String],
61 imported :: [FilePath],
62 idris_prims :: [(Name, ([E.Name], E.Term))],
63 idris_objs :: [FilePath],
64 idris_libs :: [String],
65 idris_hdrs :: [String],
66 last_proof :: Maybe (Name, [String]),
68 lastParse :: Maybe Name,
69 indent_stack :: [Int],
70 brace_stack :: [Maybe Int],
71 hide_list :: [(Name, Maybe Accessibility)],
72 default_access :: Accessibility,
73 ibc_write :: [IBCWrite],
74 compiled_so :: Maybe String
77-- information that needs writing for the current module's .ibc file
78data IBCWrite = IBCFix FixDecl
82 | IBCInstance Bool Name Name
92 | IBCAccess Name Accessibility
93 | IBCTotal Name Totality
94 | IBCFlags Name [FnOpt]
96 | IBCDef Name -- i.e. main context
99idrisInit = IState initContext [] [] emptyContext emptyContext emptyContext
100 emptyContext emptyContext emptyContext emptyContext
101 emptyContext emptyContext
102 [] "" defaultOpts 6 [] [] [] [] [] [] [] []
103 Nothing Nothing Nothing [] [] [] Hidden [] Nothing
105-- The monad for the main REPL - reading and processing files and updating
106-- global state (hence the IO inner monad).
107type Idris = StateT IState (InputT IO)
109getContext :: Idris Context
110getContext = do i <- get; return (tt_ctxt i)
112getObjectFiles :: Idris [FilePath]
113getObjectFiles = do i <- get; return (idris_objs i)
115addObjectFile :: FilePath -> Idris ()
116addObjectFile f = do i <- get; put (i { idris_objs = f : idris_objs i })
118getLibs :: Idris [String]
119getLibs = do i <- get; return (idris_libs i)
121addLib :: String -> Idris ()
122addLib f = do i <- get; put (i { idris_libs = f : idris_libs i })
124addHdr :: String -> Idris ()
125addHdr f = do i <- get; put (i { idris_hdrs = f : idris_hdrs i })
127totcheck :: (FC, Name) -> Idris ()
128totcheck n = do i <- get; put (i { idris_totcheck = n : idris_totcheck i })
130setFlags :: Name -> [FnOpt] -> Idris ()
131setFlags n fs = do i <- get; put (i { idris_flags = addDef n fs (idris_flags i) })
133setAccessibility :: Name -> Accessibility -> Idris ()
136 let ctxt = setAccess n a (tt_ctxt i)
137 put (i { tt_ctxt = ctxt })
139setTotality :: Name -> Totality -> Idris ()
142 let ctxt = setTotal n a (tt_ctxt i)
143 put (i { tt_ctxt = ctxt })
145getTotality :: Name -> Idris Totality
148 case lookupTotal n (tt_ctxt i) of
150 _ -> return (Total [])
152addToCG :: Name -> [Name] -> Idris ()
153addToCG n ns = do i <- get
154 put (i { idris_callgraph = addDef n ns (idris_callgraph i) })
156-- Add a class instance function. Dodgy hack: Put integer instances first in the
157-- list so they are resolved by default.
159addInstance :: Bool -> Name -> Name -> Idris ()
162 case lookupCtxt Nothing n (idris_classes ist) of
164 do let cs = addDef n (CI a b c d (addI i ins)) (idris_classes ist)
165 put (ist { idris_classes = cs })
166 _ -> do let cs = addDef n (CI (MN 0 "none") [] [] [] [i]) (idris_classes ist)
167 put (ist { idris_classes = cs })
168 where addI i ins | int = i : ins
169 | otherwise = ins ++ [i]
171addClass :: Name -> ClassInfo -> Idris ()
174 let i' = case lookupCtxt Nothing n (idris_classes ist) of
175 [c] -> c { class_instances = class_instances i }
177 put (ist { idris_classes = addDef n i' (idris_classes ist) })
179addIBC :: IBCWrite -> Idris ()
182 when (notDef (ibc_write i)) $
183 put (i { ibc_write = ibc : ibc_write i })
184 where notDef [] = True
185 notDef (IBCDef n': is) | n == n' = False
186 notDef (_ : is) = notDef is
187addIBC ibc = do i <- get; put (i { ibc_write = ibc : ibc_write i })
190clearIBC = do i <- get; put (i { ibc_write = [] })
192getHdrs :: Idris [String]
193getHdrs = do i <- get; return (idris_hdrs i)
195setErrLine :: Int -> Idris ()
196setErrLine x = do i <- get;
198 Nothing -> put (i { errLine = Just x })
202clearErr = do i <- get
203 put (i { errLine = Nothing })
205getSO :: Idris (Maybe String)
207 return (compiled_so i)
209setSO :: Maybe String -> Idris ()
211 put (i { compiled_so = s })
213getIState :: Idris IState
216putIState :: IState -> Idris ()
220getName = do i <- get;
221 let idx = idris_name i;
222 put (i { idris_name = idx + 1 })
225checkUndefined :: FC -> Name -> Idris ()
228 case lookupTy Nothing n i of
229 (_:_) -> fail $ show fc ++ ":" ++
230 show n ++ " already defined"
233setContext :: Context -> Idris ()
234setContext ctxt = do i <- get; put (i { tt_ctxt = ctxt } )
236updateContext :: (Context -> Context) -> Idris ()
237updateContext f = do i <- get; put (i { tt_ctxt = f (tt_ctxt i) } )
239addConstraints :: FC -> (Int, [UConstraint]) -> Idris ()
240addConstraints fc (v, cs)
243 let ctxt' = ctxt { uconstraints = cs ++ uconstraints ctxt,
245 let ics = zip cs (repeat fc) ++ idris_constraints i
246 put (i { tt_ctxt = ctxt', idris_constraints = ics })
248addDeferred :: [(Name, Type)] -> Idris ()
249addDeferred ns = do mapM_ (\(n, t) -> updateContext (addTyDecl n (tidyNames [] t))) ns
251 put (i { idris_metavars = map fst ns ++ idris_metavars i })
252 where tidyNames used (Bind (MN i x) b sc)
253 = let n' = uniqueName (UN x) used in
254 Bind n' b $ tidyNames (n':used) sc
255 tidyNames used (Bind n b sc)
256 = let n' = uniqueName n used in
257 Bind n' b $ tidyNames (n':used) sc
260solveDeferred :: Name -> Idris ()
261solveDeferred n = do i <- get
262 put (i { idris_metavars = idris_metavars i \\ [n] })
264iputStrLn :: String -> Idris ()
265iputStrLn = liftIO . putStrLn
267iWarn :: FC -> String -> Idris ()
268iWarn fc err = liftIO $ putStrLn (show fc ++ ":" ++ err)
270setLogLevel :: Int -> Idris ()
271setLogLevel l = do i <- get
272 let opts = idris_options i
273 let opt' = opts { opt_logLevel = l }
274 put (i { idris_options = opt' } )
277logLevel = do i <- get
278 return (opt_logLevel (idris_options i))
282 return (opt_repl (idris_options i))
284setREPL :: Bool -> Idris ()
285setREPL t = do i <- get
286 let opts = idris_options i
287 let opt' = opts { opt_repl = t }
288 put (i { idris_options = opt' })
292 return (opt_verbose (idris_options i))
294setVerbose :: Bool -> Idris ()
295setVerbose t = do i <- get
296 let opts = idris_options i
297 let opt' = opts { opt_verbose = t }
298 put (i { idris_options = opt' })
300typeInType :: Idris Bool
301typeInType = do i <- get
302 return (opt_typeintype (idris_options i))
304setTypeInType :: Bool -> Idris ()
305setTypeInType t = do i <- get
306 let opts = idris_options i
307 let opt' = opts { opt_typeintype = t }
308 put (i { idris_options = opt' })
310coverage :: Idris Bool
311coverage = do i <- get
312 return (opt_coverage (idris_options i))
314setCoverage :: Bool -> Idris ()
315setCoverage t = do i <- get
316 let opts = idris_options i
317 let opt' = opts { opt_coverage = t }
318 put (i { idris_options = opt' })
322 return (opt_showimp (idris_options i))
324setImpShow :: Bool -> Idris ()
325setImpShow t = do i <- get
326 let opts = idris_options i
327 let opt' = opts { opt_showimp = t }
328 put (i { idris_options = opt' })
330logLvl :: Int -> String -> Idris ()
331logLvl l str = do i <- get
332 let lvl = opt_logLevel (idris_options i)
334 $ do liftIO (putStrLn str)
335 put (i { idris_log = idris_log i ++ str ++ "\n" } )
337iLOG :: String -> Idris ()
340noErrors :: Idris Bool
341noErrors = do i <- get
343 Nothing -> return True
346setTypeCase :: Bool -> Idris ()
347setTypeCase t = do i <- get
348 let opts = idris_options i
349 let opt' = opts { opt_typecase = t }
350 put (i { idris_options = opt' })
352-- Commands in the REPL
354data Command = Quit | Help | Eval PTerm | Check PTerm | TotCheck Name
356 | Compile String | Execute | ExecVal PTerm
357 | Metavars | Prove Name | AddProof | Universes
359 | LogLvl Int | Spec PTerm | HNF PTerm | Defn Name | Info Name
362-- Parsed declarations
364data Fixity = Infixl { prec :: Int }
365 | Infixr { prec :: Int }
366 | InfixN { prec :: Int }
367 | PrefixN { prec :: Int }
370deriving instance Binary Fixity
373instance Show Fixity where
374 show (Infixl i) = "infixl " ++ show i
375 show (Infixr i) = "infixr " ++ show i
376 show (InfixN i) = "infix " ++ show i
377 show (PrefixN i) = "prefix " ++ show i
379data FixDecl = Fix Fixity String
382deriving instance Binary FixDecl
385instance Ord FixDecl where
386 compare (Fix x _) (Fix y _) = compare (prec x) (prec y)
389data Static = Static | Dynamic
392deriving instance Binary Static
395-- Mark bindings with their explicitness, and laziness
396data Plicity = Imp { plazy :: Bool,
398 | Exp { plazy :: Bool,
400 | Constraint { plazy :: Bool,
402 | TacImp { plazy :: Bool,
408deriving instance Binary Plicity
411impl = Imp False Dynamic
412expl = Exp False Dynamic
413constraint = Constraint False Dynamic
414tacimpl = TacImp False Dynamic
416data FnOpt = Inlinable | TotalFn | AssertTotal | TCGen
417 | Specialise [Name] -- specialise it, freeze these names
420deriving instance Binary FnOpt
425inlinable :: FnOpts -> Bool
426inlinable = elem Inlinable
428data PDecl' t = PFix FC Fixity [String] -- fixity declaration
429 | PTy SyntaxInfo FC FnOpts Name t -- type declaration
430 | PClauses FC FnOpts Name [PClause' t] -- pattern clause
431 | PData SyntaxInfo FC (PData' t) -- data declaration
432 | PParams FC [(Name, t)] [PDecl' t] -- params block
433 | PNamespace String [PDecl' t] -- new namespace
434 | PRecord SyntaxInfo FC Name t Name t -- record declaration
435 | PClass SyntaxInfo FC
438 [(Name, t)] -- parameters
439 [PDecl' t] -- declarations
440 | PInstance SyntaxInfo FC [t] -- constraints
443 t -- full instance type
447 | PDirective (Idris ())
450data PClause' t = PClause FC Name t [t] t [PDecl' t]
451 | PWith FC Name t [t] t [PDecl' t]
452 | PClauseR FC [t] t [PDecl' t]
453 | PWithR FC [t] t [PDecl' t]
456data PData' t = PDatadecl { d_name :: Name,
458 d_cons :: [(Name, t, FC)] }
461-- Handy to get a free function for applying PTerm -> PTerm functions
462-- across a program, by deriving Functor
464type PDecl = PDecl' PTerm
465type PData = PData' PTerm
466type PClause = PClause' PTerm
468-- get all the names declared in a decl
470declared :: PDecl -> [Name]
471declared (PFix _ _ _) = []
472declared (PTy _ _ _ n t) = [n]
473declared (PClauses _ _ n _) = [] -- not a declaration
474declared (PData _ _ (PDatadecl n _ ts)) = n : map fstt ts
475 where fstt (a, _, _) = a
476declared (PParams _ _ ds) = concatMap declared ds
477declared (PNamespace _ ds) = concatMap declared ds
478-- declared (PImport _) = []
480defined :: PDecl -> [Name]
481defined (PFix _ _ _) = []
482defined (PTy _ _ _ n t) = []
483defined (PClauses _ _ n _) = [n] -- not a declaration
484defined (PData _ _ (PDatadecl n _ ts)) = n : map fstt ts
485 where fstt (a, _, _) = a
486defined (PParams _ _ ds) = concatMap defined ds
487defined (PNamespace _ ds) = concatMap defined ds
488-- declared (PImport _) = []
490updateN :: [(Name, Name)] -> Name -> Name
491updateN ns n | Just n' <- lookup n ns = n'
494updateNs :: [(Name, Name)] -> PTerm -> PTerm
496updateNs ns t = mapPT updateRef t
497 where updateRef (PRef fc f) = PRef fc (updateN ns f)
500-- updateDNs :: [(Name, Name)] -> PDecl -> PDecl
502-- updateDNs ns (PTy s f n t) | Just n' <- lookup n ns = PTy s f n' t
503-- updateDNs ns (PClauses f n c) | Just n' <- lookup n ns = PClauses f n' (map updateCNs c)
504-- where updateCNs ns (PClause n l ts r ds)
505-- = PClause (updateN ns n) (fmap (updateNs ns) l)
506-- (map (fmap (updateNs ns)) ts)
507-- (fmap (updateNs ns) r)
508-- (map (updateDNs ns) ds)
511-- High level language terms
513data PTerm = PQuote Raw
515 | PLam Name PTerm PTerm
516 | PPi Plicity Name PTerm PTerm
517 | PLet Name PTerm PTerm PTerm
518 | PTyped PTerm PTerm -- term with explicit type
519 | PApp FC PTerm [PArg]
520 | PCase FC PTerm [(PTerm, PTerm)]
526 | PPair FC PTerm PTerm
527 | PDPair FC PTerm PTerm PTerm
528 | PAlternative [PTerm]
529 | PHidden PTerm -- irrelevant or hidden pattern
538 | PTactics [PTactic] -- as PProof, but no auto solving
539 | PElabError Err -- error to report on elaboration
540 | PImpossible -- special case for declaring when an LHS can't typecheck
543deriving instance Binary PTerm
546mapPT :: (PTerm -> PTerm) -> PTerm -> PTerm
547mapPT f t = f (mpt t) where
548 mpt (PLam n t s) = PLam n (mapPT f t) (mapPT f s)
549 mpt (PPi p n t s) = PPi p n (mapPT f t) (mapPT f s)
550 mpt (PLet n ty v s) = PLet n (mapPT f ty) (mapPT f v) (mapPT f s)
551 mpt (PApp fc t as) = PApp fc (mapPT f t) (map (fmap (mapPT f)) as)
552 mpt (PCase fc c os) = PCase fc (mapPT f c) (map (pmap (mapPT f)) os)
553 mpt (PEq fc l r) = PEq fc (mapPT f l) (mapPT f r)
554 mpt (PTyped l r) = PTyped (mapPT f l) (mapPT f r)
555 mpt (PPair fc l r) = PPair fc (mapPT f l) (mapPT f r)
556 mpt (PDPair fc l t r) = PDPair fc (mapPT f l) (mapPT f t) (mapPT f r)
557 mpt (PAlternative as) = PAlternative (map (mapPT f) as)
558 mpt (PHidden t) = PHidden (mapPT f t)
559 mpt (PDoBlock ds) = PDoBlock (map (fmap (mapPT f)) ds)
560 mpt (PProof ts) = PProof (map (fmap (mapPT f)) ts)
561 mpt (PTactics ts) = PTactics (map (fmap (mapPT f)) ts)
565data PTactic' t = Intro [Name] | Intros | Focus Name
566 | Refine Name [Bool] | Rewrite t | LetTac Name t
567 | Exact t | Compute | Trivial
570 | ProofState | ProofTerm | Undo
571 | Try (PTactic' t) (PTactic' t)
572 | TSeq (PTactic' t) (PTactic' t)
574 deriving (Show, Eq, Functor)
576deriving instance Binary PTactic'
579instance Sized a => Sized (PTactic' a) where
580 size (Intro nms) = 1 + size nms
582 size (Focus nm) = 1 + size nm
583 size (Refine nm bs) = 1 + size nm + length bs
584 size (Rewrite t) = 1 + size t
585 size (LetTac nm t) = 1 + size nm + size t
586 size (Exact t) = 1 + size t
594 size (Try l r) = 1 + size l + size r
595 size (TSeq l r) = 1 + size l + size r
599type PTactic = PTactic' PTerm
601data PDo' t = DoExp FC t
606 deriving (Eq, Functor)
608deriving instance Binary PDo'
611instance Sized a => Sized (PDo' a) where
612 size (DoExp fc t) = 1 + size fc + size t
613 size (DoBind fc nm t) = 1 + size fc + size nm + size t
614 size (DoBindP fc l r) = 1 + size fc + size l + size r
615 size (DoLet fc nm l r) = 1 + size fc + size nm + size l + size r
616 size (DoLetP fc l r) = 1 + size fc + size l + size r
620-- The priority gives a hint as to elaboration order. Best to elaborate
621-- things early which will help give a more concrete type to other
622-- variables, e.g. a before (interpTy a).
624data PArg' t = PImp { priority :: Int,
625 lazyarg :: Bool, pname :: Name, getTm :: t }
626 | PExp { priority :: Int,
627 lazyarg :: Bool, getTm :: t }
628 | PConstraint { priority :: Int,
629 lazyarg :: Bool, getTm :: t }
630 | PTacImplicit { priority :: Int,
631 lazyarg :: Bool, pname :: Name,
634 deriving (Show, Eq, Functor)
636instance Sized a => Sized (PArg' a) where
637 size (PImp p l nm trm) = 1 + size nm + size trm
638 size (PExp p l trm) = 1 + size trm
639 size (PConstraint p l trm) = 1 + size trm
640 size (PTacImplicit p l nm scr trm) = 1 + size nm + size scr + size trm
643deriving instance Binary PArg'
648pconst = PConstraint 0 False
649ptacimp = PTacImplicit 0 True
651type PArg = PArg' PTerm
655data ClassInfo = CI { instanceName :: Name,
656 class_methods :: [(Name, (FnOpts, PTerm))],
657 class_defaults :: [(Name, Name)], -- method name -> default impl
658 class_params :: [Name],
659 class_instances :: [Name] }
662deriving instance Binary ClassInfo
665data OptInfo = Optimise { collapsible :: Bool,
666 forceable :: [Int], -- argument positions
670deriving instance Binary OptInfo
674data TypeInfo = TI { con_names :: [Name] }
677deriving instance Binary TypeInfo
680-- Syntactic sugar info
682data DSL' t = DSL { dsl_bind :: t,
687 index_first :: Maybe t,
688 index_next :: Maybe t,
689 dsl_lambda :: Maybe t,
692 deriving (Show, Functor)
694deriving instance Binary DSL'
699data SynContext = PatternSyntax | TermSyntax | AnySyntax
702deriving instance Binary SynContext
705data Syntax = Rule [SSymbol] PTerm SynContext
708deriving instance Binary Syntax
711data SSymbol = Keyword Name
717deriving instance Binary SSymbol
720initDSL = DSL (PRef f (UN ">>="))
721 (PRef f (UN "return"))
729 where f = FC "(builtin)" 0
731data SyntaxInfo = Syn { using :: [(Name, PTerm)],
732 syn_params :: [(Name, PTerm)],
733 syn_namespace :: [String],
735 decoration :: Name -> Name,
740defaultSyntax = Syn [] [] [] [] id False initDSL
742expandNS :: SyntaxInfo -> Name -> Name
743expandNS syn n@(NS _ _) = n
744expandNS syn n = case syn_namespace syn of
749--- Pretty printing declarations and terms
751instance Show PTerm where
752 show tm = showImp False tm
754instance Pretty PTerm where
755 pretty = prettyImp False
757instance Show PDecl where
758 show d = showDeclImp False d
760instance Show PClause where
761 show c = showCImp True c
763instance Show PData where
764 show d = showDImp False d
766showDeclImp _ (PFix _ f ops) = show f ++ " " ++ showSep ", " ops
767showDeclImp t (PTy _ _ _ n ty) = show n ++ " : " ++ showImp t ty
768showDeclImp _ (PClauses _ _ n c) = showSep "\n" (map show c)
769showDeclImp _ (PData _ _ d) = show d
771showCImp :: Bool -> PClause -> String
772showCImp impl (PClause _ n l ws r w)
773 = showImp impl l ++ showWs ws ++ " = " ++ showImp impl r
774 ++ " where " ++ show w
777 showWs (x : xs) = " | " ++ showImp impl x ++ showWs xs
778showCImp impl (PWith _ n l ws r w)
779 = showImp impl l ++ showWs ws ++ " with " ++ showImp impl r
780 ++ " { " ++ show w ++ " } "
783 showWs (x : xs) = " | " ++ showImp impl x ++ showWs xs
786showDImp :: Bool -> PData -> String
787showDImp impl (PDatadecl n ty cons)
788 = "data " ++ show n ++ " : " ++ showImp impl ty ++ " where\n\t"
790 (map (\ (n, t, _) -> show n ++ " : " ++ showImp impl t) cons)
792getImps :: [PArg] -> [(Name, PTerm)]
794getImps (PImp _ _ n tm : xs) = (n, tm) : getImps xs
795getImps (_ : xs) = getImps xs
797getExps :: [PArg] -> [PTerm]
799getExps (PExp _ _ tm : xs) = tm : getExps xs
800getExps (_ : xs) = getExps xs
802getConsts :: [PArg] -> [PTerm]
804getConsts (PConstraint _ _ tm : xs) = tm : getConsts xs
805getConsts (_ : xs) = getConsts xs
807getAll :: [PArg] -> [PTerm]
810prettyImp :: Bool -> PTerm -> Doc
811prettyImp impl = prettySe 10
813 prettySe p (PQuote r) =
814 if size r > breakingSize then
815 text "![" $$ pretty r <> text "]"
817 text "![" <> pretty r <> text "]"
818 prettySe p (PRef fc n) =
824 prettyBasic n@(UN _) = pretty n
825 prettyBasic (MN _ s) = text s
826 prettyBasic (NS n s) = (foldr (<>) empty (intersperse (text ".") (map text $ reverse s))) <> prettyBasic n
827 prettySe p (PLam n ty sc) =
829 if size sc > breakingSize then
830 text "λ" <> pretty n <+> text "=>" $+$ pretty sc
832 text "λ" <> pretty n <+> text "=>" <+> pretty sc
833 prettySe p (PLet n ty v sc) =
835 if size sc > breakingSize then
836 text "let" <+> pretty n <+> text "=" <+> prettySe 10 v <+> text "in" $+$
837 nest nestingSize (prettySe 10 sc)
839 text "let" <+> pretty n <+> text "=" <+> prettySe 10 v <+> text "in" <+>
841 prettySe p (PPi (Exp l s) n ty sc)
842 | n `elem` allNamesIn sc || impl =
843 let open = if l then text "|" <> lparen else lparen in
845 if size sc > breakingSize then
846 open <> pretty n <+> colon <+> prettySe 10 ty <> rparen <+>
847 st <+> text "->" $+$ prettySe 10 sc
849 open <> pretty n <+> colon <+> prettySe 10 ty <> rparen <+>
850 st <+> text "->" <+> prettySe 10 sc
853 if size sc > breakingSize then
854 prettySe 0 ty <+> st <+> text "->" $+$ prettySe 10 sc
856 prettySe 0 ty <+> st <+> text "->" <+> prettySe 10 sc
860 Static -> text "[static]"
862 prettySe p (PPi (Imp l s) n ty sc)
864 let open = if l then text "|" <> lbrace else lbrace in
866 if size sc > breakingSize then
867 open <> pretty n <+> colon <+> prettySe 10 ty <> rbrace <+>
868 st <+> text "->" <+> prettySe 10 sc
870 open <> pretty n <+> colon <+> prettySe 10 ty <> rbrace <+>
871 st <+> text "->" <+> prettySe 10 sc
872 | otherwise = prettySe 10 sc
876 Static -> text $ "[static]"
878 prettySe p (PPi (Constraint _ _) n ty sc) =
880 if size sc > breakingSize then
881 prettySe 10 ty <+> text "=>" <+> prettySe 10 sc
883 prettySe 10 ty <+> text "=>" $+$ prettySe 10 sc
884 prettySe p (PPi (TacImp _ _ s) n ty sc) =
886 if size sc > breakingSize then
887 lbrace <> text "tacimp" <+> pretty n <+> colon <+> prettySe 10 ty <>
888 rbrace <+> text "->" $+$ prettySe 10 sc
890 lbrace <> text "tacimp" <+> pretty n <+> colon <+> prettySe 10 ty <>
891 rbrace <+> text "->" <+> prettySe 10 sc
892 prettySe p (PApp _ (PRef _ f) [])
893 | not impl = pretty f
894 prettySe p (PApp _ (PRef _ op@(UN (f:_))) args)
895 | length (getExps args) == 2 && (not impl) && (not $ isAlpha f) =
896 let [l, r] = getExps args in
898 if size r > breakingSize then
899 prettySe 1 l <+> pretty op $+$ prettySe 0 r
901 prettySe 1 l <+> pretty op <+> prettySe 0 r
902 prettySe p (PApp _ f as) =
903 let args = getExps as in
908 -- foldr (<+>) empty $ map prettyArgS as
911 -- foldr (<+>) empty $ map prettyArgSe args
914 if size r > breakingSize then
915 l $+$ nest nestingSize (prettyArgS r)
920 if size r > breakingSize then
921 l $+$ nest nestingSize (prettyArgSe r)
924 prettySe p (PCase _ scr opts) =
925 text "case" <+> prettySe 10 scr <+> text "of" $+$ nest nestingSize prettyBody
927 prettyBody = foldr ($$) empty $ intersperse (text "|") $ map sc opts
929 sc (l, r) = prettySe 10 l <+> text "=>" <+> prettySe 10 r
930 prettySe p (PHidden tm) = text "." <> prettySe 0 tm
931 prettySe p (PRefl _) = text "refl"
932 prettySe p (PResolveTC _) = text "resolvetc"
933 prettySe p (PTrue _) = text "()"
934 prettySe p (PFalse _) = text "_|_"
935 prettySe p (PEq _ l r) =
937 if size r > breakingSize then
938 prettySe 10 l <+> text "=" $$ nest nestingSize (prettySe 10 r)
940 prettySe 10 l <+> text "=" <+> prettySe 10 r
941 prettySe p (PTyped l r) =
942 lparen <> prettySe 10 l <+> colon <+> prettySe 10 r <> rparen
943 prettySe p (PPair _ l r) =
944 if size r > breakingSize then
945 lparen <> prettySe 10 l <> text "," $+$
946 prettySe 10 r <> rparen
948 lparen <> prettySe 10 l <> text "," <+> prettySe 10 r <> rparen
949 prettySe p (PDPair _ l t r) =
950 if size r > breakingSize then
951 lparen <> prettySe 10 l <+> text "**" $+$
952 prettySe 10 r <> rparen
954 lparen <> prettySe 10 l <+> text "**" <+> prettySe 10 r <> rparen
955 prettySe p (PAlternative as) =
956 lparen <> text "|" <> prettyAs <> text "|" <> rparen
959 foldr (\l -> \r -> l <+> text "," <+> r) empty $ map (prettySe 10) as
960 prettySe p PSet = text "Set"
961 prettySe p (PConstant c) = pretty c
962 -- XXX: add pretty for tactics
963 prettySe p (PProof ts) =
964 text "proof" <+> lbrace $+$ nest nestingSize (text . show $ ts) $+$ rbrace
965 prettySe p (PTactics ts) =
966 text "tactics" <+> lbrace $+$ nest nestingSize (text . show $ ts) $+$ rbrace
967 prettySe p (PMetavar n) = text "?" <> pretty n
968 prettySe p (PReturn f) = text "return"
969 prettySe p PImpossible = text "impossible"
970 prettySe p Placeholder = text "_"
971 prettySe p (PDoBlock _) = text "do block pretty not implemented"
972 prettySe p (PElabError s) = pretty s
974 prettySe p _ = text "test"
976 prettyArgS (PImp _ _ n tm) = prettyArgSi (n, tm)
977 prettyArgS (PExp _ _ tm) = prettyArgSe tm
978 prettyArgS (PConstraint _ _ tm) = prettyArgSc tm
979 prettyArgS (PTacImplicit _ _ n _ tm) = prettyArgSti (n, tm)
981 prettyArgSe arg = prettySe 0 arg
982 prettyArgSi (n, val) = lbrace <> pretty n <+> text "=" <+> prettySe 10 val <> rbrace
983 prettyArgSc val = lbrace <> lbrace <> prettySe 10 val <> rbrace <> rbrace
984 prettyArgSti (n, val) = lbrace <> text "auto" <+> pretty n <+> text "=" <+> prettySe 10 val <> rbrace
986 bracket outer inner doc
987 | inner > outer = lparen <> doc <> rparen
990showImp :: Bool -> PTerm -> String
991showImp impl tm = se 10 tm where
992 se p (PQuote r) = "![" ++ show r ++ "]"
993 se p (PRef fc n) = if impl then show n -- ++ "[" ++ show fc ++ "]"
995 where showbasic n@(UN _) = show n
996 showbasic (MN _ s) = s
997 showbasic (NS n s) = showSep "." (reverse s) ++ "." ++ showbasic n
998 se p (PLam n ty sc) = bracket p 2 $ "\\ " ++ show n ++
999 (if impl then " : " ++ se 10 ty else "") ++ " => "
1001 se p (PLet n ty v sc) = bracket p 2 $ "let " ++ show n ++ " = " ++ se 10 v ++
1003 se p (PPi (Exp l s) n ty sc)
1004 | n `elem` allNamesIn sc || impl
1006 if l then "|(" else "(" ++
1007 show n ++ " : " ++ se 10 ty ++
1010 | otherwise = bracket p 2 $ se 0 ty ++ " " ++ st ++ "-> " ++ se 10 sc
1011 where st = case s of
1012 Static -> "[static] "
1014 se p (PPi (Imp l s) n ty sc)
1015 | impl = bracket p 2 $ if l then "|{" else "{" ++
1016 show n ++ " : " ++ se 10 ty ++
1017 "} " ++ st ++ "-> " ++ se 10 sc
1018 | otherwise = se 10 sc
1019 where st = case s of
1020 Static -> "[static] "
1022 se p (PPi (Constraint _ _) n ty sc)
1023 = bracket p 2 $ se 10 ty ++ " => " ++ se 10 sc
1024 se p (PPi (TacImp _ _ s) n ty sc)
1025 = bracket p 2 $ "{tacimp " ++ show n ++ " : " ++ se 10 ty ++ "} -> " ++ se 10 sc
1026 se p (PApp _ (PRef _ f) [])
1028 se p (PApp _ (PRef _ op@(UN (f:_))) args)
1029 | length (getExps args) == 2 && not impl && not (isAlpha f)
1030 = let [l, r] = getExps args in
1031 bracket p 1 $ se 1 l ++ " " ++ show op ++ " " ++ se 0 r
1033 = let args = getExps as in
1034 bracket p 1 $ se 1 f ++ if impl then concatMap sArg as
1035 else concatMap seArg args
1036 se p (PCase _ scr opts) = "case " ++ se 10 scr ++ " of " ++ showSep " | " (map sc opts)
1037 where sc (l, r) = se 10 l ++ " => " ++ se 10 r
1038 se p (PHidden tm) = "." ++ se 0 tm
1039 se p (PRefl _) = "refl"
1040 se p (PResolveTC _) = "resolvetc"
1041 se p (PTrue _) = "()"
1042 se p (PFalse _) = "_|_"
1043 se p (PEq _ l r) = bracket p 2 $ se 10 l ++ " = " ++ se 10 r
1044 se p (PTyped l r) = "(" ++ se 10 l ++ " : " ++ se 10 r ++ ")"
1045 se p (PPair _ l r) = "(" ++ se 10 l ++ ", " ++ se 10 r ++ ")"
1046 se p (PDPair _ l t r) = "(" ++ se 10 l ++ " ** " ++ se 10 r ++ ")"
1047 se p (PAlternative as) = "(|" ++ showSep " , " (map (se 10) as) ++ "|)"
1049 se p (PConstant c) = show c
1050 se p (PProof ts) = "proof { " ++ show ts ++ "}"
1051 se p (PTactics ts) = "tactics { " ++ show ts ++ "}"
1052 se p (PMetavar n) = "?" ++ show n
1053 se p (PReturn f) = "return"
1054 se p PImpossible = "impossible"
1055 se p Placeholder = "_"
1056 se p (PDoBlock _) = "do block show not implemented"
1057 se p (PElabError s) = show s
1058-- se p x = "Not implemented"
1060 sArg (PImp _ _ n tm) = siArg (n, tm)
1061 sArg (PExp _ _ tm) = seArg tm
1062 sArg (PConstraint _ _ tm) = scArg tm
1063 sArg (PTacImplicit _ _ n _ tm) = stiArg (n, tm)
1065 seArg arg = " " ++ se 0 arg
1066 siArg (n, val) = " {" ++ show n ++ " = " ++ se 10 val ++ "}"
1067 scArg val = " {{" ++ se 10 val ++ "}}"
1068 stiArg (n, val) = " {auto " ++ show n ++ " = " ++ se 10 val ++ "}"
1070 bracket outer inner str | inner > outer = "(" ++ str ++ ")"
1076 | PLam Name PTerm PTerm
1077 | PPi Plicity Name PTerm PTerm
1078 | PLet Name PTerm PTerm PTerm
1079 | PTyped PTerm PTerm -- term with explicit type
1080 | PApp FC PTerm [PArg]
1081 | PCase FC PTerm [(PTerm, PTerm)]
1086 | PEq FC PTerm PTerm
1087 | PPair FC PTerm PTerm
1088 | PDPair FC PTerm PTerm PTerm
1089 | PAlternative [PTerm]
1090 | PHidden PTerm -- irrelevant or hidden pattern
1099 | PTactics [PTactic] -- as PProof, but no auto solving
1100 | PElabError Err -- error to report on elaboration
1101 | PImpossible -- special case for declaring when an LHS can't typecheck
1104instance Sized PTerm where
1105 size (PQuote rawTerm) = size rawTerm
1106 size (PRef fc name) = size name
1107 size (PLam name ty bdy) = 1 + size ty + size bdy
1108 size (PPi plicity name ty bdy) = 1 + size ty + size bdy
1109 size (PLet name ty def bdy) = 1 + size ty + size def + size bdy
1110 size (PTyped trm ty) = 1 + size trm + size ty
1111 size (PApp fc name args) = 1 + size args
1112 size (PCase fc trm bdy) = 1 + size trm + size bdy
1114 size (PFalse fc) = 1
1116 size (PResolveTC fc) = 1
1117 size (PEq fc left right) = 1 + size left + size right
1118 size (PPair fc left right) = 1 + size left + size right
1119 size (PDPair fs left ty right) = 1 + size left + size ty + size right
1120 size (PAlternative alts) = 1 + size alts
1121 size (PHidden hidden) = size hidden
1123 size (PConstant const) = 1 + size const
1124 size Placeholder = 1
1125 size (PDoBlock dos) = 1 + size dos
1126 size (PIdiom fc term) = 1 + size term
1127 size (PReturn fc) = 1
1128 size (PMetavar name) = 1
1129 size (PProof tactics) = size tactics
1130 size (PElabError err) = size err
1131 size PImpossible = 1
1133allNamesIn :: PTerm -> [Name]
1134allNamesIn tm = nub $ ni [] tm
1137 | not (n `elem` env) = [n]
1138 ni env (PApp _ f as) = ni env f ++ concatMap (ni env) (map getTm as)
1139 ni env (PCase _ c os) = ni env c ++ concatMap (ni env) (map snd os)
1140 ni env (PLam n ty sc) = ni env ty ++ ni (n:env) sc
1141 ni env (PPi _ n ty sc) = ni env ty ++ ni (n:env) sc
1142 ni env (PHidden tm) = ni env tm
1143 ni env (PEq _ l r) = ni env l ++ ni env r
1144 ni env (PTyped l r) = ni env l ++ ni env r
1145 ni env (PPair _ l r) = ni env l ++ ni env r
1146 ni env (PDPair _ (PRef _ n) t r) = ni env t ++ ni (n:env) r
1147 ni env (PDPair _ l t r) = ni env l ++ ni env t ++ ni env r
1148 ni env (PAlternative ls) = concatMap (ni env) ls
1151namesIn :: [(Name, PTerm)] -> IState -> PTerm -> [Name]
1152namesIn uvars ist tm = nub $ ni [] tm
1155 | not (n `elem` env)
1156 = case lookupTy Nothing n (tt_ctxt ist) of
1158 _ -> if n `elem` (map fst uvars) then [n] else []
1159 ni env (PApp _ f as) = ni env f ++ concatMap (ni env) (map getTm as)
1160 ni env (PCase _ c os) = ni env c ++ concatMap (ni env) (map snd os)
1161 ni env (PLam n ty sc) = ni env ty ++ ni (n:env) sc
1162 ni env (PPi _ n ty sc) = ni env ty ++ ni (n:env) sc
1163 ni env (PEq _ l r) = ni env l ++ ni env r
1164 ni env (PTyped l r) = ni env l ++ ni env r
1165 ni env (PPair _ l r) = ni env l ++ ni env r
1166 ni env (PDPair _ (PRef _ n) t r) = ni env t ++ ni (n:env) r
1167 ni env (PDPair _ l t r) = ni env l ++ ni env t ++ ni env r
1168 ni env (PAlternative as) = concatMap (ni env) as
1169 ni env (PHidden tm) = ni env tm
1172-- For inferring types of things
1176inferTy = MN 0 "__Infer"
1177inferCon = MN 0 "__infer"
1178inferDecl = PDatadecl inferTy
1180 [(inferCon, PPi impl (MN 0 "A") PSet (
1181 PPi expl (MN 0 "a") (PRef bi (MN 0 "A"))
1182 (PRef bi inferTy)), bi)]
1184infTerm t = PApp bi (PRef bi inferCon) [pimp (MN 0 "A") Placeholder, pexp t]
1185infP = P (TCon 6 0) inferTy (Set (UVal 0))
1187getInferTerm, getInferType :: Term -> Term
1188getInferTerm (Bind n b sc) = Bind n b $ getInferTerm sc
1189getInferTerm (App (App _ _) tm) = tm
1190getInferTerm tm = error ("getInferTerm " ++ show tm)
1192getInferType (Bind n b sc) = Bind n b $ getInferType sc
1193getInferType (App (App _ ty) _) = ty
1195-- Handy primitives: Unit, False, Pair, MkPair, =, mkForeign
1197primNames = [unitTy, unitCon,
1198 falseTy, pairTy, pairCon,
1199 eqTy, eqCon, inferTy, inferCon]
1201unitTy = MN 0 "__Unit"
1202unitCon = MN 0 "__II"
1203unitDecl = PDatadecl unitTy PSet
1204 [(unitCon, PRef bi unitTy, bi)]
1206falseTy = MN 0 "__False"
1207falseDecl = PDatadecl falseTy PSet []
1209pairTy = MN 0 "__Pair"
1210pairCon = MN 0 "__MkPair"
1211pairDecl = PDatadecl pairTy (piBind [(n "A", PSet), (n "B", PSet)] PSet)
1212 [(pairCon, PPi impl (n "A") PSet (
1213 PPi impl (n "B") PSet (
1214 PPi expl (n "a") (PRef bi (n "A")) (
1215 PPi expl (n "b") (PRef bi (n "B"))
1216 (PApp bi (PRef bi pairTy) [pexp (PRef bi (n "A")),
1217 pexp (PRef bi (n "B"))])))), bi)]
1222eqDecl = PDatadecl eqTy (piBind [(n "a", PSet), (n "b", PSet),
1223 (n "x", PRef bi (n "a")), (n "y", PRef bi (n "b"))]
1225 [(eqCon, PPi impl (n "a") PSet (
1226 PPi impl (n "x") (PRef bi (n "a"))
1227 (PApp bi (PRef bi eqTy) [pimp (n "a") Placeholder,
1228 pimp (n "b") Placeholder,
1229 pexp (PRef bi (n "x")),
1230 pexp (PRef bi (n "x"))])), bi)]
1233-- Defined in builtins.idr
1234sigmaTy = UN "Exists"
1235existsCon = UN "Ex_intro"
1237piBind :: [(Name, PTerm)] -> PTerm -> PTerm
1239piBind ((n, ty):ns) t = PPi expl n ty (piBind ns t)
1241tcname (UN ('@':_)) = True
1242tcname (NS n _) = tcname n
1245-- Dealing with parameters
1247expandParams :: (Name -> Name) -> [(Name, PTerm)] -> [Name] -> PTerm -> PTerm
1248expandParams dec ps ns tm = en tm
1250 -- if we shadow a name (say in a lambda binding) that is used in a call to
1251 -- a lifted function, we need access to both names - once in the scope of the
1252 -- binding and once to call the lifted functions. So we'll explicitly shadow
1253 -- it. (Yes, it's a hack. The alternative would be to resolve names earlier
1254 -- but we didn't...)
1256 mkShadow (UN n) = MN 0 n
1257 mkShadow (MN i n) = MN (i+1) n
1258 mkShadow (NS x s) = NS (mkShadow x) s
1261 | n `elem` map fst ps
1262 = let n' = mkShadow n in
1263 PLam n' (en t) (en (shadow n n' s))
1264 | otherwise = PLam n (en t) (en s)
1266 | n `elem` map fst ps
1267 = let n' = mkShadow n in
1268 PPi p n' (en t) (en (shadow n n' s))
1269 | otherwise = PPi p n (en t) (en s)
1271 | n `elem` map fst ps
1272 = let n' = mkShadow n in
1273 PLet n' (en ty) (en v) (en (shadow n n' s))
1274 | otherwise = PLet n (en ty) (en v) (en s)
1275 en (PEq f l r) = PEq f (en l) (en r)
1276 en (PTyped l r) = PTyped (en l) (en r)
1277 en (PPair f l r) = PPair f (en l) (en r)
1278 en (PDPair f l t r) = PDPair f (en l) (en t) (en r)
1279 en (PAlternative as) = PAlternative (map en as)
1280 en (PHidden t) = PHidden (en t)
1281 en (PDoBlock ds) = PDoBlock (map (fmap en) ds)
1282 en (PProof ts) = PProof (map (fmap en) ts)
1283 en (PTactics ts) = PTactics (map (fmap en) ts)
1286 | n `elem` ns = PQuote (Var (dec n))
1287 en (PApp fc (PRef fc' n) as)
1288 | n `elem` ns = PApp fc (PRef fc' (dec n))
1289 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
1291 | n `elem` ns = PApp fc (PRef fc (dec n))
1292 (map (pexp . (PRef fc)) (map fst ps))
1293 en (PApp fc f as) = PApp fc (en f) (map (fmap en) as)
1294 en (PCase fc c os) = PCase fc (en c) (map (pmap en) os)
1297expandParamsD :: IState ->
1298 (Name -> Name) -> [(Name, PTerm)] -> [Name] -> PDecl -> PDecl
1299expandParamsD ist dec ps ns (PTy syn fc o n ty)
1301 then PTy syn fc o (dec n) (piBind ps (expandParams dec ps ns ty))
1302 else PTy syn fc o n (expandParams dec ps ns ty)
1303expandParamsD ist dec ps ns (PClauses fc opts n cs)
1304 = let n' = if n `elem` ns then dec n else n in
1305 PClauses fc opts n' (map expandParamsC cs)
1307 expandParamsC (PClause fc n lhs ws rhs ds)
1308 = let -- ps' = updateps True (namesIn ist rhs) (zip ps [0..])
1309 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
1310 n' = if n `elem` ns then dec n else n in
1311 PClause fc n' (expandParams dec ps'' ns lhs)
1312 (map (expandParams dec ps'' ns) ws)
1313 (expandParams dec ps'' ns rhs)
1314 (map (expandParamsD ist dec ps'' ns) ds)
1315 expandParamsC (PWith fc n lhs ws wval ds)
1316 = let -- ps' = updateps True (namesIn ist wval) (zip ps [0..])
1317 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
1318 n' = if n `elem` ns then dec n else n in
1319 PWith fc n' (expandParams dec ps'' ns lhs)
1320 (map (expandParams dec ps'' ns) ws)
1321 (expandParams dec ps'' ns wval)
1322 (map (expandParamsD ist dec ps'' ns) ds)
1323 updateps yn nm [] = []
1324 updateps yn nm (((a, t), i):as)
1325 | (a `elem` nm) == yn = (a, t) : updateps yn nm as
1326 | otherwise = (MN i (show n ++ "_u"), t) : updateps yn nm as
1328expandParamsD ist dec ps ns d = d
1330-- Calculate a priority for a type, for deciding elaboration order
1331-- * if it's just a type variable or concrete type, do it early (0)
1332-- * if there's only type variables and injective constructors, do it next (1)
1333-- * if there's a function type, next (2)
1334-- * finally, everything else (3)
1336getPriority :: IState -> PTerm -> Int
1337getPriority i tm = pri tm
1340 case lookupP Nothing n (tt_ctxt i) of
1341 ((P (DCon _ _) _ _):_) -> 1
1342 ((P (TCon _ _) _ _):_) -> 1
1343 ((P Ref _ _):_) -> 4
1344 [] -> 0 -- must be locally bound, if it's not an error...
1345 pri (PPi _ _ x y) = max 5 (max (pri x) (pri y))
1349 pri (PEq _ l r) = max 1 (max (pri l) (pri r))
1350 pri (PApp _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.getTm) as)))
1351 pri (PCase _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.snd) as)))
1352 pri (PTyped l r) = pri l
1353 pri (PPair _ l r) = max 1 (max (pri l) (pri r))
1354 pri (PDPair _ l t r) = max 1 (max (pri l) (max (pri t) (pri r)))
1355 pri (PAlternative as) = maximum (map pri as)
1356 pri (PConstant _) = 0
1360addStatics :: Name -> Term -> PTerm -> Idris ()
1361addStatics n tm ptm =
1362 do let (statics, dynamics) = initStatics tm ptm
1363 let stnames = nub $ concatMap freeNames (map snd statics)
1364 let dnames = nub $ concatMap freeNames (map snd dynamics)
1365 when (not (null statics)) $
1366 logLvl 7 $ show n ++ " " ++ show statics ++ "\n" ++ show dynamics
1367 ++ "\n" ++ show stnames ++ "\n" ++ show dnames
1368 let statics' = nub $ map fst statics ++
1369 filter (\x -> not (elem x dnames)) stnames
1370 let stpos = staticList statics' tm
1372 put (i { idris_statics = addDef n stpos (idris_statics i) })
1373 addIBC (IBCStatic n)
1375 initStatics (Bind n (Pi ty) sc) (PPi p _ _ s)
1376 = let (static, dynamic) = initStatics (instantiate (P Bound n ty) sc) s in
1377 if pstatic p == Static then ((n, ty) : static, dynamic)
1378 else (static, (n, ty) : dynamic)
1379 initStatics t pt = ([], [])
1381 staticList sts (Bind n (Pi _) sc) = (n `elem` sts) : staticList sts sc
1384-- Dealing with implicit arguments
1386-- Add implicit Pi bindings for any names in the term which appear in an
1387-- argument position.
1389-- This has become a right mess already. Better redo it some time...
1391implicit :: SyntaxInfo -> Name -> PTerm -> Idris PTerm
1394 let (tm', impdata) = implicitise syn i ptm
1395-- let (tm'', spos) = findStatics i tm'
1396 put (i { idris_implicits = addDef n impdata (idris_implicits i) })
1398 logLvl 5 ("Implicit " ++ show n ++ " " ++ show impdata)
1400-- put (i { idris_statics = addDef n spos (idris_statics i) })
1403implicitise :: SyntaxInfo -> IState -> PTerm -> (PTerm, [PArg])
1404implicitise syn ist tm
1405 = let (declimps, ns') = execState (imps True [] tm) ([], [])
1406 ns = ns' \\ (map fst pvars ++ no_imp syn) in
1408 then (tm, reverse declimps)
1409 else implicitise syn ist (pibind uvars ns tm)
1412 pvars = syn_params syn
1414 dropAll (x:xs) ys | x `elem` ys = dropAll xs ys
1415 | otherwise = x : dropAll xs ys
1418 imps top env (PApp _ f as)
1419 = do (decls, ns) <- get
1420 let isn = concatMap (namesIn uvars ist) (map getTm as)
1421 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1422 imps top env (PPi (Imp l _) n ty sc)
1423 = do let isn = nub (namesIn uvars ist ty) `dropAll` [n]
1425 put (PImp (getPriority ist ty) l n ty : decls,
1426 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1427 imps True (n:env) sc
1428 imps top env (PPi (Exp l _) n ty sc)
1429 = do let isn = nub (namesIn uvars ist ty ++ case sc of
1430 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
1432 (decls, ns) <- get -- ignore decls in HO types
1433 put (PExp (getPriority ist ty) l ty : decls,
1434 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1435 imps True (n:env) sc
1436 imps top env (PPi (Constraint l _) n ty sc)
1437 = do let isn = nub (namesIn uvars ist ty ++ case sc of
1438 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
1440 (decls, ns) <- get -- ignore decls in HO types
1441 put (PConstraint 10 l ty : decls,
1442 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1443 imps True (n:env) sc
1444 imps top env (PPi (TacImp l _ scr) n ty sc)
1445 = do let isn = nub (namesIn uvars ist ty ++ case sc of
1446 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
1448 (decls, ns) <- get -- ignore decls in HO types
1449 put (PTacImplicit 10 l n scr ty : decls,
1450 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1451 imps True (n:env) sc
1452 imps top env (PEq _ l r)
1453 = do (decls, ns) <- get
1454 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1455 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1456 imps top env (PTyped l r)
1458 imps top env (PPair _ l r)
1459 = do (decls, ns) <- get
1460 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1461 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1462 imps top env (PDPair _ (PRef _ n) t r)
1463 = do (decls, ns) <- get
1464 let isn = nub (namesIn uvars ist t ++ namesIn uvars ist r) \\ [n]
1465 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
1466 imps top env (PDPair _ l t r)
1467 = do (decls, ns) <- get
1468 let isn = namesIn uvars ist l ++ namesIn uvars ist t ++
1470 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
1471 imps top env (PAlternative as)
1472 = do (decls, ns) <- get
1473 let isn = concatMap (namesIn uvars ist) as
1474 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1475 imps top env (PLam n ty sc)
1476 = do imps False env ty
1477 imps False (n:env) sc
1478 imps top env (PHidden tm) = imps False env tm
1479 imps top env _ = return ()
1481 pibind using [] sc = sc
1482 pibind using (n:ns) sc
1483 = case lookup n using of
1484 Just ty -> PPi (Imp False Dynamic) n ty (pibind using ns sc)
1485 Nothing -> PPi (Imp False Dynamic) n Placeholder (pibind using ns sc)
1487-- Add implicit arguments in function calls
1488addImplPat :: IState -> PTerm -> PTerm
1489addImplPat = addImpl' True []
1491addImplBound :: IState -> [Name] -> PTerm -> PTerm
1492addImplBound ist ns = addImpl' False ns ist
1494addImpl :: IState -> PTerm -> PTerm
1495addImpl = addImpl' False []
1497-- TODO: in patterns, don't add implicits to function names guarded by constructors
1498-- and *not* inside a PHidden
1500addImpl' :: Bool -> [Name] -> IState -> PTerm -> PTerm
1501addImpl' inpat env ist ptm = ai env ptm
1504 | not (f `elem` env) = handleErr $ aiFn inpat ist fc f []
1505 ai env (PHidden (PRef fc f))
1506 | not (f `elem` env) = handleErr $ aiFn False ist fc f []
1507 ai env (PEq fc l r) = let l' = ai env l
1510 ai env (PTyped l r) = let l' = ai env l
1513 ai env (PPair fc l r) = let l' = ai env l
1516 ai env (PDPair fc l t r) = let l' = ai env l
1520 ai env (PAlternative as) = let as' = map (ai env) as in
1522 ai env (PApp fc (PRef _ f) as)
1523 | not (f `elem` env)
1524 = let as' = map (fmap (ai env)) as in
1525 handleErr $ aiFn False ist fc f as'
1526 ai env (PApp fc f as) = let f' = ai env f
1527 as' = map (fmap (ai env)) as in
1529 ai env (PCase fc c os) = let c' = ai env c
1530 os' = map (pmap (ai env)) os in
1532 ai env (PLam n ty sc) = let ty' = ai env ty
1533 sc' = ai (n:env) sc in
1535 ai env (PLet n ty val sc)
1536 = let ty' = ai env ty
1538 sc' = ai (n:env) sc in
1540 ai env (PPi p n ty sc) = let ty' = ai env ty
1541 sc' = ai (n:env) sc in
1543 ai env (PHidden tm) = PHidden (ai env tm)
1544 ai env (PProof ts) = PProof (map (fmap (ai env)) ts)
1545 ai env (PTactics ts) = PTactics (map (fmap (ai env)) ts)
1548 handleErr (Left err) = PElabError err
1549 handleErr (Right x) = x
1551-- if in a pattern, and there are no arguments, and there's no possible
1552-- names with zero explicit arguments, don't add implicits.
1554aiFn :: Bool -> IState -> FC -> Name -> [PArg] -> Either Err PTerm
1555aiFn True ist fc f []
1556 = case lookupCtxt Nothing f (idris_implicits ist) of
1557 [] -> Right $ PRef fc f
1558 alts -> if (any (all imp) alts)
1559 then aiFn False ist fc f [] -- use it as a constructor
1560 else Right $ PRef fc f
1561 where imp (PExp _ _ _) = False
1563aiFn inpat ist fc f as
1564 | f `elem` primNames = Right $ PApp fc (PRef fc f) as
1565aiFn inpat ist fc f as
1566 -- This is where namespaces get resolved by adding PAlternative
1567 = case lookupCtxtName Nothing f (idris_implicits ist) of
1568 [(f',ns)] -> Right $ mkPApp fc (length ns) (PRef fc f') (insertImpl ns as)
1569 [] -> if f `elem` idris_metavars ist
1570 then Right $ PApp fc (PRef fc f) as
1571 else Right $ mkPApp fc (length as) (PRef fc f) as
1574 map (\(f', ns) -> mkPApp fc (length ns) (PRef fc f')
1575 (insertImpl ns as)) alts
1577 insertImpl :: [PArg] -> [PArg] -> [PArg]
1578 insertImpl (PExp p l ty : ps) (PExp _ _ tm : given) =
1579 PExp p l tm : insertImpl ps given
1580 insertImpl (PConstraint p l ty : ps) (PConstraint _ _ tm : given) =
1581 PConstraint p l tm : insertImpl ps given
1582 insertImpl (PConstraint p l ty : ps) given =
1583 PConstraint p l (PResolveTC fc) : insertImpl ps given
1584 insertImpl (PImp p l n ty : ps) given =
1585 case find n given [] of
1586 Just (tm, given') -> PImp p l n tm : insertImpl ps given'
1587 Nothing -> PImp p l n Placeholder : insertImpl ps given
1588 insertImpl (PTacImplicit p l n sc ty : ps) given =
1589 case find n given [] of
1590 Just (tm, given') -> PTacImplicit p l n sc tm : insertImpl ps given'
1591 Nothing -> PTacImplicit p l n sc sc
1592 : insertImpl ps given
1593 insertImpl expected [] = []
1594 insertImpl _ given = given
1596 find n [] acc = Nothing
1597 find n (PImp _ _ n' t : gs) acc
1598 | n == n' = Just (t, reverse acc ++ gs)
1599 find n (g : gs) acc = find n gs (g : acc)
1602mkPApp fc a f as = let rest = drop a as in
1603 appRest fc (PApp fc f (take a as)) rest
1606 appRest fc f (a : as) = appRest fc (PApp fc f [a]) as
1608-- Find 'static' argument positions
1609-- (the declared ones, plus any names in argument position in the declared
1611-- FIXME: It's possible that this really has to happen after elaboration
1613findStatics :: IState -> PTerm -> (PTerm, [Bool])
1614findStatics ist tm = trace (showImp True tm) $
1615 let (ns, ss) = fs tm in
1616 runState (pos ns ss tm) []
1617 where fs (PPi p n t sc)
1618 | Static <- pstatic p
1619 = let (ns, ss) = fs sc in
1620 (namesIn [] ist t : ns, n : ss)
1621 | otherwise = let (ns, ss) = fs sc in
1625 inOne n ns = length (filter id (map (elem n) ns)) == 1
1627 pos ns ss (PPi p n t sc)
1628 | elem n ss = do sc' <- pos ns ss sc
1631 return (PPi (p { pstatic = Static }) n t sc')
1632 | otherwise = do sc' <- pos ns ss sc
1635 return (PPi p n t sc')
1636 pos ns ss t = return t
1638-- Debugging/logging stuff
1640dumpDecls :: [PDecl] -> String
1642dumpDecls (d:ds) = dumpDecl d ++ "\n" ++ dumpDecls ds
1644dumpDecl (PFix _ f ops) = show f ++ " " ++ showSep ", " ops
1645dumpDecl (PTy _ _ _ n t) = "tydecl " ++ show n ++ " : " ++ showImp True t
1646dumpDecl (PClauses _ _ n cs) = "pat " ++ show n ++ "\t" ++ showSep "\n\t" (map (showCImp True) cs)
1647dumpDecl (PData _ _ d) = showDImp True d
1648dumpDecl (PParams _ ns ps) = "params {" ++ show ns ++ "\n" ++ dumpDecls ps ++ "}\n"
1649dumpDecl (PNamespace n ps) = "namespace {" ++ n ++ "\n" ++ dumpDecls ps ++ "}\n"
1650dumpDecl (PSyntax _ syn) = "syntax " ++ show syn
1651dumpDecl (PClass _ _ cs n ps ds)
1652 = "class " ++ show cs ++ " " ++ show n ++ " " ++ show ps ++ "\n" ++ dumpDecls ds
1653dumpDecl (PInstance _ _ cs n _ t ds)
1654 = "instance " ++ show cs ++ " " ++ show n ++ " " ++ show t ++ "\n" ++ dumpDecls ds
1656-- dumpDecl (PImport i) = "import " ++ i
1658-- for 6.12/7 compatibility
1659data EitherErr a b = LeftErr a | RightOK b
1661instance Monad (EitherErr a) where
1664 (LeftErr e) >>= k = LeftErr e
1665 RightOK v >>= k = k v
1667toEither (LeftErr e) = Left e
1668toEither (RightOK ho) = Right ho
1670-- syntactic match of a against b, returning pair of variables in a
1671-- and what they match. Returns the pair that failed if not a match.
1673matchClause :: IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
1674matchClause = matchClause' False
1676matchClause' :: Bool -> IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
1677matchClause' names i x y = checkRpts $ match (fullApp x) (fullApp y) where
1678 matchArg x y = match (fullApp (getTm x)) (fullApp (getTm y))
1680 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
1683 match' x y = match (fullApp x) (fullApp y)
1684 match (PApp _ (PRef _ (NS (UN "fromInteger") ["builtins"])) [_,_,x]) x'
1685 | PConstant (I _) <- getTm x = match (getTm x) x'
1686 match x' (PApp _ (PRef _ (NS (UN "fromInteger") ["builtins"])) [_,_,x])
1687 | PConstant (I _) <- getTm x = match (getTm x) x'
1688 match (PApp _ (PRef _ (UN "lazy")) [_,x]) x' = match (getTm x) x'
1689 match x (PApp _ (PRef _ (UN "lazy")) [_,x']) = match x (getTm x')
1690 match (PApp _ f args) (PApp _ f' args')
1691 | length args == length args'
1692 = do mf <- match' f f'
1693 ms <- zipWithM matchArg args args'
1694 return (mf ++ concat ms)
1695-- match (PRef _ n) (PRef _ n') | n == n' = return []
1696-- | otherwise = Nothing
1697 match (PRef f n) (PApp _ x []) = match (PRef f n) x
1698 match (PApp _ x []) (PRef f n) = match x (PRef f n)
1699 match (PRef _ n) (PRef _ n') | n == n' = return []
1701 | not names && (not (isConName Nothing n (tt_ctxt i)) || tm == Placeholder)
1703 match (PEq _ l r) (PEq _ l' r') = do ml <- match' l l'
1706 match (PTyped l r) (PTyped l' r') = do ml <- match l l'
1709 match (PTyped l r) x = match l x
1710 match x (PTyped l r) = match x l
1711 match (PPair _ l r) (PPair _ l' r') = do ml <- match' l l'
1714 match (PDPair _ l t r) (PDPair _ l' t' r') = do ml <- match' l l'
1717 return (ml ++ mt ++ mr)
1718 match (PAlternative as) (PAlternative as')
1719 = do ms <- zipWithM match' as as'
1721 match a@(PAlternative as) b
1722 = do let ms = zipWith match' as (repeat b)
1723 case (rights (map toEither ms)) of
1726 match (PCase _ _ _) _ = return [] -- lifted out
1727 match (PMetavar _) _ = return [] -- modified
1728 match (PQuote _) _ = return []
1729 match (PProof _) _ = return []
1730 match (PTactics _) _ = return []
1731 match (PRefl _) (PRefl _) = return []
1732 match (PResolveTC _) (PResolveTC _) = return []
1733 match (PTrue _) (PTrue _) = return []
1734 match (PFalse _) (PFalse _) = return []
1735 match (PReturn _) (PReturn _) = return []
1736 match (PPi _ _ t s) (PPi _ _ t' s') = do mt <- match' t t'
1739 match (PLam _ t s) (PLam _ t' s') = do mt <- match' t t'
1742 match (PLet _ t ty s) (PLet _ t' ty' s') = do mt <- match' t t'
1743 mty <- match' ty ty'
1745 return (mt ++ mty ++ ms)
1746 match (PHidden x) (PHidden y) = match' x y
1747 match Placeholder _ = return []
1748-- match _ Placeholder = return []
1749 match (PResolveTC _) _ = return []
1750 match a b | a == b = return []
1751 | otherwise = LeftErr (a, b)
1753 checkRpts (RightOK ms) = check ms where
1755 | Just t' <- lookup n xs = if t/=t' && t/=Placeholder && t'/=Placeholder
1758 check (_:xs) = check xs
1760 checkRpts (LeftErr x) = Left x
1762substMatches :: [(Name, PTerm)] -> PTerm -> PTerm
1763substMatches [] t = t
1764substMatches ((n,tm):ns) t = substMatch n tm (substMatches ns t)
1766substMatch :: Name -> PTerm -> PTerm -> PTerm
1767substMatch n tm t = sm t where
1768 sm (PRef _ n') | n == n' = tm
1769 sm (PLam x t sc) = PLam x (sm t) (sm sc)
1770 sm (PPi p x t sc) = PPi p x (sm t) (sm sc)
1771 sm (PApp f x as) = PApp f (sm x) (map (fmap sm) as)
1772 sm (PCase f x as) = PCase f (sm x) (map (pmap sm) as)
1773 sm (PEq f x y) = PEq f (sm x) (sm y)
1774 sm (PTyped x y) = PTyped (sm x) (sm y)
1775 sm (PPair f x y) = PPair f (sm x) (sm y)
1776 sm (PDPair f x t y) = PDPair f (sm x) (sm t) (sm y)
1777 sm (PAlternative as) = PAlternative (map sm as)
1778 sm (PHidden x) = PHidden (sm x)
1781shadow :: Name -> Name -> PTerm -> PTerm
1782shadow n n' t = sm t where
1783 sm (PRef fc x) | n == x = PRef fc n'
1784 sm (PLam x t sc) = PLam x (sm t) (sm sc)
1785 sm (PPi p x t sc) = PPi p x (sm t) (sm sc)
1786 sm (PApp f x as) = PApp f (sm x) (map (fmap sm) as)
1787 sm (PCase f x as) = PCase f (sm x) (map (pmap sm) as)
1788 sm (PEq f x y) = PEq f (sm x) (sm y)
1789 sm (PTyped x y) = PTyped (sm x) (sm y)
1790 sm (PPair f x y) = PPair f (sm x) (sm y)
1791 sm (PDPair f x t y) = PDPair f (sm x) (sm t) (sm y)
1792 sm (PAlternative as) = PAlternative (map sm as)
1793 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