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 #-}
6module Idris.Reflection where
8import Control.Monad (liftM, liftM2)
10import qualified Data.Text as T
12import Idris.Core.Elaborate (claim, fill, focus, getNameFrom, initElaborator,
13 movelast, runElab, solve)
14import Idris.Core.Evaluate (initContext)
17import Idris.AbsSyntaxTree (ElabD, IState, PArg'(..), PArg, PTactic, PTactic'(..),
18 PTerm(..), initEState, pairCon, pairTy)
19import Idris.Delaborate (delab)
21data RArg = RExplicit { argName :: Name, argTy :: Raw }
22 | RImplicit { argName :: Name, argTy :: Raw }
23 | RConstraint { argName :: Name, argTy :: Raw }
25data RTyDecl = RDeclare Name [RArg] Raw
27rArgToPArg :: RArg -> PArg
28rArgToPArg (RExplicit n _) = PExp 0 [] n Placeholder
29rArgToPArg (RImplicit n _) = PImp 0 False [] n Placeholder
30rArgToPArg (RConstraint n _) = PConstraint 0 [] n Placeholder
32data RFunClause = RMkFunClause Raw Raw
33 | RMkImpossibleClause Raw
36data RFunDefn = RDefineFun Name [RFunClause] deriving Show
38-- | Prefix a name with the "Language.Reflection" namespace
39reflm :: String -> Name
40reflm n = sNS (sUN n) ["Reflection", "Language"]
42-- | Prefix a name with the "Language.Reflection.Elab" namespace
44tacN str = sNS (sUN str) ["Elab", "Reflection", "Language"]
46-- | Reify tactics from their reflected representation
47reify :: IState -> Term -> ElabD PTactic
48reify _ (P _ n _) | n == reflm "Intros" = return Intros
49reify _ (P _ n _) | n == reflm "Trivial" = return Trivial
50reify _ (P _ n _) | n == reflm "Instance" = return TCInstance
51reify _ (P _ n _) | n == reflm "Solve" = return Solve
52reify _ (P _ n _) | n == reflm "Compute" = return Compute
53reify _ (P _ n _) | n == reflm "Skip" = return Skip
54reify _ (P _ n _) | n == reflm "SourceFC" = return SourceFC
55reify _ (P _ n _) | n == reflm "Unfocus" = return Unfocus
56reify ist t@(App _ _ _)
57 | (P _ f _, args) <- unApply t = reifyApp ist f args
58reify _ t = fail ("Unknown tactic " ++ show t)
60reifyApp :: IState -> Name -> [Term] -> ElabD PTactic
61reifyApp ist t [l, r] | t == reflm "Try" = liftM2 Try (reify ist l) (reify ist r)
62reifyApp _ t [Constant (I i)]
63 | t == reflm "Search" = return (ProofSearch True True i Nothing [])
65 | t == reflm "Refine" = do n <- reifyTTName x
67reifyApp ist t [n, ty] | t == reflm "Claim" = do n' <- reifyTTName n
69 return $ Claim n' (delab ist goal)
70reifyApp ist t [l, r] | t == reflm "Seq" = liftM2 TSeq (reify ist l) (reify ist r)
71reifyApp ist t [Constant (Str n), x]
72 | t == reflm "GoalType" = liftM (GoalType n) (reify ist x)
73reifyApp _ t [n] | t == reflm "Intro" = liftM (Intro . (:[])) (reifyTTName n)
74reifyApp ist t [t'] | t == reflm "Induction" = liftM (Induction . delab ist) (reifyTT t')
75reifyApp ist t [t'] | t == reflm "Case" = liftM (Induction . delab ist) (reifyTT t')
77 | t == reflm "ApplyTactic" = liftM (ApplyTactic . delab ist) (reifyTT t')
79 | t == reflm "Reflect" = liftM (Reflect . delab ist) (reifyTT t')
81 | t == reflm "ByReflection" = liftM (ByReflection . delab ist) (reifyTT t')
83 | t == reflm "Fill" = liftM (Fill . PQuote) (reifyRaw t')
85 | t == reflm "Exact" = liftM (Exact . delab ist) (reifyTT t')
87 | t == reflm "Focus" = liftM Focus (reifyTTName x)
89 | t == reflm "Rewrite" = liftM (Rewrite . delab ist) (reifyTT t')
91 | t == reflm "LetTac" = do n' <- reifyTTName n
93 return $ LetTac n' (delab ist t')
94reifyApp ist t [n, tt', t']
95 | t == reflm "LetTacTy" = do n' <- reifyTTName n
98 return $ LetTacTy n' (delab ist tt'') (delab ist t'')
100 | t == reflm "Fail" = fmap TFail (reifyReportParts errs)
101reifyApp _ f args = fail ("Unknown tactic " ++ show (f, args)) -- shouldn't happen
103reifyReportParts :: Term -> ElabD [ErrorReportPart]
104reifyReportParts errs =
106 Nothing -> fail "Failed to reify errors"
108 let parts = mapM reifyReportPart errs' in
110 Left err -> fail $ "Couldn't reify \"Fail\" tactic - " ++ show err
114-- | Reify terms from their reflected representation
115reifyTT :: Term -> ElabD Term
117 | (P _ f _, args) <- unApply t = reifyTTApp f args
119 | n == reflm "Erased" = return $ Erased
121 | n == reflm "Impossible" = return $ Impossible
122reifyTT t = fail ("Unknown reflection term: " ++ show t)
124reifyTTApp :: Name -> [Term] -> ElabD Term
125reifyTTApp t [nt, n, x]
126 | t == reflm "P" = do nt' <- reifyTTNameType nt
130reifyTTApp t [Constant (I i)]
131 | t == reflm "V" = return $ V i
132reifyTTApp t [n, b, x]
133 | t == reflm "Bind" = do n' <- reifyTTName n
134 b' <- reifyTTBinder reifyTT (reflm "TT") b
136 return $ Bind n' b' x'
138 | t == reflm "App" = do f' <- reifyTT f
140 return $ App Complete f' x'
142 | t == reflm "TConst" = liftM Constant (reifyTTConst c)
143reifyTTApp t [t', Constant (I i)]
144 | t == reflm "Proj" = do t'' <- reifyTT t'
147 | t == reflm "TType" = liftM TType (reifyTTUExp tt)
148reifyTTApp t args = fail ("Unknown reflection term: " ++ show (t, args))
150-- | Reify raw terms from their reflected representation
151reifyRaw :: Term -> ElabD Raw
152reifyRaw t@(App _ _ _)
153 | (P _ f _, args) <- unApply t = reifyRawApp f args
155 | n == reflm "RType" = return $ RType
156reifyRaw t = fail ("Unknown reflection raw term in reifyRaw: " ++ show t)
158reifyRawApp :: Name -> [Term] -> ElabD Raw
160 | t == reflm "Var" = liftM Var (reifyTTName n)
161reifyRawApp t [n, b, x]
162 | t == reflm "RBind" = do n' <- reifyTTName n
163 b' <- reifyTTBinder reifyRaw (reflm "Raw") b
165 return $ RBind n' b' x'
167 | t == reflm "RApp" = liftM2 RApp (reifyRaw f) (reifyRaw x)
169 | t == reflm "RForce" = liftM RForce (reifyRaw t')
171 | t == reflm "RConstant" = liftM RConstant (reifyTTConst c)
172reifyRawApp t args = fail ("Unknown reflection raw term in reifyRawApp: " ++ show (t, args))
174reifyTTName :: Term -> ElabD Name
176 | (P _ f _, args) <- unApply t = reifyTTNameApp f args
177reifyTTName t = fail ("Unknown reflection term name: " ++ show t)
179reifyTTNameApp :: Name -> [Term] -> ElabD Name
180reifyTTNameApp t [Constant (Str n)]
181 | t == reflm "UN" = return $ sUN n
182reifyTTNameApp t [n, ns]
183 | t == reflm "NS" = do n' <- reifyTTName n
184 ns' <- reifyTTNamespace ns
186reifyTTNameApp t [Constant (I i), Constant (Str n)]
187 | t == reflm "MN" = return $ sMN i n
189 | t == reflm "NErased" = return NErased
190reifyTTNameApp t args = fail ("Unknown reflection term name: " ++ show (t, args))
192reifyTTNamespace :: Term -> ElabD [String]
193reifyTTNamespace t@(App _ _ _)
195 (P _ f _, [Constant StrType])
196 | f == sNS (sUN "Nil") ["List", "Prelude"] -> return []
197 (P _ f _, [Constant StrType, Constant (Str n), ns])
198 | f == sNS (sUN "::") ["List", "Prelude"] -> liftM (n:) (reifyTTNamespace ns)
199 _ -> fail ("Unknown reflection namespace arg: " ++ show t)
200reifyTTNamespace t = fail ("Unknown reflection namespace arg: " ++ show t)
202reifyTTNameType :: Term -> ElabD NameType
203reifyTTNameType t@(P _ n _) | n == reflm "Bound" = return $ Bound
204reifyTTNameType t@(P _ n _) | n == reflm "Ref" = return $ Ref
205reifyTTNameType t@(App _ _ _)
207 (P _ f _, [Constant (I tag), Constant (I num)])
208 | f == reflm "DCon" -> return $ DCon tag num False -- FIXME: Uniqueness!
209 | f == reflm "TCon" -> return $ TCon tag num
210 _ -> fail ("Unknown reflection name type: " ++ show t)
211reifyTTNameType t = fail ("Unknown reflection name type: " ++ show t)
213reifyTTBinder :: (Term -> ElabD a) -> Name -> Term -> ElabD (Binder a)
214reifyTTBinder reificator binderType t@(App _ _ _)
216 (P _ f _, bt:args) | forget bt == Var binderType
217 -> reifyTTBinderApp reificator f args
218 _ -> fail ("Mismatching binder reflection: " ++ show t)
219reifyTTBinder _ _ t = fail ("Unknown reflection binder: " ++ show t)
221reifyTTBinderApp :: (Term -> ElabD a) -> Name -> [Term] -> ElabD (Binder a)
222reifyTTBinderApp reif f [t]
223 | f == reflm "Lam" = liftM Lam (reif t)
224reifyTTBinderApp reif f [t, k]
225 | f == reflm "Pi" = liftM2 (Pi Nothing) (reif t) (reif k)
226reifyTTBinderApp reif f [x, y]
227 | f == reflm "Let" = liftM2 Let (reif x) (reif y)
228reifyTTBinderApp reif f [x, y]
229 | f == reflm "NLet" = liftM2 NLet (reif x) (reif y)
230reifyTTBinderApp reif f [t]
231 | f == reflm "Hole" = liftM Hole (reif t)
232reifyTTBinderApp reif f [t]
233 | f == reflm "GHole" = liftM (GHole 0) (reif t)
234reifyTTBinderApp reif f [x, y]
235 | f == reflm "Guess" = liftM2 Guess (reif x) (reif y)
236reifyTTBinderApp reif f [t]
237 | f == reflm "PVar" = liftM PVar (reif t)
238reifyTTBinderApp reif f [t]
239 | f == reflm "PVTy" = liftM PVTy (reif t)
240reifyTTBinderApp _ f args = fail ("Unknown reflection binder: " ++ show (f, args))
242reifyTTConst :: Term -> ElabD Const
243reifyTTConst (P _ n _) | n == reflm "StrType" = return $ StrType
244reifyTTConst (P _ n _) | n == reflm "VoidType" = return $ VoidType
245reifyTTConst (P _ n _) | n == reflm "Forgot" = return $ Forgot
246reifyTTConst t@(App _ _ _)
247 | (P _ f _, [arg]) <- unApply t = reifyTTConstApp f arg
248reifyTTConst t = fail ("Unknown reflection constant: " ++ show t)
250reifyTTConstApp :: Name -> Term -> ElabD Const
252 | f == reflm "AType" = fmap AType (reifyArithTy aty)
253reifyTTConstApp f (Constant c@(I _))
254 | f == reflm "I" = return $ c
255reifyTTConstApp f (Constant c@(BI _))
256 | f == reflm "BI" = return $ c
257reifyTTConstApp f (Constant c@(Fl _))
258 | f == reflm "Fl" = return $ c
259reifyTTConstApp f (Constant c@(I _))
260 | f == reflm "Ch" = return $ c
261reifyTTConstApp f (Constant c@(Str _))
262 | f == reflm "Str" = return $ c
263reifyTTConstApp f (Constant c@(B8 _))
264 | f == reflm "B8" = return $ c
265reifyTTConstApp f (Constant c@(B16 _))
266 | f == reflm "B16" = return $ c
267reifyTTConstApp f (Constant c@(B32 _))
268 | f == reflm "B32" = return $ c
269reifyTTConstApp f (Constant c@(B64 _))
270 | f == reflm "B64" = return $ c
271reifyTTConstApp f arg = fail ("Unknown reflection constant: " ++ show (f, arg))
273reifyArithTy :: Term -> ElabD ArithTy
274reifyArithTy (App _ (P _ n _) intTy) | n == reflm "ATInt" = fmap ATInt (reifyIntTy intTy)
275reifyArithTy (P _ n _) | n == reflm "ATFloat" = return ATFloat
276reifyArithTy x = fail ("Couldn't reify reflected ArithTy: " ++ show x)
278reifyNativeTy :: Term -> ElabD NativeTy
279reifyNativeTy (P _ n _) | n == reflm "IT8" = return IT8
280reifyNativeTy (P _ n _) | n == reflm "IT8" = return IT8
281reifyNativeTy (P _ n _) | n == reflm "IT8" = return IT8
282reifyNativeTy (P _ n _) | n == reflm "IT8" = return IT8
283reifyNativeTy x = fail $ "Couldn't reify reflected NativeTy " ++ show x
285reifyIntTy :: Term -> ElabD IntTy
286reifyIntTy (App _ (P _ n _) nt) | n == reflm "ITFixed" = fmap ITFixed (reifyNativeTy nt)
287reifyIntTy (P _ n _) | n == reflm "ITNative" = return ITNative
288reifyIntTy (P _ n _) | n == reflm "ITBig" = return ITBig
289reifyIntTy (P _ n _) | n == reflm "ITChar" = return ITChar
290reifyIntTy tm = fail $ "The term " ++ show tm ++ " is not a reflected IntTy"
292reifyTTUExp :: Term -> ElabD UExp
293reifyTTUExp t@(App _ _ _)
295 (P _ f _, [Constant (I i)]) | f == reflm "UVar" -> return $ UVar i
296 (P _ f _, [Constant (I i)]) | f == reflm "UVal" -> return $ UVal i
297 _ -> fail ("Unknown reflection type universe expression: " ++ show t)
298reifyTTUExp t = fail ("Unknown reflection type universe expression: " ++ show t)
300-- | Create a reflected call to a named function/constructor
301reflCall :: String -> [Raw] -> Raw
303 = raw_apply (Var (reflm funName)) args
305-- | Lift a term into its Language.Reflection.TT representation
306reflect :: Term -> Raw
307reflect = reflectTTQuote []
309-- | Lift a term into its Language.Reflection.Raw representation
310reflectRaw :: Raw -> Raw
311reflectRaw = reflectRawQuote []
313claimTT :: Name -> ElabD Name
314claimTT n = do n' <- getNameFrom n
315 claim n' (Var (sNS (sUN "TT") ["Reflection", "Language"]))
318-- | Convert a reflected term to a more suitable form for pattern-matching.
319-- In particular, the less-interesting bits are elaborated to _ patterns. This
320-- happens to NameTypes, universe levels, names that are bound but not used,
321-- and the type annotation field of the P constructor.
322reflectTTQuotePattern :: [Name] -> Term -> ElabD ()
323reflectTTQuotePattern unq (P _ n _)
324 | n `elem` unq = -- the unquoted names have been claimed as TT already - just use them
325 do fill (Var n) ; solve
327 do tyannot <- claimTT (sMN 0 "pTyAnnot")
328 movelast tyannot -- use a _ pattern here
329 nt <- getNameFrom (sMN 0 "nt")
330 claim nt (Var (reflm "NameType"))
331 movelast nt -- use a _ pattern here
332 n' <- getNameFrom (sMN 0 "n")
333 claim n' (Var (reflm "TTName"))
334 fill $ reflCall "P" [Var nt, Var n', Var tyannot]
336 focus n'; reflectNameQuotePattern n
337reflectTTQuotePattern unq (V n)
338 = do fill $ reflCall "V" [RConstant (I n)]
340reflectTTQuotePattern unq (Bind n b x)
341 = do x' <- claimTT (sMN 0 "sc")
343 b' <- getNameFrom (sMN 0 "binder")
344 claim b' (RApp (Var (sNS (sUN "Binder") ["Reflection", "Language"]))
345 (Var (sNS (sUN "TT") ["Reflection", "Language"])))
346 if n `elem` freeNames x
347 then do fill $ reflCall "Bind"
352 else do any <- getNameFrom (sMN 0 "anyName")
353 claim any (Var (reflm "TTName"))
355 fill $ reflCall "Bind"
360 focus x'; reflectTTQuotePattern unq x
361 focus b'; reflectBinderQuotePattern reflectTTQuotePattern unq b
362reflectTTQuotePattern unq (App _ f x)
363 = do f' <- claimTT (sMN 0 "f"); movelast f'
364 x' <- claimTT (sMN 0 "x"); movelast x'
365 fill $ reflCall "App" [Var f', Var x']
367 focus f'; reflectTTQuotePattern unq f
368 focus x'; reflectTTQuotePattern unq x
369reflectTTQuotePattern unq (Constant c)
370 = do fill $ reflCall "TConst" [reflectConstant c]
372reflectTTQuotePattern unq (Proj t i)
373 = do t' <- claimTT (sMN 0 "t"); movelast t'
374 fill $ reflCall "Proj" [Var t', RConstant (I i)]
376 focus t'; reflectTTQuotePattern unq t
377reflectTTQuotePattern unq (Erased)
378 = do erased <- claimTT (sMN 0 "erased")
382reflectTTQuotePattern unq (Impossible)
383 = do fill $ Var (reflm "Impossible")
385reflectTTQuotePattern unq (TType exp)
386 = do ue <- getNameFrom (sMN 0 "uexp")
387 claim ue (Var (sNS (sUN "TTUExp") ["Reflection", "Language"]))
389 fill $ reflCall "TType" [Var ue]
391reflectTTQuotePattern unq (UType u)
392 = do uH <- getNameFrom (sMN 0 "someUniv")
393 claim uH (Var (reflm "Universe"))
395 fill $ reflCall "UType" [Var uH]
398 fill (Var (reflm (case u of
399 NullType -> "NullType"
400 UniqueType -> "UniqueType"
401 AllTypes -> "AllTypes")))
404reflectRawQuotePattern :: [Name] -> Raw -> ElabD ()
405reflectRawQuotePattern unq (Var n)
406 -- the unquoted names already have types, just use them
407 | n `elem` unq = do fill (Var n); solve
408 | otherwise = do fill (reflCall "Var" [reflectName n]); solve
409reflectRawQuotePattern unq (RBind n b sc) =
410 do scH <- getNameFrom (sMN 0 "sc")
411 claim scH (Var (reflm "Raw"))
413 bH <- getNameFrom (sMN 0 "binder")
414 claim bH (RApp (Var (reflm "Binder"))
416 if n `elem` freeNamesR sc
417 then do fill $ reflCall "RBind" [reflectName n,
421 else do any <- getNameFrom (sMN 0 "anyName")
422 claim any (Var (reflm "TTName"))
424 fill $ reflCall "RBind" [Var any, Var bH, Var scH]
426 focus scH; reflectRawQuotePattern unq sc
427 focus bH; reflectBinderQuotePattern reflectRawQuotePattern unq b
428 where freeNamesR (Var n) = [n]
429 freeNamesR (RBind n (Let t v) body) = concat [freeNamesR v,
430 freeNamesR body \\ [n],
432 freeNamesR (RBind n b body) = freeNamesR (binderTy b) ++
433 (freeNamesR body \\ [n])
434 freeNamesR (RApp f x) = freeNamesR f ++ freeNamesR x
435 freeNamesR RType = []
436 freeNamesR (RUType _) = []
437 freeNamesR (RForce r) = freeNamesR r
438 freeNamesR (RConstant _) = []
439reflectRawQuotePattern unq (RApp f x) =
440 do fH <- getNameFrom (sMN 0 "f")
441 claim fH (Var (reflm "Raw"))
443 xH <- getNameFrom (sMN 0 "x")
444 claim xH (Var (reflm "Raw"))
446 fill $ reflCall "RApp" [Var fH, Var xH]
448 focus fH; reflectRawQuotePattern unq f
449 focus xH; reflectRawQuotePattern unq x
450reflectRawQuotePattern unq RType =
451 do fill (Var (reflm "RType"))
453reflectRawQuotePattern unq (RUType univ) =
454 do uH <- getNameFrom (sMN 0 "universe")
455 claim uH (Var (reflm "Universe"))
457 fill $ reflCall "RUType" [Var uH]
459 focus uH; fill (reflectUniverse univ); solve
460reflectRawQuotePattern unq (RForce r) =
461 do rH <- getNameFrom (sMN 0 "raw")
462 claim rH (Var (reflm "Raw"))
464 fill $ reflCall "RForce" [Var rH]
466 focus rH; reflectRawQuotePattern unq r
467reflectRawQuotePattern unq (RConstant c) =
468 do cH <- getNameFrom (sMN 0 "const")
469 claim cH (Var (reflm "Constant"))
471 fill (reflCall "RConstant" [Var cH]); solve
473 fill (reflectConstant c); solve
475reflectBinderQuotePattern :: ([Name] -> a -> ElabD ()) -> [Name] -> Binder a -> ElabD ()
476reflectBinderQuotePattern q unq (Lam t)
477 = do t' <- claimTT (sMN 0 "ty"); movelast t'
478 fill $ reflCall "Lam" [Var (reflm "TT"), Var t']
481reflectBinderQuotePattern q unq (Pi _ t k)
482 = do t' <- claimTT (sMN 0 "ty") ; movelast t'
483 k' <- claimTT (sMN 0 "k"); movelast k';
484 fill $ reflCall "Pi" [Var (reflm "TT"), Var t', Var k']
487reflectBinderQuotePattern q unq (Let x y)
488 = do x' <- claimTT (sMN 0 "ty"); movelast x';
489 y' <- claimTT (sMN 0 "v"); movelast y';
490 fill $ reflCall "Let" [Var (reflm "TT"), Var x', Var y']
494reflectBinderQuotePattern q unq (NLet x y)
495 = do x' <- claimTT (sMN 0 "ty"); movelast x'
496 y' <- claimTT (sMN 0 "v"); movelast y'
497 fill $ reflCall "NLet" [Var (reflm "TT"), Var x', Var y']
501reflectBinderQuotePattern q unq (Hole t)
502 = do t' <- claimTT (sMN 0 "ty"); movelast t'
503 fill $ reflCall "Hole" [Var (reflm "TT"), Var t']
506reflectBinderQuotePattern q unq (GHole _ t)
507 = do t' <- claimTT (sMN 0 "ty"); movelast t'
508 fill $ reflCall "GHole" [Var (reflm "TT"), Var t']
511reflectBinderQuotePattern q unq (Guess x y)
512 = do x' <- claimTT (sMN 0 "ty"); movelast x'
513 y' <- claimTT (sMN 0 "v"); movelast y'
514 fill $ reflCall "Guess" [Var (reflm "TT"), Var x', Var y']
518reflectBinderQuotePattern q unq (PVar t)
519 = do t' <- claimTT (sMN 0 "ty"); movelast t'
520 fill $ reflCall "PVar" [Var (reflm "TT"), Var t']
523reflectBinderQuotePattern q unq (PVTy t)
524 = do t' <- claimTT (sMN 0 "ty"); movelast t'
525 fill $ reflCall "PVTy" [Var (reflm "TT"), Var t']
529reflectUniverse :: Universe -> Raw
531 (Var (reflm (case u of
532 NullType -> "NullType"
533 UniqueType -> "UniqueType"
534 AllTypes -> "AllTypes")))
536-- | Create a reflected TT term, but leave refs to the provided name intact
537reflectTTQuote :: [Name] -> Term -> Raw
538reflectTTQuote unq (P nt n t)
539 | n `elem` unq = Var n
540 | otherwise = reflCall "P" [reflectNameType nt, reflectName n, reflectTTQuote unq t]
541reflectTTQuote unq (V n)
542 = reflCall "V" [RConstant (I n)]
543reflectTTQuote unq (Bind n b x)
544 = reflCall "Bind" [reflectName n, reflectBinderQuote reflectTTQuote (reflm "TT") unq b, reflectTTQuote unq x]
545reflectTTQuote unq (App _ f x)
546 = reflCall "App" [reflectTTQuote unq f, reflectTTQuote unq x]
547reflectTTQuote unq (Constant c)
548 = reflCall "TConst" [reflectConstant c]
549reflectTTQuote unq (Proj t i)
550 = reflCall "Proj" [reflectTTQuote unq t, RConstant (I i)]
551reflectTTQuote unq (Erased) = Var (reflm "Erased")
552reflectTTQuote unq (Impossible) = Var (reflm "Impossible")
553reflectTTQuote unq (TType exp) = reflCall "TType" [reflectUExp exp]
554reflectTTQuote unq (UType u) = reflCall "UType" [reflectUniverse u]
556reflectRawQuote :: [Name] -> Raw -> Raw
557reflectRawQuote unq (Var n)
558 | n `elem` unq = Var n
559 | otherwise = reflCall "Var" [reflectName n]
560reflectRawQuote unq (RBind n b r) =
561 reflCall "RBind" [reflectName n, reflectBinderQuote reflectRawQuote (reflm "Raw") unq b, reflectRawQuote unq r]
562reflectRawQuote unq (RApp f x) =
563 reflCall "RApp" [reflectRawQuote unq f, reflectRawQuote unq x]
564reflectRawQuote unq RType = Var (reflm "RType")
565reflectRawQuote unq (RUType u) =
566 reflCall "RUType" [reflectUniverse u]
567reflectRawQuote unq (RForce r) = reflCall "RForce" [reflectRawQuote unq r]
568reflectRawQuote unq (RConstant cst) = reflCall "RConstant" [reflectConstant cst]
570reflectNameType :: NameType -> Raw
571reflectNameType (Bound) = Var (reflm "Bound")
572reflectNameType (Ref) = Var (reflm "Ref")
573reflectNameType (DCon x y _)
574 = reflCall "DCon" [RConstant (I x), RConstant (I y)] -- FIXME: Uniqueness!
575reflectNameType (TCon x y)
576 = reflCall "TCon" [RConstant (I x), RConstant (I y)]
578reflectName :: Name -> Raw
580 = reflCall "UN" [RConstant (Str (str s))]
582 = reflCall "NS" [ reflectName n
584 raw_apply ( Var $ sNS (sUN "::") ["List", "Prelude"] )
585 [ RConstant StrType, RConstant (Str n), s ])
586 ( raw_apply ( Var $ sNS (sUN "Nil") ["List", "Prelude"] )
587 [ RConstant StrType ])
591 = reflCall "MN" [RConstant (I i), RConstant (Str (str n))]
592reflectName (NErased) = Var (reflm "NErased")
593reflectName n = Var (reflm "NErased") -- special name, not yet implemented
595-- | Elaborate a name to a pattern. This means that NS and UN will be intact.
596-- MNs corresponding to will care about the string but not the number. All
598reflectNameQuotePattern :: Name -> ElabD ()
599reflectNameQuotePattern n@(UN s)
600 = do fill $ reflectName n
602reflectNameQuotePattern n@(NS _ _)
603 = do fill $ reflectName n
605reflectNameQuotePattern (MN _ n)
606 = do i <- getNameFrom (sMN 0 "mnCounter")
607 claim i (RConstant (AType (ATInt ITNative)))
609 fill $ reflCall "MN" [Var i, RConstant (Str $ T.unpack n)]
611reflectNameQuotePattern _ -- for all other names, match any
612 = do nameHole <- getNameFrom (sMN 0 "name")
613 claim nameHole (Var (reflm "TTName"))
618reflectBinder :: Binder Term -> Raw
619reflectBinder = reflectBinderQuote reflectTTQuote (reflm "TT") []
621reflectBinderQuote :: ([Name] -> a -> Raw) -> Name -> [Name] -> Binder a -> Raw
622reflectBinderQuote q ty unq (Lam t)
623 = reflCall "Lam" [Var ty, q unq t]
624reflectBinderQuote q ty unq (Pi _ t k)
625 = reflCall "Pi" [Var ty, q unq t, q unq k]
626reflectBinderQuote q ty unq (Let x y)
627 = reflCall "Let" [Var ty, q unq x, q unq y]
628reflectBinderQuote q ty unq (NLet x y)
629 = reflCall "NLet" [Var ty, q unq x, q unq y]
630reflectBinderQuote q ty unq (Hole t)
631 = reflCall "Hole" [Var ty, q unq t]
632reflectBinderQuote q ty unq (GHole _ t)
633 = reflCall "GHole" [Var ty, q unq t]
634reflectBinderQuote q ty unq (Guess x y)
635 = reflCall "Guess" [Var ty, q unq x, q unq y]
636reflectBinderQuote q ty unq (PVar t)
637 = reflCall "PVar" [Var ty, q unq t]
638reflectBinderQuote q ty unq (PVTy t)
639 = reflCall "PVTy" [Var ty, q unq t]
641mkList :: Raw -> [Raw] -> Raw
642mkList ty [] = RApp (Var (sNS (sUN "Nil") ["List", "Prelude"])) ty
643mkList ty (x:xs) = RApp (RApp (RApp (Var (sNS (sUN "::") ["List", "Prelude"])) ty)
647reflectConstant :: Const -> Raw
648reflectConstant c@(I _) = reflCall "I" [RConstant c]
649reflectConstant c@(BI _) = reflCall "BI" [RConstant c]
650reflectConstant c@(Fl _) = reflCall "Fl" [RConstant c]
651reflectConstant c@(Ch _) = reflCall "Ch" [RConstant c]
652reflectConstant c@(Str _) = reflCall "Str" [RConstant c]
653reflectConstant c@(B8 _) = reflCall "B8" [RConstant c]
654reflectConstant c@(B16 _) = reflCall "B16" [RConstant c]
655reflectConstant c@(B32 _) = reflCall "B32" [RConstant c]
656reflectConstant c@(B64 _) = reflCall "B64" [RConstant c]
657reflectConstant (AType (ATInt ITNative)) = reflCall "AType" [reflCall "ATInt" [Var (reflm "ITNative")]]
658reflectConstant (AType (ATInt ITBig)) = reflCall "AType" [reflCall "ATInt" [Var (reflm "ITBig")]]
659reflectConstant (AType ATFloat) = reflCall "AType" [Var (reflm "ATFloat")]
660reflectConstant (AType (ATInt ITChar)) = reflCall "AType" [reflCall "ATInt" [Var (reflm "ITChar")]]
661reflectConstant StrType = Var (reflm "StrType")
662reflectConstant (AType (ATInt (ITFixed IT8))) = reflCall "AType" [reflCall "ATInt" [reflCall "ITFixed" [Var (reflm "IT8")]]]
663reflectConstant (AType (ATInt (ITFixed IT16))) = reflCall "AType" [reflCall "ATInt" [reflCall "ITFixed" [Var (reflm "IT16")]]]
664reflectConstant (AType (ATInt (ITFixed IT32))) = reflCall "AType" [reflCall "ATInt" [reflCall "ITFixed" [Var (reflm "IT32")]]]
665reflectConstant (AType (ATInt (ITFixed IT64))) = reflCall "AType" [reflCall "ATInt" [reflCall "ITFixed" [Var (reflm "IT64")]]]
666reflectConstant VoidType = Var (reflm "VoidType")
667reflectConstant Forgot = Var (reflm "Forgot")
668reflectConstant WorldType = Var (reflm "WorldType")
669reflectConstant TheWorld = Var (reflm "TheWorld")
671reflectUExp :: UExp -> Raw
672reflectUExp (UVar i) = reflCall "UVar" [RConstant (I i)]
673reflectUExp (UVal i) = reflCall "UVal" [RConstant (I i)]
675-- | Reflect the environment of a proof into a List (TTName, Binder TT)
676reflectEnv :: Env -> Raw
677reflectEnv = foldr consToEnvList emptyEnvList
679 consToEnvList :: (Name, Binder Term) -> Raw -> Raw
680 consToEnvList (n, b) l
681 = raw_apply (Var (sNS (sUN "::") ["List", "Prelude"]))
683 , raw_apply (Var pairCon) [ (Var $ reflm "TTName")
684 , (RApp (Var $ reflm "Binder")
693 emptyEnvList = raw_apply (Var (sNS (sUN "Nil") ["List", "Prelude"]))
696-- | Reflect an error into the internal datatype of Idris -- TODO
697rawBool :: Bool -> Raw
698rawBool True = Var (sNS (sUN "True") ["Bool", "Prelude"])
699rawBool False = Var (sNS (sUN "False") ["Bool", "Prelude"])
702rawNil ty = raw_apply (Var (sNS (sUN "Nil") ["List", "Prelude"])) [ty]
704rawCons :: Raw -> Raw -> Raw -> Raw
705rawCons ty hd tl = raw_apply (Var (sNS (sUN "::") ["List", "Prelude"])) [ty, hd, tl]
707rawList :: Raw -> [Raw] -> Raw
708rawList ty = foldr (rawCons ty) (rawNil ty)
710rawPairTy :: Raw -> Raw -> Raw
711rawPairTy t1 t2 = raw_apply (Var pairTy) [t1, t2]
713rawPair :: (Raw, Raw) -> (Raw, Raw) -> Raw
714rawPair (a, b) (x, y) = raw_apply (Var pairCon) [a, b, x, y]
716reflectCtxt :: [(Name, Type)] -> Raw
717reflectCtxt ctxt = rawList (rawPairTy (Var $ reflm "TTName") (Var $ reflm "TT"))
718 (map (\ (n, t) -> (rawPair (Var $ reflm "TTName", Var $ reflm "TT")
719 (reflectName n, reflect t)))
722reflectErr :: Err -> Raw
723reflectErr (Msg msg) = raw_apply (Var $ reflErrName "Msg") [RConstant (Str msg)]
724reflectErr (InternalMsg msg) = raw_apply (Var $ reflErrName "InternalMsg") [RConstant (Str msg)]
725reflectErr (CantUnify b (t1,_) (t2,_) e ctxt i) =
726 raw_apply (Var $ reflErrName "CantUnify")
733reflectErr (InfiniteUnify n tm ctxt) =
734 raw_apply (Var $ reflErrName "InfiniteUnify")
739reflectErr (CantConvert t t' ctxt) =
740 raw_apply (Var $ reflErrName "CantConvert")
745reflectErr (CantSolveGoal t ctxt) =
746 raw_apply (Var $ reflErrName "CantSolveGoal")
750reflectErr (UnifyScope n n' t ctxt) =
751 raw_apply (Var $ reflErrName "UnifyScope")
757reflectErr (CantInferType str) =
758 raw_apply (Var $ reflErrName "CantInferType") [RConstant (Str str)]
759reflectErr (NonFunctionType t t') =
760 raw_apply (Var $ reflErrName "NonFunctionType") [reflect t, reflect t']
761reflectErr (NotEquality t t') =
762 raw_apply (Var $ reflErrName "NotEquality") [reflect t, reflect t']
763reflectErr (TooManyArguments n) = raw_apply (Var $ reflErrName "TooManyArguments") [reflectName n]
764reflectErr (CantIntroduce t) = raw_apply (Var $ reflErrName "CantIntroduce") [reflect t]
765reflectErr (NoSuchVariable n) = raw_apply (Var $ reflErrName "NoSuchVariable") [reflectName n]
766reflectErr (WithFnType t) = raw_apply (Var $ reflErrName "WithFnType") [reflect t]
767reflectErr (CantMatch t) = raw_apply (Var $ reflErrName "CantMatch") [reflect t]
768reflectErr (NoTypeDecl n) = raw_apply (Var $ reflErrName "NoTypeDecl") [reflectName n]
769reflectErr (NotInjective t1 t2 t3) =
770 raw_apply (Var $ reflErrName "NotInjective")
775reflectErr (CantResolve _ t) = raw_apply (Var $ reflErrName "CantResolve") [reflect t]
776reflectErr (InvalidTCArg n t) = raw_apply (Var $ reflErrName "InvalidTCArg") [reflectName n, reflect t]
777reflectErr (CantResolveAlts ss) =
778 raw_apply (Var $ reflErrName "CantResolveAlts")
779 [rawList (Var $ reflm "TTName") (map reflectName ss)]
780reflectErr (IncompleteTerm t) = raw_apply (Var $ reflErrName "IncompleteTerm") [reflect t]
781reflectErr (NoEliminator str t)
782 = raw_apply (Var $ reflErrName "NoEliminator") [RConstant (Str str),
784reflectErr UniverseError = Var $ reflErrName "UniverseError"
785reflectErr ProgramLineComment = Var $ reflErrName "ProgramLineComment"
786reflectErr (Inaccessible n) = raw_apply (Var $ reflErrName "Inaccessible") [reflectName n]
787reflectErr (NonCollapsiblePostulate n) = raw_apply (Var $ reflErrName "NonCollabsiblePostulate") [reflectName n]
788reflectErr (AlreadyDefined n) = raw_apply (Var $ reflErrName "AlreadyDefined") [reflectName n]
789reflectErr (ProofSearchFail e) = raw_apply (Var $ reflErrName "ProofSearchFail") [reflectErr e]
790reflectErr (NoRewriting tm) = raw_apply (Var $ reflErrName "NoRewriting") [reflect tm]
791reflectErr (ProviderError str) =
792 raw_apply (Var $ reflErrName "ProviderError") [RConstant (Str str)]
793reflectErr (LoadingFailed str err) =
794 raw_apply (Var $ reflErrName "LoadingFailed") [RConstant (Str str)]
795reflectErr x = raw_apply (Var (sNS (sUN "Msg") ["Errors", "Reflection", "Language"])) [RConstant . Str $ "Default reflection: " ++ show x]
797-- | Reflect a file context
798reflectFC :: FC -> Raw
799reflectFC fc = raw_apply (Var (reflm "FileLoc"))
800 [ RConstant (Str (fc_fname fc))
801 , raw_apply (Var pairCon) $
807 , raw_apply (Var pairCon) $
814 where intTy = RConstant (AType (ATInt ITNative))
816fromTTMaybe :: Term -> Maybe Term -- WARNING: Assumes the term has type Maybe a
817fromTTMaybe (App _ (App _ (P (DCon _ _ _) (NS (UN just) _) _) ty) tm)
818 | just == txt "Just" = Just tm
819fromTTMaybe x = Nothing
821reflErrName :: String -> Name
822reflErrName n = sNS (sUN n) ["Errors", "Reflection", "Language"]
824-- | Attempt to reify a report part from TT to the internal
825-- representation. Not in Idris or ElabD monads because it should be usable
827reifyReportPart :: Term -> Either Err ErrorReportPart
828reifyReportPart (App _ (P (DCon _ _ _) n _) (Constant (Str msg))) | n == reflm "TextPart" =
830reifyReportPart (App _ (P (DCon _ _ _) n _) ttn)
831 | n == reflm "NamePart" =
832 case runElab initEState (reifyTTName ttn) (initElaborator NErased initContext Erased) of
833 Error e -> Left . InternalMsg $
834 "could not reify name term " ++
836 " when reflecting an error:" ++ show e
837 OK (n', _)-> Right $ NamePart n'
838reifyReportPart (App _ (P (DCon _ _ _) n _) tm)
839 | n == reflm "TermPart" =
840 case runElab initEState (reifyTT tm) (initElaborator NErased initContext Erased) of
841 Error e -> Left . InternalMsg $
842 "could not reify reflected term " ++
844 " when reflecting an error:" ++ show e
845 OK (tm', _) -> Right $ TermPart tm'
846reifyReportPart (App _ (P (DCon _ _ _) n _) tm)
847 | n == reflm "SubReport" =
849 Just xs -> do subParts <- mapM reifyReportPart xs
850 Right (SubReport subParts)
851 Nothing -> Left . InternalMsg $ "could not reify subreport " ++ show tm
852reifyReportPart x = Left . InternalMsg $ "could not reify " ++ show x
854reifyTyDecl :: Term -> ElabD RTyDecl
855reifyTyDecl (App _ (App _ (App _ (P (DCon _ _ _) n _) tyN) args) ret)
856 | n == tacN "Declare" =
857 do tyN' <- reifyTTName tyN
858 args' <- case unList args of
859 Nothing -> fail $ "Couldn't reify " ++ show args ++ " as an arglist."
860 Just xs -> mapM reifyRArg xs
862 return $ RDeclare tyN' args' ret'
863 where reifyRArg :: Term -> ElabD RArg
864 reifyRArg (App _ (App _ (P (DCon _ _ _) n _) argN) argTy)
865 | n == tacN "Explicit" = liftM2 RExplicit
868 | n == tacN "Implicit" = liftM2 RImplicit
870 (reifyRaw argTy) | n == tacN "Constraint" = liftM2 RConstraint
873 reifyRArg aTm = fail $ "Couldn't reify " ++ show aTm ++ " as an RArg."
874reifyTyDecl tm = fail $ "Couldn't reify " ++ show tm ++ " as a type declaration."
876reifyFunDefn :: Term -> ElabD RFunDefn
877reifyFunDefn (App _ (App _ (P _ n _) fnN) clauses)
878 | n == tacN "DefineFun" =
879 do fnN' <- reifyTTName fnN
880 clauses' <- case unList clauses of
881 Nothing -> fail $ "Couldn't reify " ++ show clauses ++ " as a clause list"
882 Just cs -> mapM reifyC cs
883 return $ RDefineFun fnN' clauses'
884 where reifyC :: Term -> ElabD RFunClause
885 reifyC (App _ (App _ (P (DCon _ _ _) n _) lhs) rhs)
886 | n == tacN "MkFunClause" = liftM2 RMkFunClause
889 reifyC (App _ (P (DCon _ _ _) n _) lhs)
890 | n == tacN "MkImpossibleClause" = fmap RMkImpossibleClause $ reifyRaw lhs
891 reifyC tm = fail $ "Couldn't reify " ++ show tm ++ " as a clause."
892reifyFunDefn tm = fail $ "Couldn't reify " ++ show tm ++ " as a function declaration."
896 = raw_apply (Var pairTy) [ (Var $ reflm "TTName")
897 , (RApp (Var $ reflm "Binder") (Var $ reflm "TT"))
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