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],
49 idris_totcheck :: [(FC, Name)],
51 idris_options :: IOption,
53 idris_metavars :: [Name],
54 syntax_rules :: [Syntax],
55 syntax_keywords :: [String],
56 imported :: [FilePath],
57 idris_prims :: [(Name, ([E.Name], E.Term))],
58 idris_objs :: [FilePath],
59 idris_libs :: [String],
60 idris_hdrs :: [String],
61 last_proof :: Maybe (Name, [String]),
63 lastParse :: Maybe Name,
64 indent_stack :: [Int],
65 brace_stack :: [Maybe Int],
66 hide_list :: [(Name, Maybe Accessibility)],
67 default_access :: Accessibility,
68 ibc_write :: [IBCWrite],
69 compiled_so :: Maybe String
72-- information that needs writing for the current module's .ibc file
73data IBCWrite = IBCFix FixDecl
77 | IBCInstance Name Name
87 | IBCAccess Name Accessibility
88 | IBCTotal Name Totality
89 | IBCFlags Name [FnOpt]
91 | IBCDef Name -- i.e. main context
94idrisInit = IState initContext [] [] emptyContext emptyContext emptyContext
95 emptyContext emptyContext emptyContext emptyContext
96 emptyContext emptyContext
97 [] "" defaultOpts 6 [] [] [] [] [] [] [] []
98 Nothing Nothing Nothing [] [] [] Hidden [] Nothing
100-- The monad for the main REPL - reading and processing files and updating
101-- global state (hence the IO inner monad).
102type Idris = StateT IState (InputT IO)
104getContext :: Idris Context
105getContext = do i <- get; return (tt_ctxt i)
107getObjectFiles :: Idris [FilePath]
108getObjectFiles = do i <- get; return (idris_objs i)
110addObjectFile :: FilePath -> Idris ()
111addObjectFile f = do i <- get; put (i { idris_objs = f : idris_objs i })
113getLibs :: Idris [String]
114getLibs = do i <- get; return (idris_libs i)
116addLib :: String -> Idris ()
117addLib f = do i <- get; put (i { idris_libs = f : idris_libs i })
119addHdr :: String -> Idris ()
120addHdr f = do i <- get; put (i { idris_hdrs = f : idris_hdrs i })
122totcheck :: (FC, Name) -> Idris ()
123totcheck n = do i <- get; put (i { idris_totcheck = n : idris_totcheck i })
125setFlags :: Name -> [FnOpt] -> Idris ()
126setFlags n fs = do i <- get; put (i { idris_flags = addDef n fs (idris_flags i) })
128setAccessibility :: Name -> Accessibility -> Idris ()
131 let ctxt = setAccess n a (tt_ctxt i)
132 put (i { tt_ctxt = ctxt })
134setTotality :: Name -> Totality -> Idris ()
137 let ctxt = setTotal n a (tt_ctxt i)
138 put (i { tt_ctxt = ctxt })
140getTotality :: Name -> Idris Totality
143 case lookupTotal n (tt_ctxt i) of
145 _ -> return (Total [])
147addToCG :: Name -> [Name] -> Idris ()
148addToCG n ns = do i <- get
149 put (i { idris_callgraph = addDef n ns (idris_callgraph i) })
151addInstance :: Name -> Name -> Idris ()
154 case lookupCtxt Nothing n (idris_classes ist) of
156 do let cs = addDef n (CI a b c d (i : ins)) (idris_classes ist)
157 put (ist { idris_classes = cs })
158 _ -> do let cs = addDef n (CI (MN 0 "none") [] [] [] [i]) (idris_classes ist)
159 put (ist { idris_classes = cs })
161addClass :: Name -> ClassInfo -> Idris ()
164 let i' = case lookupCtxt Nothing n (idris_classes ist) of
165 [c] -> c { class_instances = class_instances i }
167 put (ist { idris_classes = addDef n i' (idris_classes ist) })
169addIBC :: IBCWrite -> Idris ()
172 when (notDef (ibc_write i)) $
173 put (i { ibc_write = ibc : ibc_write i })
174 where notDef [] = True
175 notDef (IBCDef n': is) | n == n' = False
176 notDef (_ : is) = notDef is
177addIBC ibc = do i <- get; put (i { ibc_write = ibc : ibc_write i })
180clearIBC = do i <- get; put (i { ibc_write = [] })
182getHdrs :: Idris [String]
183getHdrs = do i <- get; return (idris_hdrs i)
185setErrLine :: Int -> Idris ()
186setErrLine x = do i <- get;
188 Nothing -> put (i { errLine = Just x })
192clearErr = do i <- get
193 put (i { errLine = Nothing })
195getSO :: Idris (Maybe String)
197 return (compiled_so i)
199setSO :: Maybe String -> Idris ()
201 put (i { compiled_so = s })
203getIState :: Idris IState
206putIState :: IState -> Idris ()
210getName = do i <- get;
211 let idx = idris_name i;
212 put (i { idris_name = idx + 1 })
215checkUndefined :: FC -> Name -> Idris ()
218 case lookupTy Nothing n i of
219 (_:_) -> fail $ show fc ++ ":" ++
220 show n ++ " already defined"
223setContext :: Context -> Idris ()
224setContext ctxt = do i <- get; put (i { tt_ctxt = ctxt } )
226updateContext :: (Context -> Context) -> Idris ()
227updateContext f = do i <- get; put (i { tt_ctxt = f (tt_ctxt i) } )
229addConstraints :: FC -> (Int, [UConstraint]) -> Idris ()
230addConstraints fc (v, cs)
233 let ctxt' = ctxt { uconstraints = cs ++ uconstraints ctxt,
235 let ics = zip cs (repeat fc) ++ idris_constraints i
236 put (i { tt_ctxt = ctxt', idris_constraints = ics })
238addDeferred :: [(Name, Type)] -> Idris ()
239addDeferred ns = do mapM_ (\(n, t) -> updateContext (addTyDecl n (tidyNames [] t))) ns
241 put (i { idris_metavars = map fst ns ++ idris_metavars i })
242 where tidyNames used (Bind (MN i x) b sc)
243 = let n' = uniqueName (UN x) used in
244 Bind n' b $ tidyNames (n':used) sc
245 tidyNames used (Bind n b sc)
246 = let n' = uniqueName n used in
247 Bind n' b $ tidyNames (n':used) sc
250solveDeferred :: Name -> Idris ()
251solveDeferred n = do i <- get
252 put (i { idris_metavars = idris_metavars i \\ [n] })
254iputStrLn :: String -> Idris ()
255iputStrLn = liftIO . putStrLn
257iWarn :: FC -> String -> Idris ()
258iWarn fc err = liftIO $ putStrLn (show fc ++ ":" ++ err)
260setLogLevel :: Int -> Idris ()
261setLogLevel l = do i <- get
262 let opts = idris_options i
263 let opt' = opts { opt_logLevel = l }
264 put (i { idris_options = opt' } )
267logLevel = do i <- get
268 return (opt_logLevel (idris_options i))
272 return (opt_repl (idris_options i))
274setREPL :: Bool -> Idris ()
275setREPL t = do i <- get
276 let opts = idris_options i
277 let opt' = opts { opt_repl = t }
278 put (i { idris_options = opt' })
282 return (opt_verbose (idris_options i))
284setVerbose :: Bool -> Idris ()
285setVerbose t = do i <- get
286 let opts = idris_options i
287 let opt' = opts { opt_verbose = t }
288 put (i { idris_options = opt' })
290typeInType :: Idris Bool
291typeInType = do i <- get
292 return (opt_typeintype (idris_options i))
294setTypeInType :: Bool -> Idris ()
295setTypeInType t = do i <- get
296 let opts = idris_options i
297 let opt' = opts { opt_typeintype = t }
298 put (i { idris_options = opt' })
300coverage :: Idris Bool
301coverage = do i <- get
302 return (opt_coverage (idris_options i))
304setCoverage :: Bool -> Idris ()
305setCoverage t = do i <- get
306 let opts = idris_options i
307 let opt' = opts { opt_coverage = t }
308 put (i { idris_options = opt' })
312 return (opt_showimp (idris_options i))
314setImpShow :: Bool -> Idris ()
315setImpShow t = do i <- get
316 let opts = idris_options i
317 let opt' = opts { opt_showimp = t }
318 put (i { idris_options = opt' })
320logLvl :: Int -> String -> Idris ()
321logLvl l str = do i <- get
322 let lvl = opt_logLevel (idris_options i)
324 $ do liftIO (putStrLn str)
325 put (i { idris_log = idris_log i ++ str ++ "\n" } )
327iLOG :: String -> Idris ()
330noErrors :: Idris Bool
331noErrors = do i <- get
333 Nothing -> return True
336setTypeCase :: Bool -> Idris ()
337setTypeCase t = do i <- get
338 let opts = idris_options i
339 let opt' = opts { opt_typecase = t }
340 put (i { idris_options = opt' })
342-- Commands in the REPL
344data Command = Quit | Help | Eval PTerm | Check PTerm | TotCheck Name
346 | Compile String | Execute | ExecVal PTerm
347 | Metavars | Prove Name | AddProof | Universes
349 | LogLvl Int | Spec PTerm | HNF PTerm | Defn Name | Info Name
352-- Parsed declarations
354data Fixity = Infixl { prec :: Int }
355 | Infixr { prec :: Int }
356 | InfixN { prec :: Int }
357 | PrefixN { prec :: Int }
360deriving instance Binary Fixity
363instance Show Fixity where
364 show (Infixl i) = "infixl " ++ show i
365 show (Infixr i) = "infixr " ++ show i
366 show (InfixN i) = "infix " ++ show i
367 show (PrefixN i) = "prefix " ++ show i
369data FixDecl = Fix Fixity String
372deriving instance Binary FixDecl
375instance Ord FixDecl where
376 compare (Fix x _) (Fix y _) = compare (prec x) (prec y)
379data Static = Static | Dynamic
382deriving instance Binary Static
385-- Mark bindings with their explicitness, and laziness
386data Plicity = Imp { plazy :: Bool,
388 | Exp { plazy :: Bool,
390 | Constraint { plazy :: Bool,
392 | TacImp { plazy :: Bool,
398deriving instance Binary Plicity
401impl = Imp False Dynamic
402expl = Exp False Dynamic
403constraint = Constraint False Dynamic
404tacimpl = TacImp False Dynamic
406data FnOpt = Inlinable | TotalFn | AssertTotal | TCGen
407 | Specialise [Name] -- specialise it, freeze these names
410deriving instance Binary FnOpt
415inlinable :: FnOpts -> Bool
416inlinable = elem Inlinable
418data PDecl' t = PFix FC Fixity [String] -- fixity declaration
419 | PTy SyntaxInfo FC FnOpts Name t -- type declaration
420 | PClauses FC FnOpts Name [PClause' t] -- pattern clause
421 | PData SyntaxInfo FC (PData' t) -- data declaration
422 | PParams FC [(Name, t)] [PDecl' t] -- params block
423 | PNamespace String [PDecl' t] -- new namespace
424 | PRecord SyntaxInfo FC Name t Name t -- record declaration
425 | PClass SyntaxInfo FC
428 [(Name, t)] -- parameters
429 [PDecl' t] -- declarations
430 | PInstance SyntaxInfo FC [t] -- constraints
433 t -- full instance type
437 | PDirective (Idris ())
440data PClause' t = PClause FC Name t [t] t [PDecl' t]
441 | PWith FC Name t [t] t [PDecl' t]
442 | PClauseR FC [t] t [PDecl' t]
443 | PWithR FC [t] t [PDecl' t]
446data PData' t = PDatadecl { d_name :: Name,
448 d_cons :: [(Name, t, FC)] }
451-- Handy to get a free function for applying PTerm -> PTerm functions
452-- across a program, by deriving Functor
454type PDecl = PDecl' PTerm
455type PData = PData' PTerm
456type PClause = PClause' PTerm
458-- get all the names declared in a decl
460declared :: PDecl -> [Name]
461declared (PFix _ _ _) = []
462declared (PTy _ _ _ n t) = [n]
463declared (PClauses _ _ n _) = [] -- not a declaration
464declared (PData _ _ (PDatadecl n _ ts)) = n : map fstt ts
465 where fstt (a, _, _) = a
466declared (PParams _ _ ds) = concatMap declared ds
467declared (PNamespace _ ds) = concatMap declared ds
468-- declared (PImport _) = []
470updateN :: [(Name, Name)] -> Name -> Name
471updateN ns n | Just n' <- lookup n ns = n'
474updateNs :: [(Name, Name)] -> PTerm -> PTerm
476updateNs ns t = mapPT updateRef t
477 where updateRef (PRef fc f) = PRef fc (updateN ns f)
480-- updateDNs :: [(Name, Name)] -> PDecl -> PDecl
482-- updateDNs ns (PTy s f n t) | Just n' <- lookup n ns = PTy s f n' t
483-- updateDNs ns (PClauses f n c) | Just n' <- lookup n ns = PClauses f n' (map updateCNs c)
484-- where updateCNs ns (PClause n l ts r ds)
485-- = PClause (updateN ns n) (fmap (updateNs ns) l)
486-- (map (fmap (updateNs ns)) ts)
487-- (fmap (updateNs ns) r)
488-- (map (updateDNs ns) ds)
491-- High level language terms
493data PTerm = PQuote Raw
495 | PLam Name PTerm PTerm
496 | PPi Plicity Name PTerm PTerm
497 | PLet Name PTerm PTerm PTerm
498 | PTyped PTerm PTerm -- term with explicit type
499 | PApp FC PTerm [PArg]
500 | PCase FC PTerm [(PTerm, PTerm)]
506 | PPair FC PTerm PTerm
507 | PDPair FC PTerm PTerm PTerm
508 | PAlternative [PTerm]
509 | PHidden PTerm -- irrelevant or hidden pattern
518 | PTactics [PTactic] -- as PProof, but no auto solving
519 | PElabError Err -- error to report on elaboration
520 | PImpossible -- special case for declaring when an LHS can't typecheck
523deriving instance Binary PTerm
526mapPT :: (PTerm -> PTerm) -> PTerm -> PTerm
527mapPT f t = f (mpt t) where
528 mpt (PLam n t s) = PLam n (mapPT f t) (mapPT f s)
529 mpt (PPi p n t s) = PPi p n (mapPT f t) (mapPT f s)
530 mpt (PLet n ty v s) = PLet n (mapPT f ty) (mapPT f v) (mapPT f s)
531 mpt (PApp fc t as) = PApp fc (mapPT f t) (map (fmap (mapPT f)) as)
532 mpt (PCase fc c os) = PCase fc (mapPT f c) (map (pmap (mapPT f)) os)
533 mpt (PEq fc l r) = PEq fc (mapPT f l) (mapPT f r)
534 mpt (PTyped l r) = PTyped (mapPT f l) (mapPT f r)
535 mpt (PPair fc l r) = PPair fc (mapPT f l) (mapPT f r)
536 mpt (PDPair fc l t r) = PDPair fc (mapPT f l) (mapPT f t) (mapPT f r)
537 mpt (PAlternative as) = PAlternative (map (mapPT f) as)
538 mpt (PHidden t) = PHidden (mapPT f t)
539 mpt (PDoBlock ds) = PDoBlock (map (fmap (mapPT f)) ds)
540 mpt (PProof ts) = PProof (map (fmap (mapPT f)) ts)
541 mpt (PTactics ts) = PTactics (map (fmap (mapPT f)) ts)
545data PTactic' t = Intro [Name] | Intros | Focus Name
546 | Refine Name [Bool] | Rewrite t | LetTac Name t
547 | Exact t | Compute | Trivial
550 | ProofState | ProofTerm | Undo
551 | Try (PTactic' t) (PTactic' t)
552 | TSeq (PTactic' t) (PTactic' t)
554 deriving (Show, Eq, Functor)
556deriving instance Binary PTactic'
559type PTactic = PTactic' PTerm
561data PDo' t = DoExp FC t
566 deriving (Eq, Functor)
568deriving instance Binary PDo'
573-- The priority gives a hint as to elaboration order. Best to elaborate
574-- things early which will help give a more concrete type to other
575-- variables, e.g. a before (interpTy a).
577data PArg' t = PImp { priority :: Int,
578 lazyarg :: Bool, pname :: Name, getTm :: t }
579 | PExp { priority :: Int,
580 lazyarg :: Bool, getTm :: t }
581 | PConstraint { priority :: Int,
582 lazyarg :: Bool, getTm :: t }
583 | PTacImplicit { priority :: Int,
584 lazyarg :: Bool, pname :: Name,
587 deriving (Show, Eq, Functor)
589deriving instance Binary PArg'
594pconst = PConstraint 0 False
595ptacimp = PTacImplicit 0 True
597type PArg = PArg' PTerm
601data ClassInfo = CI { instanceName :: Name,
602 class_methods :: [(Name, (FnOpts, PTerm))],
603 class_defaults :: [(Name, Name)], -- method name -> default impl
604 class_params :: [Name],
605 class_instances :: [Name] }
608deriving instance Binary ClassInfo
611data OptInfo = Optimise { collapsible :: Bool,
612 forceable :: [Int], -- argument positions
616deriving instance Binary OptInfo
620data TypeInfo = TI { con_names :: [Name] }
623deriving instance Binary TypeInfo
626-- Syntactic sugar info
628data DSL' t = DSL { dsl_bind :: t,
633 index_first :: Maybe t,
634 index_next :: Maybe t,
635 dsl_lambda :: Maybe t,
638 deriving (Show, Functor)
640deriving instance Binary DSL'
645data SynContext = PatternSyntax | TermSyntax | AnySyntax
648deriving instance Binary SynContext
651data Syntax = Rule [SSymbol] PTerm SynContext
654deriving instance Binary Syntax
657data SSymbol = Keyword Name
663deriving instance Binary SSymbol
666initDSL = DSL (PRef f (UN ">>="))
667 (PRef f (UN "return"))
675 where f = FC "(builtin)" 0
677data SyntaxInfo = Syn { using :: [(Name, PTerm)],
678 syn_params :: [(Name, PTerm)],
679 syn_namespace :: [String],
681 decoration :: Name -> Name,
686defaultSyntax = Syn [] [] [] [] id False initDSL
688expandNS :: SyntaxInfo -> Name -> Name
689expandNS syn n@(NS _ _) = n
690expandNS syn n = case syn_namespace syn of
695--- Pretty printing declarations and terms
697instance Show PTerm where
698 show tm = showImp False tm
700instance Show PDecl where
701 show d = showDeclImp False d
703instance Show PClause where
704 show c = showCImp True c
706instance Show PData where
707 show d = showDImp False d
709showDeclImp _ (PFix _ f ops) = show f ++ " " ++ showSep ", " ops
710showDeclImp t (PTy _ _ _ n ty) = show n ++ " : " ++ showImp t ty
711showDeclImp _ (PClauses _ _ n c) = showSep "\n" (map show c)
712showDeclImp _ (PData _ _ d) = show d
714showCImp :: Bool -> PClause -> String
715showCImp impl (PClause _ n l ws r w)
716 = showImp impl l ++ showWs ws ++ " = " ++ showImp impl r
717 ++ " where " ++ show w
720 showWs (x : xs) = " | " ++ showImp impl x ++ showWs xs
721showCImp impl (PWith _ n l ws r w)
722 = showImp impl l ++ showWs ws ++ " with " ++ showImp impl r
723 ++ " { " ++ show w ++ " } "
726 showWs (x : xs) = " | " ++ showImp impl x ++ showWs xs
729showDImp :: Bool -> PData -> String
730showDImp impl (PDatadecl n ty cons)
731 = "data " ++ show n ++ " : " ++ showImp impl ty ++ " where\n\t"
733 (map (\ (n, t, _) -> show n ++ " : " ++ showImp impl t) cons)
735getImps :: [PArg] -> [(Name, PTerm)]
737getImps (PImp _ _ n tm : xs) = (n, tm) : getImps xs
738getImps (_ : xs) = getImps xs
740getExps :: [PArg] -> [PTerm]
742getExps (PExp _ _ tm : xs) = tm : getExps xs
743getExps (_ : xs) = getExps xs
745getConsts :: [PArg] -> [PTerm]
747getConsts (PConstraint _ _ tm : xs) = tm : getConsts xs
748getConsts (_ : xs) = getConsts xs
750getAll :: [PArg] -> [PTerm]
753showImp :: Bool -> PTerm -> String
754showImp impl tm = se 10 tm where
755 se p (PQuote r) = "![" ++ show r ++ "]"
756 se p (PRef fc n) = if impl then show n -- ++ "[" ++ show fc ++ "]"
758 where showbasic n@(UN _) = show n
759 showbasic (MN _ s) = s
760 showbasic (NS n s) = showSep "." (reverse s) ++ "." ++ showbasic n
761 se p (PLam n ty sc) = bracket p 2 $ "\\ " ++ show n ++ " => " ++ show sc
762 se p (PLet n ty v sc) = bracket p 2 $ "let " ++ show n ++ " = " ++ se 10 v ++
764 se p (PPi (Exp l s) n ty sc)
765 | n `elem` allNamesIn sc || impl
767 if l then "|(" else "(" ++
768 show n ++ " : " ++ se 10 ty ++
771 | otherwise = bracket p 2 $ se 0 ty ++ " " ++ st ++ "-> " ++ se 10 sc
773 Static -> "[static] "
775 se p (PPi (Imp l s) n ty sc)
776 | impl = bracket p 2 $ if l then "|{" else "{" ++
777 show n ++ " : " ++ se 10 ty ++
778 "} " ++ st ++ "-> " ++ se 10 sc
779 | otherwise = se 10 sc
781 Static -> "[static] "
783 se p (PPi (Constraint _ _) n ty sc)
784 = bracket p 2 $ se 10 ty ++ " => " ++ se 10 sc
785 se p (PApp _ (PRef _ f) [])
787 se p (PApp _ (PRef _ op@(UN (f:_))) args)
788 | length (getExps args) == 2 && not impl && not (isAlpha f)
789 = let [l, r] = getExps args in
790 bracket p 1 $ se 1 l ++ " " ++ show op ++ " " ++ se 0 r
792 = let args = getExps as in
793 bracket p 1 $ se 1 f ++ if impl then concatMap sArg as
794 else concatMap seArg args
795 se p (PCase _ scr opts) = "case " ++ se 10 scr ++ " of " ++ showSep " | " (map sc opts)
796 where sc (l, r) = se 10 l ++ " => " ++ se 10 r
797 se p (PHidden tm) = "." ++ se 0 tm
798 se p (PRefl _) = "refl"
799 se p (PResolveTC _) = "resolvetc"
800 se p (PTrue _) = "()"
801 se p (PFalse _) = "_|_"
802 se p (PEq _ l r) = bracket p 2 $ se 10 l ++ " = " ++ se 10 r
803 se p (PTyped l r) = "(" ++ se 10 l ++ " : " ++ se 10 r ++ ")"
804 se p (PPair _ l r) = "(" ++ se 10 l ++ ", " ++ se 10 r ++ ")"
805 se p (PDPair _ l t r) = "(" ++ se 10 l ++ " ** " ++ se 10 r ++ ")"
806 se p (PAlternative as) = "(|" ++ showSep " , " (map (se 10) as) ++ "|)"
808 se p (PConstant c) = show c
809 se p (PProof ts) = "proof { " ++ show ts ++ "}"
810 se p (PTactics ts) = "tactics { " ++ show ts ++ "}"
811 se p (PMetavar n) = "?" ++ show n
812 se p (PReturn f) = "return"
813 se p PImpossible = "impossible"
814 se p Placeholder = "_"
815 se p (PDoBlock _) = "do block show not implemented"
816 se p (PElabError s) = show s
817-- se p x = "Not implemented"
819 sArg (PImp _ _ n tm) = siArg (n, tm)
820 sArg (PExp _ _ tm) = seArg tm
821 sArg (PConstraint _ _ tm) = scArg tm
822 sArg (PTacImplicit _ _ n _ tm) = stiArg (n, tm)
824 seArg arg = " " ++ se 0 arg
825 siArg (n, val) = " {" ++ show n ++ " = " ++ se 10 val ++ "}"
826 scArg val = " {{" ++ se 10 val ++ "}}"
827 stiArg (n, val) = " {auto " ++ show n ++ " = " ++ se 10 val ++ "}"
829 bracket outer inner str | inner > outer = "(" ++ str ++ ")"
832allNamesIn :: PTerm -> [Name]
833allNamesIn tm = nub $ ni [] tm
836 | not (n `elem` env) = [n]
837 ni env (PApp _ f as) = ni env f ++ concatMap (ni env) (map getTm as)
838 ni env (PCase _ c os) = ni env c ++ concatMap (ni env) (map snd os)
839 ni env (PLam n ty sc) = ni env ty ++ ni (n:env) sc
840 ni env (PPi _ n ty sc) = ni env ty ++ ni (n:env) sc
841 ni env (PHidden tm) = ni env tm
842 ni env (PEq _ l r) = ni env l ++ ni env r
843 ni env (PTyped l r) = ni env l ++ ni env r
844 ni env (PPair _ l r) = ni env l ++ ni env r
845 ni env (PDPair _ (PRef _ n) t r) = ni env t ++ ni (n:env) r
846 ni env (PDPair _ l t r) = ni env l ++ ni env t ++ ni env r
847 ni env (PAlternative ls) = concatMap (ni env) ls
850namesIn :: [(Name, PTerm)] -> IState -> PTerm -> [Name]
851namesIn uvars ist tm = nub $ ni [] tm
855 = case lookupTy Nothing n (tt_ctxt ist) of
857 _ -> if n `elem` (map fst uvars) then [n] else []
858 ni env (PApp _ f as) = ni env f ++ concatMap (ni env) (map getTm as)
859 ni env (PCase _ c os) = ni env c ++ concatMap (ni env) (map snd os)
860 ni env (PLam n ty sc) = ni env ty ++ ni (n:env) sc
861 ni env (PPi _ n ty sc) = ni env ty ++ ni (n:env) sc
862 ni env (PEq _ l r) = ni env l ++ ni env r
863 ni env (PTyped l r) = ni env l ++ ni env r
864 ni env (PPair _ l r) = ni env l ++ ni env r
865 ni env (PDPair _ (PRef _ n) t r) = ni env t ++ ni (n:env) r
866 ni env (PDPair _ l t r) = ni env l ++ ni env t ++ ni env r
867 ni env (PAlternative as) = concatMap (ni env) as
868 ni env (PHidden tm) = ni env tm
871-- For inferring types of things
875inferTy = MN 0 "__Infer"
876inferCon = MN 0 "__infer"
877inferDecl = PDatadecl inferTy
879 [(inferCon, PPi impl (MN 0 "A") PSet (
880 PPi expl (MN 0 "a") (PRef bi (MN 0 "A"))
881 (PRef bi inferTy)), bi)]
883infTerm t = PApp bi (PRef bi inferCon) [pimp (MN 0 "A") Placeholder, pexp t]
884infP = P (TCon 6 0) inferTy (Set (UVal 0))
886getInferTerm, getInferType :: Term -> Term
887getInferTerm (Bind n b sc) = Bind n b $ getInferTerm sc
888getInferTerm (App (App _ _) tm) = tm
889getInferTerm tm = error ("getInferTerm " ++ show tm)
891getInferType (Bind n b sc) = Bind n b $ getInferType sc
892getInferType (App (App _ ty) _) = ty
894-- Handy primitives: Unit, False, Pair, MkPair, =, mkForeign
896primNames = [unitTy, unitCon,
897 falseTy, pairTy, pairCon,
898 eqTy, eqCon, inferTy, inferCon]
900unitTy = MN 0 "__Unit"
902unitDecl = PDatadecl unitTy PSet
903 [(unitCon, PRef bi unitTy, bi)]
905falseTy = MN 0 "__False"
906falseDecl = PDatadecl falseTy PSet []
908pairTy = MN 0 "__Pair"
909pairCon = MN 0 "__MkPair"
910pairDecl = PDatadecl pairTy (piBind [(n "A", PSet), (n "B", PSet)] PSet)
911 [(pairCon, PPi impl (n "A") PSet (
912 PPi impl (n "B") PSet (
913 PPi expl (n "a") (PRef bi (n "A")) (
914 PPi expl (n "b") (PRef bi (n "B"))
915 (PApp bi (PRef bi pairTy) [pexp (PRef bi (n "A")),
916 pexp (PRef bi (n "B"))])))), bi)]
921eqDecl = PDatadecl eqTy (piBind [(n "a", PSet), (n "b", PSet),
922 (n "x", PRef bi (n "a")), (n "y", PRef bi (n "b"))]
924 [(eqCon, PPi impl (n "a") PSet (
925 PPi impl (n "x") (PRef bi (n "a"))
926 (PApp bi (PRef bi eqTy) [pimp (n "a") Placeholder,
927 pimp (n "b") Placeholder,
928 pexp (PRef bi (n "x")),
929 pexp (PRef bi (n "x"))])), bi)]
932-- Defined in builtins.idr
934existsCon = UN "Ex_intro"
936piBind :: [(Name, PTerm)] -> PTerm -> PTerm
938piBind ((n, ty):ns) t = PPi expl n ty (piBind ns t)
940tcname (UN ('@':_)) = True
941tcname (NS n _) = tcname n
944-- Dealing with parameters
946expandParams :: (Name -> Name) -> [(Name, PTerm)] -> [Name] -> PTerm -> PTerm
947expandParams dec ps ns tm = en tm
949 -- if we shadow a name (say in a lambda binding) that is used in a call to
950 -- a lifted function, we need access to both names - once in the scope of the
951 -- binding and once to call the lifted functions. So we'll explicitly shadow
952 -- it. (Yes, it's a hack. The alternative would be to resolve names earlier
955 mkShadow (UN n) = MN 0 n
956 mkShadow (MN i n) = MN (i+1) n
957 mkShadow (NS x s) = NS (mkShadow x) s
960 | n `elem` map fst ps
961 = let n' = mkShadow n in
962 PLam n' (en t) (en (shadow n n' s))
963 | otherwise = PLam n (en t) (en s)
965 | n `elem` map fst ps
966 = let n' = mkShadow n in
967 PPi p n' (en t) (en (shadow n n' s))
968 | otherwise = PPi p n (en t) (en s)
970 | n `elem` map fst ps
971 = let n' = mkShadow n in
972 PLet n' (en ty) (en v) (en (shadow n n' s))
973 | otherwise = PLet n (en ty) (en v) (en s)
974 en (PEq f l r) = PEq f (en l) (en r)
975 en (PTyped l r) = PTyped (en l) (en r)
976 en (PPair f l r) = PPair f (en l) (en r)
977 en (PDPair f l t r) = PDPair f (en l) (en t) (en r)
978 en (PAlternative as) = PAlternative (map en as)
979 en (PHidden t) = PHidden (en t)
980 en (PDoBlock ds) = PDoBlock (map (fmap en) ds)
981 en (PProof ts) = PProof (map (fmap en) ts)
982 en (PTactics ts) = PTactics (map (fmap en) ts)
985 | n `elem` ns = PQuote (Var (dec n))
986 en (PApp fc (PRef fc' n) as)
987 | n `elem` ns = PApp fc (PRef fc' (dec n))
988 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
990 | n `elem` ns = PApp fc (PRef fc (dec n))
991 (map (pexp . (PRef fc)) (map fst ps))
992 en (PApp fc f as) = PApp fc (en f) (map (fmap en) as)
993 en (PCase fc c os) = PCase fc (en c) (map (pmap en) os)
996expandParamsD :: IState ->
997 (Name -> Name) -> [(Name, PTerm)] -> [Name] -> PDecl -> PDecl
998expandParamsD ist dec ps ns (PTy syn fc o n ty)
1000 then PTy syn fc o (dec n) (piBind ps (expandParams dec ps ns ty))
1001 else PTy syn fc o n (expandParams dec ps ns ty)
1002expandParamsD ist dec ps ns (PClauses fc opts n cs)
1003 = let n' = if n `elem` ns then dec n else n in
1004 PClauses fc opts n' (map expandParamsC cs)
1006 expandParamsC (PClause fc n lhs ws rhs ds)
1007 = let -- ps' = updateps True (namesIn ist rhs) (zip ps [0..])
1008 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
1009 n' = if n `elem` ns then dec n else n in
1010 PClause fc n' (expandParams dec ps'' ns lhs)
1011 (map (expandParams dec ps'' ns) ws)
1012 (expandParams dec ps'' ns rhs)
1013 (map (expandParamsD ist dec ps'' ns) ds)
1014 expandParamsC (PWith fc n lhs ws wval ds)
1015 = let -- ps' = updateps True (namesIn ist wval) (zip ps [0..])
1016 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
1017 n' = if n `elem` ns then dec n else n in
1018 PWith fc n' (expandParams dec ps'' ns lhs)
1019 (map (expandParams dec ps'' ns) ws)
1020 (expandParams dec ps'' ns wval)
1021 (map (expandParamsD ist dec ps'' ns) ds)
1022 updateps yn nm [] = []
1023 updateps yn nm (((a, t), i):as)
1024 | (a `elem` nm) == yn = (a, t) : updateps yn nm as
1025 | otherwise = (MN i (show n ++ "_u"), t) : updateps yn nm as
1027expandParamsD ist dec ps ns d = d
1029-- Calculate a priority for a type, for deciding elaboration order
1030-- * if it's just a type variable or concrete type, do it early (0)
1031-- * if there's only type variables and injective constructors, do it next (1)
1032-- * if there's a function type, next (2)
1033-- * finally, everything else (3)
1035getPriority :: IState -> PTerm -> Int
1036getPriority i tm = pri tm
1039 case lookupP Nothing n (tt_ctxt i) of
1040 ((P (DCon _ _) _ _):_) -> 1
1041 ((P (TCon _ _) _ _):_) -> 1
1042 ((P Ref _ _):_) -> 4
1043 [] -> 0 -- must be locally bound, if it's not an error...
1044 pri (PPi _ _ x y) = max 5 (max (pri x) (pri y))
1048 pri (PEq _ l r) = max 1 (max (pri l) (pri r))
1049 pri (PApp _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.getTm) as)))
1050 pri (PCase _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.snd) as)))
1051 pri (PTyped l r) = pri l
1052 pri (PPair _ l r) = max 1 (max (pri l) (pri r))
1053 pri (PDPair _ l t r) = max 1 (max (pri l) (max (pri t) (pri r)))
1054 pri (PAlternative as) = maximum (map pri as)
1055 pri (PConstant _) = 0
1059addStatics :: Name -> Term -> PTerm -> Idris ()
1060addStatics n tm ptm =
1061 do let (statics, dynamics) = initStatics tm ptm
1062 let stnames = nub $ concatMap freeNames (map snd statics)
1063 let dnames = nub $ concatMap freeNames (map snd dynamics)
1064 when (not (null statics)) $
1065 logLvl 7 $ show n ++ " " ++ show statics ++ "\n" ++ show dynamics
1066 ++ "\n" ++ show stnames ++ "\n" ++ show dnames
1067 let statics' = nub $ map fst statics ++
1068 filter (\x -> not (elem x dnames)) stnames
1069 let stpos = staticList statics' tm
1071 put (i { idris_statics = addDef n stpos (idris_statics i) })
1072 addIBC (IBCStatic n)
1074 initStatics (Bind n (Pi ty) sc) (PPi p _ _ s)
1075 = let (static, dynamic) = initStatics (instantiate (P Bound n ty) sc) s in
1076 if pstatic p == Static then ((n, ty) : static, dynamic)
1077 else (static, (n, ty) : dynamic)
1078 initStatics t pt = ([], [])
1080 staticList sts (Bind n (Pi _) sc) = (n `elem` sts) : staticList sts sc
1083-- Dealing with implicit arguments
1085-- Add implicit Pi bindings for any names in the term which appear in an
1086-- argument position.
1088-- This has become a right mess already. Better redo it some time...
1090implicit :: SyntaxInfo -> Name -> PTerm -> Idris PTerm
1093 let (tm', impdata) = implicitise syn i ptm
1094-- let (tm'', spos) = findStatics i tm'
1095 put (i { idris_implicits = addDef n impdata (idris_implicits i) })
1097 logLvl 5 ("Implicit " ++ show n ++ " " ++ show impdata)
1099-- put (i { idris_statics = addDef n spos (idris_statics i) })
1102implicitise :: SyntaxInfo -> IState -> PTerm -> (PTerm, [PArg])
1103implicitise syn ist tm
1104 = let (declimps, ns') = execState (imps True [] tm) ([], [])
1105 ns = ns' \\ (map fst pvars ++ no_imp syn) in
1107 then (tm, reverse declimps)
1108 else implicitise syn ist (pibind uvars ns tm)
1111 pvars = syn_params syn
1113 dropAll (x:xs) ys | x `elem` ys = dropAll xs ys
1114 | otherwise = x : dropAll xs ys
1117 imps top env (PApp _ f as)
1118 = do (decls, ns) <- get
1119 let isn = concatMap (namesIn uvars ist) (map getTm as)
1120 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1121 imps top env (PPi (Imp l _) n ty sc)
1122 = do let isn = nub (namesIn uvars ist ty) `dropAll` [n]
1124 put (PImp (getPriority ist ty) l n ty : decls,
1125 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1126 imps True (n:env) sc
1127 imps top env (PPi (Exp l _) n ty sc)
1128 = do let isn = nub (namesIn uvars ist ty ++ case sc of
1129 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
1131 (decls, ns) <- get -- ignore decls in HO types
1132 put (PExp (getPriority ist ty) l ty : decls,
1133 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1134 imps True (n:env) sc
1135 imps top env (PPi (Constraint l _) n ty sc)
1136 = do let isn = nub (namesIn uvars ist ty ++ case sc of
1137 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
1139 (decls, ns) <- get -- ignore decls in HO types
1140 put (PConstraint 10 l ty : decls,
1141 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1142 imps True (n:env) sc
1143 imps top env (PPi (TacImp l _ scr) n ty sc)
1144 = do let isn = nub (namesIn uvars ist ty ++ case sc of
1145 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
1147 (decls, ns) <- get -- ignore decls in HO types
1148 put (PTacImplicit 10 l n scr ty : decls,
1149 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1150 imps True (n:env) sc
1151 imps top env (PEq _ l r)
1152 = do (decls, ns) <- get
1153 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1154 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1155 imps top env (PTyped l r)
1157 imps top env (PPair _ l r)
1158 = do (decls, ns) <- get
1159 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1160 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1161 imps top env (PDPair _ (PRef _ n) t r)
1162 = do (decls, ns) <- get
1163 let isn = nub (namesIn uvars ist t ++ namesIn uvars ist r) \\ [n]
1164 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
1165 imps top env (PDPair _ l t r)
1166 = do (decls, ns) <- get
1167 let isn = namesIn uvars ist l ++ namesIn uvars ist t ++
1169 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
1170 imps top env (PAlternative as)
1171 = do (decls, ns) <- get
1172 let isn = concatMap (namesIn uvars ist) as
1173 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1174 imps top env (PLam n ty sc)
1175 = do imps False env ty
1176 imps False (n:env) sc
1177 imps top env (PHidden tm) = imps False env tm
1178 imps top env _ = return ()
1180 pibind using [] sc = sc
1181 pibind using (n:ns) sc
1182 = case lookup n using of
1183 Just ty -> PPi (Imp False Dynamic) n ty (pibind using ns sc)
1184 Nothing -> PPi (Imp False Dynamic) n Placeholder (pibind using ns sc)
1186-- Add implicit arguments in function calls
1187addImplPat :: IState -> PTerm -> PTerm
1188addImplPat = addImpl' True []
1190addImplBound :: IState -> [Name] -> PTerm -> PTerm
1191addImplBound ist ns = addImpl' False ns ist
1193addImpl :: IState -> PTerm -> PTerm
1194addImpl = addImpl' False []
1196-- TODO: in patterns, don't add implicits to function names guarded by constructors
1197-- and *not* inside a PHidden
1199addImpl' :: Bool -> [Name] -> IState -> PTerm -> PTerm
1200addImpl' inpat env ist ptm = ai env ptm
1203 | not (f `elem` env) = handleErr $ aiFn inpat ist fc f []
1204 ai env (PHidden (PRef fc f))
1205 | not (f `elem` env) = handleErr $ aiFn False ist fc f []
1206 ai env (PEq fc l r) = let l' = ai env l
1209 ai env (PTyped l r) = let l' = ai env l
1212 ai env (PPair fc l r) = let l' = ai env l
1215 ai env (PDPair fc l t r) = let l' = ai env l
1219 ai env (PAlternative as) = let as' = map (ai env) as in
1221 ai env (PApp fc (PRef _ f) as)
1222 | not (f `elem` env)
1223 = let as' = map (fmap (ai env)) as in
1224 handleErr $ aiFn False ist fc f as'
1225 ai env (PApp fc f as) = let f' = ai env f
1226 as' = map (fmap (ai env)) as in
1228 ai env (PCase fc c os) = let c' = ai env c
1229 os' = map (pmap (ai env)) os in
1231 ai env (PLam n ty sc) = let ty' = ai env ty
1232 sc' = ai (n:env) sc in
1234 ai env (PLet n ty val sc)
1235 = let ty' = ai env ty
1237 sc' = ai (n:env) sc in
1239 ai env (PPi p n ty sc) = let ty' = ai env ty
1240 sc' = ai (n:env) sc in
1242 ai env (PHidden tm) = PHidden (ai env tm)
1243 ai env (PProof ts) = PProof (map (fmap (ai env)) ts)
1244 ai env (PTactics ts) = PTactics (map (fmap (ai env)) ts)
1247 handleErr (Left err) = PElabError err
1248 handleErr (Right x) = x
1250-- if in a pattern, and there are no arguments, and there's no possible
1251-- names with zero explicit arguments, don't add implicits.
1253aiFn :: Bool -> IState -> FC -> Name -> [PArg] -> Either Err PTerm
1254aiFn True ist fc f []
1255 = case lookupCtxt Nothing f (idris_implicits ist) of
1256 [] -> Right $ PRef fc f
1257 alts -> if (any (all imp) alts)
1258 then aiFn False ist fc f [] -- use it as a constructor
1259 else Right $ PRef fc f
1260 where imp (PExp _ _ _) = False
1262aiFn inpat ist fc f as
1263 | f `elem` primNames = Right $ PApp fc (PRef fc f) as
1264aiFn inpat ist fc f as
1265 -- This is where namespaces get resolved by adding PAlternative
1266 = case lookupCtxtName Nothing f (idris_implicits ist) of
1267 [(f',ns)] -> Right $ mkPApp fc (length ns) (PRef fc f') (insertImpl ns as)
1268 [] -> if f `elem` idris_metavars ist
1269 then Right $ PApp fc (PRef fc f) as
1270 else Right $ mkPApp fc (length as) (PRef fc f) as
1273 map (\(f', ns) -> mkPApp fc (length ns) (PRef fc f')
1274 (insertImpl ns as)) alts
1276 insertImpl :: [PArg] -> [PArg] -> [PArg]
1277 insertImpl (PExp p l ty : ps) (PExp _ _ tm : given) =
1278 PExp p l tm : insertImpl ps given
1279 insertImpl (PConstraint p l ty : ps) (PConstraint _ _ tm : given) =
1280 PConstraint p l tm : insertImpl ps given
1281 insertImpl (PConstraint p l ty : ps) given =
1282 PConstraint p l (PResolveTC fc) : insertImpl ps given
1283 insertImpl (PImp p l n ty : ps) given =
1284 case find n given [] of
1285 Just (tm, given') -> PImp p l n tm : insertImpl ps given'
1286 Nothing -> PImp p l n Placeholder : insertImpl ps given
1287 insertImpl (PTacImplicit p l n sc ty : ps) given =
1288 case find n given [] of
1289 Just (tm, given') -> PTacImplicit p l n sc tm : insertImpl ps given'
1290 Nothing -> PTacImplicit p l n sc sc
1291 : insertImpl ps given
1292 insertImpl expected [] = []
1293 insertImpl _ given = given
1295 find n [] acc = Nothing
1296 find n (PImp _ _ n' t : gs) acc
1297 | n == n' = Just (t, reverse acc ++ gs)
1298 find n (g : gs) acc = find n gs (g : acc)
1301mkPApp fc a f as = let rest = drop a as in
1302 appRest fc (PApp fc f (take a as)) rest
1305 appRest fc f (a : as) = appRest fc (PApp fc f [a]) as
1307-- Find 'static' argument positions
1308-- (the declared ones, plus any names in argument position in the declared
1310-- FIXME: It's possible that this really has to happen after elaboration
1312findStatics :: IState -> PTerm -> (PTerm, [Bool])
1313findStatics ist tm = trace (showImp True tm) $
1314 let (ns, ss) = fs tm in
1315 runState (pos ns ss tm) []
1316 where fs (PPi p n t sc)
1317 | Static <- pstatic p
1318 = let (ns, ss) = fs sc in
1319 (namesIn [] ist t : ns, n : ss)
1320 | otherwise = let (ns, ss) = fs sc in
1324 inOne n ns = length (filter id (map (elem n) ns)) == 1
1326 pos ns ss (PPi p n t sc)
1327 | elem n ss = do sc' <- pos ns ss sc
1330 return (PPi (p { pstatic = Static }) n t sc')
1331 | otherwise = do sc' <- pos ns ss sc
1334 return (PPi p n t sc')
1335 pos ns ss t = return t
1337-- Debugging/logging stuff
1339dumpDecls :: [PDecl] -> String
1341dumpDecls (d:ds) = dumpDecl d ++ "\n" ++ dumpDecls ds
1343dumpDecl (PFix _ f ops) = show f ++ " " ++ showSep ", " ops
1344dumpDecl (PTy _ _ _ n t) = "tydecl " ++ show n ++ " : " ++ showImp True t
1345dumpDecl (PClauses _ _ n cs) = "pat " ++ show n ++ "\t" ++ showSep "\n\t" (map (showCImp True) cs)
1346dumpDecl (PData _ _ d) = showDImp True d
1347dumpDecl (PParams _ ns ps) = "params {" ++ show ns ++ "\n" ++ dumpDecls ps ++ "}\n"
1348dumpDecl (PNamespace n ps) = "namespace {" ++ n ++ "\n" ++ dumpDecls ps ++ "}\n"
1349dumpDecl (PSyntax _ syn) = "syntax " ++ show syn
1350dumpDecl (PClass _ _ cs n ps ds)
1351 = "class " ++ show cs ++ " " ++ show n ++ " " ++ show ps ++ "\n" ++ dumpDecls ds
1352dumpDecl (PInstance _ _ cs n _ t ds)
1353 = "instance " ++ show cs ++ " " ++ show n ++ " " ++ show t ++ "\n" ++ dumpDecls ds
1355-- dumpDecl (PImport i) = "import " ++ i
1357-- for 6.12/7 compatibility
1358data EitherErr a b = LeftErr a | RightOK b
1360instance Monad (EitherErr a) where
1363 (LeftErr e) >>= k = LeftErr e
1364 RightOK v >>= k = k v
1366toEither (LeftErr e) = Left e
1367toEither (RightOK ho) = Right ho
1369-- syntactic match of a against b, returning pair of variables in a
1370-- and what they match. Returns the pair that failed if not a match.
1372matchClause :: IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
1373matchClause = matchClause' False
1375matchClause' :: Bool -> IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
1376matchClause' names i x y = checkRpts $ match (fullApp x) (fullApp y) where
1377 matchArg x y = match (fullApp (getTm x)) (fullApp (getTm y))
1379 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
1382 match' x y = match (fullApp x) (fullApp y)
1383 match (PApp _ (PRef _ (NS (UN "fromInteger") ["builtins"])) [_,_,x]) x'
1384 | PConstant (I _) <- getTm x = match (getTm x) x'
1385 match x' (PApp _ (PRef _ (NS (UN "fromInteger") ["builtins"])) [_,_,x])
1386 | PConstant (I _) <- getTm x = match (getTm x) x'
1387 match (PApp _ f args) (PApp _ f' args')
1388 | length args == length args'
1389 = do mf <- match' f f'
1390 ms <- zipWithM matchArg args args'
1391 return (mf ++ concat ms)
1392-- match (PRef _ n) (PRef _ n') | n == n' = return []
1393-- | otherwise = Nothing
1394 match (PRef f n) (PApp _ x []) = match (PRef f n) x
1395 match (PApp _ x []) (PRef f n) = match x (PRef f n)
1396 match (PRef _ n) (PRef _ n') | n == n' = return []
1398 | not names && (not (isConName Nothing n (tt_ctxt i)) || tm == Placeholder)
1400 match (PEq _ l r) (PEq _ l' r') = do ml <- match' l l'
1403 match (PTyped l r) (PTyped l' r') = do ml <- match l l'
1406 match (PTyped l r) x = match l x
1407 match x (PTyped l r) = match x l
1408 match (PPair _ l r) (PPair _ l' r') = do ml <- match' l l'
1411 match (PDPair _ l t r) (PDPair _ l' t' r') = do ml <- match' l l'
1414 return (ml ++ mt ++ mr)
1415 match (PAlternative as) (PAlternative as')
1416 = do ms <- zipWithM match' as as'
1418 match a@(PAlternative as) b
1419 = do let ms = zipWith match' as (repeat b)
1420 case (rights (map toEither ms)) of
1423 match (PCase _ _ _) _ = return [] -- lifted out
1424 match (PMetavar _) _ = return [] -- modified
1425 match (PQuote _) _ = return []
1426 match (PProof _) _ = return []
1427 match (PTactics _) _ = return []
1428 match (PRefl _) (PRefl _) = return []
1429 match (PResolveTC _) (PResolveTC _) = return []
1430 match (PTrue _) (PTrue _) = return []
1431 match (PFalse _) (PFalse _) = return []
1432 match (PReturn _) (PReturn _) = return []
1433 match (PPi _ _ t s) (PPi _ _ t' s') = do mt <- match' t t'
1436 match (PLam _ t s) (PLam _ t' s') = do mt <- match' t t'
1439 match (PLet _ t ty s) (PLet _ t' ty' s') = do mt <- match' t t'
1440 mty <- match' ty ty'
1442 return (mt ++ mty ++ ms)
1443 match (PHidden x) (PHidden y) = match' x y
1444 match Placeholder _ = return []
1445-- match _ Placeholder = return []
1446 match (PResolveTC _) _ = return []
1447 match a b | a == b = return []
1448 | otherwise = LeftErr (a, b)
1450 checkRpts (RightOK ms) = check ms where
1452 | Just t' <- lookup n xs = if t/=t' && t/=Placeholder && t'/=Placeholder
1455 check (_:xs) = check xs
1457 checkRpts (LeftErr x) = Left x
1459substMatches :: [(Name, PTerm)] -> PTerm -> PTerm
1460substMatches [] t = t
1461substMatches ((n,tm):ns) t = substMatch n tm (substMatches ns t)
1463substMatch :: Name -> PTerm -> PTerm -> PTerm
1464substMatch n tm t = sm t where
1465 sm (PRef _ n') | n == n' = tm
1466 sm (PLam x t sc) = PLam x (sm t) (sm sc)
1467 sm (PPi p x t sc) = PPi p x (sm t) (sm sc)
1468 sm (PApp f x as) = PApp f (sm x) (map (fmap sm) as)
1469 sm (PCase f x as) = PCase f (sm x) (map (pmap sm) as)
1470 sm (PEq f x y) = PEq f (sm x) (sm y)
1471 sm (PTyped x y) = PTyped (sm x) (sm y)
1472 sm (PPair f x y) = PPair f (sm x) (sm y)
1473 sm (PDPair f x t y) = PDPair f (sm x) (sm t) (sm y)
1474 sm (PAlternative as) = PAlternative (map sm as)
1475 sm (PHidden x) = PHidden (sm x)
1478shadow :: Name -> Name -> PTerm -> PTerm
1479shadow n n' t = sm t where
1480 sm (PRef fc x) | n == x = PRef fc n'
1481 sm (PLam x t sc) = PLam x (sm t) (sm sc)
1482 sm (PPi p x t sc) = PPi p x (sm t) (sm sc)
1483 sm (PApp f x as) = PApp f (sm x) (map (fmap sm) as)
1484 sm (PCase f x as) = PCase f (sm x) (map (pmap sm) as)
1485 sm (PEq f x y) = PEq f (sm x) (sm y)
1486 sm (PTyped x y) = PTyped (sm x) (sm y)
1487 sm (PPair f x y) = PPair f (sm x) (sm y)
1488 sm (PDPair f x t y) = PDPair f (sm x) (sm t) (sm y)
1489 sm (PAlternative as) = PAlternative (map sm as)
1490 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