1{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, DeriveFunctor,
2 TypeSynonymInstances, PatternGuards #-}
4module Idris.AbsSyntax where
8import Core.Elaborate hiding (Tactic(..))
14import System.Console.Haskeline
16import Control.Monad.State
24import qualified Epic.Epic as E
28data IOption = IOption { opt_logLevel :: Int,
30 opt_typeintype :: Bool,
33 opt_errContext :: Bool,
36 opt_ibcsubdir :: FilePath,
37 opt_importdirs :: [FilePath]
41defaultOpts = IOption 0 False False True False False True True "" []
43-- TODO: Add 'module data' to IState, which can be saved out and reloaded quickly (i.e
44-- without typechecking).
45-- This will include all the functions and data declarations, plus fixity declarations
48data IState = IState { tt_ctxt :: Context,
49 idris_constraints :: [(UConstraint, FC)],
50 idris_infixes :: [FixDecl],
51 idris_implicits :: Ctxt [PArg],
52 idris_statics :: Ctxt [Bool],
53 idris_classes :: Ctxt ClassInfo,
54 idris_dsls :: Ctxt DSL,
55 idris_optimisation :: Ctxt OptInfo,
56 idris_datatypes :: Ctxt TypeInfo,
57 idris_patdefs :: Ctxt [([Name], Term, Term)], -- not exported
58 idris_flags :: Ctxt [FnOpt],
59 idris_callgraph :: Ctxt [Name],
60 idris_calledgraph :: Ctxt [Name],
61 idris_totcheck :: [(FC, Name)],
63 idris_options :: IOption,
65 idris_metavars :: [Name],
66 syntax_rules :: [Syntax],
67 syntax_keywords :: [String],
68 imported :: [FilePath],
69 idris_prims :: [(Name, ([E.Name], E.Term))],
70 idris_scprims :: Prims,
71 idris_objs :: [FilePath],
72 idris_libs :: [String],
73 idris_hdrs :: [String],
74 last_proof :: Maybe (Name, [String]),
76 lastParse :: Maybe Name,
77 indent_stack :: [Int],
78 brace_stack :: [Maybe Int],
79 hide_list :: [(Name, Maybe Accessibility)],
80 default_access :: Accessibility,
81 ibc_write :: [IBCWrite],
82 compiled_so :: Maybe String
85-- information that needs writing for the current module's .ibc file
86data IBCWrite = IBCFix FixDecl
90 | IBCInstance Bool Name Name
100 | IBCAccess Name Accessibility
101 | IBCTotal Name Totality
102 | IBCFlags Name [FnOpt]
104 | IBCDef Name -- i.e. main context
107idrisInit = IState initContext [] [] emptyContext emptyContext emptyContext
108 emptyContext emptyContext emptyContext emptyContext
109 emptyContext emptyContext emptyContext
110 [] "" defaultOpts 6 [] [] [] [] [] [] [] [] []
111 Nothing Nothing Nothing [] [] [] Hidden [] Nothing
113-- The monad for the main REPL - reading and processing files and updating
114-- global state (hence the IO inner monad).
115type Idris = StateT IState (InputT IO)
117getContext :: Idris Context
118getContext = do i <- get; return (tt_ctxt i)
120getObjectFiles :: Idris [FilePath]
121getObjectFiles = do i <- get; return (idris_objs i)
123addObjectFile :: FilePath -> Idris ()
124addObjectFile f = do i <- get; put (i { idris_objs = f : idris_objs i })
126getLibs :: Idris [String]
127getLibs = do i <- get; return (idris_libs i)
129addLib :: String -> Idris ()
130addLib f = do i <- get; put (i { idris_libs = f : idris_libs i })
132addHdr :: String -> Idris ()
133addHdr f = do i <- get; put (i { idris_hdrs = f : idris_hdrs i })
135totcheck :: (FC, Name) -> Idris ()
136totcheck n = do i <- get; put (i { idris_totcheck = n : idris_totcheck i })
138setFlags :: Name -> [FnOpt] -> Idris ()
139setFlags n fs = do i <- get; put (i { idris_flags = addDef n fs (idris_flags i) })
141setAccessibility :: Name -> Accessibility -> Idris ()
144 let ctxt = setAccess n a (tt_ctxt i)
145 put (i { tt_ctxt = ctxt })
147setTotality :: Name -> Totality -> Idris ()
150 let ctxt = setTotal n a (tt_ctxt i)
151 put (i { tt_ctxt = ctxt })
153getTotality :: Name -> Idris Totality
156 case lookupTotal n (tt_ctxt i) of
158 _ -> return (Total [])
160addToCG :: Name -> [Name] -> Idris ()
161addToCG n ns = do i <- get
162 put (i { idris_callgraph = addDef n ns (idris_callgraph i) })
164addToCalledG :: Name -> [Name] -> Idris ()
165addToCalledG n ns = return () -- TODO
167-- Add a class instance function. Dodgy hack: Put integer instances first in the
168-- list so they are resolved by default.
170addInstance :: Bool -> Name -> Name -> Idris ()
173 case lookupCtxt Nothing n (idris_classes ist) of
175 do let cs = addDef n (CI a b c d (addI i ins)) (idris_classes ist)
176 put (ist { idris_classes = cs })
177 _ -> do let cs = addDef n (CI (MN 0 "none") [] [] [] [i]) (idris_classes ist)
178 put (ist { idris_classes = cs })
179 where addI i ins | int = i : ins
180 | otherwise = ins ++ [i]
182addClass :: Name -> ClassInfo -> Idris ()
185 let i' = case lookupCtxt Nothing n (idris_classes ist) of
186 [c] -> c { class_instances = class_instances i }
188 put (ist { idris_classes = addDef n i' (idris_classes ist) })
190addIBC :: IBCWrite -> Idris ()
193 when (notDef (ibc_write i)) $
194 put (i { ibc_write = ibc : ibc_write i })
195 where notDef [] = True
196 notDef (IBCDef n': is) | n == n' = False
197 notDef (_ : is) = notDef is
198addIBC ibc = do i <- get; put (i { ibc_write = ibc : ibc_write i })
201clearIBC = do i <- get; put (i { ibc_write = [] })
203getHdrs :: Idris [String]
204getHdrs = do i <- get; return (idris_hdrs i)
206setErrLine :: Int -> Idris ()
207setErrLine x = do i <- get;
209 Nothing -> put (i { errLine = Just x })
213clearErr = do i <- get
214 put (i { errLine = Nothing })
216getSO :: Idris (Maybe String)
218 return (compiled_so i)
220setSO :: Maybe String -> Idris ()
222 put (i { compiled_so = s })
224getIState :: Idris IState
227putIState :: IState -> Idris ()
231getName = do i <- get;
232 let idx = idris_name i;
233 put (i { idris_name = idx + 1 })
236checkUndefined :: FC -> Name -> Idris ()
239 case lookupTy Nothing n i of
240 (_:_) -> fail $ show fc ++ ":" ++
241 show n ++ " already defined"
244setContext :: Context -> Idris ()
245setContext ctxt = do i <- get; put (i { tt_ctxt = ctxt } )
247updateContext :: (Context -> Context) -> Idris ()
248updateContext f = do i <- get; put (i { tt_ctxt = f (tt_ctxt i) } )
250addConstraints :: FC -> (Int, [UConstraint]) -> Idris ()
251addConstraints fc (v, cs)
254 let ctxt' = ctxt { uconstraints = cs ++ uconstraints ctxt,
256 let ics = zip cs (repeat fc) ++ idris_constraints i
257 put (i { tt_ctxt = ctxt', idris_constraints = ics })
259addDeferred :: [(Name, Type)] -> Idris ()
260addDeferred ns = do mapM_ (\(n, t) -> updateContext (addTyDecl n (tidyNames [] t))) ns
262 put (i { idris_metavars = map fst ns ++ idris_metavars i })
263 where tidyNames used (Bind (MN i x) b sc)
264 = let n' = uniqueName (UN x) used in
265 Bind n' b $ tidyNames (n':used) sc
266 tidyNames used (Bind n b sc)
267 = let n' = uniqueName n used in
268 Bind n' b $ tidyNames (n':used) sc
271solveDeferred :: Name -> Idris ()
272solveDeferred n = do i <- get
273 put (i { idris_metavars = idris_metavars i \\ [n] })
275iputStrLn :: String -> Idris ()
276iputStrLn = liftIO . putStrLn
278iWarn :: FC -> String -> Idris ()
279iWarn fc err = liftIO $ putStrLn (show fc ++ ":" ++ err)
281setLogLevel :: Int -> Idris ()
282setLogLevel l = do i <- get
283 let opts = idris_options i
284 let opt' = opts { opt_logLevel = l }
285 put (i { idris_options = opt' } )
288logLevel = do i <- get
289 return (opt_logLevel (idris_options i))
291setErrContext :: Bool -> Idris ()
292setErrContext t = do i <- get
293 let opts = idris_options i
294 let opt' = opts { opt_errContext = t }
295 put (i { idris_options = opt' })
297errContext :: Idris Bool
298errContext = do i <- get
299 return (opt_errContext (idris_options i))
303 return (opt_repl (idris_options i))
305setREPL :: Bool -> Idris ()
306setREPL t = do i <- get
307 let opts = idris_options i
308 let opt' = opts { opt_repl = t }
309 put (i { idris_options = opt' })
313 return (opt_verbose (idris_options i))
315setVerbose :: Bool -> Idris ()
316setVerbose t = do i <- get
317 let opts = idris_options i
318 let opt' = opts { opt_verbose = t }
319 put (i { idris_options = opt' })
321typeInType :: Idris Bool
322typeInType = do i <- get
323 return (opt_typeintype (idris_options i))
325setTypeInType :: Bool -> Idris ()
326setTypeInType t = do i <- get
327 let opts = idris_options i
328 let opt' = opts { opt_typeintype = t }
329 put (i { idris_options = opt' })
331coverage :: Idris Bool
332coverage = do i <- get
333 return (opt_coverage (idris_options i))
335setCoverage :: Bool -> Idris ()
336setCoverage t = do i <- get
337 let opts = idris_options i
338 let opt' = opts { opt_coverage = t }
339 put (i { idris_options = opt' })
341setIBCSubDir :: FilePath -> Idris ()
342setIBCSubDir fp = do i <- get
343 let opts = idris_options i
344 let opt' = opts { opt_ibcsubdir = fp }
345 put (i { idris_options = opt' })
347valIBCSubDir :: IState -> Idris FilePath
348valIBCSubDir i = return (opt_ibcsubdir (idris_options i))
350setImportDirs :: [FilePath] -> Idris ()
351setImportDirs fps = do i <- get
352 let opts = idris_options i
353 let opt' = opts { opt_importdirs = fps }
354 put (i { idris_options = opt' })
356allImportDirs :: IState -> Idris [FilePath]
357allImportDirs i = do datadir <- liftIO $ getDataDir
358 let optdirs = opt_importdirs (idris_options i)
359 return ("." : (optdirs ++ [datadir]))
363 return (opt_showimp (idris_options i))
365setImpShow :: Bool -> Idris ()
366setImpShow t = do i <- get
367 let opts = idris_options i
368 let opt' = opts { opt_showimp = t }
369 put (i { idris_options = opt' })
371logLvl :: Int -> String -> Idris ()
372logLvl l str = do i <- get
373 let lvl = opt_logLevel (idris_options i)
375 $ do liftIO (putStrLn str)
376 put (i { idris_log = idris_log i ++ str ++ "\n" } )
378iLOG :: String -> Idris ()
381noErrors :: Idris Bool
382noErrors = do i <- get
384 Nothing -> return True
387setTypeCase :: Bool -> Idris ()
388setTypeCase t = do i <- get
389 let opts = idris_options i
390 let opt' = opts { opt_typecase = t }
391 put (i { idris_options = opt' })
393-- Commands in the REPL
395data Command = Quit | Help | Eval PTerm | Check PTerm | TotCheck Name
397 | Compile String | Execute | ExecVal PTerm
398 | Metavars | Prove Name | AddProof | Universes
400 | LogLvl Int | Spec PTerm | HNF PTerm | Defn Name
401 | Info Name | DebugInfo Name
403 | SetOpt Opt | UnsetOpt Opt
406data Opt = Filename String
427-- Parsed declarations
429data Fixity = Infixl { prec :: Int }
430 | Infixr { prec :: Int }
431 | InfixN { prec :: Int }
432 | PrefixN { prec :: Int }
435deriving instance Binary Fixity
438instance Show Fixity where
439 show (Infixl i) = "infixl " ++ show i
440 show (Infixr i) = "infixr " ++ show i
441 show (InfixN i) = "infix " ++ show i
442 show (PrefixN i) = "prefix " ++ show i
444data FixDecl = Fix Fixity String
447deriving instance Binary FixDecl
450instance Ord FixDecl where
451 compare (Fix x _) (Fix y _) = compare (prec x) (prec y)
454data Static = Static | Dynamic
457deriving instance Binary Static
460-- Mark bindings with their explicitness, and laziness
461data Plicity = Imp { plazy :: Bool,
463 | Exp { plazy :: Bool,
465 | Constraint { plazy :: Bool,
467 | TacImp { plazy :: Bool,
473deriving instance Binary Plicity
476impl = Imp False Dynamic
477expl = Exp False Dynamic
478constraint = Constraint False Dynamic
479tacimpl = TacImp False Dynamic
481data FnOpt = Inlinable | TotalFn | AssertTotal | TCGen
482 | CExport String -- export, with a C name
483 | Specialise [Name] -- specialise it, freeze these names
486deriving instance Binary FnOpt
491inlinable :: FnOpts -> Bool
492inlinable = elem Inlinable
494data PDecl' t = PFix FC Fixity [String] -- fixity declaration
495 | PTy SyntaxInfo FC FnOpts Name t -- type declaration
496 | PClauses FC FnOpts Name [PClause' t] -- pattern clause
497 | PData SyntaxInfo FC (PData' t) -- data declaration
498 | PParams FC [(Name, t)] [PDecl' t] -- params block
499 | PNamespace String [PDecl' t] -- new namespace
500 | PRecord SyntaxInfo FC Name t Name t -- record declaration
501 | PClass SyntaxInfo FC
504 [(Name, t)] -- parameters
505 [PDecl' t] -- declarations
506 | PInstance SyntaxInfo FC [t] -- constraints
509 t -- full instance type
510 (Maybe Name) -- explicit name
514 | PDirective (Idris ())
517deriving instance Binary PDecl'
520data PClause' t = PClause FC Name t [t] t [PDecl' t]
521 | PWith FC Name t [t] t [PDecl' t]
522 | PClauseR FC [t] t [PDecl' t]
523 | PWithR FC [t] t [PDecl' t]
526deriving instance Binary PClause'
529data PData' t = PDatadecl { d_name :: Name,
531 d_cons :: [(Name, t, FC)] }
534deriving instance Binary PData'
537-- Handy to get a free function for applying PTerm -> PTerm functions
538-- across a program, by deriving Functor
540type PDecl = PDecl' PTerm
541type PData = PData' PTerm
542type PClause = PClause' PTerm
544-- get all the names declared in a decl
546declared :: PDecl -> [Name]
547declared (PFix _ _ _) = []
548declared (PTy _ _ _ n t) = [n]
549declared (PClauses _ _ n _) = [] -- not a declaration
550declared (PData _ _ (PDatadecl n _ ts)) = n : map fstt ts
551 where fstt (a, _, _) = a
552declared (PParams _ _ ds) = concatMap declared ds
553declared (PNamespace _ ds) = concatMap declared ds
554-- declared (PImport _) = []
556defined :: PDecl -> [Name]
557defined (PFix _ _ _) = []
558defined (PTy _ _ _ n t) = []
559defined (PClauses _ _ n _) = [n] -- not a declaration
560defined (PData _ _ (PDatadecl n _ ts)) = n : map fstt ts
561 where fstt (a, _, _) = a
562defined (PParams _ _ ds) = concatMap defined ds
563defined (PNamespace _ ds) = concatMap defined ds
564-- declared (PImport _) = []
566updateN :: [(Name, Name)] -> Name -> Name
567updateN ns n | Just n' <- lookup n ns = n'
570updateNs :: [(Name, Name)] -> PTerm -> PTerm
572updateNs ns t = mapPT updateRef t
573 where updateRef (PRef fc f) = PRef fc (updateN ns f)
576-- updateDNs :: [(Name, Name)] -> PDecl -> PDecl
578-- updateDNs ns (PTy s f n t) | Just n' <- lookup n ns = PTy s f n' t
579-- updateDNs ns (PClauses f n c) | Just n' <- lookup n ns = PClauses f n' (map updateCNs c)
580-- where updateCNs ns (PClause n l ts r ds)
581-- = PClause (updateN ns n) (fmap (updateNs ns) l)
582-- (map (fmap (updateNs ns)) ts)
583-- (fmap (updateNs ns) r)
584-- (map (updateDNs ns) ds)
587-- High level language terms
589data PTerm = PQuote Raw
591 | PLam Name PTerm PTerm
592 | PPi Plicity Name PTerm PTerm
593 | PLet Name PTerm PTerm PTerm
594 | PTyped PTerm PTerm -- term with explicit type
595 | PApp FC PTerm [PArg]
596 | PCase FC PTerm [(PTerm, PTerm)]
602 | PPair FC PTerm PTerm
603 | PDPair FC PTerm PTerm PTerm
604 | PAlternative Bool [PTerm] -- True if only one may work
605 | PHidden PTerm -- irrelevant or hidden pattern
614 | PTactics [PTactic] -- as PProof, but no auto solving
615 | PElabError Err -- error to report on elaboration
616 | PImpossible -- special case for declaring when an LHS can't typecheck
619deriving instance Binary PTerm
622mapPT :: (PTerm -> PTerm) -> PTerm -> PTerm
623mapPT f t = f (mpt t) where
624 mpt (PLam n t s) = PLam n (mapPT f t) (mapPT f s)
625 mpt (PPi p n t s) = PPi p n (mapPT f t) (mapPT f s)
626 mpt (PLet n ty v s) = PLet n (mapPT f ty) (mapPT f v) (mapPT f s)
627 mpt (PApp fc t as) = PApp fc (mapPT f t) (map (fmap (mapPT f)) as)
628 mpt (PCase fc c os) = PCase fc (mapPT f c) (map (pmap (mapPT f)) os)
629 mpt (PEq fc l r) = PEq fc (mapPT f l) (mapPT f r)
630 mpt (PTyped l r) = PTyped (mapPT f l) (mapPT f r)
631 mpt (PPair fc l r) = PPair fc (mapPT f l) (mapPT f r)
632 mpt (PDPair fc l t r) = PDPair fc (mapPT f l) (mapPT f t) (mapPT f r)
633 mpt (PAlternative a as) = PAlternative a (map (mapPT f) as)
634 mpt (PHidden t) = PHidden (mapPT f t)
635 mpt (PDoBlock ds) = PDoBlock (map (fmap (mapPT f)) ds)
636 mpt (PProof ts) = PProof (map (fmap (mapPT f)) ts)
637 mpt (PTactics ts) = PTactics (map (fmap (mapPT f)) ts)
641data PTactic' t = Intro [Name] | Intros | Focus Name
642 | Refine Name [Bool] | Rewrite t | LetTac Name t
643 | Exact t | Compute | Trivial
646 | ProofState | ProofTerm | Undo
647 | Try (PTactic' t) (PTactic' t)
648 | TSeq (PTactic' t) (PTactic' t)
650 deriving (Show, Eq, Functor)
652deriving instance Binary PTactic'
655instance Sized a => Sized (PTactic' a) where
656 size (Intro nms) = 1 + size nms
658 size (Focus nm) = 1 + size nm
659 size (Refine nm bs) = 1 + size nm + length bs
660 size (Rewrite t) = 1 + size t
661 size (LetTac nm t) = 1 + size nm + size t
662 size (Exact t) = 1 + size t
670 size (Try l r) = 1 + size l + size r
671 size (TSeq l r) = 1 + size l + size r
675type PTactic = PTactic' PTerm
677data PDo' t = DoExp FC t
682 deriving (Eq, Functor)
684deriving instance Binary PDo'
687instance Sized a => Sized (PDo' a) where
688 size (DoExp fc t) = 1 + size fc + size t
689 size (DoBind fc nm t) = 1 + size fc + size nm + size t
690 size (DoBindP fc l r) = 1 + size fc + size l + size r
691 size (DoLet fc nm l r) = 1 + size fc + size nm + size l + size r
692 size (DoLetP fc l r) = 1 + size fc + size l + size r
696-- The priority gives a hint as to elaboration order. Best to elaborate
697-- things early which will help give a more concrete type to other
698-- variables, e.g. a before (interpTy a).
700data PArg' t = PImp { priority :: Int,
701 lazyarg :: Bool, pname :: Name, getTm :: t }
702 | PExp { priority :: Int,
703 lazyarg :: Bool, getTm :: t }
704 | PConstraint { priority :: Int,
705 lazyarg :: Bool, getTm :: t }
706 | PTacImplicit { priority :: Int,
707 lazyarg :: Bool, pname :: Name,
710 deriving (Show, Eq, Functor)
712instance Sized a => Sized (PArg' a) where
713 size (PImp p l nm trm) = 1 + size nm + size trm
714 size (PExp p l trm) = 1 + size trm
715 size (PConstraint p l trm) = 1 + size trm
716 size (PTacImplicit p l nm scr trm) = 1 + size nm + size scr + size trm
719deriving instance Binary PArg'
724pconst = PConstraint 0 False
725ptacimp = PTacImplicit 0 True
727type PArg = PArg' PTerm
731data ClassInfo = CI { instanceName :: Name,
732 class_methods :: [(Name, (FnOpts, PTerm))],
733 class_defaults :: [(Name, (Name, PDecl))], -- method name -> default impl
734 class_params :: [Name],
735 class_instances :: [Name] }
738deriving instance Binary ClassInfo
741data OptInfo = Optimise { collapsible :: Bool,
742 forceable :: [Int], -- argument positions
746deriving instance Binary OptInfo
750data TypeInfo = TI { con_names :: [Name] }
753deriving instance Binary TypeInfo
756-- Syntactic sugar info
758data DSL' t = DSL { dsl_bind :: t,
763 index_first :: Maybe t,
764 index_next :: Maybe t,
765 dsl_lambda :: Maybe t,
768 deriving (Show, Functor)
770deriving instance Binary DSL'
775data SynContext = PatternSyntax | TermSyntax | AnySyntax
778deriving instance Binary SynContext
781data Syntax = Rule [SSymbol] PTerm SynContext
784deriving instance Binary Syntax
787data SSymbol = Keyword Name
793deriving instance Binary SSymbol
796initDSL = DSL (PRef f (UN ">>="))
797 (PRef f (UN "return"))
805 where f = FC "(builtin)" 0
807data SyntaxInfo = Syn { using :: [(Name, PTerm)],
808 syn_params :: [(Name, PTerm)],
809 syn_namespace :: [String],
811 decoration :: Name -> Name,
813 implicitAllowed :: Bool,
817deriving instance Binary SyntaxInfo
820defaultSyntax = Syn [] [] [] [] id False False initDSL
822expandNS :: SyntaxInfo -> Name -> Name
823expandNS syn n@(NS _ _) = n
824expandNS syn n = case syn_namespace syn of
829--- Pretty printing declarations and terms
831instance Show PTerm where
832 show tm = showImp False tm
834instance Pretty PTerm where
835 pretty = prettyImp False
837instance Show PDecl where
838 show d = showDeclImp False d
840instance Show PClause where
841 show c = showCImp True c
843instance Show PData where
844 show d = showDImp False d
846showDeclImp _ (PFix _ f ops) = show f ++ " " ++ showSep ", " ops
847showDeclImp t (PTy _ _ _ n ty) = show n ++ " : " ++ showImp t ty
848showDeclImp _ (PClauses _ _ n c) = showSep "\n" (map show c)
849showDeclImp _ (PData _ _ d) = show d
851showCImp :: Bool -> PClause -> String
852showCImp impl (PClause _ n l ws r w)
853 = showImp impl l ++ showWs ws ++ " = " ++ showImp impl r
854 ++ " where " ++ show w
857 showWs (x : xs) = " | " ++ showImp impl x ++ showWs xs
858showCImp impl (PWith _ n l ws r w)
859 = showImp impl l ++ showWs ws ++ " with " ++ showImp impl r
860 ++ " { " ++ show w ++ " } "
863 showWs (x : xs) = " | " ++ showImp impl x ++ showWs xs
866showDImp :: Bool -> PData -> String
867showDImp impl (PDatadecl n ty cons)
868 = "data " ++ show n ++ " : " ++ showImp impl ty ++ " where\n\t"
870 (map (\ (n, t, _) -> show n ++ " : " ++ showImp impl t) cons)
872getImps :: [PArg] -> [(Name, PTerm)]
874getImps (PImp _ _ n tm : xs) = (n, tm) : getImps xs
875getImps (_ : xs) = getImps xs
877getExps :: [PArg] -> [PTerm]
879getExps (PExp _ _ tm : xs) = tm : getExps xs
880getExps (_ : xs) = getExps xs
882getConsts :: [PArg] -> [PTerm]
884getConsts (PConstraint _ _ tm : xs) = tm : getConsts xs
885getConsts (_ : xs) = getConsts xs
887getAll :: [PArg] -> [PTerm]
890prettyImp :: Bool -> PTerm -> Doc
891prettyImp impl = prettySe 10
893 prettySe p (PQuote r) =
894 if size r > breakingSize then
895 text "![" $$ pretty r <> text "]"
897 text "![" <> pretty r <> text "]"
898 prettySe p (PRef fc n) =
904 prettyBasic n@(UN _) = pretty n
905 prettyBasic (MN _ s) = text s
906 prettyBasic (NS n s) = (foldr (<>) empty (intersperse (text ".") (map text $ reverse s))) <> prettyBasic n
907 prettySe p (PLam n ty sc) =
909 if size sc > breakingSize then
910 text "λ" <> pretty n <+> text "=>" $+$ pretty sc
912 text "λ" <> pretty n <+> text "=>" <+> pretty sc
913 prettySe p (PLet n ty v sc) =
915 if size sc > breakingSize then
916 text "let" <+> pretty n <+> text "=" <+> prettySe 10 v <+> text "in" $+$
917 nest nestingSize (prettySe 10 sc)
919 text "let" <+> pretty n <+> text "=" <+> prettySe 10 v <+> text "in" <+>
921 prettySe p (PPi (Exp l s) n ty sc)
922 | n `elem` allNamesIn sc || impl =
923 let open = if l then text "|" <> lparen else lparen in
925 if size sc > breakingSize then
926 open <> pretty n <+> colon <+> prettySe 10 ty <> rparen <+>
927 st <+> text "->" $+$ prettySe 10 sc
929 open <> pretty n <+> colon <+> prettySe 10 ty <> rparen <+>
930 st <+> text "->" <+> prettySe 10 sc
933 if size sc > breakingSize then
934 prettySe 0 ty <+> st <+> text "->" $+$ prettySe 10 sc
936 prettySe 0 ty <+> st <+> text "->" <+> prettySe 10 sc
940 Static -> text "[static]"
942 prettySe p (PPi (Imp l s) n ty sc)
944 let open = if l then text "|" <> lbrace else lbrace in
946 if size sc > breakingSize then
947 open <> pretty n <+> colon <+> prettySe 10 ty <> rbrace <+>
948 st <+> text "->" <+> prettySe 10 sc
950 open <> pretty n <+> colon <+> prettySe 10 ty <> rbrace <+>
951 st <+> text "->" <+> prettySe 10 sc
952 | otherwise = prettySe 10 sc
956 Static -> text $ "[static]"
958 prettySe p (PPi (Constraint _ _) n ty sc) =
960 if size sc > breakingSize then
961 prettySe 10 ty <+> text "=>" <+> prettySe 10 sc
963 prettySe 10 ty <+> text "=>" $+$ prettySe 10 sc
964 prettySe p (PPi (TacImp _ _ s) n ty sc) =
966 if size sc > breakingSize then
967 lbrace <> text "tacimp" <+> pretty n <+> colon <+> prettySe 10 ty <>
968 rbrace <+> text "->" $+$ prettySe 10 sc
970 lbrace <> text "tacimp" <+> pretty n <+> colon <+> prettySe 10 ty <>
971 rbrace <+> text "->" <+> prettySe 10 sc
972 prettySe p (PApp _ (PRef _ f) [])
973 | not impl = pretty f
974 prettySe p (PApp _ (PRef _ op@(UN (f:_))) args)
975 | length (getExps args) == 2 && (not impl) && (not $ isAlpha f) =
976 let [l, r] = getExps args in
978 if size r > breakingSize then
979 prettySe 1 l <+> pretty op $+$ prettySe 0 r
981 prettySe 1 l <+> pretty op <+> prettySe 0 r
982 prettySe p (PApp _ f as) =
983 let args = getExps as in
988 -- foldr (<+>) empty $ map prettyArgS as
991 -- foldr (<+>) empty $ map prettyArgSe args
994 if size r > breakingSize then
995 l $+$ nest nestingSize (prettyArgS r)
1000 if size r > breakingSize then
1001 l $+$ nest nestingSize (prettyArgSe r)
1004 prettySe p (PCase _ scr opts) =
1005 text "case" <+> prettySe 10 scr <+> text "of" $+$ nest nestingSize prettyBody
1007 prettyBody = foldr ($$) empty $ intersperse (text "|") $ map sc opts
1009 sc (l, r) = prettySe 10 l <+> text "=>" <+> prettySe 10 r
1010 prettySe p (PHidden tm) = text "." <> prettySe 0 tm
1011 prettySe p (PRefl _) = text "refl"
1012 prettySe p (PResolveTC _) = text "resolvetc"
1013 prettySe p (PTrue _) = text "()"
1014 prettySe p (PFalse _) = text "_|_"
1015 prettySe p (PEq _ l r) =
1017 if size r > breakingSize then
1018 prettySe 10 l <+> text "=" $$ nest nestingSize (prettySe 10 r)
1020 prettySe 10 l <+> text "=" <+> prettySe 10 r
1021 prettySe p (PTyped l r) =
1022 lparen <> prettySe 10 l <+> colon <+> prettySe 10 r <> rparen
1023 prettySe p (PPair _ l r) =
1024 if size r > breakingSize then
1025 lparen <> prettySe 10 l <> text "," $+$
1026 prettySe 10 r <> rparen
1028 lparen <> prettySe 10 l <> text "," <+> prettySe 10 r <> rparen
1029 prettySe p (PDPair _ l t r) =
1030 if size r > breakingSize then
1031 lparen <> prettySe 10 l <+> text "**" $+$
1032 prettySe 10 r <> rparen
1034 lparen <> prettySe 10 l <+> text "**" <+> prettySe 10 r <> rparen
1035 prettySe p (PAlternative a as) =
1036 lparen <> text "|" <> prettyAs <> text "|" <> rparen
1039 foldr (\l -> \r -> l <+> text "," <+> r) empty $ map (prettySe 10) as
1040 prettySe p PSet = text "Set"
1041 prettySe p (PConstant c) = pretty c
1042 -- XXX: add pretty for tactics
1043 prettySe p (PProof ts) =
1044 text "proof" <+> lbrace $+$ nest nestingSize (text . show $ ts) $+$ rbrace
1045 prettySe p (PTactics ts) =
1046 text "tactics" <+> lbrace $+$ nest nestingSize (text . show $ ts) $+$ rbrace
1047 prettySe p (PMetavar n) = text "?" <> pretty n
1048 prettySe p (PReturn f) = text "return"
1049 prettySe p PImpossible = text "impossible"
1050 prettySe p Placeholder = text "_"
1051 prettySe p (PDoBlock _) = text "do block pretty not implemented"
1052 prettySe p (PElabError s) = pretty s
1054 prettySe p _ = text "test"
1056 prettyArgS (PImp _ _ n tm) = prettyArgSi (n, tm)
1057 prettyArgS (PExp _ _ tm) = prettyArgSe tm
1058 prettyArgS (PConstraint _ _ tm) = prettyArgSc tm
1059 prettyArgS (PTacImplicit _ _ n _ tm) = prettyArgSti (n, tm)
1061 prettyArgSe arg = prettySe 0 arg
1062 prettyArgSi (n, val) = lbrace <> pretty n <+> text "=" <+> prettySe 10 val <> rbrace
1063 prettyArgSc val = lbrace <> lbrace <> prettySe 10 val <> rbrace <> rbrace
1064 prettyArgSti (n, val) = lbrace <> text "auto" <+> pretty n <+> text "=" <+> prettySe 10 val <> rbrace
1066 bracket outer inner doc
1067 | inner > outer = lparen <> doc <> rparen
1070showImp :: Bool -> PTerm -> String
1071showImp impl tm = se 10 tm where
1072 se p (PQuote r) = "![" ++ show r ++ "]"
1073 se p (PRef fc n) = if impl then show n -- ++ "[" ++ show fc ++ "]"
1075 where showbasic n@(UN _) = show n
1076 showbasic (MN _ s) = s
1077 showbasic (NS n s) = showSep "." (reverse s) ++ "." ++ showbasic n
1078 se p (PLam n ty sc) = bracket p 2 $ "\\ " ++ show n ++
1079 (if impl then " : " ++ se 10 ty else "") ++ " => "
1081 se p (PLet n ty v sc) = bracket p 2 $ "let " ++ show n ++ " = " ++ se 10 v ++
1083 se p (PPi (Exp l s) n ty sc)
1084 | n `elem` allNamesIn sc || impl
1086 if l then "|(" else "(" ++
1087 show n ++ " : " ++ se 10 ty ++
1090 | otherwise = bracket p 2 $ se 0 ty ++ " " ++ st ++ "-> " ++ se 10 sc
1091 where st = case s of
1092 Static -> "[static] "
1094 se p (PPi (Imp l s) n ty sc)
1095 | impl = bracket p 2 $ if l then "|{" else "{" ++
1096 show n ++ " : " ++ se 10 ty ++
1097 "} " ++ st ++ "-> " ++ se 10 sc
1098 | otherwise = se 10 sc
1099 where st = case s of
1100 Static -> "[static] "
1102 se p (PPi (Constraint _ _) n ty sc)
1103 = bracket p 2 $ se 10 ty ++ " => " ++ se 10 sc
1104 se p (PPi (TacImp _ _ s) n ty sc)
1105 = bracket p 2 $ "{tacimp " ++ show n ++ " : " ++ se 10 ty ++ "} -> " ++ se 10 sc
1106 se p (PApp _ (PRef _ f) [])
1108 se p (PApp _ (PRef _ op@(UN (f:_))) args)
1109 | length (getExps args) == 2 && not impl && not (isAlpha f)
1110 = let [l, r] = getExps args in
1111 bracket p 1 $ se 1 l ++ " " ++ show op ++ " " ++ se 0 r
1113 = let args = getExps as in
1114 bracket p 1 $ se 1 f ++ if impl then concatMap sArg as
1115 else concatMap seArg args
1116 se p (PCase _ scr opts) = "case " ++ se 10 scr ++ " of " ++ showSep " | " (map sc opts)
1117 where sc (l, r) = se 10 l ++ " => " ++ se 10 r
1118 se p (PHidden tm) = "." ++ se 0 tm
1119 se p (PRefl _) = "refl"
1120 se p (PResolveTC _) = "resolvetc"
1121 se p (PTrue _) = "()"
1122 se p (PFalse _) = "_|_"
1123 se p (PEq _ l r) = bracket p 2 $ se 10 l ++ " = " ++ se 10 r
1124 se p (PTyped l r) = "(" ++ se 10 l ++ " : " ++ se 10 r ++ ")"
1125 se p (PPair _ l r) = "(" ++ se 10 l ++ ", " ++ se 10 r ++ ")"
1126 se p (PDPair _ l t r) = "(" ++ se 10 l ++ " ** " ++ se 10 r ++ ")"
1127 se p (PAlternative a as) = "(|" ++ showSep " , " (map (se 10) as) ++ "|)"
1129 se p (PConstant c) = show c
1130 se p (PProof ts) = "proof { " ++ show ts ++ "}"
1131 se p (PTactics ts) = "tactics { " ++ show ts ++ "}"
1132 se p (PMetavar n) = "?" ++ show n
1133 se p (PReturn f) = "return"
1134 se p PImpossible = "impossible"
1135 se p Placeholder = "_"
1136 se p (PDoBlock _) = "do block show not implemented"
1137 se p (PElabError s) = show s
1138-- se p x = "Not implemented"
1140 sArg (PImp _ _ n tm) = siArg (n, tm)
1141 sArg (PExp _ _ tm) = seArg tm
1142 sArg (PConstraint _ _ tm) = scArg tm
1143 sArg (PTacImplicit _ _ n _ tm) = stiArg (n, tm)
1145 seArg arg = " " ++ se 0 arg
1146 siArg (n, val) = " {" ++ show n ++ " = " ++ se 10 val ++ "}"
1147 scArg val = " {{" ++ se 10 val ++ "}}"
1148 stiArg (n, val) = " {auto " ++ show n ++ " = " ++ se 10 val ++ "}"
1150 bracket outer inner str | inner > outer = "(" ++ str ++ ")"
1156 | PLam Name PTerm PTerm
1157 | PPi Plicity Name PTerm PTerm
1158 | PLet Name PTerm PTerm PTerm
1159 | PTyped PTerm PTerm -- term with explicit type
1160 | PApp FC PTerm [PArg]
1161 | PCase FC PTerm [(PTerm, PTerm)]
1166 | PEq FC PTerm PTerm
1167 | PPair FC PTerm PTerm
1168 | PDPair FC PTerm PTerm PTerm
1169 | PAlternative [PTerm]
1170 | PHidden PTerm -- irrelevant or hidden pattern
1179 | PTactics [PTactic] -- as PProof, but no auto solving
1180 | PElabError Err -- error to report on elaboration
1181 | PImpossible -- special case for declaring when an LHS can't typecheck
1184instance Sized PTerm where
1185 size (PQuote rawTerm) = size rawTerm
1186 size (PRef fc name) = size name
1187 size (PLam name ty bdy) = 1 + size ty + size bdy
1188 size (PPi plicity name ty bdy) = 1 + size ty + size bdy
1189 size (PLet name ty def bdy) = 1 + size ty + size def + size bdy
1190 size (PTyped trm ty) = 1 + size trm + size ty
1191 size (PApp fc name args) = 1 + size args
1192 size (PCase fc trm bdy) = 1 + size trm + size bdy
1194 size (PFalse fc) = 1
1196 size (PResolveTC fc) = 1
1197 size (PEq fc left right) = 1 + size left + size right
1198 size (PPair fc left right) = 1 + size left + size right
1199 size (PDPair fs left ty right) = 1 + size left + size ty + size right
1200 size (PAlternative a alts) = 1 + size alts
1201 size (PHidden hidden) = size hidden
1203 size (PConstant const) = 1 + size const
1204 size Placeholder = 1
1205 size (PDoBlock dos) = 1 + size dos
1206 size (PIdiom fc term) = 1 + size term
1207 size (PReturn fc) = 1
1208 size (PMetavar name) = 1
1209 size (PProof tactics) = size tactics
1210 size (PElabError err) = size err
1211 size PImpossible = 1
1213allNamesIn :: PTerm -> [Name]
1214allNamesIn tm = nub $ ni [] tm
1217 | not (n `elem` env) = [n]
1218 ni env (PApp _ f as) = ni env f ++ concatMap (ni env) (map getTm as)
1219 ni env (PCase _ c os) = ni env c ++ concatMap (ni env) (map snd os)
1220 ni env (PLam n ty sc) = ni env ty ++ ni (n:env) sc
1221 ni env (PPi _ n ty sc) = ni env ty ++ ni (n:env) sc
1222 ni env (PHidden tm) = ni env tm
1223 ni env (PEq _ l r) = ni env l ++ ni env r
1224 ni env (PTyped l r) = ni env l ++ ni env r
1225 ni env (PPair _ l r) = ni env l ++ ni env r
1226 ni env (PDPair _ (PRef _ n) t r) = ni env t ++ ni (n:env) r
1227 ni env (PDPair _ l t r) = ni env l ++ ni env t ++ ni env r
1228 ni env (PAlternative a ls) = concatMap (ni env) ls
1231namesIn :: [(Name, PTerm)] -> IState -> PTerm -> [Name]
1232namesIn uvars ist tm = nub $ ni [] tm
1235 | not (n `elem` env)
1236 = case lookupTy Nothing n (tt_ctxt ist) of
1238 _ -> if n `elem` (map fst uvars) then [n] else []
1239 ni env (PApp _ f as) = ni env f ++ concatMap (ni env) (map getTm as)
1240 ni env (PCase _ c os) = ni env c ++ concatMap (ni env) (map snd os)
1241 ni env (PLam n ty sc) = ni env ty ++ ni (n:env) sc
1242 ni env (PPi _ n ty sc) = ni env ty ++ ni (n:env) sc
1243 ni env (PEq _ l r) = ni env l ++ ni env r
1244 ni env (PTyped l r) = ni env l ++ ni env r
1245 ni env (PPair _ l r) = ni env l ++ ni env r
1246 ni env (PDPair _ (PRef _ n) t r) = ni env t ++ ni (n:env) r
1247 ni env (PDPair _ l t r) = ni env l ++ ni env t ++ ni env r
1248 ni env (PAlternative a as) = concatMap (ni env) as
1249 ni env (PHidden tm) = ni env tm
1252-- For inferring types of things
1256inferTy = MN 0 "__Infer"
1257inferCon = MN 0 "__infer"
1258inferDecl = PDatadecl inferTy
1260 [(inferCon, PPi impl (MN 0 "A") PSet (
1261 PPi expl (MN 0 "a") (PRef bi (MN 0 "A"))
1262 (PRef bi inferTy)), bi)]
1264infTerm t = PApp bi (PRef bi inferCon) [pimp (MN 0 "A") Placeholder, pexp t]
1265infP = P (TCon 6 0) inferTy (Set (UVal 0))
1267getInferTerm, getInferType :: Term -> Term
1268getInferTerm (Bind n b sc) = Bind n b $ getInferTerm sc
1269getInferTerm (App (App _ _) tm) = tm
1270getInferTerm tm = error ("getInferTerm " ++ show tm)
1272getInferType (Bind n b sc) = Bind n b $ getInferType sc
1273getInferType (App (App _ ty) _) = ty
1275-- Handy primitives: Unit, False, Pair, MkPair, =, mkForeign
1277primNames = [unitTy, unitCon,
1278 falseTy, pairTy, pairCon,
1279 eqTy, eqCon, inferTy, inferCon]
1281unitTy = MN 0 "__Unit"
1282unitCon = MN 0 "__II"
1283unitDecl = PDatadecl unitTy PSet
1284 [(unitCon, PRef bi unitTy, bi)]
1286falseTy = MN 0 "__False"
1287falseDecl = PDatadecl falseTy PSet []
1289pairTy = MN 0 "__Pair"
1290pairCon = MN 0 "__MkPair"
1291pairDecl = PDatadecl pairTy (piBind [(n "A", PSet), (n "B", PSet)] PSet)
1292 [(pairCon, PPi impl (n "A") PSet (
1293 PPi impl (n "B") PSet (
1294 PPi expl (n "a") (PRef bi (n "A")) (
1295 PPi expl (n "b") (PRef bi (n "B"))
1296 (PApp bi (PRef bi pairTy) [pexp (PRef bi (n "A")),
1297 pexp (PRef bi (n "B"))])))), bi)]
1302eqDecl = PDatadecl eqTy (piBind [(n "a", PSet), (n "b", PSet),
1303 (n "x", PRef bi (n "a")), (n "y", PRef bi (n "b"))]
1305 [(eqCon, PPi impl (n "a") PSet (
1306 PPi impl (n "x") (PRef bi (n "a"))
1307 (PApp bi (PRef bi eqTy) [pimp (n "a") Placeholder,
1308 pimp (n "b") Placeholder,
1309 pexp (PRef bi (n "x")),
1310 pexp (PRef bi (n "x"))])), bi)]
1313-- Defined in builtins.idr
1314sigmaTy = UN "Exists"
1315existsCon = UN "Ex_intro"
1317piBind :: [(Name, PTerm)] -> PTerm -> PTerm
1319piBind ((n, ty):ns) t = PPi expl n ty (piBind ns t)
1321tcname (UN ('@':_)) = True
1322tcname (NS n _) = tcname n
1325-- Dealing with parameters
1327expandParams :: (Name -> Name) -> [(Name, PTerm)] -> [Name] -> PTerm -> PTerm
1328expandParams dec ps ns tm = en tm
1330 -- if we shadow a name (say in a lambda binding) that is used in a call to
1331 -- a lifted function, we need access to both names - once in the scope of the
1332 -- binding and once to call the lifted functions. So we'll explicitly shadow
1333 -- it. (Yes, it's a hack. The alternative would be to resolve names earlier
1334 -- but we didn't...)
1336 mkShadow (UN n) = MN 0 n
1337 mkShadow (MN i n) = MN (i+1) n
1338 mkShadow (NS x s) = NS (mkShadow x) s
1341 | n `elem` map fst ps
1342 = let n' = mkShadow n in
1343 PLam n' (en t) (en (shadow n n' s))
1344 | otherwise = PLam n (en t) (en s)
1346 | n `elem` map fst ps
1347 = let n' = mkShadow n in
1348 PPi p n' (en t) (en (shadow n n' s))
1349 | otherwise = PPi p n (en t) (en s)
1351 | n `elem` map fst ps
1352 = let n' = mkShadow n in
1353 PLet n' (en ty) (en v) (en (shadow n n' s))
1354 | otherwise = PLet n (en ty) (en v) (en s)
1355 en (PEq f l r) = PEq f (en l) (en r)
1356 en (PTyped l r) = PTyped (en l) (en r)
1357 en (PPair f l r) = PPair f (en l) (en r)
1358 en (PDPair f l t r) = PDPair f (en l) (en t) (en r)
1359 en (PAlternative a as) = PAlternative a (map en as)
1360 en (PHidden t) = PHidden (en t)
1361 en (PDoBlock ds) = PDoBlock (map (fmap en) ds)
1362 en (PProof ts) = PProof (map (fmap en) ts)
1363 en (PTactics ts) = PTactics (map (fmap en) ts)
1366 | n `elem` ns = PQuote (Var (dec n))
1367 en (PApp fc (PRef fc' n) as)
1368 | n `elem` ns = PApp fc (PRef fc' (dec n))
1369 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
1371 | n `elem` ns = PApp fc (PRef fc (dec n))
1372 (map (pexp . (PRef fc)) (map fst ps))
1373 en (PApp fc f as) = PApp fc (en f) (map (fmap en) as)
1374 en (PCase fc c os) = PCase fc (en c) (map (pmap en) os)
1377expandParamsD :: IState ->
1378 (Name -> Name) -> [(Name, PTerm)] -> [Name] -> PDecl -> PDecl
1379expandParamsD ist dec ps ns (PTy syn fc o n ty)
1381 then PTy syn fc o (dec n) (piBind ps (expandParams dec ps ns ty))
1382 else PTy syn fc o n (expandParams dec ps ns ty)
1383expandParamsD ist dec ps ns (PClauses fc opts n cs)
1384 = let n' = if n `elem` ns then dec n else n in
1385 PClauses fc opts n' (map expandParamsC cs)
1387 expandParamsC (PClause fc n lhs ws rhs ds)
1388 = let -- ps' = updateps True (namesIn ist rhs) (zip ps [0..])
1389 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
1390 n' = if n `elem` ns then dec n else n in
1391 PClause fc n' (expandParams dec ps'' ns lhs)
1392 (map (expandParams dec ps'' ns) ws)
1393 (expandParams dec ps'' ns rhs)
1394 (map (expandParamsD ist dec ps'' ns) ds)
1395 expandParamsC (PWith fc n lhs ws wval ds)
1396 = let -- ps' = updateps True (namesIn ist wval) (zip ps [0..])
1397 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
1398 n' = if n `elem` ns then dec n else n in
1399 PWith fc n' (expandParams dec ps'' ns lhs)
1400 (map (expandParams dec ps'' ns) ws)
1401 (expandParams dec ps'' ns wval)
1402 (map (expandParamsD ist dec ps'' ns) ds)
1403 updateps yn nm [] = []
1404 updateps yn nm (((a, t), i):as)
1405 | (a `elem` nm) == yn = (a, t) : updateps yn nm as
1406 | otherwise = (MN i (show n ++ "_u"), t) : updateps yn nm as
1408expandParamsD ist dec ps ns d = d
1410-- Calculate a priority for a type, for deciding elaboration order
1411-- * if it's just a type variable or concrete type, do it early (0)
1412-- * if there's only type variables and injective constructors, do it next (1)
1413-- * if there's a function type, next (2)
1414-- * finally, everything else (3)
1416getPriority :: IState -> PTerm -> Int
1417getPriority i tm = pri tm
1420 case lookupP Nothing n (tt_ctxt i) of
1421 ((P (DCon _ _) _ _):_) -> 1
1422 ((P (TCon _ _) _ _):_) -> 1
1423 ((P Ref _ _):_) -> 4
1424 [] -> 0 -- must be locally bound, if it's not an error...
1425 pri (PPi _ _ x y) = max 5 (max (pri x) (pri y))
1429 pri (PEq _ l r) = max 1 (max (pri l) (pri r))
1430 pri (PApp _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.getTm) as)))
1431 pri (PCase _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.snd) as)))
1432 pri (PTyped l r) = pri l
1433 pri (PPair _ l r) = max 1 (max (pri l) (pri r))
1434 pri (PDPair _ l t r) = max 1 (max (pri l) (max (pri t) (pri r)))
1435 pri (PAlternative a as) = maximum (map pri as)
1436 pri (PConstant _) = 0
1440addStatics :: Name -> Term -> PTerm -> Idris ()
1441addStatics n tm ptm =
1442 do let (statics, dynamics) = initStatics tm ptm
1443 let stnames = nub $ concatMap freeNames (map snd statics)
1444 let dnames = nub $ concatMap freeNames (map snd dynamics)
1445 when (not (null statics)) $
1446 logLvl 7 $ show n ++ " " ++ show statics ++ "\n" ++ show dynamics
1447 ++ "\n" ++ show stnames ++ "\n" ++ show dnames
1448 let statics' = nub $ map fst statics ++
1449 filter (\x -> not (elem x dnames)) stnames
1450 let stpos = staticList statics' tm
1452 put (i { idris_statics = addDef n stpos (idris_statics i) })
1453 addIBC (IBCStatic n)
1455 initStatics (Bind n (Pi ty) sc) (PPi p _ _ s)
1456 = let (static, dynamic) = initStatics (instantiate (P Bound n ty) sc) s in
1457 if pstatic p == Static then ((n, ty) : static, dynamic)
1458 else (static, (n, ty) : dynamic)
1459 initStatics t pt = ([], [])
1461 staticList sts (Bind n (Pi _) sc) = (n `elem` sts) : staticList sts sc
1464-- Dealing with implicit arguments
1466-- Add implicit Pi bindings for any names in the term which appear in an
1467-- argument position.
1469-- This has become a right mess already. Better redo it some time...
1471implicit :: SyntaxInfo -> Name -> PTerm -> Idris PTerm
1474 let (tm', impdata) = implicitise syn i ptm
1475-- let (tm'', spos) = findStatics i tm'
1476 put (i { idris_implicits = addDef n impdata (idris_implicits i) })
1478 logLvl 5 ("Implicit " ++ show n ++ " " ++ show impdata)
1480-- put (i { idris_statics = addDef n spos (idris_statics i) })
1483implicitise :: SyntaxInfo -> IState -> PTerm -> (PTerm, [PArg])
1484implicitise syn ist tm
1485 = let (declimps, ns') = execState (imps True [] tm) ([], [])
1486 ns = ns' \\ (map fst pvars ++ no_imp syn) in
1488 then (tm, reverse declimps)
1489 else implicitise syn ist (pibind uvars ns tm)
1492 pvars = syn_params syn
1494 dropAll (x:xs) ys | x `elem` ys = dropAll xs ys
1495 | otherwise = x : dropAll xs ys
1498 imps top env (PApp _ f as)
1499 = do (decls, ns) <- get
1500 let isn = concatMap (namesIn uvars ist) (map getTm as)
1501 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1502 imps top env (PPi (Imp l _) n ty sc)
1503 = do let isn = nub (namesIn uvars ist ty) `dropAll` [n]
1505 put (PImp (getPriority ist ty) l n ty : decls,
1506 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1507 imps True (n:env) sc
1508 imps top env (PPi (Exp l _) n ty sc)
1509 = do let isn = nub (namesIn uvars ist ty ++ case sc of
1510 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
1512 (decls, ns) <- get -- ignore decls in HO types
1513 put (PExp (getPriority ist ty) l ty : decls,
1514 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1515 imps True (n:env) sc
1516 imps top env (PPi (Constraint l _) n ty sc)
1517 = do let isn = nub (namesIn uvars ist ty ++ case sc of
1518 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
1520 (decls, ns) <- get -- ignore decls in HO types
1521 put (PConstraint 10 l ty : decls,
1522 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1523 imps True (n:env) sc
1524 imps top env (PPi (TacImp l _ scr) n ty sc)
1525 = do let isn = nub (namesIn uvars ist ty ++ case sc of
1526 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
1528 (decls, ns) <- get -- ignore decls in HO types
1529 put (PTacImplicit 10 l n scr ty : decls,
1530 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1531 imps True (n:env) sc
1532 imps top env (PEq _ l r)
1533 = do (decls, ns) <- get
1534 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1535 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1536 imps top env (PTyped l r)
1538 imps top env (PPair _ l r)
1539 = do (decls, ns) <- get
1540 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1541 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1542 imps top env (PDPair _ (PRef _ n) t r)
1543 = do (decls, ns) <- get
1544 let isn = nub (namesIn uvars ist t ++ namesIn uvars ist r) \\ [n]
1545 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
1546 imps top env (PDPair _ l t r)
1547 = do (decls, ns) <- get
1548 let isn = namesIn uvars ist l ++ namesIn uvars ist t ++
1550 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
1551 imps top env (PAlternative a as)
1552 = do (decls, ns) <- get
1553 let isn = concatMap (namesIn uvars ist) as
1554 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1555 imps top env (PLam n ty sc)
1556 = do imps False env ty
1557 imps False (n:env) sc
1558 imps top env (PHidden tm) = imps False env tm
1559 imps top env _ = return ()
1561 pibind using [] sc = sc
1562 pibind using (n:ns) sc
1563 = case lookup n using of
1564 Just ty -> PPi (Imp False Dynamic) n ty (pibind using ns sc)
1565 Nothing -> PPi (Imp False Dynamic) n Placeholder (pibind using ns sc)
1567-- Add implicit arguments in function calls
1568addImplPat :: IState -> PTerm -> PTerm
1569addImplPat = addImpl' True []
1571addImplBound :: IState -> [Name] -> PTerm -> PTerm
1572addImplBound ist ns = addImpl' False ns ist
1574addImpl :: IState -> PTerm -> PTerm
1575addImpl = addImpl' False []
1577-- TODO: in patterns, don't add implicits to function names guarded by constructors
1578-- and *not* inside a PHidden
1580addImpl' :: Bool -> [Name] -> IState -> PTerm -> PTerm
1581addImpl' inpat env ist ptm = ai env ptm
1584 | not (f `elem` env) = handleErr $ aiFn inpat inpat ist fc f []
1585 ai env (PHidden (PRef fc f))
1586 | not (f `elem` env) = handleErr $ aiFn inpat False ist fc f []
1587 ai env (PEq fc l r) = let l' = ai env l
1590 ai env (PTyped l r) = let l' = ai env l
1593 ai env (PPair fc l r) = let l' = ai env l
1596 ai env (PDPair fc l t r) = let l' = ai env l
1600 ai env (PAlternative a as) = let as' = map (ai env) as in
1602 ai env (PApp fc (PRef _ f) as)
1603 | not (f `elem` env)
1604 = let as' = map (fmap (ai env)) as in
1605 handleErr $ aiFn inpat False ist fc f as'
1606 ai env (PApp fc f as) = let f' = ai env f
1607 as' = map (fmap (ai env)) as in
1609 ai env (PCase fc c os) = let c' = ai env c
1610 os' = map (pmap (ai env)) os in
1612 ai env (PLam n ty sc) = let ty' = ai env ty
1613 sc' = ai (n:env) sc in
1615 ai env (PLet n ty val sc)
1616 = let ty' = ai env ty
1618 sc' = ai (n:env) sc in
1620 ai env (PPi p n ty sc) = let ty' = ai env ty
1621 sc' = ai (n:env) sc in
1623 ai env (PHidden tm) = PHidden (ai env tm)
1624 ai env (PProof ts) = PProof (map (fmap (ai env)) ts)
1625 ai env (PTactics ts) = PTactics (map (fmap (ai env)) ts)
1628 handleErr (Left err) = PElabError err
1629 handleErr (Right x) = x
1631-- if in a pattern, and there are no arguments, and there's no possible
1632-- names with zero explicit arguments, don't add implicits.
1634aiFn :: Bool -> Bool -> IState -> FC -> Name -> [PArg] -> Either Err PTerm
1635aiFn inpat True ist fc f []
1636 = case lookupCtxt Nothing f (idris_implicits ist) of
1637 [] -> Right $ PRef fc f
1638 alts -> if (any (all imp) alts)
1639 then aiFn inpat False ist fc f [] -- use it as a constructor
1640 else Right $ PRef fc f
1641 where imp (PExp _ _ _) = False
1643aiFn inpat expat ist fc f as
1644 | f `elem` primNames = Right $ PApp fc (PRef fc f) as
1645aiFn inpat expat ist fc f as
1646 -- This is where namespaces get resolved by adding PAlternative
1647 = case lookupCtxtName Nothing f (idris_implicits ist) of
1648 [(f',ns)] -> Right $ mkPApp fc (length ns) (PRef fc f') (insertImpl ns as)
1649 [] -> if f `elem` idris_metavars ist
1650 then Right $ PApp fc (PRef fc f) as
1651 else Right $ mkPApp fc (length as) (PRef fc f) as
1654 map (\(f', ns) -> mkPApp fc (length ns) (PRef fc f')
1655 (insertImpl ns as)) alts
1657 insertImpl :: [PArg] -> [PArg] -> [PArg]
1658 insertImpl (PExp p l ty : ps) (PExp _ _ tm : given) =
1659 PExp p l tm : insertImpl ps given
1660 insertImpl (PConstraint p l ty : ps) (PConstraint _ _ tm : given) =
1661 PConstraint p l tm : insertImpl ps given
1662 insertImpl (PConstraint p l ty : ps) given =
1663 PConstraint p l (PResolveTC fc) : insertImpl ps given
1664 insertImpl (PImp p l n ty : ps) given =
1665 case find n given [] of
1666 Just (tm, given') -> PImp p l n tm : insertImpl ps given'
1667 Nothing -> PImp p l n Placeholder : insertImpl ps given
1668 insertImpl (PTacImplicit p l n sc ty : ps) given =
1669 case find n given [] of
1670 Just (tm, given') -> PTacImplicit p l n sc tm : insertImpl ps given'
1672 then PTacImplicit p l n sc Placeholder : insertImpl ps given
1673 else PTacImplicit p l n sc sc : insertImpl ps given
1674 insertImpl expected [] = []
1675 insertImpl _ given = given
1677 find n [] acc = Nothing
1678 find n (PImp _ _ n' t : gs) acc
1679 | n == n' = Just (t, reverse acc ++ gs)
1680 find n (PTacImplicit _ _ n' _ t : gs) acc
1681 | n == n' = Just (t, reverse acc ++ gs)
1682 find n (g : gs) acc = find n gs (g : acc)
1685mkPApp fc a f as = let rest = drop a as in
1686 appRest fc (PApp fc f (take a as)) rest
1689 appRest fc f (a : as) = appRest fc (PApp fc f [a]) as
1691-- Find 'static' argument positions
1692-- (the declared ones, plus any names in argument position in the declared
1694-- FIXME: It's possible that this really has to happen after elaboration
1696findStatics :: IState -> PTerm -> (PTerm, [Bool])
1697findStatics ist tm = trace (showImp True tm) $
1698 let (ns, ss) = fs tm in
1699 runState (pos ns ss tm) []
1700 where fs (PPi p n t sc)
1701 | Static <- pstatic p
1702 = let (ns, ss) = fs sc in
1703 (namesIn [] ist t : ns, n : ss)
1704 | otherwise = let (ns, ss) = fs sc in
1708 inOne n ns = length (filter id (map (elem n) ns)) == 1
1710 pos ns ss (PPi p n t sc)
1711 | elem n ss = do sc' <- pos ns ss sc
1714 return (PPi (p { pstatic = Static }) n t sc')
1715 | otherwise = do sc' <- pos ns ss sc
1718 return (PPi p n t sc')
1719 pos ns ss t = return t
1721-- Debugging/logging stuff
1723dumpDecls :: [PDecl] -> String
1725dumpDecls (d:ds) = dumpDecl d ++ "\n" ++ dumpDecls ds
1727dumpDecl (PFix _ f ops) = show f ++ " " ++ showSep ", " ops
1728dumpDecl (PTy _ _ _ n t) = "tydecl " ++ show n ++ " : " ++ showImp True t
1729dumpDecl (PClauses _ _ n cs) = "pat " ++ show n ++ "\t" ++ showSep "\n\t" (map (showCImp True) cs)
1730dumpDecl (PData _ _ d) = showDImp True d
1731dumpDecl (PParams _ ns ps) = "params {" ++ show ns ++ "\n" ++ dumpDecls ps ++ "}\n"
1732dumpDecl (PNamespace n ps) = "namespace {" ++ n ++ "\n" ++ dumpDecls ps ++ "}\n"
1733dumpDecl (PSyntax _ syn) = "syntax " ++ show syn
1734dumpDecl (PClass _ _ cs n ps ds)
1735 = "class " ++ show cs ++ " " ++ show n ++ " " ++ show ps ++ "\n" ++ dumpDecls ds
1736dumpDecl (PInstance _ _ cs n _ t _ ds)
1737 = "instance " ++ show cs ++ " " ++ show n ++ " " ++ show t ++ "\n" ++ dumpDecls ds
1739-- dumpDecl (PImport i) = "import " ++ i
1741-- for 6.12/7 compatibility
1742data EitherErr a b = LeftErr a | RightOK b
1744instance Monad (EitherErr a) where
1747 (LeftErr e) >>= k = LeftErr e
1748 RightOK v >>= k = k v
1750toEither (LeftErr e) = Left e
1751toEither (RightOK ho) = Right ho
1753-- syntactic match of a against b, returning pair of variables in a
1754-- and what they match. Returns the pair that failed if not a match.
1756matchClause :: IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
1757matchClause = matchClause' False
1759matchClause' :: Bool -> IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
1760matchClause' names i x y = checkRpts $ match (fullApp x) (fullApp y) where
1761 matchArg x y = match (fullApp (getTm x)) (fullApp (getTm y))
1763 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
1766 match' x y = match (fullApp x) (fullApp y)
1767 match (PApp _ (PRef _ (NS (UN "fromInteger") ["builtins"])) [_,_,x]) x'
1768 | PConstant (I _) <- getTm x = match (getTm x) x'
1769 match x' (PApp _ (PRef _ (NS (UN "fromInteger") ["builtins"])) [_,_,x])
1770 | PConstant (I _) <- getTm x = match (getTm x) x'
1771 match (PApp _ (PRef _ (UN "lazy")) [_,x]) x' = match (getTm x) x'
1772 match x (PApp _ (PRef _ (UN "lazy")) [_,x']) = match x (getTm x')
1773 match (PApp _ f args) (PApp _ f' args')
1774 | length args == length args'
1775 = do mf <- match' f f'
1776 ms <- zipWithM matchArg args args'
1777 return (mf ++ concat ms)
1778-- match (PRef _ n) (PRef _ n') | n == n' = return []
1779-- | otherwise = Nothing
1780 match (PRef f n) (PApp _ x []) = match (PRef f n) x
1781 match (PApp _ x []) (PRef f n) = match x (PRef f n)
1782 match (PRef _ n) (PRef _ n') | n == n' = return []
1784 | not names && (not (isConName Nothing n (tt_ctxt i)) || tm == Placeholder)
1786 match (PEq _ l r) (PEq _ l' r') = do ml <- match' l l'
1789 match (PTyped l r) (PTyped l' r') = do ml <- match l l'
1792 match (PTyped l r) x = match l x
1793 match x (PTyped l r) = match x l
1794 match (PPair _ l r) (PPair _ l' r') = do ml <- match' l l'
1797 match (PDPair _ l t r) (PDPair _ l' t' r') = do ml <- match' l l'
1800 return (ml ++ mt ++ mr)
1801 match (PAlternative a as) (PAlternative a' as')
1802 = do ms <- zipWithM match' as as'
1804 match a@(PAlternative _ as) b
1805 = do let ms = zipWith match' as (repeat b)
1806 case (rights (map toEither ms)) of
1809 match (PCase _ _ _) _ = return [] -- lifted out
1810 match (PMetavar _) _ = return [] -- modified
1811 match (PQuote _) _ = return []
1812 match (PProof _) _ = return []
1813 match (PTactics _) _ = return []
1814 match (PRefl _) (PRefl _) = return []
1815 match (PResolveTC _) (PResolveTC _) = return []
1816 match (PTrue _) (PTrue _) = return []
1817 match (PFalse _) (PFalse _) = return []
1818 match (PReturn _) (PReturn _) = return []
1819 match (PPi _ _ t s) (PPi _ _ t' s') = do mt <- match' t t'
1822 match (PLam _ t s) (PLam _ t' s') = do mt <- match' t t'
1825 match (PLet _ t ty s) (PLet _ t' ty' s') = do mt <- match' t t'
1826 mty <- match' ty ty'
1828 return (mt ++ mty ++ ms)
1829 match (PHidden x) (PHidden y) = match' x y
1830 match Placeholder _ = return []
1831-- match _ Placeholder = return []
1832 match (PResolveTC _) _ = return []
1833 match a b | a == b = return []
1834 | otherwise = LeftErr (a, b)
1836 checkRpts (RightOK ms) = check ms where
1838 | Just t' <- lookup n xs = if t/=t' && t/=Placeholder && t'/=Placeholder
1841 check (_:xs) = check xs
1843 checkRpts (LeftErr x) = Left x
1845substMatches :: [(Name, PTerm)] -> PTerm -> PTerm
1846substMatches [] t = t
1847substMatches ((n,tm):ns) t = substMatch n tm (substMatches ns t)
1849substMatch :: Name -> PTerm -> PTerm -> PTerm
1850substMatch n tm t = sm t where
1851 sm (PRef _ n') | n == n' = tm
1852 sm (PLam x t sc) = PLam x (sm t) (sm sc)
1853 sm (PPi p x t sc) = PPi p x (sm t) (sm sc)
1854 sm (PApp f x as) = PApp f (sm x) (map (fmap sm) as)
1855 sm (PCase f x as) = PCase f (sm x) (map (pmap sm) as)
1856 sm (PEq f x y) = PEq f (sm x) (sm y)
1857 sm (PTyped x y) = PTyped (sm x) (sm y)
1858 sm (PPair f x y) = PPair f (sm x) (sm y)
1859 sm (PDPair f x t y) = PDPair f (sm x) (sm t) (sm y)
1860 sm (PAlternative a as) = PAlternative a (map sm as)
1861 sm (PHidden x) = PHidden (sm x)
1864shadow :: Name -> Name -> PTerm -> PTerm
1865shadow n n' t = sm t where
1866 sm (PRef fc x) | n == x = PRef fc n'
1867 sm (PLam x t sc) = PLam x (sm t) (sm sc)
1868 sm (PPi p x t sc) = PPi p x (sm t) (sm sc)
1869 sm (PApp f x as) = PApp f (sm x) (map (fmap sm) as)
1870 sm (PCase f x as) = PCase f (sm x) (map (pmap sm) as)
1871 sm (PEq f x y) = PEq f (sm x) (sm y)
1872 sm (PTyped x y) = PTyped (sm x) (sm y)
1873 sm (PPair f x y) = PPair f (sm x) (sm y)
1874 sm (PDPair f x t y) = PDPair f (sm x) (sm t) (sm y)
1875 sm (PAlternative a as) = PAlternative a (map sm as)
1876 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