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,
32 opt_ibcsubdir :: FilePath
36defaultOpts = IOption 0 False False True False True True ""
38-- TODO: Add 'module data' to IState, which can be saved out and reloaded quickly (i.e
39-- without typechecking).
40-- This will include all the functions and data declarations, plus fixity declarations
43data IState = IState { tt_ctxt :: Context,
44 idris_constraints :: [(UConstraint, FC)],
45 idris_infixes :: [FixDecl],
46 idris_implicits :: Ctxt [PArg],
47 idris_statics :: Ctxt [Bool],
48 idris_classes :: Ctxt ClassInfo,
49 idris_dsls :: Ctxt DSL,
50 idris_optimisation :: Ctxt OptInfo,
51 idris_datatypes :: Ctxt TypeInfo,
52 idris_patdefs :: Ctxt [([Name], Term, Term)], -- not exported
53 idris_flags :: Ctxt [FnOpt],
54 idris_callgraph :: Ctxt [Name],
55 idris_totcheck :: [(FC, Name)],
57 idris_options :: IOption,
59 idris_metavars :: [Name],
60 syntax_rules :: [Syntax],
61 syntax_keywords :: [String],
62 imported :: [FilePath],
63 idris_prims :: [(Name, ([E.Name], E.Term))],
64 idris_objs :: [FilePath],
65 idris_libs :: [String],
66 idris_hdrs :: [String],
67 last_proof :: Maybe (Name, [String]),
69 lastParse :: Maybe Name,
70 indent_stack :: [Int],
71 brace_stack :: [Maybe Int],
72 hide_list :: [(Name, Maybe Accessibility)],
73 default_access :: Accessibility,
74 ibc_write :: [IBCWrite],
75 compiled_so :: Maybe String
78-- information that needs writing for the current module's .ibc file
79data IBCWrite = IBCFix FixDecl
83 | IBCInstance Bool Name Name
93 | IBCAccess Name Accessibility
94 | IBCTotal Name Totality
95 | IBCFlags Name [FnOpt]
97 | IBCDef Name -- i.e. main context
100idrisInit = IState initContext [] [] emptyContext emptyContext emptyContext
101 emptyContext emptyContext emptyContext emptyContext
102 emptyContext emptyContext
103 [] "" defaultOpts 6 [] [] [] [] [] [] [] []
104 Nothing Nothing Nothing [] [] [] Hidden [] Nothing
106-- The monad for the main REPL - reading and processing files and updating
107-- global state (hence the IO inner monad).
108type Idris = StateT IState (InputT IO)
110getContext :: Idris Context
111getContext = do i <- get; return (tt_ctxt i)
113getObjectFiles :: Idris [FilePath]
114getObjectFiles = do i <- get; return (idris_objs i)
116addObjectFile :: FilePath -> Idris ()
117addObjectFile f = do i <- get; put (i { idris_objs = f : idris_objs i })
119getLibs :: Idris [String]
120getLibs = do i <- get; return (idris_libs i)
122addLib :: String -> Idris ()
123addLib f = do i <- get; put (i { idris_libs = f : idris_libs i })
125addHdr :: String -> Idris ()
126addHdr f = do i <- get; put (i { idris_hdrs = f : idris_hdrs i })
128totcheck :: (FC, Name) -> Idris ()
129totcheck n = do i <- get; put (i { idris_totcheck = n : idris_totcheck i })
131setFlags :: Name -> [FnOpt] -> Idris ()
132setFlags n fs = do i <- get; put (i { idris_flags = addDef n fs (idris_flags i) })
134setAccessibility :: Name -> Accessibility -> Idris ()
137 let ctxt = setAccess n a (tt_ctxt i)
138 put (i { tt_ctxt = ctxt })
140setTotality :: Name -> Totality -> Idris ()
143 let ctxt = setTotal n a (tt_ctxt i)
144 put (i { tt_ctxt = ctxt })
146getTotality :: Name -> Idris Totality
149 case lookupTotal n (tt_ctxt i) of
151 _ -> return (Total [])
153addToCG :: Name -> [Name] -> Idris ()
154addToCG n ns = do i <- get
155 put (i { idris_callgraph = addDef n ns (idris_callgraph i) })
157-- Add a class instance function. Dodgy hack: Put integer instances first in the
158-- list so they are resolved by default.
160addInstance :: Bool -> Name -> Name -> Idris ()
163 case lookupCtxt Nothing n (idris_classes ist) of
165 do let cs = addDef n (CI a b c d (addI i ins)) (idris_classes ist)
166 put (ist { idris_classes = cs })
167 _ -> do let cs = addDef n (CI (MN 0 "none") [] [] [] [i]) (idris_classes ist)
168 put (ist { idris_classes = cs })
169 where addI i ins | int = i : ins
170 | otherwise = ins ++ [i]
172addClass :: Name -> ClassInfo -> Idris ()
175 let i' = case lookupCtxt Nothing n (idris_classes ist) of
176 [c] -> c { class_instances = class_instances i }
178 put (ist { idris_classes = addDef n i' (idris_classes ist) })
180addIBC :: IBCWrite -> Idris ()
183 when (notDef (ibc_write i)) $
184 put (i { ibc_write = ibc : ibc_write i })
185 where notDef [] = True
186 notDef (IBCDef n': is) | n == n' = False
187 notDef (_ : is) = notDef is
188addIBC ibc = do i <- get; put (i { ibc_write = ibc : ibc_write i })
191clearIBC = do i <- get; put (i { ibc_write = [] })
193getHdrs :: Idris [String]
194getHdrs = do i <- get; return (idris_hdrs i)
196setErrLine :: Int -> Idris ()
197setErrLine x = do i <- get;
199 Nothing -> put (i { errLine = Just x })
203clearErr = do i <- get
204 put (i { errLine = Nothing })
206getSO :: Idris (Maybe String)
208 return (compiled_so i)
210setSO :: Maybe String -> Idris ()
212 put (i { compiled_so = s })
214getIState :: Idris IState
217putIState :: IState -> Idris ()
221getName = do i <- get;
222 let idx = idris_name i;
223 put (i { idris_name = idx + 1 })
226checkUndefined :: FC -> Name -> Idris ()
229 case lookupTy Nothing n i of
230 (_:_) -> fail $ show fc ++ ":" ++
231 show n ++ " already defined"
234setContext :: Context -> Idris ()
235setContext ctxt = do i <- get; put (i { tt_ctxt = ctxt } )
237updateContext :: (Context -> Context) -> Idris ()
238updateContext f = do i <- get; put (i { tt_ctxt = f (tt_ctxt i) } )
240addConstraints :: FC -> (Int, [UConstraint]) -> Idris ()
241addConstraints fc (v, cs)
244 let ctxt' = ctxt { uconstraints = cs ++ uconstraints ctxt,
246 let ics = zip cs (repeat fc) ++ idris_constraints i
247 put (i { tt_ctxt = ctxt', idris_constraints = ics })
249addDeferred :: [(Name, Type)] -> Idris ()
250addDeferred ns = do mapM_ (\(n, t) -> updateContext (addTyDecl n (tidyNames [] t))) ns
252 put (i { idris_metavars = map fst ns ++ idris_metavars i })
253 where tidyNames used (Bind (MN i x) b sc)
254 = let n' = uniqueName (UN x) used in
255 Bind n' b $ tidyNames (n':used) sc
256 tidyNames used (Bind n b sc)
257 = let n' = uniqueName n used in
258 Bind n' b $ tidyNames (n':used) sc
261solveDeferred :: Name -> Idris ()
262solveDeferred n = do i <- get
263 put (i { idris_metavars = idris_metavars i \\ [n] })
265iputStrLn :: String -> Idris ()
266iputStrLn = liftIO . putStrLn
268iWarn :: FC -> String -> Idris ()
269iWarn fc err = liftIO $ putStrLn (show fc ++ ":" ++ err)
271setLogLevel :: Int -> Idris ()
272setLogLevel l = do i <- get
273 let opts = idris_options i
274 let opt' = opts { opt_logLevel = l }
275 put (i { idris_options = opt' } )
278logLevel = do i <- get
279 return (opt_logLevel (idris_options i))
283 return (opt_repl (idris_options i))
285setREPL :: Bool -> Idris ()
286setREPL t = do i <- get
287 let opts = idris_options i
288 let opt' = opts { opt_repl = t }
289 put (i { idris_options = opt' })
293 return (opt_verbose (idris_options i))
295setVerbose :: Bool -> Idris ()
296setVerbose t = do i <- get
297 let opts = idris_options i
298 let opt' = opts { opt_verbose = t }
299 put (i { idris_options = opt' })
301typeInType :: Idris Bool
302typeInType = do i <- get
303 return (opt_typeintype (idris_options i))
305setTypeInType :: Bool -> Idris ()
306setTypeInType t = do i <- get
307 let opts = idris_options i
308 let opt' = opts { opt_typeintype = t }
309 put (i { idris_options = opt' })
311coverage :: Idris Bool
312coverage = do i <- get
313 return (opt_coverage (idris_options i))
315setCoverage :: Bool -> Idris ()
316setCoverage t = do i <- get
317 let opts = idris_options i
318 let opt' = opts { opt_coverage = t }
319 put (i { idris_options = opt' })
321setIBCSubDir :: FilePath -> Idris ()
322setIBCSubDir fp = do i <- get
323 let opts = idris_options i
324 let opt' = opts { opt_ibcsubdir =fp }
325 put (i { idris_options = opt' })
327valIBCSubDir :: IState -> Idris FilePath
328valIBCSubDir i = return (opt_ibcsubdir (idris_options i))
332 return (opt_showimp (idris_options i))
334setImpShow :: Bool -> Idris ()
335setImpShow t = do i <- get
336 let opts = idris_options i
337 let opt' = opts { opt_showimp = t }
338 put (i { idris_options = opt' })
340logLvl :: Int -> String -> Idris ()
341logLvl l str = do i <- get
342 let lvl = opt_logLevel (idris_options i)
344 $ do liftIO (putStrLn str)
345 put (i { idris_log = idris_log i ++ str ++ "\n" } )
347iLOG :: String -> Idris ()
350noErrors :: Idris Bool
351noErrors = do i <- get
353 Nothing -> return True
356setTypeCase :: Bool -> Idris ()
357setTypeCase t = do i <- get
358 let opts = idris_options i
359 let opt' = opts { opt_typecase = t }
360 put (i { idris_options = opt' })
362-- Commands in the REPL
364data Command = Quit | Help | Eval PTerm | Check PTerm | TotCheck Name
366 | Compile String | Execute | ExecVal PTerm
367 | Metavars | Prove Name | AddProof | Universes
369 | LogLvl Int | Spec PTerm | HNF PTerm | Defn Name
370 | Info Name | DebugInfo Name
374-- Parsed declarations
376data Fixity = Infixl { prec :: Int }
377 | Infixr { prec :: Int }
378 | InfixN { prec :: Int }
379 | PrefixN { prec :: Int }
382deriving instance Binary Fixity
385instance Show Fixity where
386 show (Infixl i) = "infixl " ++ show i
387 show (Infixr i) = "infixr " ++ show i
388 show (InfixN i) = "infix " ++ show i
389 show (PrefixN i) = "prefix " ++ show i
391data FixDecl = Fix Fixity String
394deriving instance Binary FixDecl
397instance Ord FixDecl where
398 compare (Fix x _) (Fix y _) = compare (prec x) (prec y)
401data Static = Static | Dynamic
404deriving instance Binary Static
407-- Mark bindings with their explicitness, and laziness
408data Plicity = Imp { plazy :: Bool,
410 | Exp { plazy :: Bool,
412 | Constraint { plazy :: Bool,
414 | TacImp { plazy :: Bool,
420deriving instance Binary Plicity
423impl = Imp False Dynamic
424expl = Exp False Dynamic
425constraint = Constraint False Dynamic
426tacimpl = TacImp False Dynamic
428data FnOpt = Inlinable | TotalFn | AssertTotal | TCGen
429 | Specialise [Name] -- specialise it, freeze these names
432deriving instance Binary FnOpt
437inlinable :: FnOpts -> Bool
438inlinable = elem Inlinable
440data PDecl' t = PFix FC Fixity [String] -- fixity declaration
441 | PTy SyntaxInfo FC FnOpts Name t -- type declaration
442 | PClauses FC FnOpts Name [PClause' t] -- pattern clause
443 | PData SyntaxInfo FC (PData' t) -- data declaration
444 | PParams FC [(Name, t)] [PDecl' t] -- params block
445 | PNamespace String [PDecl' t] -- new namespace
446 | PRecord SyntaxInfo FC Name t Name t -- record declaration
447 | PClass SyntaxInfo FC
450 [(Name, t)] -- parameters
451 [PDecl' t] -- declarations
452 | PInstance SyntaxInfo FC [t] -- constraints
455 t -- full instance type
459 | PDirective (Idris ())
462data PClause' t = PClause FC Name t [t] t [PDecl' t]
463 | PWith FC Name t [t] t [PDecl' t]
464 | PClauseR FC [t] t [PDecl' t]
465 | PWithR FC [t] t [PDecl' t]
468data PData' t = PDatadecl { d_name :: Name,
470 d_cons :: [(Name, t, FC)] }
473-- Handy to get a free function for applying PTerm -> PTerm functions
474-- across a program, by deriving Functor
476type PDecl = PDecl' PTerm
477type PData = PData' PTerm
478type PClause = PClause' PTerm
480-- get all the names declared in a decl
482declared :: PDecl -> [Name]
483declared (PFix _ _ _) = []
484declared (PTy _ _ _ n t) = [n]
485declared (PClauses _ _ n _) = [] -- not a declaration
486declared (PData _ _ (PDatadecl n _ ts)) = n : map fstt ts
487 where fstt (a, _, _) = a
488declared (PParams _ _ ds) = concatMap declared ds
489declared (PNamespace _ ds) = concatMap declared ds
490-- declared (PImport _) = []
492defined :: PDecl -> [Name]
493defined (PFix _ _ _) = []
494defined (PTy _ _ _ n t) = []
495defined (PClauses _ _ n _) = [n] -- not a declaration
496defined (PData _ _ (PDatadecl n _ ts)) = n : map fstt ts
497 where fstt (a, _, _) = a
498defined (PParams _ _ ds) = concatMap defined ds
499defined (PNamespace _ ds) = concatMap defined ds
500-- declared (PImport _) = []
502updateN :: [(Name, Name)] -> Name -> Name
503updateN ns n | Just n' <- lookup n ns = n'
506updateNs :: [(Name, Name)] -> PTerm -> PTerm
508updateNs ns t = mapPT updateRef t
509 where updateRef (PRef fc f) = PRef fc (updateN ns f)
512-- updateDNs :: [(Name, Name)] -> PDecl -> PDecl
514-- updateDNs ns (PTy s f n t) | Just n' <- lookup n ns = PTy s f n' t
515-- updateDNs ns (PClauses f n c) | Just n' <- lookup n ns = PClauses f n' (map updateCNs c)
516-- where updateCNs ns (PClause n l ts r ds)
517-- = PClause (updateN ns n) (fmap (updateNs ns) l)
518-- (map (fmap (updateNs ns)) ts)
519-- (fmap (updateNs ns) r)
520-- (map (updateDNs ns) ds)
523-- High level language terms
525data PTerm = PQuote Raw
527 | PLam Name PTerm PTerm
528 | PPi Plicity Name PTerm PTerm
529 | PLet Name PTerm PTerm PTerm
530 | PTyped PTerm PTerm -- term with explicit type
531 | PApp FC PTerm [PArg]
532 | PCase FC PTerm [(PTerm, PTerm)]
538 | PPair FC PTerm PTerm
539 | PDPair FC PTerm PTerm PTerm
540 | PAlternative Bool [PTerm] -- True if only one may work
541 | PHidden PTerm -- irrelevant or hidden pattern
550 | PTactics [PTactic] -- as PProof, but no auto solving
551 | PElabError Err -- error to report on elaboration
552 | PImpossible -- special case for declaring when an LHS can't typecheck
555deriving instance Binary PTerm
558mapPT :: (PTerm -> PTerm) -> PTerm -> PTerm
559mapPT f t = f (mpt t) where
560 mpt (PLam n t s) = PLam n (mapPT f t) (mapPT f s)
561 mpt (PPi p n t s) = PPi p n (mapPT f t) (mapPT f s)
562 mpt (PLet n ty v s) = PLet n (mapPT f ty) (mapPT f v) (mapPT f s)
563 mpt (PApp fc t as) = PApp fc (mapPT f t) (map (fmap (mapPT f)) as)
564 mpt (PCase fc c os) = PCase fc (mapPT f c) (map (pmap (mapPT f)) os)
565 mpt (PEq fc l r) = PEq fc (mapPT f l) (mapPT f r)
566 mpt (PTyped l r) = PTyped (mapPT f l) (mapPT f r)
567 mpt (PPair fc l r) = PPair fc (mapPT f l) (mapPT f r)
568 mpt (PDPair fc l t r) = PDPair fc (mapPT f l) (mapPT f t) (mapPT f r)
569 mpt (PAlternative a as) = PAlternative a (map (mapPT f) as)
570 mpt (PHidden t) = PHidden (mapPT f t)
571 mpt (PDoBlock ds) = PDoBlock (map (fmap (mapPT f)) ds)
572 mpt (PProof ts) = PProof (map (fmap (mapPT f)) ts)
573 mpt (PTactics ts) = PTactics (map (fmap (mapPT f)) ts)
577data PTactic' t = Intro [Name] | Intros | Focus Name
578 | Refine Name [Bool] | Rewrite t | LetTac Name t
579 | Exact t | Compute | Trivial
582 | ProofState | ProofTerm | Undo
583 | Try (PTactic' t) (PTactic' t)
584 | TSeq (PTactic' t) (PTactic' t)
586 deriving (Show, Eq, Functor)
588deriving instance Binary PTactic'
591instance Sized a => Sized (PTactic' a) where
592 size (Intro nms) = 1 + size nms
594 size (Focus nm) = 1 + size nm
595 size (Refine nm bs) = 1 + size nm + length bs
596 size (Rewrite t) = 1 + size t
597 size (LetTac nm t) = 1 + size nm + size t
598 size (Exact t) = 1 + size t
606 size (Try l r) = 1 + size l + size r
607 size (TSeq l r) = 1 + size l + size r
611type PTactic = PTactic' PTerm
613data PDo' t = DoExp FC t
618 deriving (Eq, Functor)
620deriving instance Binary PDo'
623instance Sized a => Sized (PDo' a) where
624 size (DoExp fc t) = 1 + size fc + size t
625 size (DoBind fc nm t) = 1 + size fc + size nm + size t
626 size (DoBindP fc l r) = 1 + size fc + size l + size r
627 size (DoLet fc nm l r) = 1 + size fc + size nm + size l + size r
628 size (DoLetP fc l r) = 1 + size fc + size l + size r
632-- The priority gives a hint as to elaboration order. Best to elaborate
633-- things early which will help give a more concrete type to other
634-- variables, e.g. a before (interpTy a).
636data PArg' t = PImp { priority :: Int,
637 lazyarg :: Bool, pname :: Name, getTm :: t }
638 | PExp { priority :: Int,
639 lazyarg :: Bool, getTm :: t }
640 | PConstraint { priority :: Int,
641 lazyarg :: Bool, getTm :: t }
642 | PTacImplicit { priority :: Int,
643 lazyarg :: Bool, pname :: Name,
646 deriving (Show, Eq, Functor)
648instance Sized a => Sized (PArg' a) where
649 size (PImp p l nm trm) = 1 + size nm + size trm
650 size (PExp p l trm) = 1 + size trm
651 size (PConstraint p l trm) = 1 + size trm
652 size (PTacImplicit p l nm scr trm) = 1 + size nm + size scr + size trm
655deriving instance Binary PArg'
660pconst = PConstraint 0 False
661ptacimp = PTacImplicit 0 True
663type PArg = PArg' PTerm
667data ClassInfo = CI { instanceName :: Name,
668 class_methods :: [(Name, (FnOpts, PTerm))],
669 class_defaults :: [(Name, Name)], -- method name -> default impl
670 class_params :: [Name],
671 class_instances :: [Name] }
674deriving instance Binary ClassInfo
677data OptInfo = Optimise { collapsible :: Bool,
678 forceable :: [Int], -- argument positions
682deriving instance Binary OptInfo
686data TypeInfo = TI { con_names :: [Name] }
689deriving instance Binary TypeInfo
692-- Syntactic sugar info
694data DSL' t = DSL { dsl_bind :: t,
699 index_first :: Maybe t,
700 index_next :: Maybe t,
701 dsl_lambda :: Maybe t,
704 deriving (Show, Functor)
706deriving instance Binary DSL'
711data SynContext = PatternSyntax | TermSyntax | AnySyntax
714deriving instance Binary SynContext
717data Syntax = Rule [SSymbol] PTerm SynContext
720deriving instance Binary Syntax
723data SSymbol = Keyword Name
729deriving instance Binary SSymbol
732initDSL = DSL (PRef f (UN ">>="))
733 (PRef f (UN "return"))
741 where f = FC "(builtin)" 0
743data SyntaxInfo = Syn { using :: [(Name, PTerm)],
744 syn_params :: [(Name, PTerm)],
745 syn_namespace :: [String],
747 decoration :: Name -> Name,
752defaultSyntax = Syn [] [] [] [] id False initDSL
754expandNS :: SyntaxInfo -> Name -> Name
755expandNS syn n@(NS _ _) = n
756expandNS syn n = case syn_namespace syn of
761--- Pretty printing declarations and terms
763instance Show PTerm where
764 show tm = showImp False tm
766instance Pretty PTerm where
767 pretty = prettyImp False
769instance Show PDecl where
770 show d = showDeclImp False d
772instance Show PClause where
773 show c = showCImp True c
775instance Show PData where
776 show d = showDImp False d
778showDeclImp _ (PFix _ f ops) = show f ++ " " ++ showSep ", " ops
779showDeclImp t (PTy _ _ _ n ty) = show n ++ " : " ++ showImp t ty
780showDeclImp _ (PClauses _ _ n c) = showSep "\n" (map show c)
781showDeclImp _ (PData _ _ d) = show d
783showCImp :: Bool -> PClause -> String
784showCImp impl (PClause _ n l ws r w)
785 = showImp impl l ++ showWs ws ++ " = " ++ showImp impl r
786 ++ " where " ++ show w
789 showWs (x : xs) = " | " ++ showImp impl x ++ showWs xs
790showCImp impl (PWith _ n l ws r w)
791 = showImp impl l ++ showWs ws ++ " with " ++ showImp impl r
792 ++ " { " ++ show w ++ " } "
795 showWs (x : xs) = " | " ++ showImp impl x ++ showWs xs
798showDImp :: Bool -> PData -> String
799showDImp impl (PDatadecl n ty cons)
800 = "data " ++ show n ++ " : " ++ showImp impl ty ++ " where\n\t"
802 (map (\ (n, t, _) -> show n ++ " : " ++ showImp impl t) cons)
804getImps :: [PArg] -> [(Name, PTerm)]
806getImps (PImp _ _ n tm : xs) = (n, tm) : getImps xs
807getImps (_ : xs) = getImps xs
809getExps :: [PArg] -> [PTerm]
811getExps (PExp _ _ tm : xs) = tm : getExps xs
812getExps (_ : xs) = getExps xs
814getConsts :: [PArg] -> [PTerm]
816getConsts (PConstraint _ _ tm : xs) = tm : getConsts xs
817getConsts (_ : xs) = getConsts xs
819getAll :: [PArg] -> [PTerm]
822prettyImp :: Bool -> PTerm -> Doc
823prettyImp impl = prettySe 10
825 prettySe p (PQuote r) =
826 if size r > breakingSize then
827 text "![" $$ pretty r <> text "]"
829 text "![" <> pretty r <> text "]"
830 prettySe p (PRef fc n) =
836 prettyBasic n@(UN _) = pretty n
837 prettyBasic (MN _ s) = text s
838 prettyBasic (NS n s) = (foldr (<>) empty (intersperse (text ".") (map text $ reverse s))) <> prettyBasic n
839 prettySe p (PLam n ty sc) =
841 if size sc > breakingSize then
842 text "λ" <> pretty n <+> text "=>" $+$ pretty sc
844 text "λ" <> pretty n <+> text "=>" <+> pretty sc
845 prettySe p (PLet n ty v sc) =
847 if size sc > breakingSize then
848 text "let" <+> pretty n <+> text "=" <+> prettySe 10 v <+> text "in" $+$
849 nest nestingSize (prettySe 10 sc)
851 text "let" <+> pretty n <+> text "=" <+> prettySe 10 v <+> text "in" <+>
853 prettySe p (PPi (Exp l s) n ty sc)
854 | n `elem` allNamesIn sc || impl =
855 let open = if l then text "|" <> lparen else lparen in
857 if size sc > breakingSize then
858 open <> pretty n <+> colon <+> prettySe 10 ty <> rparen <+>
859 st <+> text "->" $+$ prettySe 10 sc
861 open <> pretty n <+> colon <+> prettySe 10 ty <> rparen <+>
862 st <+> text "->" <+> prettySe 10 sc
865 if size sc > breakingSize then
866 prettySe 0 ty <+> st <+> text "->" $+$ prettySe 10 sc
868 prettySe 0 ty <+> st <+> text "->" <+> prettySe 10 sc
872 Static -> text "[static]"
874 prettySe p (PPi (Imp l s) n ty sc)
876 let open = if l then text "|" <> lbrace else lbrace in
878 if size sc > breakingSize then
879 open <> pretty n <+> colon <+> prettySe 10 ty <> rbrace <+>
880 st <+> text "->" <+> prettySe 10 sc
882 open <> pretty n <+> colon <+> prettySe 10 ty <> rbrace <+>
883 st <+> text "->" <+> prettySe 10 sc
884 | otherwise = prettySe 10 sc
888 Static -> text $ "[static]"
890 prettySe p (PPi (Constraint _ _) n ty sc) =
892 if size sc > breakingSize then
893 prettySe 10 ty <+> text "=>" <+> prettySe 10 sc
895 prettySe 10 ty <+> text "=>" $+$ prettySe 10 sc
896 prettySe p (PPi (TacImp _ _ s) n ty sc) =
898 if size sc > breakingSize then
899 lbrace <> text "tacimp" <+> pretty n <+> colon <+> prettySe 10 ty <>
900 rbrace <+> text "->" $+$ prettySe 10 sc
902 lbrace <> text "tacimp" <+> pretty n <+> colon <+> prettySe 10 ty <>
903 rbrace <+> text "->" <+> prettySe 10 sc
904 prettySe p (PApp _ (PRef _ f) [])
905 | not impl = pretty f
906 prettySe p (PApp _ (PRef _ op@(UN (f:_))) args)
907 | length (getExps args) == 2 && (not impl) && (not $ isAlpha f) =
908 let [l, r] = getExps args in
910 if size r > breakingSize then
911 prettySe 1 l <+> pretty op $+$ prettySe 0 r
913 prettySe 1 l <+> pretty op <+> prettySe 0 r
914 prettySe p (PApp _ f as) =
915 let args = getExps as in
920 -- foldr (<+>) empty $ map prettyArgS as
923 -- foldr (<+>) empty $ map prettyArgSe args
926 if size r > breakingSize then
927 l $+$ nest nestingSize (prettyArgS r)
932 if size r > breakingSize then
933 l $+$ nest nestingSize (prettyArgSe r)
936 prettySe p (PCase _ scr opts) =
937 text "case" <+> prettySe 10 scr <+> text "of" $+$ nest nestingSize prettyBody
939 prettyBody = foldr ($$) empty $ intersperse (text "|") $ map sc opts
941 sc (l, r) = prettySe 10 l <+> text "=>" <+> prettySe 10 r
942 prettySe p (PHidden tm) = text "." <> prettySe 0 tm
943 prettySe p (PRefl _) = text "refl"
944 prettySe p (PResolveTC _) = text "resolvetc"
945 prettySe p (PTrue _) = text "()"
946 prettySe p (PFalse _) = text "_|_"
947 prettySe p (PEq _ l r) =
949 if size r > breakingSize then
950 prettySe 10 l <+> text "=" $$ nest nestingSize (prettySe 10 r)
952 prettySe 10 l <+> text "=" <+> prettySe 10 r
953 prettySe p (PTyped l r) =
954 lparen <> prettySe 10 l <+> colon <+> prettySe 10 r <> rparen
955 prettySe p (PPair _ l r) =
956 if size r > breakingSize then
957 lparen <> prettySe 10 l <> text "," $+$
958 prettySe 10 r <> rparen
960 lparen <> prettySe 10 l <> text "," <+> prettySe 10 r <> rparen
961 prettySe p (PDPair _ l t r) =
962 if size r > breakingSize then
963 lparen <> prettySe 10 l <+> text "**" $+$
964 prettySe 10 r <> rparen
966 lparen <> prettySe 10 l <+> text "**" <+> prettySe 10 r <> rparen
967 prettySe p (PAlternative a as) =
968 lparen <> text "|" <> prettyAs <> text "|" <> rparen
971 foldr (\l -> \r -> l <+> text "," <+> r) empty $ map (prettySe 10) as
972 prettySe p PSet = text "Set"
973 prettySe p (PConstant c) = pretty c
974 -- XXX: add pretty for tactics
975 prettySe p (PProof ts) =
976 text "proof" <+> lbrace $+$ nest nestingSize (text . show $ ts) $+$ rbrace
977 prettySe p (PTactics ts) =
978 text "tactics" <+> lbrace $+$ nest nestingSize (text . show $ ts) $+$ rbrace
979 prettySe p (PMetavar n) = text "?" <> pretty n
980 prettySe p (PReturn f) = text "return"
981 prettySe p PImpossible = text "impossible"
982 prettySe p Placeholder = text "_"
983 prettySe p (PDoBlock _) = text "do block pretty not implemented"
984 prettySe p (PElabError s) = pretty s
986 prettySe p _ = text "test"
988 prettyArgS (PImp _ _ n tm) = prettyArgSi (n, tm)
989 prettyArgS (PExp _ _ tm) = prettyArgSe tm
990 prettyArgS (PConstraint _ _ tm) = prettyArgSc tm
991 prettyArgS (PTacImplicit _ _ n _ tm) = prettyArgSti (n, tm)
993 prettyArgSe arg = prettySe 0 arg
994 prettyArgSi (n, val) = lbrace <> pretty n <+> text "=" <+> prettySe 10 val <> rbrace
995 prettyArgSc val = lbrace <> lbrace <> prettySe 10 val <> rbrace <> rbrace
996 prettyArgSti (n, val) = lbrace <> text "auto" <+> pretty n <+> text "=" <+> prettySe 10 val <> rbrace
998 bracket outer inner doc
999 | inner > outer = lparen <> doc <> rparen
1002showImp :: Bool -> PTerm -> String
1003showImp impl tm = se 10 tm where
1004 se p (PQuote r) = "![" ++ show r ++ "]"
1005 se p (PRef fc n) = if impl then show n -- ++ "[" ++ show fc ++ "]"
1007 where showbasic n@(UN _) = show n
1008 showbasic (MN _ s) = s
1009 showbasic (NS n s) = showSep "." (reverse s) ++ "." ++ showbasic n
1010 se p (PLam n ty sc) = bracket p 2 $ "\\ " ++ show n ++
1011 (if impl then " : " ++ se 10 ty else "") ++ " => "
1013 se p (PLet n ty v sc) = bracket p 2 $ "let " ++ show n ++ " = " ++ se 10 v ++
1015 se p (PPi (Exp l s) n ty sc)
1016 | n `elem` allNamesIn sc || impl
1018 if l then "|(" else "(" ++
1019 show n ++ " : " ++ se 10 ty ++
1022 | otherwise = bracket p 2 $ se 0 ty ++ " " ++ st ++ "-> " ++ se 10 sc
1023 where st = case s of
1024 Static -> "[static] "
1026 se p (PPi (Imp l s) n ty sc)
1027 | impl = bracket p 2 $ if l then "|{" else "{" ++
1028 show n ++ " : " ++ se 10 ty ++
1029 "} " ++ st ++ "-> " ++ se 10 sc
1030 | otherwise = se 10 sc
1031 where st = case s of
1032 Static -> "[static] "
1034 se p (PPi (Constraint _ _) n ty sc)
1035 = bracket p 2 $ se 10 ty ++ " => " ++ se 10 sc
1036 se p (PPi (TacImp _ _ s) n ty sc)
1037 = bracket p 2 $ "{tacimp " ++ show n ++ " : " ++ se 10 ty ++ "} -> " ++ se 10 sc
1038 se p (PApp _ (PRef _ f) [])
1040 se p (PApp _ (PRef _ op@(UN (f:_))) args)
1041 | length (getExps args) == 2 && not impl && not (isAlpha f)
1042 = let [l, r] = getExps args in
1043 bracket p 1 $ se 1 l ++ " " ++ show op ++ " " ++ se 0 r
1045 = let args = getExps as in
1046 bracket p 1 $ se 1 f ++ if impl then concatMap sArg as
1047 else concatMap seArg args
1048 se p (PCase _ scr opts) = "case " ++ se 10 scr ++ " of " ++ showSep " | " (map sc opts)
1049 where sc (l, r) = se 10 l ++ " => " ++ se 10 r
1050 se p (PHidden tm) = "." ++ se 0 tm
1051 se p (PRefl _) = "refl"
1052 se p (PResolveTC _) = "resolvetc"
1053 se p (PTrue _) = "()"
1054 se p (PFalse _) = "_|_"
1055 se p (PEq _ l r) = bracket p 2 $ se 10 l ++ " = " ++ se 10 r
1056 se p (PTyped l r) = "(" ++ se 10 l ++ " : " ++ se 10 r ++ ")"
1057 se p (PPair _ l r) = "(" ++ se 10 l ++ ", " ++ se 10 r ++ ")"
1058 se p (PDPair _ l t r) = "(" ++ se 10 l ++ " ** " ++ se 10 r ++ ")"
1059 se p (PAlternative a as) = "(|" ++ showSep " , " (map (se 10) as) ++ "|)"
1061 se p (PConstant c) = show c
1062 se p (PProof ts) = "proof { " ++ show ts ++ "}"
1063 se p (PTactics ts) = "tactics { " ++ show ts ++ "}"
1064 se p (PMetavar n) = "?" ++ show n
1065 se p (PReturn f) = "return"
1066 se p PImpossible = "impossible"
1067 se p Placeholder = "_"
1068 se p (PDoBlock _) = "do block show not implemented"
1069 se p (PElabError s) = show s
1070-- se p x = "Not implemented"
1072 sArg (PImp _ _ n tm) = siArg (n, tm)
1073 sArg (PExp _ _ tm) = seArg tm
1074 sArg (PConstraint _ _ tm) = scArg tm
1075 sArg (PTacImplicit _ _ n _ tm) = stiArg (n, tm)
1077 seArg arg = " " ++ se 0 arg
1078 siArg (n, val) = " {" ++ show n ++ " = " ++ se 10 val ++ "}"
1079 scArg val = " {{" ++ se 10 val ++ "}}"
1080 stiArg (n, val) = " {auto " ++ show n ++ " = " ++ se 10 val ++ "}"
1082 bracket outer inner str | inner > outer = "(" ++ str ++ ")"
1088 | PLam Name PTerm PTerm
1089 | PPi Plicity Name PTerm PTerm
1090 | PLet Name PTerm PTerm PTerm
1091 | PTyped PTerm PTerm -- term with explicit type
1092 | PApp FC PTerm [PArg]
1093 | PCase FC PTerm [(PTerm, PTerm)]
1098 | PEq FC PTerm PTerm
1099 | PPair FC PTerm PTerm
1100 | PDPair FC PTerm PTerm PTerm
1101 | PAlternative [PTerm]
1102 | PHidden PTerm -- irrelevant or hidden pattern
1111 | PTactics [PTactic] -- as PProof, but no auto solving
1112 | PElabError Err -- error to report on elaboration
1113 | PImpossible -- special case for declaring when an LHS can't typecheck
1116instance Sized PTerm where
1117 size (PQuote rawTerm) = size rawTerm
1118 size (PRef fc name) = size name
1119 size (PLam name ty bdy) = 1 + size ty + size bdy
1120 size (PPi plicity name ty bdy) = 1 + size ty + size bdy
1121 size (PLet name ty def bdy) = 1 + size ty + size def + size bdy
1122 size (PTyped trm ty) = 1 + size trm + size ty
1123 size (PApp fc name args) = 1 + size args
1124 size (PCase fc trm bdy) = 1 + size trm + size bdy
1126 size (PFalse fc) = 1
1128 size (PResolveTC fc) = 1
1129 size (PEq fc left right) = 1 + size left + size right
1130 size (PPair fc left right) = 1 + size left + size right
1131 size (PDPair fs left ty right) = 1 + size left + size ty + size right
1132 size (PAlternative a alts) = 1 + size alts
1133 size (PHidden hidden) = size hidden
1135 size (PConstant const) = 1 + size const
1136 size Placeholder = 1
1137 size (PDoBlock dos) = 1 + size dos
1138 size (PIdiom fc term) = 1 + size term
1139 size (PReturn fc) = 1
1140 size (PMetavar name) = 1
1141 size (PProof tactics) = size tactics
1142 size (PElabError err) = size err
1143 size PImpossible = 1
1145allNamesIn :: PTerm -> [Name]
1146allNamesIn tm = nub $ ni [] tm
1149 | not (n `elem` env) = [n]
1150 ni env (PApp _ f as) = ni env f ++ concatMap (ni env) (map getTm as)
1151 ni env (PCase _ c os) = ni env c ++ concatMap (ni env) (map snd os)
1152 ni env (PLam n ty sc) = ni env ty ++ ni (n:env) sc
1153 ni env (PPi _ n ty sc) = ni env ty ++ ni (n:env) sc
1154 ni env (PHidden tm) = ni env tm
1155 ni env (PEq _ l r) = ni env l ++ ni env r
1156 ni env (PTyped l r) = ni env l ++ ni env r
1157 ni env (PPair _ l r) = ni env l ++ ni env r
1158 ni env (PDPair _ (PRef _ n) t r) = ni env t ++ ni (n:env) r
1159 ni env (PDPair _ l t r) = ni env l ++ ni env t ++ ni env r
1160 ni env (PAlternative a ls) = concatMap (ni env) ls
1163namesIn :: [(Name, PTerm)] -> IState -> PTerm -> [Name]
1164namesIn uvars ist tm = nub $ ni [] tm
1167 | not (n `elem` env)
1168 = case lookupTy Nothing n (tt_ctxt ist) of
1170 _ -> if n `elem` (map fst uvars) then [n] else []
1171 ni env (PApp _ f as) = ni env f ++ concatMap (ni env) (map getTm as)
1172 ni env (PCase _ c os) = ni env c ++ concatMap (ni env) (map snd os)
1173 ni env (PLam n ty sc) = ni env ty ++ ni (n:env) sc
1174 ni env (PPi _ n ty sc) = ni env ty ++ ni (n:env) sc
1175 ni env (PEq _ l r) = ni env l ++ ni env r
1176 ni env (PTyped l r) = ni env l ++ ni env r
1177 ni env (PPair _ l r) = ni env l ++ ni env r
1178 ni env (PDPair _ (PRef _ n) t r) = ni env t ++ ni (n:env) r
1179 ni env (PDPair _ l t r) = ni env l ++ ni env t ++ ni env r
1180 ni env (PAlternative a as) = concatMap (ni env) as
1181 ni env (PHidden tm) = ni env tm
1184-- For inferring types of things
1188inferTy = MN 0 "__Infer"
1189inferCon = MN 0 "__infer"
1190inferDecl = PDatadecl inferTy
1192 [(inferCon, PPi impl (MN 0 "A") PSet (
1193 PPi expl (MN 0 "a") (PRef bi (MN 0 "A"))
1194 (PRef bi inferTy)), bi)]
1196infTerm t = PApp bi (PRef bi inferCon) [pimp (MN 0 "A") Placeholder, pexp t]
1197infP = P (TCon 6 0) inferTy (Set (UVal 0))
1199getInferTerm, getInferType :: Term -> Term
1200getInferTerm (Bind n b sc) = Bind n b $ getInferTerm sc
1201getInferTerm (App (App _ _) tm) = tm
1202getInferTerm tm = error ("getInferTerm " ++ show tm)
1204getInferType (Bind n b sc) = Bind n b $ getInferType sc
1205getInferType (App (App _ ty) _) = ty
1207-- Handy primitives: Unit, False, Pair, MkPair, =, mkForeign
1209primNames = [unitTy, unitCon,
1210 falseTy, pairTy, pairCon,
1211 eqTy, eqCon, inferTy, inferCon]
1213unitTy = MN 0 "__Unit"
1214unitCon = MN 0 "__II"
1215unitDecl = PDatadecl unitTy PSet
1216 [(unitCon, PRef bi unitTy, bi)]
1218falseTy = MN 0 "__False"
1219falseDecl = PDatadecl falseTy PSet []
1221pairTy = MN 0 "__Pair"
1222pairCon = MN 0 "__MkPair"
1223pairDecl = PDatadecl pairTy (piBind [(n "A", PSet), (n "B", PSet)] PSet)
1224 [(pairCon, PPi impl (n "A") PSet (
1225 PPi impl (n "B") PSet (
1226 PPi expl (n "a") (PRef bi (n "A")) (
1227 PPi expl (n "b") (PRef bi (n "B"))
1228 (PApp bi (PRef bi pairTy) [pexp (PRef bi (n "A")),
1229 pexp (PRef bi (n "B"))])))), bi)]
1234eqDecl = PDatadecl eqTy (piBind [(n "a", PSet), (n "b", PSet),
1235 (n "x", PRef bi (n "a")), (n "y", PRef bi (n "b"))]
1237 [(eqCon, PPi impl (n "a") PSet (
1238 PPi impl (n "x") (PRef bi (n "a"))
1239 (PApp bi (PRef bi eqTy) [pimp (n "a") Placeholder,
1240 pimp (n "b") Placeholder,
1241 pexp (PRef bi (n "x")),
1242 pexp (PRef bi (n "x"))])), bi)]
1245-- Defined in builtins.idr
1246sigmaTy = UN "Exists"
1247existsCon = UN "Ex_intro"
1249piBind :: [(Name, PTerm)] -> PTerm -> PTerm
1251piBind ((n, ty):ns) t = PPi expl n ty (piBind ns t)
1253tcname (UN ('@':_)) = True
1254tcname (NS n _) = tcname n
1257-- Dealing with parameters
1259expandParams :: (Name -> Name) -> [(Name, PTerm)] -> [Name] -> PTerm -> PTerm
1260expandParams dec ps ns tm = en tm
1262 -- if we shadow a name (say in a lambda binding) that is used in a call to
1263 -- a lifted function, we need access to both names - once in the scope of the
1264 -- binding and once to call the lifted functions. So we'll explicitly shadow
1265 -- it. (Yes, it's a hack. The alternative would be to resolve names earlier
1266 -- but we didn't...)
1268 mkShadow (UN n) = MN 0 n
1269 mkShadow (MN i n) = MN (i+1) n
1270 mkShadow (NS x s) = NS (mkShadow x) s
1273 | n `elem` map fst ps
1274 = let n' = mkShadow n in
1275 PLam n' (en t) (en (shadow n n' s))
1276 | otherwise = PLam n (en t) (en s)
1278 | n `elem` map fst ps
1279 = let n' = mkShadow n in
1280 PPi p n' (en t) (en (shadow n n' s))
1281 | otherwise = PPi p n (en t) (en s)
1283 | n `elem` map fst ps
1284 = let n' = mkShadow n in
1285 PLet n' (en ty) (en v) (en (shadow n n' s))
1286 | otherwise = PLet n (en ty) (en v) (en s)
1287 en (PEq f l r) = PEq f (en l) (en r)
1288 en (PTyped l r) = PTyped (en l) (en r)
1289 en (PPair f l r) = PPair f (en l) (en r)
1290 en (PDPair f l t r) = PDPair f (en l) (en t) (en r)
1291 en (PAlternative a as) = PAlternative a (map en as)
1292 en (PHidden t) = PHidden (en t)
1293 en (PDoBlock ds) = PDoBlock (map (fmap en) ds)
1294 en (PProof ts) = PProof (map (fmap en) ts)
1295 en (PTactics ts) = PTactics (map (fmap en) ts)
1298 | n `elem` ns = PQuote (Var (dec n))
1299 en (PApp fc (PRef fc' n) as)
1300 | n `elem` ns = PApp fc (PRef fc' (dec n))
1301 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
1303 | n `elem` ns = PApp fc (PRef fc (dec n))
1304 (map (pexp . (PRef fc)) (map fst ps))
1305 en (PApp fc f as) = PApp fc (en f) (map (fmap en) as)
1306 en (PCase fc c os) = PCase fc (en c) (map (pmap en) os)
1309expandParamsD :: IState ->
1310 (Name -> Name) -> [(Name, PTerm)] -> [Name] -> PDecl -> PDecl
1311expandParamsD ist dec ps ns (PTy syn fc o n ty)
1313 then PTy syn fc o (dec n) (piBind ps (expandParams dec ps ns ty))
1314 else PTy syn fc o n (expandParams dec ps ns ty)
1315expandParamsD ist dec ps ns (PClauses fc opts n cs)
1316 = let n' = if n `elem` ns then dec n else n in
1317 PClauses fc opts n' (map expandParamsC cs)
1319 expandParamsC (PClause fc n lhs ws rhs ds)
1320 = let -- ps' = updateps True (namesIn ist rhs) (zip ps [0..])
1321 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
1322 n' = if n `elem` ns then dec n else n in
1323 PClause fc n' (expandParams dec ps'' ns lhs)
1324 (map (expandParams dec ps'' ns) ws)
1325 (expandParams dec ps'' ns rhs)
1326 (map (expandParamsD ist dec ps'' ns) ds)
1327 expandParamsC (PWith fc n lhs ws wval ds)
1328 = let -- ps' = updateps True (namesIn ist wval) (zip ps [0..])
1329 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
1330 n' = if n `elem` ns then dec n else n in
1331 PWith fc n' (expandParams dec ps'' ns lhs)
1332 (map (expandParams dec ps'' ns) ws)
1333 (expandParams dec ps'' ns wval)
1334 (map (expandParamsD ist dec ps'' ns) ds)
1335 updateps yn nm [] = []
1336 updateps yn nm (((a, t), i):as)
1337 | (a `elem` nm) == yn = (a, t) : updateps yn nm as
1338 | otherwise = (MN i (show n ++ "_u"), t) : updateps yn nm as
1340expandParamsD ist dec ps ns d = d
1342-- Calculate a priority for a type, for deciding elaboration order
1343-- * if it's just a type variable or concrete type, do it early (0)
1344-- * if there's only type variables and injective constructors, do it next (1)
1345-- * if there's a function type, next (2)
1346-- * finally, everything else (3)
1348getPriority :: IState -> PTerm -> Int
1349getPriority i tm = pri tm
1352 case lookupP Nothing n (tt_ctxt i) of
1353 ((P (DCon _ _) _ _):_) -> 1
1354 ((P (TCon _ _) _ _):_) -> 1
1355 ((P Ref _ _):_) -> 4
1356 [] -> 0 -- must be locally bound, if it's not an error...
1357 pri (PPi _ _ x y) = max 5 (max (pri x) (pri y))
1361 pri (PEq _ l r) = max 1 (max (pri l) (pri r))
1362 pri (PApp _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.getTm) as)))
1363 pri (PCase _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.snd) as)))
1364 pri (PTyped l r) = pri l
1365 pri (PPair _ l r) = max 1 (max (pri l) (pri r))
1366 pri (PDPair _ l t r) = max 1 (max (pri l) (max (pri t) (pri r)))
1367 pri (PAlternative a as) = maximum (map pri as)
1368 pri (PConstant _) = 0
1372addStatics :: Name -> Term -> PTerm -> Idris ()
1373addStatics n tm ptm =
1374 do let (statics, dynamics) = initStatics tm ptm
1375 let stnames = nub $ concatMap freeNames (map snd statics)
1376 let dnames = nub $ concatMap freeNames (map snd dynamics)
1377 when (not (null statics)) $
1378 logLvl 7 $ show n ++ " " ++ show statics ++ "\n" ++ show dynamics
1379 ++ "\n" ++ show stnames ++ "\n" ++ show dnames
1380 let statics' = nub $ map fst statics ++
1381 filter (\x -> not (elem x dnames)) stnames
1382 let stpos = staticList statics' tm
1384 put (i { idris_statics = addDef n stpos (idris_statics i) })
1385 addIBC (IBCStatic n)
1387 initStatics (Bind n (Pi ty) sc) (PPi p _ _ s)
1388 = let (static, dynamic) = initStatics (instantiate (P Bound n ty) sc) s in
1389 if pstatic p == Static then ((n, ty) : static, dynamic)
1390 else (static, (n, ty) : dynamic)
1391 initStatics t pt = ([], [])
1393 staticList sts (Bind n (Pi _) sc) = (n `elem` sts) : staticList sts sc
1396-- Dealing with implicit arguments
1398-- Add implicit Pi bindings for any names in the term which appear in an
1399-- argument position.
1401-- This has become a right mess already. Better redo it some time...
1403implicit :: SyntaxInfo -> Name -> PTerm -> Idris PTerm
1406 let (tm', impdata) = implicitise syn i ptm
1407-- let (tm'', spos) = findStatics i tm'
1408 put (i { idris_implicits = addDef n impdata (idris_implicits i) })
1410 logLvl 5 ("Implicit " ++ show n ++ " " ++ show impdata)
1412-- put (i { idris_statics = addDef n spos (idris_statics i) })
1415implicitise :: SyntaxInfo -> IState -> PTerm -> (PTerm, [PArg])
1416implicitise syn ist tm
1417 = let (declimps, ns') = execState (imps True [] tm) ([], [])
1418 ns = ns' \\ (map fst pvars ++ no_imp syn) in
1420 then (tm, reverse declimps)
1421 else implicitise syn ist (pibind uvars ns tm)
1424 pvars = syn_params syn
1426 dropAll (x:xs) ys | x `elem` ys = dropAll xs ys
1427 | otherwise = x : dropAll xs ys
1430 imps top env (PApp _ f as)
1431 = do (decls, ns) <- get
1432 let isn = concatMap (namesIn uvars ist) (map getTm as)
1433 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1434 imps top env (PPi (Imp l _) n ty sc)
1435 = do let isn = nub (namesIn uvars ist ty) `dropAll` [n]
1437 put (PImp (getPriority ist ty) l n ty : decls,
1438 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1439 imps True (n:env) sc
1440 imps top env (PPi (Exp l _) n ty sc)
1441 = do let isn = nub (namesIn uvars ist ty ++ case sc of
1442 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
1444 (decls, ns) <- get -- ignore decls in HO types
1445 put (PExp (getPriority ist ty) l ty : decls,
1446 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1447 imps True (n:env) sc
1448 imps top env (PPi (Constraint l _) n ty sc)
1449 = do let isn = nub (namesIn uvars ist ty ++ case sc of
1450 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
1452 (decls, ns) <- get -- ignore decls in HO types
1453 put (PConstraint 10 l ty : decls,
1454 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1455 imps True (n:env) sc
1456 imps top env (PPi (TacImp l _ scr) n ty sc)
1457 = do let isn = nub (namesIn uvars ist ty ++ case sc of
1458 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
1460 (decls, ns) <- get -- ignore decls in HO types
1461 put (PTacImplicit 10 l n scr ty : decls,
1462 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1463 imps True (n:env) sc
1464 imps top env (PEq _ l r)
1465 = do (decls, ns) <- get
1466 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1467 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1468 imps top env (PTyped l r)
1470 imps top env (PPair _ l r)
1471 = do (decls, ns) <- get
1472 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1473 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1474 imps top env (PDPair _ (PRef _ n) t r)
1475 = do (decls, ns) <- get
1476 let isn = nub (namesIn uvars ist t ++ namesIn uvars ist r) \\ [n]
1477 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
1478 imps top env (PDPair _ l t r)
1479 = do (decls, ns) <- get
1480 let isn = namesIn uvars ist l ++ namesIn uvars ist t ++
1482 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
1483 imps top env (PAlternative a as)
1484 = do (decls, ns) <- get
1485 let isn = concatMap (namesIn uvars ist) as
1486 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1487 imps top env (PLam n ty sc)
1488 = do imps False env ty
1489 imps False (n:env) sc
1490 imps top env (PHidden tm) = imps False env tm
1491 imps top env _ = return ()
1493 pibind using [] sc = sc
1494 pibind using (n:ns) sc
1495 = case lookup n using of
1496 Just ty -> PPi (Imp False Dynamic) n ty (pibind using ns sc)
1497 Nothing -> PPi (Imp False Dynamic) n Placeholder (pibind using ns sc)
1499-- Add implicit arguments in function calls
1500addImplPat :: IState -> PTerm -> PTerm
1501addImplPat = addImpl' True []
1503addImplBound :: IState -> [Name] -> PTerm -> PTerm
1504addImplBound ist ns = addImpl' False ns ist
1506addImpl :: IState -> PTerm -> PTerm
1507addImpl = addImpl' False []
1509-- TODO: in patterns, don't add implicits to function names guarded by constructors
1510-- and *not* inside a PHidden
1512addImpl' :: Bool -> [Name] -> IState -> PTerm -> PTerm
1513addImpl' inpat env ist ptm = ai env ptm
1516 | not (f `elem` env) = handleErr $ aiFn inpat ist fc f []
1517 ai env (PHidden (PRef fc f))
1518 | not (f `elem` env) = handleErr $ aiFn False ist fc f []
1519 ai env (PEq fc l r) = let l' = ai env l
1522 ai env (PTyped l r) = let l' = ai env l
1525 ai env (PPair fc l r) = let l' = ai env l
1528 ai env (PDPair fc l t r) = let l' = ai env l
1532 ai env (PAlternative a as) = let as' = map (ai env) as in
1534 ai env (PApp fc (PRef _ f) as)
1535 | not (f `elem` env)
1536 = let as' = map (fmap (ai env)) as in
1537 handleErr $ aiFn False ist fc f as'
1538 ai env (PApp fc f as) = let f' = ai env f
1539 as' = map (fmap (ai env)) as in
1541 ai env (PCase fc c os) = let c' = ai env c
1542 os' = map (pmap (ai env)) os in
1544 ai env (PLam n ty sc) = let ty' = ai env ty
1545 sc' = ai (n:env) sc in
1547 ai env (PLet n ty val sc)
1548 = let ty' = ai env ty
1550 sc' = ai (n:env) sc in
1552 ai env (PPi p n ty sc) = let ty' = ai env ty
1553 sc' = ai (n:env) sc in
1555 ai env (PHidden tm) = PHidden (ai env tm)
1556 ai env (PProof ts) = PProof (map (fmap (ai env)) ts)
1557 ai env (PTactics ts) = PTactics (map (fmap (ai env)) ts)
1560 handleErr (Left err) = PElabError err
1561 handleErr (Right x) = x
1563-- if in a pattern, and there are no arguments, and there's no possible
1564-- names with zero explicit arguments, don't add implicits.
1566aiFn :: Bool -> IState -> FC -> Name -> [PArg] -> Either Err PTerm
1567aiFn True ist fc f []
1568 = case lookupCtxt Nothing f (idris_implicits ist) of
1569 [] -> Right $ PRef fc f
1570 alts -> if (any (all imp) alts)
1571 then aiFn False ist fc f [] -- use it as a constructor
1572 else Right $ PRef fc f
1573 where imp (PExp _ _ _) = False
1575aiFn inpat ist fc f as
1576 | f `elem` primNames = Right $ PApp fc (PRef fc f) as
1577aiFn inpat ist fc f as
1578 -- This is where namespaces get resolved by adding PAlternative
1579 = case lookupCtxtName Nothing f (idris_implicits ist) of
1580 [(f',ns)] -> Right $ mkPApp fc (length ns) (PRef fc f') (insertImpl ns as)
1581 [] -> if f `elem` idris_metavars ist
1582 then Right $ PApp fc (PRef fc f) as
1583 else Right $ mkPApp fc (length as) (PRef fc f) as
1586 map (\(f', ns) -> mkPApp fc (length ns) (PRef fc f')
1587 (insertImpl ns as)) alts
1589 insertImpl :: [PArg] -> [PArg] -> [PArg]
1590 insertImpl (PExp p l ty : ps) (PExp _ _ tm : given) =
1591 PExp p l tm : insertImpl ps given
1592 insertImpl (PConstraint p l ty : ps) (PConstraint _ _ tm : given) =
1593 PConstraint p l tm : insertImpl ps given
1594 insertImpl (PConstraint p l ty : ps) given =
1595 PConstraint p l (PResolveTC fc) : insertImpl ps given
1596 insertImpl (PImp p l n ty : ps) given =
1597 case find n given [] of
1598 Just (tm, given') -> PImp p l n tm : insertImpl ps given'
1599 Nothing -> PImp p l n Placeholder : insertImpl ps given
1600 insertImpl (PTacImplicit p l n sc ty : ps) given =
1601 case find n given [] of
1602 Just (tm, given') -> PTacImplicit p l n sc tm : insertImpl ps given'
1603 Nothing -> PTacImplicit p l n sc sc
1604 : insertImpl ps given
1605 insertImpl expected [] = []
1606 insertImpl _ given = given
1608 find n [] acc = Nothing
1609 find n (PImp _ _ n' t : gs) acc
1610 | n == n' = Just (t, reverse acc ++ gs)
1611 find n (g : gs) acc = find n gs (g : acc)
1614mkPApp fc a f as = let rest = drop a as in
1615 appRest fc (PApp fc f (take a as)) rest
1618 appRest fc f (a : as) = appRest fc (PApp fc f [a]) as
1620-- Find 'static' argument positions
1621-- (the declared ones, plus any names in argument position in the declared
1623-- FIXME: It's possible that this really has to happen after elaboration
1625findStatics :: IState -> PTerm -> (PTerm, [Bool])
1626findStatics ist tm = trace (showImp True tm) $
1627 let (ns, ss) = fs tm in
1628 runState (pos ns ss tm) []
1629 where fs (PPi p n t sc)
1630 | Static <- pstatic p
1631 = let (ns, ss) = fs sc in
1632 (namesIn [] ist t : ns, n : ss)
1633 | otherwise = let (ns, ss) = fs sc in
1637 inOne n ns = length (filter id (map (elem n) ns)) == 1
1639 pos ns ss (PPi p n t sc)
1640 | elem n ss = do sc' <- pos ns ss sc
1643 return (PPi (p { pstatic = Static }) n t sc')
1644 | otherwise = do sc' <- pos ns ss sc
1647 return (PPi p n t sc')
1648 pos ns ss t = return t
1650-- Debugging/logging stuff
1652dumpDecls :: [PDecl] -> String
1654dumpDecls (d:ds) = dumpDecl d ++ "\n" ++ dumpDecls ds
1656dumpDecl (PFix _ f ops) = show f ++ " " ++ showSep ", " ops
1657dumpDecl (PTy _ _ _ n t) = "tydecl " ++ show n ++ " : " ++ showImp True t
1658dumpDecl (PClauses _ _ n cs) = "pat " ++ show n ++ "\t" ++ showSep "\n\t" (map (showCImp True) cs)
1659dumpDecl (PData _ _ d) = showDImp True d
1660dumpDecl (PParams _ ns ps) = "params {" ++ show ns ++ "\n" ++ dumpDecls ps ++ "}\n"
1661dumpDecl (PNamespace n ps) = "namespace {" ++ n ++ "\n" ++ dumpDecls ps ++ "}\n"
1662dumpDecl (PSyntax _ syn) = "syntax " ++ show syn
1663dumpDecl (PClass _ _ cs n ps ds)
1664 = "class " ++ show cs ++ " " ++ show n ++ " " ++ show ps ++ "\n" ++ dumpDecls ds
1665dumpDecl (PInstance _ _ cs n _ t ds)
1666 = "instance " ++ show cs ++ " " ++ show n ++ " " ++ show t ++ "\n" ++ dumpDecls ds
1668-- dumpDecl (PImport i) = "import " ++ i
1670-- for 6.12/7 compatibility
1671data EitherErr a b = LeftErr a | RightOK b
1673instance Monad (EitherErr a) where
1676 (LeftErr e) >>= k = LeftErr e
1677 RightOK v >>= k = k v
1679toEither (LeftErr e) = Left e
1680toEither (RightOK ho) = Right ho
1682-- syntactic match of a against b, returning pair of variables in a
1683-- and what they match. Returns the pair that failed if not a match.
1685matchClause :: IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
1686matchClause = matchClause' False
1688matchClause' :: Bool -> IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
1689matchClause' names i x y = checkRpts $ match (fullApp x) (fullApp y) where
1690 matchArg x y = match (fullApp (getTm x)) (fullApp (getTm y))
1692 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
1695 match' x y = match (fullApp x) (fullApp y)
1696 match (PApp _ (PRef _ (NS (UN "fromInteger") ["builtins"])) [_,_,x]) x'
1697 | PConstant (I _) <- getTm x = match (getTm x) x'
1698 match x' (PApp _ (PRef _ (NS (UN "fromInteger") ["builtins"])) [_,_,x])
1699 | PConstant (I _) <- getTm x = match (getTm x) x'
1700 match (PApp _ (PRef _ (UN "lazy")) [_,x]) x' = match (getTm x) x'
1701 match x (PApp _ (PRef _ (UN "lazy")) [_,x']) = match x (getTm x')
1702 match (PApp _ f args) (PApp _ f' args')
1703 | length args == length args'
1704 = do mf <- match' f f'
1705 ms <- zipWithM matchArg args args'
1706 return (mf ++ concat ms)
1707-- match (PRef _ n) (PRef _ n') | n == n' = return []
1708-- | otherwise = Nothing
1709 match (PRef f n) (PApp _ x []) = match (PRef f n) x
1710 match (PApp _ x []) (PRef f n) = match x (PRef f n)
1711 match (PRef _ n) (PRef _ n') | n == n' = return []
1713 | not names && (not (isConName Nothing n (tt_ctxt i)) || tm == Placeholder)
1715 match (PEq _ l r) (PEq _ l' r') = do ml <- match' l l'
1718 match (PTyped l r) (PTyped l' r') = do ml <- match l l'
1721 match (PTyped l r) x = match l x
1722 match x (PTyped l r) = match x l
1723 match (PPair _ l r) (PPair _ l' r') = do ml <- match' l l'
1726 match (PDPair _ l t r) (PDPair _ l' t' r') = do ml <- match' l l'
1729 return (ml ++ mt ++ mr)
1730 match (PAlternative a as) (PAlternative a' as')
1731 = do ms <- zipWithM match' as as'
1733 match a@(PAlternative _ as) b
1734 = do let ms = zipWith match' as (repeat b)
1735 case (rights (map toEither ms)) of
1738 match (PCase _ _ _) _ = return [] -- lifted out
1739 match (PMetavar _) _ = return [] -- modified
1740 match (PQuote _) _ = return []
1741 match (PProof _) _ = return []
1742 match (PTactics _) _ = return []
1743 match (PRefl _) (PRefl _) = return []
1744 match (PResolveTC _) (PResolveTC _) = return []
1745 match (PTrue _) (PTrue _) = return []
1746 match (PFalse _) (PFalse _) = return []
1747 match (PReturn _) (PReturn _) = return []
1748 match (PPi _ _ t s) (PPi _ _ t' s') = do mt <- match' t t'
1751 match (PLam _ t s) (PLam _ t' s') = do mt <- match' t t'
1754 match (PLet _ t ty s) (PLet _ t' ty' s') = do mt <- match' t t'
1755 mty <- match' ty ty'
1757 return (mt ++ mty ++ ms)
1758 match (PHidden x) (PHidden y) = match' x y
1759 match Placeholder _ = return []
1760-- match _ Placeholder = return []
1761 match (PResolveTC _) _ = return []
1762 match a b | a == b = return []
1763 | otherwise = LeftErr (a, b)
1765 checkRpts (RightOK ms) = check ms where
1767 | Just t' <- lookup n xs = if t/=t' && t/=Placeholder && t'/=Placeholder
1770 check (_:xs) = check xs
1772 checkRpts (LeftErr x) = Left x
1774substMatches :: [(Name, PTerm)] -> PTerm -> PTerm
1775substMatches [] t = t
1776substMatches ((n,tm):ns) t = substMatch n tm (substMatches ns t)
1778substMatch :: Name -> PTerm -> PTerm -> PTerm
1779substMatch n tm t = sm t where
1780 sm (PRef _ n') | n == n' = tm
1781 sm (PLam x t sc) = PLam x (sm t) (sm sc)
1782 sm (PPi p x t sc) = PPi p x (sm t) (sm sc)
1783 sm (PApp f x as) = PApp f (sm x) (map (fmap sm) as)
1784 sm (PCase f x as) = PCase f (sm x) (map (pmap sm) as)
1785 sm (PEq f x y) = PEq f (sm x) (sm y)
1786 sm (PTyped x y) = PTyped (sm x) (sm y)
1787 sm (PPair f x y) = PPair f (sm x) (sm y)
1788 sm (PDPair f x t y) = PDPair f (sm x) (sm t) (sm y)
1789 sm (PAlternative a as) = PAlternative a (map sm as)
1790 sm (PHidden x) = PHidden (sm x)
1793shadow :: Name -> Name -> PTerm -> PTerm
1794shadow n n' t = sm t where
1795 sm (PRef fc x) | n == x = PRef fc n'
1796 sm (PLam x t sc) = PLam x (sm t) (sm sc)
1797 sm (PPi p x t sc) = PPi p x (sm t) (sm sc)
1798 sm (PApp f x as) = PApp f (sm x) (map (fmap sm) as)
1799 sm (PCase f x as) = PCase f (sm x) (map (pmap sm) as)
1800 sm (PEq f x y) = PEq f (sm x) (sm y)
1801 sm (PTyped x y) = PTyped (sm x) (sm y)
1802 sm (PPair f x y) = PPair f (sm x) (sm y)
1803 sm (PDPair f x t y) = PDPair f (sm x) (sm t) (sm y)
1804 sm (PAlternative a as) = PAlternative a (map sm as)
1805 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