1{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, DeriveFunctor,
2 TypeSynonymInstances, PatternGuards #-}
4module Idris.AbsSyntax where
11import System.Console.Haskeline
12import Control.Monad.State
18import qualified Epic.Epic as E
20data IOption = IOption { opt_logLevel :: Int,
22 opt_typeintype :: Bool,
30defaultOpts = IOption 0 False False True False True True
32-- TODO: Add 'module data' to IState, which can be saved out and reloaded quickly (i.e
33-- without typechecking).
34-- This will include all the functions and data declarations, plus fixity declarations
37data IState = IState { tt_ctxt :: Context,
38 idris_constraints :: [(UConstraint, FC)],
39 idris_infixes :: [FixDecl],
40 idris_implicits :: Ctxt [PArg],
41 idris_statics :: Ctxt [Bool],
42 idris_classes :: Ctxt ClassInfo,
43 idris_dsls :: Ctxt DSL,
44 idris_optimisation :: Ctxt OptInfo,
45 idris_datatypes :: Ctxt TypeInfo,
46 idris_patdefs :: Ctxt [(Term, Term)], -- not exported
47 idris_flags :: Ctxt [FnOpt],
48 idris_callgraph :: Ctxt [Name],
50 idris_options :: IOption,
52 idris_metavars :: [Name],
53 syntax_rules :: [Syntax],
54 syntax_keywords :: [String],
55 imported :: [FilePath],
56 idris_prims :: [(Name, ([E.Name], E.Term))],
57 idris_objs :: [FilePath],
58 idris_libs :: [String],
59 idris_hdrs :: [String],
60 last_proof :: Maybe (Name, [String]),
62 lastParse :: Maybe Name,
63 indent_stack :: [Int],
64 brace_stack :: [Maybe Int],
65 hide_list :: [(Name, Maybe Accessibility)],
66 default_access :: Accessibility,
67 ibc_write :: [IBCWrite],
68 compiled_so :: Maybe String
71-- information that needs writing for the current module's .ibc file
72data IBCWrite = IBCFix FixDecl
85 | IBCAccess Name Accessibility
86 | IBCTotal Name Totality
87 | IBCFlags Name [FnOpt]
89 | IBCDef Name -- i.e. main context
92idrisInit = IState initContext [] [] emptyContext emptyContext emptyContext
93 emptyContext emptyContext emptyContext emptyContext
94 emptyContext emptyContext
95 "" defaultOpts 6 [] [] [] [] [] [] [] []
96 Nothing Nothing Nothing [] [] [] Hidden [] Nothing
98-- The monad for the main REPL - reading and processing files and updating
99-- global state (hence the IO inner monad).
100type Idris = StateT IState (InputT IO)
102getContext :: Idris Context
103getContext = do i <- get; return (tt_ctxt i)
105getObjectFiles :: Idris [FilePath]
106getObjectFiles = do i <- get; return (idris_objs i)
108addObjectFile :: FilePath -> Idris ()
109addObjectFile f = do i <- get; put (i { idris_objs = f : idris_objs i })
111getLibs :: Idris [String]
112getLibs = do i <- get; return (idris_libs i)
114addLib :: String -> Idris ()
115addLib f = do i <- get; put (i { idris_libs = f : idris_libs i })
117addHdr :: String -> Idris ()
118addHdr f = do i <- get; put (i { idris_hdrs = f : idris_hdrs i })
120setFlags :: Name -> [FnOpt] -> Idris ()
121setFlags n fs = do i <- get; put (i { idris_flags = addDef n fs (idris_flags i) })
123setAccessibility :: Name -> Accessibility -> Idris ()
126 let ctxt = setAccess n a (tt_ctxt i)
127 put (i { tt_ctxt = ctxt })
129setTotality :: Name -> Totality -> Idris ()
132 let ctxt = setTotal n a (tt_ctxt i)
133 put (i { tt_ctxt = ctxt })
135addToCG :: Name -> [Name] -> Idris ()
136addToCG n ns = do i <- get
137 put (i { idris_callgraph = addDef n ns (idris_callgraph i) })
139addIBC :: IBCWrite -> Idris ()
142 when (notDef (ibc_write i)) $
143 put (i { ibc_write = ibc : ibc_write i })
144 where notDef [] = True
145 notDef (IBCDef n': is) | n == n' = False
146 notDef (_ : is) = notDef is
147addIBC ibc = do i <- get; put (i { ibc_write = ibc : ibc_write i })
150clearIBC = do i <- get; put (i { ibc_write = [] })
152getHdrs :: Idris [String]
153getHdrs = do i <- get; return (idris_hdrs i)
155setErrLine :: Int -> Idris ()
156setErrLine x = do i <- get;
158 Nothing -> put (i { errLine = Just x })
162clearErr = do i <- get
163 put (i { errLine = Nothing })
165getSO :: Idris (Maybe String)
167 return (compiled_so i)
169setSO :: Maybe String -> Idris ()
171 put (i { compiled_so = s })
173getIState :: Idris IState
176putIState :: IState -> Idris ()
180getName = do i <- get;
181 let idx = idris_name i;
182 put (i { idris_name = idx + 1 })
185checkUndefined :: FC -> Name -> Idris ()
188 case lookupTy Nothing n i of
189 (_:_) -> fail $ show fc ++ ":" ++
190 show n ++ " already defined"
193setContext :: Context -> Idris ()
194setContext ctxt = do i <- get; put (i { tt_ctxt = ctxt } )
196updateContext :: (Context -> Context) -> Idris ()
197updateContext f = do i <- get; put (i { tt_ctxt = f (tt_ctxt i) } )
199addConstraints :: FC -> (Int, [UConstraint]) -> Idris ()
200addConstraints fc (v, cs)
203 let ctxt' = ctxt { uconstraints = cs ++ uconstraints ctxt,
205 let ics = zip cs (repeat fc) ++ idris_constraints i
206 put (i { tt_ctxt = ctxt', idris_constraints = ics })
208addDeferred :: [(Name, Type)] -> Idris ()
209addDeferred ns = do mapM_ (\(n, t) -> updateContext (addTyDecl n (tidyNames [] t))) ns
211 put (i { idris_metavars = map fst ns ++ idris_metavars i })
212 where tidyNames used (Bind (MN i x) b sc)
213 = let n' = uniqueName (UN x) used in
214 Bind n' b $ tidyNames (n':used) sc
215 tidyNames used (Bind n b sc)
216 = let n' = uniqueName n used in
217 Bind n' b $ tidyNames (n':used) sc
220solveDeferred :: Name -> Idris ()
221solveDeferred n = do i <- get
222 put (i { idris_metavars = idris_metavars i \\ [n] })
224iputStrLn :: String -> Idris ()
225iputStrLn = liftIO . putStrLn
227iWarn :: FC -> String -> Idris ()
228iWarn fc err = liftIO $ putStrLn (show fc ++ ":" ++ err)
230setLogLevel :: Int -> Idris ()
231setLogLevel l = do i <- get
232 let opts = idris_options i
233 let opt' = opts { opt_logLevel = l }
234 put (i { idris_options = opt' } )
237logLevel = do i <- get
238 return (opt_logLevel (idris_options i))
242 return (opt_repl (idris_options i))
244setREPL :: Bool -> Idris ()
245setREPL t = do i <- get
246 let opts = idris_options i
247 let opt' = opts { opt_repl = t }
248 put (i { idris_options = opt' })
252 return (opt_verbose (idris_options i))
254setVerbose :: Bool -> Idris ()
255setVerbose t = do i <- get
256 let opts = idris_options i
257 let opt' = opts { opt_verbose = t }
258 put (i { idris_options = opt' })
260typeInType :: Idris Bool
261typeInType = do i <- get
262 return (opt_typeintype (idris_options i))
264setTypeInType :: Bool -> Idris ()
265setTypeInType t = do i <- get
266 let opts = idris_options i
267 let opt' = opts { opt_typeintype = t }
268 put (i { idris_options = opt' })
270coverage :: Idris Bool
271coverage = do i <- get
272 return (opt_coverage (idris_options i))
274setCoverage :: Bool -> Idris ()
275setCoverage t = do i <- get
276 let opts = idris_options i
277 let opt' = opts { opt_coverage = t }
278 put (i { idris_options = opt' })
282 return (opt_showimp (idris_options i))
284setImpShow :: Bool -> Idris ()
285setImpShow t = do i <- get
286 let opts = idris_options i
287 let opt' = opts { opt_showimp = t }
288 put (i { idris_options = opt' })
290logLvl :: Int -> String -> Idris ()
291logLvl l str = do i <- get
292 let lvl = opt_logLevel (idris_options i)
294 $ do liftIO (putStrLn str)
295 put (i { idris_log = idris_log i ++ str ++ "\n" } )
297iLOG :: String -> Idris ()
300noErrors :: Idris Bool
301noErrors = do i <- get
303 Nothing -> return True
306setTypeCase :: Bool -> Idris ()
307setTypeCase t = do i <- get
308 let opts = idris_options i
309 let opt' = opts { opt_typecase = t }
310 put (i { idris_options = opt' })
312-- Commands in the REPL
314data Command = Quit | Help | Eval PTerm | Check PTerm | Reload | Edit
315 | Compile String | Execute | ExecVal PTerm
316 | Metavars | Prove Name | AddProof | Universes
318 | LogLvl Int | Spec PTerm | HNF PTerm | Defn Name | Info Name
321-- Parsed declarations
323data Fixity = Infixl { prec :: Int }
324 | Infixr { prec :: Int }
325 | InfixN { prec :: Int }
326 | PrefixN { prec :: Int }
329deriving instance Binary Fixity
332instance Show Fixity where
333 show (Infixl i) = "infixl " ++ show i
334 show (Infixr i) = "infixr " ++ show i
335 show (InfixN i) = "infix " ++ show i
336 show (PrefixN i) = "prefix " ++ show i
338data FixDecl = Fix Fixity String
341deriving instance Binary FixDecl
344instance Ord FixDecl where
345 compare (Fix x _) (Fix y _) = compare (prec x) (prec y)
348data Static = Static | Dynamic
351deriving instance Binary Static
354-- Mark bindings with their explicitness, and laziness
355data Plicity = Imp { plazy :: Bool,
357 | Exp { plazy :: Bool,
359 | Constraint { plazy :: Bool,
361 | TacImp { plazy :: Bool,
367deriving instance Binary Plicity
370impl = Imp False Dynamic
371expl = Exp False Dynamic
372constraint = Constraint False Static
373tacimpl = TacImp False Dynamic
375data FnOpt = Inlinable | TotalFn | TCGen
378deriving instance Binary FnOpt
383inlinable :: FnOpts -> Bool
384inlinable = elem Inlinable
386data PDecl' t = PFix FC Fixity [String] -- fixity declaration
387 | PTy SyntaxInfo FC FnOpts Name t -- type declaration
388 | PClauses FC FnOpts Name [PClause' t] -- pattern clause
389 | PData SyntaxInfo FC (PData' t) -- data declaration
390 | PParams FC [(Name, t)] [PDecl' t] -- params block
391 | PNamespace String [PDecl' t] -- new namespace
392 | PRecord SyntaxInfo FC Name t Name t -- record declaration
393 | PClass SyntaxInfo FC
396 [(Name, t)] -- parameters
397 [PDecl' t] -- declarations
398 | PInstance SyntaxInfo FC [t] -- constraints
401 t -- full instance type
405 | PDirective (Idris ())
408data PClause' t = PClause Name t [t] t [PDecl' t]
409 | PWith Name t [t] t [PDecl' t]
410 | PClauseR [t] t [PDecl' t]
411 | PWithR [t] t [PDecl' t]
414data PData' t = PDatadecl { d_name :: Name,
416 d_cons :: [(Name, t, FC)] }
419-- Handy to get a free function for applying PTerm -> PTerm functions
420-- across a program, by deriving Functor
422type PDecl = PDecl' PTerm
423type PData = PData' PTerm
424type PClause = PClause' PTerm
426-- get all the names declared in a decl
428declared :: PDecl -> [Name]
429declared (PFix _ _ _) = []
430declared (PTy _ _ _ n t) = [n]
431declared (PClauses _ _ n _) = [] -- not a declaration
432declared (PData _ _ (PDatadecl n _ ts)) = n : map fstt ts
433 where fstt (a, _, _) = a
434declared (PParams _ _ ds) = concatMap declared ds
435declared (PNamespace _ ds) = concatMap declared ds
436-- declared (PImport _) = []
438updateN :: [(Name, Name)] -> Name -> Name
439updateN ns n | Just n' <- lookup n ns = n'
442updateNs :: [(Name, Name)] -> PTerm -> PTerm
444updateNs ns t = mapPT updateRef t
445 where updateRef (PRef fc f) = PRef fc (updateN ns f)
448-- updateDNs :: [(Name, Name)] -> PDecl -> PDecl
450-- updateDNs ns (PTy s f n t) | Just n' <- lookup n ns = PTy s f n' t
451-- updateDNs ns (PClauses f n c) | Just n' <- lookup n ns = PClauses f n' (map updateCNs c)
452-- where updateCNs ns (PClause n l ts r ds)
453-- = PClause (updateN ns n) (fmap (updateNs ns) l)
454-- (map (fmap (updateNs ns)) ts)
455-- (fmap (updateNs ns) r)
456-- (map (updateDNs ns) ds)
459-- High level language terms
461data PTerm = PQuote Raw
463 | PLam Name PTerm PTerm
464 | PPi Plicity Name PTerm PTerm
465 | PLet Name PTerm PTerm PTerm
466 | PTyped PTerm PTerm -- term with explicit type
467 | PApp FC PTerm [PArg]
468 | PCase FC PTerm [(PTerm, PTerm)]
474 | PPair FC PTerm PTerm
475 | PDPair FC PTerm PTerm PTerm
476 | PAlternative [PTerm]
477 | PHidden PTerm -- irrelevant or hidden pattern
486 | PTactics [PTactic] -- as PProof, but no auto solving
487 | PElabError String -- error to report on elaboration
488 | PImpossible -- special case for declaring when an LHS can't typecheck
491deriving instance Binary PTerm
494mapPT :: (PTerm -> PTerm) -> PTerm -> PTerm
495mapPT f t = f (mpt t) where
496 mpt (PLam n t s) = PLam n (mapPT f t) (mapPT f s)
497 mpt (PPi p n t s) = PPi p n (mapPT f t) (mapPT f s)
498 mpt (PLet n ty v s) = PLet n (mapPT f ty) (mapPT f v) (mapPT f s)
499 mpt (PApp fc t as) = PApp fc (mapPT f t) (map (fmap (mapPT f)) as)
500 mpt (PCase fc c os) = PCase fc (mapPT f c) (map (pmap (mapPT f)) os)
501 mpt (PEq fc l r) = PEq fc (mapPT f l) (mapPT f r)
502 mpt (PTyped l r) = PTyped (mapPT f l) (mapPT f r)
503 mpt (PPair fc l r) = PPair fc (mapPT f l) (mapPT f r)
504 mpt (PDPair fc l t r) = PDPair fc (mapPT f l) (mapPT f t) (mapPT f r)
505 mpt (PAlternative as) = PAlternative (map (mapPT f) as)
506 mpt (PHidden t) = PHidden (mapPT f t)
507 mpt (PDoBlock ds) = PDoBlock (map (fmap (mapPT f)) ds)
508 mpt (PProof ts) = PProof (map (fmap (mapPT f)) ts)
509 mpt (PTactics ts) = PTactics (map (fmap (mapPT f)) ts)
513data PTactic' t = Intro [Name] | Intros | Focus Name
514 | Refine Name [Bool] | Rewrite t | LetTac Name t
515 | Exact t | Compute | Trivial
518 | ProofState | ProofTerm | Undo
519 | Try (PTactic' t) (PTactic' t)
520 | TSeq (PTactic' t) (PTactic' t)
522 deriving (Show, Eq, Functor)
524deriving instance Binary PTactic'
527type PTactic = PTactic' PTerm
529data PDo' t = DoExp FC t
534 deriving (Eq, Functor)
536deriving instance Binary PDo'
541-- The priority gives a hint as to elaboration order. Best to elaborate
542-- things early which will help give a more concrete type to other
543-- variables, e.g. a before (interpTy a).
545data PArg' t = PImp { priority :: Int,
546 lazyarg :: Bool, pname :: Name, getTm :: t }
547 | PExp { priority :: Int,
548 lazyarg :: Bool, getTm :: t }
549 | PConstraint { priority :: Int,
550 lazyarg :: Bool, getTm :: t }
551 | PTacImplicit { priority :: Int,
552 lazyarg :: Bool, pname :: Name,
555 deriving (Show, Eq, Functor)
557deriving instance Binary PArg'
562pconst = PConstraint 0 False
563ptacimp = PTacImplicit 0 True
565type PArg = PArg' PTerm
569data ClassInfo = CI { instanceName :: Name,
570 class_methods :: [(Name, PTerm)],
571 class_defaults :: [(Name, Name)], -- method name -> default impl
572 class_params :: [Name] }
575deriving instance Binary ClassInfo
578data OptInfo = Optimise { collapsible :: Bool,
579 forceable :: [Int], -- argument positions
583deriving instance Binary OptInfo
587data TypeInfo = TI { con_names :: [Name] }
590deriving instance Binary TypeInfo
593-- Syntactic sugar info
595data DSL' t = DSL { dsl_bind :: t,
600 index_first :: Maybe t,
601 index_next :: Maybe t,
602 dsl_lambda :: Maybe t,
605 deriving (Show, Functor)
607deriving instance Binary DSL'
612data SynContext = PatternSyntax | TermSyntax | AnySyntax
615deriving instance Binary SynContext
618data Syntax = Rule [SSymbol] PTerm SynContext
621deriving instance Binary Syntax
624data SSymbol = Keyword Name
630deriving instance Binary SSymbol
633initDSL = DSL (PRef f (UN ">>="))
634 (PRef f (UN "return"))
642 where f = FC "(builtin)" 0
644data SyntaxInfo = Syn { using :: [(Name, PTerm)],
645 syn_params :: [(Name, PTerm)],
646 syn_namespace :: [String],
648 decoration :: Name -> Name,
653defaultSyntax = Syn [] [] [] [] id False initDSL
655--- Pretty printing declarations and terms
657instance Show PTerm where
658 show tm = showImp False tm
660instance Show PDecl where
661 show (PFix _ f ops) = show f ++ " " ++ showSep ", " ops
662 show (PTy _ _ _ n ty) = show n ++ " : " ++ show ty
663 show (PClauses _ _ n c) = showSep "\n" (map show c)
664 show (PData _ _ d) = show d
666instance Show PClause where
667 show c = showCImp True c
669instance Show PData where
670 show d = showDImp False d
672showCImp :: Bool -> PClause -> String
673showCImp impl (PClause n l ws r w)
674 = showImp impl l ++ showWs ws ++ " = " ++ showImp impl r
675 ++ " where " ++ show w
678 showWs (x : xs) = " | " ++ showImp impl x ++ showWs xs
679showCImp impl (PWith n l ws r w)
680 = showImp impl l ++ showWs ws ++ " with " ++ showImp impl r
681 ++ " { " ++ show w ++ " } "
684 showWs (x : xs) = " | " ++ showImp impl x ++ showWs xs
687showDImp :: Bool -> PData -> String
688showDImp impl (PDatadecl n ty cons)
689 = "data " ++ show n ++ " : " ++ showImp impl ty ++ " where\n\t"
691 (map (\ (n, t, _) -> show n ++ " : " ++ showImp impl t) cons)
693getImps :: [PArg] -> [(Name, PTerm)]
695getImps (PImp _ _ n tm : xs) = (n, tm) : getImps xs
696getImps (_ : xs) = getImps xs
698getExps :: [PArg] -> [PTerm]
700getExps (PExp _ _ tm : xs) = tm : getExps xs
701getExps (_ : xs) = getExps xs
703getConsts :: [PArg] -> [PTerm]
705getConsts (PConstraint _ _ tm : xs) = tm : getConsts xs
706getConsts (_ : xs) = getConsts xs
708getAll :: [PArg] -> [PTerm]
711showImp :: Bool -> PTerm -> String
712showImp impl tm = se 10 tm where
713 se p (PQuote r) = "![" ++ show r ++ "]"
714 se p (PRef _ n) = if impl then show n
716 where showbasic n@(UN _) = show n
717 showbasic (MN _ s) = s
718 showbasic (NS n s) = showSep "." (reverse s) ++ "." ++ showbasic n
719 se p (PLam n ty sc) = bracket p 2 $ "\\ " ++ show n ++ " => " ++ show sc
720 se p (PLet n ty v sc) = bracket p 2 $ "let " ++ show n ++ " = " ++ se 10 v ++
722 se p (PPi (Exp l s) n ty sc)
723 | n `elem` allNamesIn sc = bracket p 2 $
724 if l then "|(" else "(" ++
725 show n ++ " : " ++ se 10 ty ++
728 | otherwise = bracket p 2 $ se 0 ty ++ " " ++ st ++ "-> " ++ se 10 sc
730 Static -> "[static] "
732 se p (PPi (Imp l s) n ty sc)
733 | impl = bracket p 2 $ if l then "|{" else "{" ++
734 show n ++ " : " ++ se 10 ty ++
735 "} " ++ st ++ "-> " ++ se 10 sc
736 | otherwise = se 10 sc
738 Static -> "[static] "
740 se p (PPi (Constraint _ _) n ty sc)
741 = bracket p 2 $ se 10 ty ++ " => " ++ se 10 sc
742 se p (PApp _ (PRef _ f) [])
744 se p (PApp _ (PRef _ op@(UN (f:_))) args)
745 | length (getExps args) == 2 && not impl && not (isAlpha f)
746 = let [l, r] = getExps args in
747 bracket p 1 $ se 1 l ++ " " ++ show op ++ " " ++ se 0 r
749 = let args = getExps as in
750 bracket p 1 $ se 1 f ++ if impl then concatMap sArg as
751 else concatMap seArg args
752 se p (PCase _ scr opts) = "case " ++ se 10 scr ++ " of " ++ showSep " | " (map sc opts)
753 where sc (l, r) = se 10 l ++ " => " ++ se 10 r
754 se p (PHidden tm) = "." ++ se 0 tm
755 se p (PRefl _) = "refl"
756 se p (PResolveTC _) = "resolvetc"
757 se p (PTrue _) = "()"
758 se p (PFalse _) = "_|_"
759 se p (PEq _ l r) = bracket p 2 $ se 10 l ++ " = " ++ se 10 r
760 se p (PTyped l r) = "(" ++ se 10 l ++ " : " ++ se 10 r ++ ")"
761 se p (PPair _ l r) = "(" ++ se 10 l ++ ", " ++ se 10 r ++ ")"
762 se p (PDPair _ l t r) = "(" ++ se 10 l ++ " ** " ++ se 10 r ++ ")"
763 se p (PAlternative as) = "(|" ++ showSep " , " (map (se 10) as) ++ "|)"
765 se p (PConstant c) = show c
766 se p (PProof ts) = "proof { " ++ show ts ++ "}"
767 se p (PTactics ts) = "tactics { " ++ show ts ++ "}"
768 se p (PMetavar n) = "?" ++ show n
769 se p (PReturn f) = "return"
770 se p PImpossible = "impossible"
771 se p Placeholder = "_"
772 se p (PDoBlock _) = "do block show not implemented"
773 se p (PElabError s) = s
774-- se p x = "Not implemented"
776 sArg (PImp _ _ n tm) = siArg (n, tm)
777 sArg (PExp _ _ tm) = seArg tm
778 sArg (PConstraint _ _ tm) = scArg tm
779 sArg (PTacImplicit _ _ n _ tm) = stiArg (n, tm)
781 seArg arg = " " ++ se 0 arg
782 siArg (n, val) = " {" ++ show n ++ " = " ++ se 10 val ++ "}"
783 scArg val = " {{" ++ se 10 val ++ "}}"
784 stiArg (n, val) = " {auto " ++ show n ++ " = " ++ se 10 val ++ "}"
786 bracket outer inner str | inner > outer = "(" ++ str ++ ")"
789allNamesIn :: PTerm -> [Name]
790allNamesIn tm = nub $ ni [] tm
793 | not (n `elem` env) = [n]
794 ni env (PApp _ f as) = ni env f ++ concatMap (ni env) (map getTm as)
795 ni env (PCase _ c os) = ni env c ++ concatMap (ni env) (map snd os)
796 ni env (PLam n ty sc) = ni env ty ++ ni (n:env) sc
797 ni env (PPi _ n ty sc) = ni env ty ++ ni (n:env) sc
798 ni env (PHidden tm) = ni env tm
799 ni env (PEq _ l r) = ni env l ++ ni env r
800 ni env (PTyped l r) = ni env l ++ ni env r
801 ni env (PPair _ l r) = ni env l ++ ni env r
802 ni env (PDPair _ (PRef _ n) t r) = ni env t ++ ni (n:env) r
803 ni env (PDPair _ l t r) = ni env l ++ ni env t ++ ni env r
804 ni env (PAlternative ls) = concatMap (ni env) ls
807namesIn :: [(Name, PTerm)] -> IState -> PTerm -> [Name]
808namesIn uvars ist tm = nub $ ni [] tm
812 = case lookupTy Nothing n (tt_ctxt ist) of
814 _ -> if n `elem` (map fst uvars) then [n] else []
815 ni env (PApp _ f as) = ni env f ++ concatMap (ni env) (map getTm as)
816 ni env (PCase _ c os) = ni env c ++ concatMap (ni env) (map snd os)
817 ni env (PLam n ty sc) = ni env ty ++ ni (n:env) sc
818 ni env (PPi _ n ty sc) = ni env ty ++ ni (n:env) sc
819 ni env (PEq _ l r) = ni env l ++ ni env r
820 ni env (PTyped l r) = ni env l ++ ni env r
821 ni env (PPair _ l r) = ni env l ++ ni env r
822 ni env (PDPair _ (PRef _ n) t r) = ni env t ++ ni (n:env) r
823 ni env (PDPair _ l t r) = ni env l ++ ni env t ++ ni env r
824 ni env (PAlternative as) = concatMap (ni env) as
825 ni env (PHidden tm) = ni env tm
828-- For inferring types of things
832inferTy = MN 0 "__Infer"
833inferCon = MN 0 "__infer"
834inferDecl = PDatadecl inferTy
836 [(inferCon, PPi impl (MN 0 "A") PSet (
837 PPi expl (MN 0 "a") (PRef bi (MN 0 "A"))
838 (PRef bi inferTy)), bi)]
840infTerm t = PApp bi (PRef bi inferCon) [pimp (MN 0 "A") Placeholder, pexp t]
841infP = P (TCon 6 0) inferTy (Set (UVal 0))
843getInferTerm, getInferType :: Term -> Term
844getInferTerm (Bind n b sc) = Bind n b $ getInferTerm sc
845getInferTerm (App (App _ _) tm) = tm
846getInferTerm tm = error ("getInferTerm " ++ show tm)
848getInferType (Bind n b sc) = Bind n b $ getInferType sc
849getInferType (App (App _ ty) _) = ty
851-- Handy primitives: Unit, False, Pair, MkPair, =, mkForeign
853primNames = [unitTy, unitCon,
854 falseTy, pairTy, pairCon,
855 eqTy, eqCon, inferTy, inferCon]
857unitTy = MN 0 "__Unit"
859unitDecl = PDatadecl unitTy PSet
860 [(unitCon, PRef bi unitTy, bi)]
862falseTy = MN 0 "__False"
863falseDecl = PDatadecl falseTy PSet []
865pairTy = MN 0 "__Pair"
866pairCon = MN 0 "__MkPair"
867pairDecl = PDatadecl pairTy (piBind [(n "A", PSet), (n "B", PSet)] PSet)
868 [(pairCon, PPi impl (n "A") PSet (
869 PPi impl (n "B") PSet (
870 PPi expl (n "a") (PRef bi (n "A")) (
871 PPi expl (n "b") (PRef bi (n "B"))
872 (PApp bi (PRef bi pairTy) [pexp (PRef bi (n "A")),
873 pexp (PRef bi (n "B"))])))), bi)]
878eqDecl = PDatadecl eqTy (piBind [(n "a", PSet), (n "b", PSet),
879 (n "x", PRef bi (n "a")), (n "y", PRef bi (n "b"))]
881 [(eqCon, PPi impl (n "a") PSet (
882 PPi impl (n "x") (PRef bi (n "a"))
883 (PApp bi (PRef bi eqTy) [pimp (n "a") Placeholder,
884 pimp (n "b") Placeholder,
885 pexp (PRef bi (n "x")),
886 pexp (PRef bi (n "x"))])), bi)]
889-- Defined in builtins.idr
891existsCon = UN "Ex_intro"
893piBind :: [(Name, PTerm)] -> PTerm -> PTerm
895piBind ((n, ty):ns) t = PPi expl n ty (piBind ns t)
897tcname (UN ('@':_)) = True
898tcname (NS n _) = tcname n
901-- Dealing with parameters
903expandParams :: (Name -> Name) -> [(Name, PTerm)] -> [Name] -> PTerm -> PTerm
904expandParams dec ps ns tm = en tm
906 -- if we shadow a name (say in a lambda binding) that is used in a call to
907 -- a lifted function, we need access to both names - once in the scope of the
908 -- binding and once to call the lifted functions. So we'll explicitly shadow
909 -- it. (Yes, it's a hack. The alternative would be to resolve names earlier
912 mkShadow (UN n) = MN 0 n
913 mkShadow (MN i n) = MN (i+1) n
914 mkShadow (NS x s) = NS (mkShadow x) s
917 | n `elem` map fst ps
918 = let n' = mkShadow n in
919 PLam n' (en t) (en (shadow n n' s))
920 | otherwise = PLam n (en t) (en s)
922 | n `elem` map fst ps
923 = let n' = mkShadow n in
924 PPi p n' (en t) (en (shadow n n' s))
925 | otherwise = PPi p n (en t) (en s)
927 | n `elem` map fst ps
928 = let n' = mkShadow n in
929 PLet n' (en ty) (en v) (en (shadow n n' s))
930 | otherwise = PLet n (en ty) (en v) (en s)
931 en (PEq f l r) = PEq f (en l) (en r)
932 en (PTyped l r) = PTyped (en l) (en r)
933 en (PPair f l r) = PPair f (en l) (en r)
934 en (PDPair f l t r) = PDPair f (en l) (en t) (en r)
935 en (PAlternative as) = PAlternative (map en as)
936 en (PHidden t) = PHidden (en t)
937 en (PDoBlock ds) = PDoBlock (map (fmap en) ds)
938 en (PProof ts) = PProof (map (fmap en) ts)
939 en (PTactics ts) = PTactics (map (fmap en) ts)
942 | n `elem` ns = PQuote (Var (dec n))
943 en (PApp fc (PRef fc' n) as)
944 | n `elem` ns = PApp fc (PRef fc' (dec n))
945 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
947 | n `elem` ns = PApp fc (PRef fc (dec n))
948 (map (pexp . (PRef fc)) (map fst ps))
949 en (PApp fc f as) = PApp fc (en f) (map (fmap en) as)
950 en (PCase fc c os) = PCase fc (en c) (map (pmap en) os)
953expandParamsD :: IState ->
954 (Name -> Name) -> [(Name, PTerm)] -> [Name] -> PDecl -> PDecl
955expandParamsD ist dec ps ns (PTy syn fc o n ty)
957 then PTy syn fc o (dec n) (piBind ps (expandParams dec ps ns ty))
958 else PTy syn fc o n (expandParams dec ps ns ty)
959expandParamsD ist dec ps ns (PClauses fc opts n cs)
960 = let n' = if n `elem` ns then dec n else n in
961 PClauses fc opts n' (map expandParamsC cs)
963 expandParamsC (PClause n lhs ws rhs ds)
964 = let -- ps' = updateps True (namesIn ist rhs) (zip ps [0..])
965 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
966 n' = if n `elem` ns then dec n else n in
967 PClause n' (expandParams dec ps'' ns lhs)
968 (map (expandParams dec ps'' ns) ws)
969 (expandParams dec ps'' ns rhs)
970 (map (expandParamsD ist dec ps'' ns) ds)
971 expandParamsC (PWith n lhs ws wval ds)
972 = let -- ps' = updateps True (namesIn ist wval) (zip ps [0..])
973 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
974 n' = if n `elem` ns then dec n else n in
975 PWith n' (expandParams dec ps'' ns lhs)
976 (map (expandParams dec ps'' ns) ws)
977 (expandParams dec ps'' ns wval)
978 (map (expandParamsD ist dec ps'' ns) ds)
979 updateps yn nm [] = []
980 updateps yn nm (((a, t), i):as)
981 | (a `elem` nm) == yn = (a, t) : updateps yn nm as
982 | otherwise = (MN i (show n ++ "_u"), t) : updateps yn nm as
984expandParamsD ist dec ps ns d = d
986-- Calculate a priority for a type, for deciding elaboration order
987-- * if it's just a type variable or concrete type, do it early (0)
988-- * if there's only type variables and injective constructors, do it next (1)
989-- * if there's a function type, next (2)
990-- * finally, everything else (3)
992getPriority :: IState -> PTerm -> Int
993getPriority i tm = pri tm
996 case lookupP Nothing n (tt_ctxt i) of
997 ((P (DCon _ _) _ _):_) -> 1
998 ((P (TCon _ _) _ _):_) -> 1
1000 [] -> 0 -- must be locally bound, if it's not an error...
1001 pri (PPi _ _ x y) = max 5 (max (pri x) (pri y))
1005 pri (PEq _ l r) = max 1 (max (pri l) (pri r))
1006 pri (PApp _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.getTm) as)))
1007 pri (PCase _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.snd) as)))
1008 pri (PTyped l r) = pri l
1009 pri (PPair _ l r) = max 1 (max (pri l) (pri r))
1010 pri (PDPair _ l t r) = max 1 (max (pri l) (max (pri t) (pri r)))
1011 pri (PAlternative as) = maximum (map pri as)
1012 pri (PConstant _) = 0
1016-- Dealing with implicit arguments
1018-- Add implicit Pi bindings for any names in the term which appear in an
1019-- argument position.
1021-- This has become a right mess already. Better redo it some time...
1023implicit :: SyntaxInfo -> Name -> PTerm -> Idris PTerm
1026 let (tm', impdata) = implicitise syn i ptm
1027 let (tm'', spos) = findStatics i tm'
1028 put (i { idris_implicits = addDef n impdata (idris_implicits i) })
1030 logLvl 5 ("Implicit " ++ show n ++ " " ++ show impdata)
1032 put (i { idris_statics = addDef n spos (idris_statics i) })
1033 addIBC (IBCStatic n)
1036implicitise :: SyntaxInfo -> IState -> PTerm -> (PTerm, [PArg])
1037implicitise syn ist tm
1038 = let (declimps, ns') = execState (imps True [] tm) ([], [])
1039 ns = ns' \\ (map fst pvars ++ no_imp syn) in
1041 then (tm, reverse declimps)
1042 else implicitise syn ist (pibind uvars ns tm)
1045 pvars = syn_params syn
1047 dropAll (x:xs) ys | x `elem` ys = dropAll xs ys
1048 | otherwise = x : dropAll xs ys
1051 imps top env (PApp _ f as)
1052 = do (decls, ns) <- get
1053 let isn = concatMap (namesIn uvars ist) (map getTm as)
1054 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1055 imps top env (PPi (Imp l _) n ty sc)
1056 = do let isn = nub (namesIn uvars ist ty) `dropAll` [n]
1058 put (PImp (getPriority ist ty) l n ty : decls,
1059 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1060 imps True (n:env) sc
1061 imps top env (PPi (Exp l _) n ty sc)
1062 = do let isn = nub (namesIn uvars ist ty ++ case sc of
1063 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
1065 (decls, ns) <- get -- ignore decls in HO types
1066 put (PExp (getPriority ist ty) l ty : decls,
1067 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1068 imps True (n:env) sc
1069 imps top env (PPi (Constraint l _) n ty sc)
1070 = do let isn = nub (namesIn uvars ist ty ++ case sc of
1071 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
1073 (decls, ns) <- get -- ignore decls in HO types
1074 put (PConstraint 10 l ty : decls,
1075 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1076 imps True (n:env) sc
1077 imps top env (PPi (TacImp l _ scr) n ty sc)
1078 = do let isn = nub (namesIn uvars ist ty ++ case sc of
1079 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
1081 (decls, ns) <- get -- ignore decls in HO types
1082 put (PTacImplicit 10 l n scr ty : decls,
1083 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1084 imps True (n:env) sc
1085 imps top env (PEq _ l r)
1086 = do (decls, ns) <- get
1087 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1088 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1089 imps top env (PTyped l r)
1091 imps top env (PPair _ l r)
1092 = do (decls, ns) <- get
1093 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1094 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1095 imps top env (PDPair _ (PRef _ n) t r)
1096 = do (decls, ns) <- get
1097 let isn = nub (namesIn uvars ist t ++ namesIn uvars ist r) \\ [n]
1098 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
1099 imps top env (PDPair _ l t r)
1100 = do (decls, ns) <- get
1101 let isn = namesIn uvars ist l ++ namesIn uvars ist t ++
1103 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
1104 imps top env (PAlternative as)
1105 = do (decls, ns) <- get
1106 let isn = concatMap (namesIn uvars ist) as
1107 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1108 imps top env (PLam n ty sc)
1109 = do imps False env ty
1110 imps False (n:env) sc
1111 imps top env (PHidden tm) = imps False env tm
1112 imps top env _ = return ()
1114 pibind using [] sc = sc
1115 pibind using (n:ns) sc
1116 = case lookup n using of
1117 Just ty -> PPi (Imp False Dynamic) n ty (pibind using ns sc)
1118 Nothing -> PPi (Imp False Dynamic) n Placeholder (pibind using ns sc)
1120-- Add implicit arguments in function calls
1122addImpl :: IState -> PTerm -> PTerm
1123addImpl ist ptm = ai [] ptm
1126 | not (f `elem` env) = aiFn ist fc f []
1127 ai env (PEq fc l r) = let l' = ai env l
1130 ai env (PTyped l r) = let l' = ai env l
1133 ai env (PPair fc l r) = let l' = ai env l
1136 ai env (PDPair fc l t r) = let l' = ai env l
1140 ai env (PAlternative as) = let as' = map (ai env) as in
1142 ai env (PApp fc (PRef _ f) as)
1143 | not (f `elem` env)
1144 = let as' = map (fmap (ai env)) as in
1146 ai env (PApp fc f as) = let f' = ai env f
1147 as' = map (fmap (ai env)) as in
1149 ai env (PCase fc c os) = let c' = ai env c
1150 os' = map (pmap (ai env)) os in
1152 ai env (PLam n ty sc) = let ty' = ai env ty
1153 sc' = ai (n:env) sc in
1155 ai env (PLet n ty val sc)
1156 = let ty' = ai env ty
1158 sc' = ai (n:env) sc in
1160 ai env (PPi p n ty sc) = let ty' = ai env ty
1161 sc' = ai (n:env) sc in
1163 ai env (PHidden tm) = PHidden (ai env tm)
1164 ai env (PProof ts) = PProof (map (fmap (ai env)) ts)
1165 ai env (PTactics ts) = PTactics (map (fmap (ai env)) ts)
1168aiFn :: IState -> FC -> Name -> [PArg] -> PTerm
1170 | f `elem` primNames = PApp fc (PRef fc f) as
1172 -- This is where namespaces get resolved by adding PAlternative
1173 = case lookupCtxtName Nothing f (idris_implicits ist) of
1174 [(f',ns)] -> mkPApp fc (length ns) (PRef fc f') (insertImpl ns as)
1175 [] -> if f `elem` idris_metavars ist
1176 then PApp fc (PRef fc f) as
1177 else mkPApp fc (length as) (PRef fc f) as
1178 alts -> PAlternative $
1179 map (\(f', ns) -> mkPApp fc (length ns) (PRef fc f')
1180 (insertImpl ns as)) alts
1182 insertImpl :: [PArg] -> [PArg] -> [PArg]
1183 insertImpl (PExp p l ty : ps) (PExp _ _ tm : given) =
1184 PExp p l tm : insertImpl ps given
1185 insertImpl (PConstraint p l ty : ps) (PConstraint _ _ tm : given) =
1186 PConstraint p l tm : insertImpl ps given
1187 insertImpl (PConstraint p l ty : ps) given =
1188 PConstraint p l (PResolveTC fc) : insertImpl ps given
1189 insertImpl (PImp p l n ty : ps) given =
1190 case find n given [] of
1191 Just (tm, given') -> PImp p l n tm : insertImpl ps given'
1192 Nothing -> PImp p l n Placeholder : insertImpl ps given
1193 insertImpl (PTacImplicit p l n sc ty : ps) given =
1194 case find n given [] of
1195 Just (tm, given') -> PTacImplicit p l n sc tm : insertImpl ps given'
1196 Nothing -> PTacImplicit p l n sc sc
1197 : insertImpl ps given
1198 insertImpl expected [] = []
1199 insertImpl _ given = given
1201 find n [] acc = Nothing
1202 find n (PImp _ _ n' t : gs) acc
1203 | n == n' = Just (t, reverse acc ++ gs)
1204 find n (g : gs) acc = find n gs (g : acc)
1207mkPApp fc a f as = let rest = drop a as in
1208 appRest fc (PApp fc f (take a as)) rest
1211 appRest fc f (a : as) = appRest fc (PApp fc f [a]) as
1213-- Find 'static' argument positions
1214-- (the declared ones, plus any names in argument position in the declared
1216-- FIXME: It's possible that this really has to happen after elaboration
1218findStatics :: IState -> PTerm -> (PTerm, [Bool])
1219findStatics ist tm = let (ns, ss) = fs tm in
1220 runState (pos ns ss tm) []
1221 where fs (PPi p n t sc)
1222 | Static <- pstatic p
1223 = let (ns, ss) = fs sc in
1224 (namesIn [] ist t : ns, namesIn [] ist t ++ n : ss)
1225 | otherwise = let (ns, ss) = fs sc in
1226 (namesIn [] ist t : ns, ss)
1229 inOne n ns = length (filter id (map (elem n) ns)) == 1
1231 pos ns ss (PPi p n t sc)
1232 | n `inOne` ns && elem n ss
1233 = do sc' <- pos ns ss sc
1236 return (PPi (p { pstatic = Static }) n t sc')
1237 | otherwise = do sc' <- pos ns ss sc
1240 return (PPi p n t sc')
1241 pos ns ss t = return t
1243-- Debugging/logging stuff
1245dumpDecls :: [PDecl] -> String
1247dumpDecls (d:ds) = dumpDecl d ++ "\n" ++ dumpDecls ds
1249dumpDecl (PFix _ f ops) = show f ++ " " ++ showSep ", " ops
1250dumpDecl (PTy _ _ _ n t) = "tydecl " ++ show n ++ " : " ++ showImp True t
1251dumpDecl (PClauses _ _ n cs) = "pat " ++ show n ++ "\t" ++ showSep "\n\t" (map (showCImp True) cs)
1252dumpDecl (PData _ _ d) = showDImp True d
1253dumpDecl (PParams _ ns ps) = "params {" ++ show ns ++ "\n" ++ dumpDecls ps ++ "}\n"
1254dumpDecl (PNamespace n ps) = "namespace {" ++ n ++ "\n" ++ dumpDecls ps ++ "}\n"
1255dumpDecl (PSyntax _ syn) = "syntax " ++ show syn
1256dumpDecl (PClass _ _ cs n ps ds)
1257 = "class " ++ show cs ++ " " ++ show n ++ " " ++ show ps ++ "\n" ++ dumpDecls ds
1258dumpDecl (PInstance _ _ cs n _ t ds)
1259 = "instance " ++ show cs ++ " " ++ show n ++ " " ++ show t ++ "\n" ++ dumpDecls ds
1261-- dumpDecl (PImport i) = "import " ++ i
1263-- for 6.12/7 compatibility
1264data EitherErr a b = LeftErr a | RightOK b
1266instance Monad (EitherErr a) where
1269 (LeftErr e) >>= k = LeftErr e
1270 RightOK v >>= k = k v
1272toEither (LeftErr e) = Left e
1273toEither (RightOK ho) = Right ho
1275-- syntactic match of a against b, returning pair of variables in a
1276-- and what they match. Returns the pair that failed if not a match.
1278matchClause :: PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
1279matchClause = matchClause' False
1281matchClause' :: Bool -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
1282matchClause' names x y = checkRpts $ match (fullApp x) (fullApp y) where
1283 matchArg x y = match (fullApp (getTm x)) (fullApp (getTm y))
1285 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
1288 match' x y = match (fullApp x) (fullApp y)
1289 match (PApp _ (PRef _ (NS (UN "fromInteger") ["builtins"])) [_,_,x]) x'
1290 | PConstant (I _) <- getTm x = match (getTm x) x'
1291 match x' (PApp _ (PRef _ (NS (UN "fromInteger") ["builtins"])) [_,_,x])
1292 | PConstant (I _) <- getTm x = match (getTm x) x'
1293 match (PApp _ f args) (PApp _ f' args')
1294 | length args == length args'
1295 = do mf <- match' f f'
1296 ms <- zipWithM matchArg args args'
1297 return (mf ++ concat ms)
1298-- match (PRef _ n) (PRef _ n') | n == n' = return []
1299-- | otherwise = Nothing
1300 match (PRef f n) (PApp _ x []) = match (PRef f n) x
1301 match (PApp _ x []) (PRef f n) = match x (PRef f n)
1302 match (PRef _ n) (PRef _ n') | n == n' = return []
1303 match (PRef _ n) tm | not names = return [(n, tm)]
1304 match (PEq _ l r) (PEq _ l' r') = do ml <- match' l l'
1307 match (PTyped l r) (PTyped l' r') = do ml <- match l l'
1310 match (PTyped l r) x = match l x
1311 match x (PTyped l r) = match x l
1312 match (PPair _ l r) (PPair _ l' r') = do ml <- match' l l'
1315 match (PDPair _ l t r) (PDPair _ l' t' r') = do ml <- match' l l'
1318 return (ml ++ mt ++ mr)
1319 match (PAlternative as) (PAlternative as')
1320 = do ms <- zipWithM match' as as'
1322 match a@(PAlternative as) b
1323 = do let ms = zipWith match' as (repeat b)
1324 case (rights (map toEither ms)) of
1327 match (PCase _ _ _) _ = return [] -- lifted out
1328 match (PMetavar _) _ = return [] -- modified
1329 match (PQuote _) _ = return []
1330 match (PProof _) _ = return []
1331 match (PTactics _) _ = return []
1332 match (PRefl _) (PRefl _) = return []
1333 match (PResolveTC _) (PResolveTC _) = return []
1334 match (PTrue _) (PTrue _) = return []
1335 match (PFalse _) (PFalse _) = return []
1336 match (PReturn _) (PReturn _) = return []
1337 match (PPi _ _ t s) (PPi _ _ t' s') = do mt <- match' t t'
1340 match (PLam _ t s) (PLam _ t' s') = do mt <- match' t t'
1343 match (PLet _ t ty s) (PLet _ t' ty' s') = do mt <- match' t t'
1344 mty <- match' ty ty'
1346 return (mt ++ mty ++ ms)
1347 match (PHidden x) (PHidden y) = match' x y
1348 match Placeholder _ = return []
1349 match _ Placeholder = return []
1350 match (PResolveTC _) _ = return []
1351 match a b | a == b = return []
1352 | otherwise = LeftErr (a, b)
1354 checkRpts (RightOK ms) = check ms where
1356 | Just t' <- lookup n xs = if t/=t' && t/=Placeholder && t'/=Placeholder
1359 check (_:xs) = check xs
1361 checkRpts (LeftErr x) = Left x
1363substMatches :: [(Name, PTerm)] -> PTerm -> PTerm
1364substMatches [] t = t
1365substMatches ((n,tm):ns) t = substMatch n tm (substMatches ns t)
1367substMatch :: Name -> PTerm -> PTerm -> PTerm
1368substMatch n tm t = sm t where
1369 sm (PRef _ n') | n == n' = tm
1370 sm (PLam x t sc) = PLam x (sm t) (sm sc)
1371 sm (PPi p x t sc) = PPi p x (sm t) (sm sc)
1372 sm (PApp f x as) = PApp f (sm x) (map (fmap sm) as)
1373 sm (PCase f x as) = PCase f (sm x) (map (pmap sm) as)
1374 sm (PEq f x y) = PEq f (sm x) (sm y)
1375 sm (PTyped x y) = PTyped (sm x) (sm y)
1376 sm (PPair f x y) = PPair f (sm x) (sm y)
1377 sm (PDPair f x t y) = PDPair f (sm x) (sm t) (sm y)
1378 sm (PAlternative as) = PAlternative (map sm as)
1379 sm (PHidden x) = PHidden (sm x)
1382shadow :: Name -> Name -> PTerm -> PTerm
1383shadow n n' t = sm t where
1384 sm (PRef fc x) | n == x = PRef fc n'
1385 sm (PLam x t sc) = PLam x (sm t) (sm sc)
1386 sm (PPi p x t sc) = PPi p x (sm t) (sm sc)
1387 sm (PApp f x as) = PApp f (sm x) (map (fmap sm) as)
1388 sm (PCase f x as) = PCase f (sm x) (map (pmap sm) as)
1389 sm (PEq f x y) = PEq f (sm x) (sm y)
1390 sm (PTyped x y) = PTyped (sm x) (sm y)
1391 sm (PPair f x y) = PPair f (sm x) (sm y)
1392 sm (PDPair f x t y) = PDPair f (sm x) (sm t) (sm y)
1393 sm (PAlternative as) = PAlternative (map sm as)
1394 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