1{-| Code related to Idris's reflection system. This module contains
2quoters and unquoters along with some supporting datatypes.
4{-# LANGUAGE PatternGuards #-}
5{-# OPTIONS_GHC -fwarn-incomplete-patterns -fwarn-unused-imports #-}
6module Idris.Reflection where
8import Control.Applicative ((<$>), (<*>), pure)
9import Control.Monad (liftM, liftM2)
10import Data.Maybe (catMaybes)
11import Data.List ((\\))
12import qualified Data.Text as T
14import Idris.Core.Elaborate (claim, fill, focus, getNameFrom, initElaborator,
15 movelast, runElab, solve)
16import Idris.Core.Evaluate (Context, Def(TyDecl), initContext, lookupDefExact, lookupTyExact)
19import Idris.AbsSyntaxTree (ElabD, IState, PArg'(..), PArg, PTactic, PTactic'(..),
20 PTerm(..), initEState, pairCon, pairTy)
21import Idris.Delaborate (delab)
23data RArg = RExplicit { argName :: Name, argTy :: Raw }
24 | RImplicit { argName :: Name, argTy :: Raw }
25 | RConstraint { argName :: Name, argTy :: Raw }
28data RTyDecl = RDeclare Name [RArg] Raw deriving Show
30data RTyConArg = RParameter { tcArgName :: Name, tcArgTy :: Raw }
31 | RIndex { tcArgName :: Name, tcArgTy :: Raw }
34data RDatatype = RDatatype Name [RTyConArg] Raw [(Name, Raw)] deriving Show
36rArgToPArg :: RArg -> PArg
37rArgToPArg (RExplicit n _) = PExp 0 [] n Placeholder
38rArgToPArg (RImplicit n _) = PImp 0 False [] n Placeholder
39rArgToPArg (RConstraint n _) = PConstraint 0 [] n Placeholder
41data RFunClause = RMkFunClause Raw Raw
42 | RMkImpossibleClause Raw
45data RFunDefn = RDefineFun Name [RFunClause] deriving Show
47-- | Prefix a name with the "Language.Reflection" namespace
48reflm :: String -> Name
49reflm n = sNS (sUN n) ["Reflection", "Language"]
51-- | Prefix a name with the "Language.Reflection.Elab" namespace
53tacN str = sNS (sUN str) ["Elab", "Reflection", "Language"]
55-- | Reify tactics from their reflected representation
56reify :: IState -> Term -> ElabD PTactic
57reify _ (P _ n _) | n == reflm "Intros" = return Intros
58reify _ (P _ n _) | n == reflm "Trivial" = return Trivial
59reify _ (P _ n _) | n == reflm "Instance" = return TCInstance
60reify _ (P _ n _) | n == reflm "Solve" = return Solve
61reify _ (P _ n _) | n == reflm "Compute" = return Compute
62reify _ (P _ n _) | n == reflm "Skip" = return Skip
63reify _ (P _ n _) | n == reflm "SourceFC" = return SourceFC
64reify _ (P _ n _) | n == reflm "Unfocus" = return Unfocus
65reify ist t@(App _ _ _)
66 | (P _ f _, args) <- unApply t = reifyApp ist f args
67reify _ t = fail ("Unknown tactic " ++ show t)
69reifyApp :: IState -> Name -> [Term] -> ElabD PTactic
70reifyApp ist t [l, r] | t == reflm "Try" = liftM2 Try (reify ist l) (reify ist r)
71reifyApp _ t [Constant (I i)]
72 | t == reflm "Search" = return (ProofSearch True True i Nothing [])
74 | t == reflm "Refine" = do n <- reifyTTName x
76reifyApp ist t [n, ty] | t == reflm "Claim" = do n' <- reifyTTName n
78 return $ Claim n' (delab ist goal)
79reifyApp ist t [l, r] | t == reflm "Seq" = liftM2 TSeq (reify ist l) (reify ist r)
80reifyApp ist t [Constant (Str n), x]
81 | t == reflm "GoalType" = liftM (GoalType n) (reify ist x)
82reifyApp _ t [n] | t == reflm "Intro" = liftM (Intro . (:[])) (reifyTTName n)
83reifyApp ist t [t'] | t == reflm "Induction" = liftM (Induction . delab ist) (reifyTT t')
84reifyApp ist t [t'] | t == reflm "Case" = liftM (Induction . delab ist) (reifyTT t')
86 | t == reflm "ApplyTactic" = liftM (ApplyTactic . delab ist) (reifyTT t')
88 | t == reflm "Reflect" = liftM (Reflect . delab ist) (reifyTT t')
90 | t == reflm "ByReflection" = liftM (ByReflection . delab ist) (reifyTT t')
92 | t == reflm "Fill" = liftM (Fill . PQuote) (reifyRaw t')
94 | t == reflm "Exact" = liftM (Exact . delab ist) (reifyTT t')
96 | t == reflm "Focus" = liftM Focus (reifyTTName x)
98 | t == reflm "Rewrite" = liftM (Rewrite . delab ist) (reifyTT t')
100 | t == reflm "LetTac" = do n' <- reifyTTName n
102 return $ LetTac n' (delab ist t')
103reifyApp ist t [n, tt', t']
104 | t == reflm "LetTacTy" = do n' <- reifyTTName n
107 return $ LetTacTy n' (delab ist tt'') (delab ist t'')
109 | t == reflm "Fail" = fmap TFail (reifyReportParts errs)
110reifyApp _ f args = fail ("Unknown tactic " ++ show (f, args)) -- shouldn't happen
112reifyReportParts :: Term -> ElabD [ErrorReportPart]
113reifyReportParts errs =
115 Nothing -> fail "Failed to reify errors"
117 let parts = mapM reifyReportPart errs' in
119 Left err -> fail $ "Couldn't reify \"Fail\" tactic - " ++ show err
123-- | Reify terms from their reflected representation
124reifyTT :: Term -> ElabD Term
126 | (P _ f _, args) <- unApply t = reifyTTApp f args
128 | n == reflm "Erased" = return $ Erased
130 | n == reflm "Impossible" = return $ Impossible
131reifyTT t = fail ("Unknown reflection term: " ++ show t)
133reifyTTApp :: Name -> [Term] -> ElabD Term
134reifyTTApp t [nt, n, x]
135 | t == reflm "P" = do nt' <- reifyTTNameType nt
139reifyTTApp t [Constant (I i)]
140 | t == reflm "V" = return $ V i
141reifyTTApp t [n, b, x]
142 | t == reflm "Bind" = do n' <- reifyTTName n
143 b' <- reifyTTBinder reifyTT (reflm "TT") b
145 return $ Bind n' b' x'
147 | t == reflm "App" = do f' <- reifyTT f
149 return $ App Complete f' x'
151 | t == reflm "TConst" = liftM Constant (reifyTTConst c)
152reifyTTApp t [t', Constant (I i)]
153 | t == reflm "Proj" = do t'' <- reifyTT t'
156 | t == reflm "TType" = liftM TType (reifyTTUExp tt)
157reifyTTApp t args = fail ("Unknown reflection term: " ++ show (t, args))
159-- | Reify raw terms from their reflected representation
160reifyRaw :: Term -> ElabD Raw
161reifyRaw t@(App _ _ _)
162 | (P _ f _, args) <- unApply t = reifyRawApp f args
164 | n == reflm "RType" = return $ RType
165reifyRaw t = fail ("Unknown reflection raw term in reifyRaw: " ++ show t)
167reifyRawApp :: Name -> [Term] -> ElabD Raw
169 | t == reflm "Var" = liftM Var (reifyTTName n)
170reifyRawApp t [n, b, x]
171 | t == reflm "RBind" = do n' <- reifyTTName n
172 b' <- reifyTTBinder reifyRaw (reflm "Raw") b
174 return $ RBind n' b' x'
176 | t == reflm "RApp" = liftM2 RApp (reifyRaw f) (reifyRaw x)
178 | t == reflm "RForce" = liftM RForce (reifyRaw t')
180 | t == reflm "RConstant" = liftM RConstant (reifyTTConst c)
181reifyRawApp t args = fail ("Unknown reflection raw term in reifyRawApp: " ++ show (t, args))
183reifyTTName :: Term -> ElabD Name
185 | (P _ f _, args) <- unApply t = reifyTTNameApp f args
186reifyTTName t = fail ("Unknown reflection term name: " ++ show t)
188reifyTTNameApp :: Name -> [Term] -> ElabD Name
189reifyTTNameApp t [Constant (Str n)]
190 | t == reflm "UN" = return $ sUN n
191reifyTTNameApp t [n, ns]
192 | t == reflm "NS" = do n' <- reifyTTName n
193 ns' <- reifyTTNamespace ns
195reifyTTNameApp t [Constant (I i), Constant (Str n)]
196 | t == reflm "MN" = return $ sMN i n
199 , (P _ f _, args) <- unApply sn = SN <$> reifySN f args
200 where reifySN :: Name -> [Term] -> ElabD SpecialName
201 reifySN t [Constant (I i), n1, n2]
202 | t == reflm "WhereN" = WhereN i <$> reifyTTName n1 <*> reifyTTName n2
203 reifySN t [Constant (I i), n]
204 | t == reflm "WithN" = WithN i <$> reifyTTName n
206 | t == reflm "InstanceN" =
208 Nothing -> fail "Can't reify InstanceN strings"
209 Just ss' -> InstanceN <$> reifyTTName n <*>
210 pure [T.pack s | Constant (Str s) <- ss']
211 reifySN t [n, Constant (Str s)]
212 | t == reflm "ParentN" =
213 ParentN <$> reifyTTName n <*> pure (T.pack s)
215 | t == reflm "MethodN" =
216 MethodN <$> reifyTTName n
218 | t == reflm "CaseN" =
219 CaseN <$> reifyTTName n
221 | t == reflm "ElimN" =
222 ElimN <$> reifyTTName n
224 | t == reflm "InstanceCtorN" =
225 InstanceCtorN <$> reifyTTName n
227 | t == reflm "MetaN" =
228 MetaN <$> reifyTTName n1 <*> reifyTTName n2
229 reifySN t args = fail $ "Can't reify special name " ++ show t ++ show args
231 | t == reflm "NErased" = return NErased
232reifyTTNameApp t args = fail ("Unknown reflection term name: " ++ show (t, args))
234reifyTTNamespace :: Term -> ElabD [String]
235reifyTTNamespace t@(App _ _ _)
237 (P _ f _, [Constant StrType])
238 | f == sNS (sUN "Nil") ["List", "Prelude"] -> return []
239 (P _ f _, [Constant StrType, Constant (Str n), ns])
240 | f == sNS (sUN "::") ["List", "Prelude"] -> liftM (n:) (reifyTTNamespace ns)
241 _ -> fail ("Unknown reflection namespace arg: " ++ show t)
242reifyTTNamespace t = fail ("Unknown reflection namespace arg: " ++ show t)
244reifyTTNameType :: Term -> ElabD NameType
245reifyTTNameType t@(P _ n _) | n == reflm "Bound" = return $ Bound
246reifyTTNameType t@(P _ n _) | n == reflm "Ref" = return $ Ref
247reifyTTNameType t@(App _ _ _)
249 (P _ f _, [Constant (I tag), Constant (I num)])
250 | f == reflm "DCon" -> return $ DCon tag num False -- FIXME: Uniqueness!
251 | f == reflm "TCon" -> return $ TCon tag num
252 _ -> fail ("Unknown reflection name type: " ++ show t)
253reifyTTNameType t = fail ("Unknown reflection name type: " ++ show t)
255reifyTTBinder :: (Term -> ElabD a) -> Name -> Term -> ElabD (Binder a)
256reifyTTBinder reificator binderType t@(App _ _ _)
258 (P _ f _, bt:args) | forget bt == Var binderType
259 -> reifyTTBinderApp reificator f args
260 _ -> fail ("Mismatching binder reflection: " ++ show t)
261reifyTTBinder _ _ t = fail ("Unknown reflection binder: " ++ show t)
263reifyTTBinderApp :: (Term -> ElabD a) -> Name -> [Term] -> ElabD (Binder a)
264reifyTTBinderApp reif f [t]
265 | f == reflm "Lam" = liftM Lam (reif t)
266reifyTTBinderApp reif f [t, k]
267 | f == reflm "Pi" = liftM2 (Pi Nothing) (reif t) (reif k)
268reifyTTBinderApp reif f [x, y]
269 | f == reflm "Let" = liftM2 Let (reif x) (reif y)
270reifyTTBinderApp reif f [x, y]
271 | f == reflm "NLet" = liftM2 NLet (reif x) (reif y)
272reifyTTBinderApp reif f [t]
273 | f == reflm "Hole" = liftM Hole (reif t)
274reifyTTBinderApp reif f [t]
275 | f == reflm "GHole" = liftM (GHole 0) (reif t)
276reifyTTBinderApp reif f [x, y]
277 | f == reflm "Guess" = liftM2 Guess (reif x) (reif y)
278reifyTTBinderApp reif f [t]
279 | f == reflm "PVar" = liftM PVar (reif t)
280reifyTTBinderApp reif f [t]
281 | f == reflm "PVTy" = liftM PVTy (reif t)
282reifyTTBinderApp _ f args = fail ("Unknown reflection binder: " ++ show (f, args))
284reifyTTConst :: Term -> ElabD Const
285reifyTTConst (P _ n _) | n == reflm "StrType" = return $ StrType
286reifyTTConst (P _ n _) | n == reflm "VoidType" = return $ VoidType
287reifyTTConst (P _ n _) | n == reflm "Forgot" = return $ Forgot
288reifyTTConst t@(App _ _ _)
289 | (P _ f _, [arg]) <- unApply t = reifyTTConstApp f arg
290reifyTTConst t = fail ("Unknown reflection constant: " ++ show t)
292reifyTTConstApp :: Name -> Term -> ElabD Const
294 | f == reflm "AType" = fmap AType (reifyArithTy aty)
295reifyTTConstApp f (Constant c@(I _))
296 | f == reflm "I" = return $ c
297reifyTTConstApp f (Constant c@(BI _))
298 | f == reflm "BI" = return $ c
299reifyTTConstApp f (Constant c@(Fl _))
300 | f == reflm "Fl" = return $ c
301reifyTTConstApp f (Constant c@(I _))
302 | f == reflm "Ch" = return $ c
303reifyTTConstApp f (Constant c@(Str _))
304 | f == reflm "Str" = return $ c
305reifyTTConstApp f (Constant c@(B8 _))
306 | f == reflm "B8" = return $ c
307reifyTTConstApp f (Constant c@(B16 _))
308 | f == reflm "B16" = return $ c
309reifyTTConstApp f (Constant c@(B32 _))
310 | f == reflm "B32" = return $ c
311reifyTTConstApp f (Constant c@(B64 _))
312 | f == reflm "B64" = return $ c
313reifyTTConstApp f arg = fail ("Unknown reflection constant: " ++ show (f, arg))
315reifyArithTy :: Term -> ElabD ArithTy
316reifyArithTy (App _ (P _ n _) intTy) | n == reflm "ATInt" = fmap ATInt (reifyIntTy intTy)
317reifyArithTy (P _ n _) | n == reflm "ATFloat" = return ATFloat
318reifyArithTy x = fail ("Couldn't reify reflected ArithTy: " ++ show x)
320reifyNativeTy :: Term -> ElabD NativeTy
321reifyNativeTy (P _ n _) | n == reflm "IT8" = return IT8
322reifyNativeTy (P _ n _) | n == reflm "IT8" = return IT8
323reifyNativeTy (P _ n _) | n == reflm "IT8" = return IT8
324reifyNativeTy (P _ n _) | n == reflm "IT8" = return IT8
325reifyNativeTy x = fail $ "Couldn't reify reflected NativeTy " ++ show x
327reifyIntTy :: Term -> ElabD IntTy
328reifyIntTy (App _ (P _ n _) nt) | n == reflm "ITFixed" = fmap ITFixed (reifyNativeTy nt)
329reifyIntTy (P _ n _) | n == reflm "ITNative" = return ITNative
330reifyIntTy (P _ n _) | n == reflm "ITBig" = return ITBig
331reifyIntTy (P _ n _) | n == reflm "ITChar" = return ITChar
332reifyIntTy tm = fail $ "The term " ++ show tm ++ " is not a reflected IntTy"
334reifyTTUExp :: Term -> ElabD UExp
335reifyTTUExp t@(App _ _ _)
337 (P _ f _, [Constant (I i)]) | f == reflm "UVar" -> return $ UVar i
338 (P _ f _, [Constant (I i)]) | f == reflm "UVal" -> return $ UVal i
339 _ -> fail ("Unknown reflection type universe expression: " ++ show t)
340reifyTTUExp t = fail ("Unknown reflection type universe expression: " ++ show t)
342-- | Create a reflected call to a named function/constructor
343reflCall :: String -> [Raw] -> Raw
345 = raw_apply (Var (reflm funName)) args
347-- | Lift a term into its Language.Reflection.TT representation
348reflect :: Term -> Raw
349reflect = reflectTTQuote []
351-- | Lift a term into its Language.Reflection.Raw representation
352reflectRaw :: Raw -> Raw
353reflectRaw = reflectRawQuote []
355claimTT :: Name -> ElabD Name
356claimTT n = do n' <- getNameFrom n
357 claim n' (Var (sNS (sUN "TT") ["Reflection", "Language"]))
360-- | Convert a reflected term to a more suitable form for pattern-matching.
361-- In particular, the less-interesting bits are elaborated to _ patterns. This
362-- happens to NameTypes, universe levels, names that are bound but not used,
363-- and the type annotation field of the P constructor.
364reflectTTQuotePattern :: [Name] -> Term -> ElabD ()
365reflectTTQuotePattern unq (P _ n _)
366 | n `elem` unq = -- the unquoted names have been claimed as TT already - just use them
367 do fill (Var n) ; solve
369 do tyannot <- claimTT (sMN 0 "pTyAnnot")
370 movelast tyannot -- use a _ pattern here
371 nt <- getNameFrom (sMN 0 "nt")
372 claim nt (Var (reflm "NameType"))
373 movelast nt -- use a _ pattern here
374 n' <- getNameFrom (sMN 0 "n")
375 claim n' (Var (reflm "TTName"))
376 fill $ reflCall "P" [Var nt, Var n', Var tyannot]
378 focus n'; reflectNameQuotePattern n
379reflectTTQuotePattern unq (V n)
380 = do fill $ reflCall "V" [RConstant (I n)]
382reflectTTQuotePattern unq (Bind n b x)
383 = do x' <- claimTT (sMN 0 "sc")
385 b' <- getNameFrom (sMN 0 "binder")
386 claim b' (RApp (Var (sNS (sUN "Binder") ["Reflection", "Language"]))
387 (Var (sNS (sUN "TT") ["Reflection", "Language"])))
388 if n `elem` freeNames x
389 then do fill $ reflCall "Bind"
394 else do any <- getNameFrom (sMN 0 "anyName")
395 claim any (Var (reflm "TTName"))
397 fill $ reflCall "Bind"
402 focus x'; reflectTTQuotePattern unq x
403 focus b'; reflectBinderQuotePattern reflectTTQuotePattern unq b
404reflectTTQuotePattern unq (App _ f x)
405 = do f' <- claimTT (sMN 0 "f"); movelast f'
406 x' <- claimTT (sMN 0 "x"); movelast x'
407 fill $ reflCall "App" [Var f', Var x']
409 focus f'; reflectTTQuotePattern unq f
410 focus x'; reflectTTQuotePattern unq x
411reflectTTQuotePattern unq (Constant c)
412 = do fill $ reflCall "TConst" [reflectConstant c]
414reflectTTQuotePattern unq (Proj t i)
415 = do t' <- claimTT (sMN 0 "t"); movelast t'
416 fill $ reflCall "Proj" [Var t', RConstant (I i)]
418 focus t'; reflectTTQuotePattern unq t
419reflectTTQuotePattern unq (Erased)
420 = do erased <- claimTT (sMN 0 "erased")
424reflectTTQuotePattern unq (Impossible)
425 = do fill $ Var (reflm "Impossible")
427reflectTTQuotePattern unq (TType exp)
428 = do ue <- getNameFrom (sMN 0 "uexp")
429 claim ue (Var (sNS (sUN "TTUExp") ["Reflection", "Language"]))
431 fill $ reflCall "TType" [Var ue]
433reflectTTQuotePattern unq (UType u)
434 = do uH <- getNameFrom (sMN 0 "someUniv")
435 claim uH (Var (reflm "Universe"))
437 fill $ reflCall "UType" [Var uH]
440 fill (Var (reflm (case u of
441 NullType -> "NullType"
442 UniqueType -> "UniqueType"
443 AllTypes -> "AllTypes")))
446reflectRawQuotePattern :: [Name] -> Raw -> ElabD ()
447reflectRawQuotePattern unq (Var n)
448 -- the unquoted names already have types, just use them
449 | n `elem` unq = do fill (Var n); solve
450 | otherwise = do fill (reflCall "Var" [reflectName n]); solve
451reflectRawQuotePattern unq (RBind n b sc) =
452 do scH <- getNameFrom (sMN 0 "sc")
453 claim scH (Var (reflm "Raw"))
455 bH <- getNameFrom (sMN 0 "binder")
456 claim bH (RApp (Var (reflm "Binder"))
458 if n `elem` freeNamesR sc
459 then do fill $ reflCall "RBind" [reflectName n,
463 else do any <- getNameFrom (sMN 0 "anyName")
464 claim any (Var (reflm "TTName"))
466 fill $ reflCall "RBind" [Var any, Var bH, Var scH]
468 focus scH; reflectRawQuotePattern unq sc
469 focus bH; reflectBinderQuotePattern reflectRawQuotePattern unq b
470 where freeNamesR (Var n) = [n]
471 freeNamesR (RBind n (Let t v) body) = concat [freeNamesR v,
472 freeNamesR body \\ [n],
474 freeNamesR (RBind n b body) = freeNamesR (binderTy b) ++
475 (freeNamesR body \\ [n])
476 freeNamesR (RApp f x) = freeNamesR f ++ freeNamesR x
477 freeNamesR RType = []
478 freeNamesR (RUType _) = []
479 freeNamesR (RForce r) = freeNamesR r
480 freeNamesR (RConstant _) = []
481reflectRawQuotePattern unq (RApp f x) =
482 do fH <- getNameFrom (sMN 0 "f")
483 claim fH (Var (reflm "Raw"))
485 xH <- getNameFrom (sMN 0 "x")
486 claim xH (Var (reflm "Raw"))
488 fill $ reflCall "RApp" [Var fH, Var xH]
490 focus fH; reflectRawQuotePattern unq f
491 focus xH; reflectRawQuotePattern unq x
492reflectRawQuotePattern unq RType =
493 do fill (Var (reflm "RType"))
495reflectRawQuotePattern unq (RUType univ) =
496 do uH <- getNameFrom (sMN 0 "universe")
497 claim uH (Var (reflm "Universe"))
499 fill $ reflCall "RUType" [Var uH]
501 focus uH; fill (reflectUniverse univ); solve
502reflectRawQuotePattern unq (RForce r) =
503 do rH <- getNameFrom (sMN 0 "raw")
504 claim rH (Var (reflm "Raw"))
506 fill $ reflCall "RForce" [Var rH]
508 focus rH; reflectRawQuotePattern unq r
509reflectRawQuotePattern unq (RConstant c) =
510 do cH <- getNameFrom (sMN 0 "const")
511 claim cH (Var (reflm "Constant"))
513 fill (reflCall "RConstant" [Var cH]); solve
515 fill (reflectConstant c); solve
517reflectBinderQuotePattern :: ([Name] -> a -> ElabD ()) -> [Name] -> Binder a -> ElabD ()
518reflectBinderQuotePattern q unq (Lam t)
519 = do t' <- claimTT (sMN 0 "ty"); movelast t'
520 fill $ reflCall "Lam" [Var (reflm "TT"), Var t']
523reflectBinderQuotePattern q unq (Pi _ t k)
524 = do t' <- claimTT (sMN 0 "ty") ; movelast t'
525 k' <- claimTT (sMN 0 "k"); movelast k';
526 fill $ reflCall "Pi" [Var (reflm "TT"), Var t', Var k']
529reflectBinderQuotePattern q unq (Let x y)
530 = do x' <- claimTT (sMN 0 "ty"); movelast x';
531 y' <- claimTT (sMN 0 "v"); movelast y';
532 fill $ reflCall "Let" [Var (reflm "TT"), Var x', Var y']
536reflectBinderQuotePattern q unq (NLet x y)
537 = do x' <- claimTT (sMN 0 "ty"); movelast x'
538 y' <- claimTT (sMN 0 "v"); movelast y'
539 fill $ reflCall "NLet" [Var (reflm "TT"), Var x', Var y']
543reflectBinderQuotePattern q unq (Hole t)
544 = do t' <- claimTT (sMN 0 "ty"); movelast t'
545 fill $ reflCall "Hole" [Var (reflm "TT"), Var t']
548reflectBinderQuotePattern q unq (GHole _ t)
549 = do t' <- claimTT (sMN 0 "ty"); movelast t'
550 fill $ reflCall "GHole" [Var (reflm "TT"), Var t']
553reflectBinderQuotePattern q unq (Guess x y)
554 = do x' <- claimTT (sMN 0 "ty"); movelast x'
555 y' <- claimTT (sMN 0 "v"); movelast y'
556 fill $ reflCall "Guess" [Var (reflm "TT"), Var x', Var y']
560reflectBinderQuotePattern q unq (PVar t)
561 = do t' <- claimTT (sMN 0 "ty"); movelast t'
562 fill $ reflCall "PVar" [Var (reflm "TT"), Var t']
565reflectBinderQuotePattern q unq (PVTy t)
566 = do t' <- claimTT (sMN 0 "ty"); movelast t'
567 fill $ reflCall "PVTy" [Var (reflm "TT"), Var t']
571reflectUniverse :: Universe -> Raw
573 (Var (reflm (case u of
574 NullType -> "NullType"
575 UniqueType -> "UniqueType"
576 AllTypes -> "AllTypes")))
578-- | Create a reflected TT term, but leave refs to the provided name intact
579reflectTTQuote :: [Name] -> Term -> Raw
580reflectTTQuote unq (P nt n t)
581 | n `elem` unq = Var n
582 | otherwise = reflCall "P" [reflectNameType nt, reflectName n, reflectTTQuote unq t]
583reflectTTQuote unq (V n)
584 = reflCall "V" [RConstant (I n)]
585reflectTTQuote unq (Bind n b x)
586 = reflCall "Bind" [reflectName n, reflectBinderQuote reflectTTQuote (reflm "TT") unq b, reflectTTQuote unq x]
587reflectTTQuote unq (App _ f x)
588 = reflCall "App" [reflectTTQuote unq f, reflectTTQuote unq x]
589reflectTTQuote unq (Constant c)
590 = reflCall "TConst" [reflectConstant c]
591reflectTTQuote unq (Proj t i)
592 = reflCall "Proj" [reflectTTQuote unq t, RConstant (I i)]
593reflectTTQuote unq (Erased) = Var (reflm "Erased")
594reflectTTQuote unq (Impossible) = Var (reflm "Impossible")
595reflectTTQuote unq (TType exp) = reflCall "TType" [reflectUExp exp]
596reflectTTQuote unq (UType u) = reflCall "UType" [reflectUniverse u]
598reflectRawQuote :: [Name] -> Raw -> Raw
599reflectRawQuote unq (Var n)
600 | n `elem` unq = Var n
601 | otherwise = reflCall "Var" [reflectName n]
602reflectRawQuote unq (RBind n b r) =
603 reflCall "RBind" [reflectName n, reflectBinderQuote reflectRawQuote (reflm "Raw") unq b, reflectRawQuote unq r]
604reflectRawQuote unq (RApp f x) =
605 reflCall "RApp" [reflectRawQuote unq f, reflectRawQuote unq x]
606reflectRawQuote unq RType = Var (reflm "RType")
607reflectRawQuote unq (RUType u) =
608 reflCall "RUType" [reflectUniverse u]
609reflectRawQuote unq (RForce r) = reflCall "RForce" [reflectRawQuote unq r]
610reflectRawQuote unq (RConstant cst) = reflCall "RConstant" [reflectConstant cst]
612reflectNameType :: NameType -> Raw
613reflectNameType (Bound) = Var (reflm "Bound")
614reflectNameType (Ref) = Var (reflm "Ref")
615reflectNameType (DCon x y _)
616 = reflCall "DCon" [RConstant (I x), RConstant (I y)] -- FIXME: Uniqueness!
617reflectNameType (TCon x y)
618 = reflCall "TCon" [RConstant (I x), RConstant (I y)]
620reflectName :: Name -> Raw
622 = reflCall "UN" [RConstant (Str (str s))]
624 = reflCall "NS" [ reflectName n
626 raw_apply ( Var $ sNS (sUN "::") ["List", "Prelude"] )
627 [ RConstant StrType, RConstant (Str n), s ])
628 ( raw_apply ( Var $ sNS (sUN "Nil") ["List", "Prelude"] )
629 [ RConstant StrType ])
633 = reflCall "MN" [RConstant (I i), RConstant (Str (str n))]
634reflectName NErased = Var (reflm "NErased")
635reflectName (SN sn) = raw_apply (Var (reflm "SN")) [reflectSpecialName sn]
636reflectName (SymRef _) = error "The impossible happened: symbol table ref survived IBC loading"
638reflectSpecialName :: SpecialName -> Raw
639reflectSpecialName (WhereN i n1 n2) =
640 reflCall "WhereN" [RConstant (I i), reflectName n1, reflectName n2]
641reflectSpecialName (WithN i n) = reflCall "WithN" [ RConstant (I i)
644reflectSpecialName (InstanceN inst ss) =
645 reflCall "InstanceN" [ reflectName inst
646 , mkList (RConstant StrType) $
647 map (RConstant . Str . T.unpack) ss
649reflectSpecialName (ParentN n s) =
650 reflCall "ParentN" [reflectName n, RConstant (Str (T.unpack s))]
651reflectSpecialName (MethodN n) =
652 reflCall "MethodN" [reflectName n]
653reflectSpecialName (CaseN n) =
654 reflCall "CaseN" [reflectName n]
655reflectSpecialName (ElimN n) =
656 reflCall "ElimN" [reflectName n]
657reflectSpecialName (InstanceCtorN n) =
658 reflCall "InstanceCtorN" [reflectName n]
659reflectSpecialName (MetaN parent meta) =
660 reflCall "MetaN" [reflectName parent, reflectName meta]
662-- | Elaborate a name to a pattern. This means that NS and UN will be intact.
663-- MNs corresponding to will care about the string but not the number. All
665reflectNameQuotePattern :: Name -> ElabD ()
666reflectNameQuotePattern n@(UN s)
667 = do fill $ reflectName n
669reflectNameQuotePattern n@(NS _ _)
670 = do fill $ reflectName n
672reflectNameQuotePattern (MN _ n)
673 = do i <- getNameFrom (sMN 0 "mnCounter")
674 claim i (RConstant (AType (ATInt ITNative)))
676 fill $ reflCall "MN" [Var i, RConstant (Str $ T.unpack n)]
678reflectNameQuotePattern _ -- for all other names, match any
679 = do nameHole <- getNameFrom (sMN 0 "name")
680 claim nameHole (Var (reflm "TTName"))
685reflectBinder :: Binder Term -> Raw
686reflectBinder = reflectBinderQuote reflectTTQuote (reflm "TT") []
688reflectBinderQuote :: ([Name] -> a -> Raw) -> Name -> [Name] -> Binder a -> Raw
689reflectBinderQuote q ty unq (Lam t)
690 = reflCall "Lam" [Var ty, q unq t]
691reflectBinderQuote q ty unq (Pi _ t k)
692 = reflCall "Pi" [Var ty, q unq t, q unq k]
693reflectBinderQuote q ty unq (Let x y)
694 = reflCall "Let" [Var ty, q unq x, q unq y]
695reflectBinderQuote q ty unq (NLet x y)
696 = reflCall "NLet" [Var ty, q unq x, q unq y]
697reflectBinderQuote q ty unq (Hole t)
698 = reflCall "Hole" [Var ty, q unq t]
699reflectBinderQuote q ty unq (GHole _ t)
700 = reflCall "GHole" [Var ty, q unq t]
701reflectBinderQuote q ty unq (Guess x y)
702 = reflCall "Guess" [Var ty, q unq x, q unq y]
703reflectBinderQuote q ty unq (PVar t)
704 = reflCall "PVar" [Var ty, q unq t]
705reflectBinderQuote q ty unq (PVTy t)
706 = reflCall "PVTy" [Var ty, q unq t]
708mkList :: Raw -> [Raw] -> Raw
709mkList ty [] = RApp (Var (sNS (sUN "Nil") ["List", "Prelude"])) ty
710mkList ty (x:xs) = RApp (RApp (RApp (Var (sNS (sUN "::") ["List", "Prelude"])) ty)
714reflectConstant :: Const -> Raw
715reflectConstant c@(I _) = reflCall "I" [RConstant c]
716reflectConstant c@(BI _) = reflCall "BI" [RConstant c]
717reflectConstant c@(Fl _) = reflCall "Fl" [RConstant c]
718reflectConstant c@(Ch _) = reflCall "Ch" [RConstant c]
719reflectConstant c@(Str _) = reflCall "Str" [RConstant c]
720reflectConstant c@(B8 _) = reflCall "B8" [RConstant c]
721reflectConstant c@(B16 _) = reflCall "B16" [RConstant c]
722reflectConstant c@(B32 _) = reflCall "B32" [RConstant c]
723reflectConstant c@(B64 _) = reflCall "B64" [RConstant c]
724reflectConstant (AType (ATInt ITNative)) = reflCall "AType" [reflCall "ATInt" [Var (reflm "ITNative")]]
725reflectConstant (AType (ATInt ITBig)) = reflCall "AType" [reflCall "ATInt" [Var (reflm "ITBig")]]
726reflectConstant (AType ATFloat) = reflCall "AType" [Var (reflm "ATFloat")]
727reflectConstant (AType (ATInt ITChar)) = reflCall "AType" [reflCall "ATInt" [Var (reflm "ITChar")]]
728reflectConstant StrType = Var (reflm "StrType")
729reflectConstant (AType (ATInt (ITFixed IT8))) = reflCall "AType" [reflCall "ATInt" [reflCall "ITFixed" [Var (reflm "IT8")]]]
730reflectConstant (AType (ATInt (ITFixed IT16))) = reflCall "AType" [reflCall "ATInt" [reflCall "ITFixed" [Var (reflm "IT16")]]]
731reflectConstant (AType (ATInt (ITFixed IT32))) = reflCall "AType" [reflCall "ATInt" [reflCall "ITFixed" [Var (reflm "IT32")]]]
732reflectConstant (AType (ATInt (ITFixed IT64))) = reflCall "AType" [reflCall "ATInt" [reflCall "ITFixed" [Var (reflm "IT64")]]]
733reflectConstant VoidType = Var (reflm "VoidType")
734reflectConstant Forgot = Var (reflm "Forgot")
735reflectConstant WorldType = Var (reflm "WorldType")
736reflectConstant TheWorld = Var (reflm "TheWorld")
738reflectUExp :: UExp -> Raw
739reflectUExp (UVar i) = reflCall "UVar" [RConstant (I i)]
740reflectUExp (UVal i) = reflCall "UVal" [RConstant (I i)]
742-- | Reflect the environment of a proof into a List (TTName, Binder TT)
743reflectEnv :: Env -> Raw
744reflectEnv = foldr consToEnvList emptyEnvList
746 consToEnvList :: (Name, Binder Term) -> Raw -> Raw
747 consToEnvList (n, b) l
748 = raw_apply (Var (sNS (sUN "::") ["List", "Prelude"]))
750 , raw_apply (Var pairCon) [ (Var $ reflm "TTName")
751 , (RApp (Var $ reflm "Binder")
760 emptyEnvList = raw_apply (Var (sNS (sUN "Nil") ["List", "Prelude"]))
763-- | Reflect an error into the internal datatype of Idris -- TODO
764rawBool :: Bool -> Raw
765rawBool True = Var (sNS (sUN "True") ["Bool", "Prelude"])
766rawBool False = Var (sNS (sUN "False") ["Bool", "Prelude"])
769rawNil ty = raw_apply (Var (sNS (sUN "Nil") ["List", "Prelude"])) [ty]
771rawCons :: Raw -> Raw -> Raw -> Raw
772rawCons ty hd tl = raw_apply (Var (sNS (sUN "::") ["List", "Prelude"])) [ty, hd, tl]
774rawList :: Raw -> [Raw] -> Raw
775rawList ty = foldr (rawCons ty) (rawNil ty)
777rawPairTy :: Raw -> Raw -> Raw
778rawPairTy t1 t2 = raw_apply (Var pairTy) [t1, t2]
780rawPair :: (Raw, Raw) -> (Raw, Raw) -> Raw
781rawPair (a, b) (x, y) = raw_apply (Var pairCon) [a, b, x, y]
783reflectCtxt :: [(Name, Type)] -> Raw
784reflectCtxt ctxt = rawList (rawPairTy (Var $ reflm "TTName") (Var $ reflm "TT"))
785 (map (\ (n, t) -> (rawPair (Var $ reflm "TTName", Var $ reflm "TT")
786 (reflectName n, reflect t)))
789reflectErr :: Err -> Raw
790reflectErr (Msg msg) = raw_apply (Var $ reflErrName "Msg") [RConstant (Str msg)]
791reflectErr (InternalMsg msg) = raw_apply (Var $ reflErrName "InternalMsg") [RConstant (Str msg)]
792reflectErr (CantUnify b (t1,_) (t2,_) e ctxt i) =
793 raw_apply (Var $ reflErrName "CantUnify")
800reflectErr (InfiniteUnify n tm ctxt) =
801 raw_apply (Var $ reflErrName "InfiniteUnify")
806reflectErr (CantConvert t t' ctxt) =
807 raw_apply (Var $ reflErrName "CantConvert")
812reflectErr (CantSolveGoal t ctxt) =
813 raw_apply (Var $ reflErrName "CantSolveGoal")
817reflectErr (UnifyScope n n' t ctxt) =
818 raw_apply (Var $ reflErrName "UnifyScope")
824reflectErr (CantInferType str) =
825 raw_apply (Var $ reflErrName "CantInferType") [RConstant (Str str)]
826reflectErr (NonFunctionType t t') =
827 raw_apply (Var $ reflErrName "NonFunctionType") [reflect t, reflect t']
828reflectErr (NotEquality t t') =
829 raw_apply (Var $ reflErrName "NotEquality") [reflect t, reflect t']
830reflectErr (TooManyArguments n) = raw_apply (Var $ reflErrName "TooManyArguments") [reflectName n]
831reflectErr (CantIntroduce t) = raw_apply (Var $ reflErrName "CantIntroduce") [reflect t]
832reflectErr (NoSuchVariable n) = raw_apply (Var $ reflErrName "NoSuchVariable") [reflectName n]
833reflectErr (WithFnType t) = raw_apply (Var $ reflErrName "WithFnType") [reflect t]
834reflectErr (CantMatch t) = raw_apply (Var $ reflErrName "CantMatch") [reflect t]
835reflectErr (NoTypeDecl n) = raw_apply (Var $ reflErrName "NoTypeDecl") [reflectName n]
836reflectErr (NotInjective t1 t2 t3) =
837 raw_apply (Var $ reflErrName "NotInjective")
842reflectErr (CantResolve _ t) = raw_apply (Var $ reflErrName "CantResolve") [reflect t]
843reflectErr (InvalidTCArg n t) = raw_apply (Var $ reflErrName "InvalidTCArg") [reflectName n, reflect t]
844reflectErr (CantResolveAlts ss) =
845 raw_apply (Var $ reflErrName "CantResolveAlts")
846 [rawList (Var $ reflm "TTName") (map reflectName ss)]
847reflectErr (IncompleteTerm t) = raw_apply (Var $ reflErrName "IncompleteTerm") [reflect t]
848reflectErr (NoEliminator str t)
849 = raw_apply (Var $ reflErrName "NoEliminator") [RConstant (Str str),
851reflectErr (UniverseError fc ue old new tys) =
852 -- NB: loses information, but OK because this is not likely to be rewritten
853 Var $ reflErrName "UniverseError"
854reflectErr ProgramLineComment = Var $ reflErrName "ProgramLineComment"
855reflectErr (Inaccessible n) = raw_apply (Var $ reflErrName "Inaccessible") [reflectName n]
856reflectErr (UnknownImplicit n f) = raw_apply (Var $ reflErrName "UnknownImplicit") [reflectName n, reflectName f]
857reflectErr (NonCollapsiblePostulate n) = raw_apply (Var $ reflErrName "NonCollabsiblePostulate") [reflectName n]
858reflectErr (AlreadyDefined n) = raw_apply (Var $ reflErrName "AlreadyDefined") [reflectName n]
859reflectErr (ProofSearchFail e) = raw_apply (Var $ reflErrName "ProofSearchFail") [reflectErr e]
860reflectErr (NoRewriting tm) = raw_apply (Var $ reflErrName "NoRewriting") [reflect tm]
861reflectErr (ProviderError str) =
862 raw_apply (Var $ reflErrName "ProviderError") [RConstant (Str str)]
863reflectErr (LoadingFailed str err) =
864 raw_apply (Var $ reflErrName "LoadingFailed") [RConstant (Str str)]
865reflectErr x = raw_apply (Var (sNS (sUN "Msg") ["Errors", "Reflection", "Language"])) [RConstant . Str $ "Default reflection: " ++ show x]
867-- | Reflect a file context
868reflectFC :: FC -> Raw
869reflectFC fc = raw_apply (Var (reflm "FileLoc"))
870 [ RConstant (Str (fc_fname fc))
871 , raw_apply (Var pairCon) $
877 , raw_apply (Var pairCon) $
884 where intTy = RConstant (AType (ATInt ITNative))
886fromTTMaybe :: Term -> Maybe Term -- WARNING: Assumes the term has type Maybe a
887fromTTMaybe (App _ (App _ (P (DCon _ _ _) (NS (UN just) _) _) ty) tm)
888 | just == txt "Just" = Just tm
889fromTTMaybe x = Nothing
891reflErrName :: String -> Name
892reflErrName n = sNS (sUN n) ["Errors", "Reflection", "Language"]
894-- | Attempt to reify a report part from TT to the internal
895-- representation. Not in Idris or ElabD monads because it should be usable
897reifyReportPart :: Term -> Either Err ErrorReportPart
898reifyReportPart (App _ (P (DCon _ _ _) n _) (Constant (Str msg))) | n == reflm "TextPart" =
900reifyReportPart (App _ (P (DCon _ _ _) n _) ttn)
901 | n == reflm "NamePart" =
902 case runElab initEState (reifyTTName ttn) (initElaborator NErased initContext emptyContext Erased) of
903 Error e -> Left . InternalMsg $
904 "could not reify name term " ++
906 " when reflecting an error:" ++ show e
907 OK (n', _)-> Right $ NamePart n'
908reifyReportPart (App _ (P (DCon _ _ _) n _) tm)
909 | n == reflm "TermPart" =
910 case runElab initEState (reifyTT tm) (initElaborator NErased initContext emptyContext Erased) of
911 Error e -> Left . InternalMsg $
912 "could not reify reflected term " ++
914 " when reflecting an error:" ++ show e
915 OK (tm', _) -> Right $ TermPart tm'
916reifyReportPart (App _ (P (DCon _ _ _) n _) tm)
917 | n == reflm "SubReport" =
919 Just xs -> do subParts <- mapM reifyReportPart xs
920 Right (SubReport subParts)
921 Nothing -> Left . InternalMsg $ "could not reify subreport " ++ show tm
922reifyReportPart x = Left . InternalMsg $ "could not reify " ++ show x
924reifyTyDecl :: Term -> ElabD RTyDecl
925reifyTyDecl (App _ (App _ (App _ (P (DCon _ _ _) n _) tyN) args) ret)
926 | n == tacN "Declare" =
927 do tyN' <- reifyTTName tyN
928 args' <- case unList args of
929 Nothing -> fail $ "Couldn't reify " ++ show args ++ " as an arglist."
930 Just xs -> mapM reifyRArg xs
932 return $ RDeclare tyN' args' ret'
933 where reifyRArg :: Term -> ElabD RArg
934 reifyRArg (App _ (App _ (P (DCon _ _ _) n _) argN) argTy)
935 | n == tacN "Explicit" = liftM2 RExplicit
938 | n == tacN "Implicit" = liftM2 RImplicit
940 (reifyRaw argTy) | n == tacN "Constraint" = liftM2 RConstraint
943 reifyRArg aTm = fail $ "Couldn't reify " ++ show aTm ++ " as an RArg."
944reifyTyDecl tm = fail $ "Couldn't reify " ++ show tm ++ " as a type declaration."
946reifyFunDefn :: Term -> ElabD RFunDefn
947reifyFunDefn (App _ (App _ (P _ n _) fnN) clauses)
948 | n == tacN "DefineFun" =
949 do fnN' <- reifyTTName fnN
950 clauses' <- case unList clauses of
951 Nothing -> fail $ "Couldn't reify " ++ show clauses ++ " as a clause list"
952 Just cs -> mapM reifyC cs
953 return $ RDefineFun fnN' clauses'
954 where reifyC :: Term -> ElabD RFunClause
955 reifyC (App _ (App _ (P (DCon _ _ _) n _) lhs) rhs)
956 | n == tacN "MkFunClause" = liftM2 RMkFunClause
959 reifyC (App _ (P (DCon _ _ _) n _) lhs)
960 | n == tacN "MkImpossibleClause" = fmap RMkImpossibleClause $ reifyRaw lhs
961 reifyC tm = fail $ "Couldn't reify " ++ show tm ++ " as a clause."
962reifyFunDefn tm = fail $ "Couldn't reify " ++ show tm ++ " as a function declaration."
966 = raw_apply (Var pairTy) [ (Var $ reflm "TTName")
967 , (RApp (Var $ reflm "Binder") (Var $ reflm "TT"))
970-- | Build the reflected datatype definition(s) that correspond(s) to
971-- a provided unqualified name
972buildDatatypes :: Context -> Ctxt TypeInfo -> Name -> [RDatatype]
973buildDatatypes ctxt datatypes n =
974 catMaybes [ mkDataType dn ti
975 | (dn, ti) <- lookupCtxtName n datatypes
977 where mkDataType name (TI {param_pos = params, con_names = constrs}) =
978 do (TyDecl (TCon _ _) ty) <- lookupDefExact name ctxt
979 let (tcargs, tcres) = getArgs params (forget ty) 0
980 conTys <- mapM (fmap forget . flip lookupTyExact ctxt) constrs
981 return $ RDatatype name tcargs tcres $ zip constrs conTys
983 getArgs params (RBind an (Pi _ ty _) body) i =
984 let (args, res) = getArgs params body (i+1)
985 in if i `elem` params
986 then (RParameter an ty : args, res )
987 else (RIndex an ty : args, res)
988 getArgs _ tm _ = ([], tm)
990reflectDatatype :: RDatatype -> Raw
991reflectDatatype (RDatatype tyn tyConArgs tyConRes constrs) =
992 raw_apply (Var $ tacN "MkDatatype") [ reflectName tyn
993 , rawList (Var $ tacN "TyConArg") (map reflectConArg tyConArgs)
994 , reflectRaw tyConRes
995 , rawList (rawPairTy (Var $ reflm "TTName") (Var $ reflm "Raw"))
996 [ rawPair ((Var $ reflm "TTName"), (Var $ reflm "Raw"))
997 (reflectName cn, reflectRaw cty)
998 | (cn, cty) <- constrs
1001 where reflectConArg (RParameter n t) =
1002 raw_apply (Var $ tacN "Parameter") [reflectName n, reflectRaw t]
1003 reflectConArg (RIndex n t) =
1004 raw_apply (Var $ tacN "Index") [reflectName n, reflectRaw t]
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