on master help sign in
Merge pull request #2358 from david-christiansen/wip/tactical

Catch up on Elab

commit8ed600091f5b8d99b0b69cfd574bd0b8ec43ff9a authorDavid Christiansen <david@davidchristiansen.dk> dateTue 9 Jun 2015, 19:24 (11 years ago) parent101f5f94ad8431
21 files changed+398−145
CHANGELOG+2 docs/reference/elaborator-reflection.rst+8 libs/prelude/Language/Reflection/Elab.idr+9 src/Idris/AbsSyntax.hs+5−5 src/Idris/AbsSyntaxTree.hs+9−4 src/Idris/DSL.hs+2−2 src/Idris/DeepSeq.hs+1−1 src/Idris/Elab/Term.hs+14−10 src/Idris/Elab/Value.hs+2−2 src/Idris/ElabQuasiquote.hs+2−2 src/Idris/Error.hs+1−1 src/Idris/IBC.hs+6−4 src/Idris/IdrisDoc.hs+1−1 src/Idris/ParseExpr.hs+5−5 src/Idris/Parser.hs+25 src/Idris/Prover.hs+265−96 src/Idris/REPL.hs+17−11 src/Idris/REPLParser.hs+3−1 test/meta003/BadDef.idr+12 test/meta003/expected+6 test/meta003/run+3
CHANGELOG+2
@@ -12,6 +12,8 @@ New in 0.9.19:
1212* Compiler output shows applications of >>= in do-notation
1313* fromInteger i where i is an integer constant is now shown just as i in
1414 compiler output
15+* An interactive shell, similar to the prover, for running reflected elaborator
16+ actions. Access it with :elab from the REPL.
1517
1618New in 0.9.18:
1719--------------
docs/reference/elaborator-reflection.rst+8
@@ -70,6 +70,14 @@ We can generate identity functions at any concrete type using the same script:
7070 idString : String -> String
7171 idString = %runElab mkId
7272
73+Interactively Building Elab Scripts
74+===================================
75+
76+To build an ``Elab`` script interactively, use the ``:elab`` command at the REPL.
77+It takes the name of a metavariable as an argument.
78+The interface is largely the same as in Idris's interactive prover, except all meta-commands start with colon.
79+For example, use ``:qed`` instead of ``qed``, ``:abandon`` instead of ``abandon``, and ``:undo`` instead of ``undo``.
80+
7381
7482Failure
7583=======
libs/prelude/Language/Reflection/Elab.idr+9
@@ -88,6 +88,7 @@ data Elab : Type -> Type where
8888 prim__Check : Raw -> Elab (TT, TT)
8989
9090 prim__SourceLocation : Elab SourceLocation
91+ prim__Namespace : Elab (List String)
9192
9293 prim__Forget : TT -> Elab Raw
9394
@@ -280,6 +281,14 @@ namespace Tactics
280281 fill (quote loc)
281282 solve
282283
284+ ||| Get the current namespace at the point of tactic execution. This
285+ ||| allows scripts to define top-level names conveniently.
286+ |||
287+ ||| The namespace is represented as a reverse-order list of strings,
288+ ||| just as in the representation of names.
289+ currentNamespace : Elab (List String)
290+ currentNamespace = prim__Namespace
291+
283292 ||| Attempt to rewrite the goal using an equality.
284293 |||
285294 ||| The tactic searches the goal for applicable subterms, and
src/Idris/AbsSyntax.hs+5−5
@@ -1040,7 +1040,7 @@ expandParams dec ps ns infs tm = en tm
10401040 en (PAppBind fc f as) = PAppBind fc (en f) (map (fmap en) as)
10411041 en (PCase fc c os) = PCase fc (en c) (map (pmap en) os)
10421042 en (PIfThenElse fc c t f) = PIfThenElse fc (en c) (en t) (en f)
1043− en (PRunElab fc tm) = PRunElab fc (en tm)
1043+ en (PRunElab fc tm ns) = PRunElab fc (en tm) ns
10441044 en t = t
10451045
10461046 nselem x [] = False
@@ -1506,7 +1506,7 @@ implicitise syn ignore ist tm = -- trace ("INCOMING " ++ showImp True tm) $
15061506 imps top env (PHidden tm) = imps False env tm
15071507 imps top env (PUnifyLog tm) = imps False env tm
15081508 imps top env (PNoImplicits tm) = imps False env tm
1509− imps top env (PRunElab fc tm) = imps False env tm
1509+ imps top env (PRunElab fc tm ns) = imps False env tm
15101510 imps top env _ = return ()
15111511
15121512 pibind using [] sc = sc
@@ -1631,7 +1631,7 @@ addImpl' inpat env infns imp_meths ist ptm
16311631 ai qq env ds (PQuasiquote tm g) = PQuasiquote (ai True env ds tm)
16321632 (fmap (ai True env ds) g)
16331633 ai qq env ds (PUnquote tm) = PUnquote (ai False env ds tm)
1634− ai qq env ds (PRunElab fc tm) = PRunElab fc (ai False env ds tm)
1634+ ai qq env ds (PRunElab fc tm ns) = PRunElab fc (ai False env ds tm) ns
16351635 ai qq env ds tm = tm
16361636
16371637 handleErr (Left err) = PElabError err
@@ -2060,7 +2060,7 @@ substMatchShadow n shs tm t = sm shs t where
20602060 sm xs (PHidden x) = PHidden (sm xs x)
20612061 sm xs (PUnifyLog x) = PUnifyLog (sm xs x)
20622062 sm xs (PNoImplicits x) = PNoImplicits (sm xs x)
2063− sm xs (PRunElab fc script) = PRunElab fc (sm xs script)
2063+ sm xs (PRunElab fc script ns) = PRunElab fc (sm xs script) ns
20642064 sm xs x = x
20652065
20662066 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
@@ -2189,5 +2189,5 @@ mkUniqueNames env tm = evalState (mkUniq tm) (S.fromList env) where
21892189 mkUniq (PNoImplicits t) = liftM PNoImplicits (mkUniq t)
21902190 mkUniq (PProof ts) = liftM PProof (mapM mkUniqT ts)
21912191 mkUniq (PTactics ts) = liftM PTactics (mapM mkUniqT ts)
2192− mkUniq (PRunElab fc ts) = liftM (PRunElab fc ) (mkUniq ts)
2192+ mkUniq (PRunElab fc ts ns) = liftM (\tm -> PRunElab fc tm ns) (mkUniq ts)
21932193 mkUniq t = return t
src/Idris/AbsSyntaxTree.hs+9−4
@@ -209,7 +209,7 @@ data IState = IState {
209209 idris_cgflags :: [(Codegen, String)],
210210 idris_hdrs :: [(Codegen, String)],
211211 idris_imported :: [(FilePath, Bool)], -- ^ Imported ibc file names, whether public
212− proof_list :: [(Name, [String])],
212+ proof_list :: [(Name, (Bool, [String]))],
213213 errSpan :: Maybe FC,
214214 parserWarnings :: [(FC, Err)],
215215 lastParse :: Maybe Name,
@@ -377,7 +377,7 @@ data Command = Quit
377377 | Execute PTerm
378378 | ExecVal PTerm
379379 | Metavars
380− | Prove Name
380+ | Prove Bool Name -- ^ If false, use prover, if true, use elab shell
381381 | AddProof (Maybe Name)
382382 | RmProof Name
383383 | ShowProof Name
@@ -486,6 +486,11 @@ data Opt = Filename String
486486 | UseConsoleWidth ConsoleWidth
487487 deriving (Show, Eq)
488488
489+data ElabShellCmd = EQED | EAbandon | EUndo | EProofState | EProofTerm
490+ | EEval PTerm | ECheck PTerm | ESearch PTerm
491+ | EDocStr (Either Name Const)
492+ deriving (Show, Eq)
493+
489494-- Parsed declarations
490495
491496data Fixity = Infixl { prec :: Int }
@@ -864,7 +869,7 @@ data PTerm = PQuote Raw -- ^ Inclusion of a core term into the high-level langua
864869 | PQuasiquote PTerm (Maybe PTerm) -- ^ `(Term [: Term])
865870 | PUnquote PTerm -- ^ ~Term
866871 | PQuoteName Name -- ^ `{n}
867− | PRunElab FC PTerm -- ^ %runElab tm - New-style proof script
872+ | PRunElab FC PTerm [String] -- ^ %runElab tm - New-style proof script. Args are location, script, enclosing namespace.
868873 deriving (Eq, Data, Typeable)
869874
870875data PAltType = ExactlyOne Bool -- ^ flag sets whether delay is allowed
@@ -1234,7 +1239,7 @@ initDSL = DSL (PRef f (sUN ">>="))
12341239
12351240data Using = UImplicit Name PTerm
12361241 | UConstraint Name [Name]
1237− deriving (Show, Eq)
1242+ deriving (Show, Eq, Data, Typeable)
12381243{-!
12391244deriving instance Binary Using
12401245deriving instance NFData Using
src/Idris/DSL.hs+2−2
@@ -112,7 +112,7 @@ expandSugar dsl (PDoBlock ds)
112112 block b _ = PElabError (Msg "Invalid statement in do block")
113113
114114expandSugar dsl (PIdiom fc e) = expandSugar dsl $ unIdiom (dsl_apply dsl) (dsl_pure dsl) fc e
115−expandSugar dsl (PRunElab fc tm) = PRunElab fc $ expandSugar dsl tm
115+expandSugar dsl (PRunElab fc tm ns) = PRunElab fc (expandSugar dsl tm) ns
116116expandSugar dsl t = t
117117
118118-- | Replace DSL-bound variable in a term
@@ -198,7 +198,7 @@ debind b tm = let (tm', (bs, _)) = runState (db' tm) ([], 0) in
198198 db' (PDPair fc p l t r) = do l' <- db' l
199199 r' <- db' r
200200 return (PDPair fc p l' t r')
201− db' (PRunElab fc t) = fmap (PRunElab fc) (db' t)
201+ db' (PRunElab fc t ns) = fmap (\tm -> PRunElab fc tm ns) (db' t)
202202 db' t = return t
203203
204204 dbArg a = do t' <- db' (getTm a)
src/Idris/DeepSeq.hs+1−1
@@ -262,7 +262,7 @@ instance NFData PTerm where
262262 rnf (PQuasiquote x1 x2) = rnf x1 `seq` rnf x2 `seq` ()
263263 rnf (PUnquote x1) = rnf x1 `seq` ()
264264 rnf (PQuoteName x1) = rnf x1 `seq` ()
265− rnf (PRunElab x1 x2) = rnf x1 `seq` rnf x2 `seq` ()
265+ rnf (PRunElab x1 x2 x3) = rnf x1 `seq` rnf x2 `seq` rnf x3 `seq` ()
266266
267267instance NFData PAltType where
268268 rnf (ExactlyOne x1) = rnf x1 `seq` ()
src/Idris/Elab/Term.hs+14−10
@@ -16,7 +16,7 @@ import Idris.Core.TT
1616import Idris.Core.Evaluate
1717import Idris.Core.Unify
1818import Idris.Core.ProofTerm (getProofTerm)
19−import Idris.Core.Typecheck (check, recheck, isType)
19+import Idris.Core.Typecheck (check, recheck, converts, isType)
2020import Idris.Coverage (buildSCG, checkDeclTotality, genClauses, recoverableCoverage, validCoverageCase)
2121import Idris.ErrReverse (errReverse)
2222import Idris.ElabQuasiquote (extractUnquotes)
@@ -1136,7 +1136,7 @@ elab ist info emode opts fn tm
11361136 delayElab 10 $ do focus h
11371137 dotterm
11381138 elab' ina fc t
1139− elab' ina fc (PRunElab fc' tm) =
1139+ elab' ina fc (PRunElab fc' tm ns) =
11401140 do attack
11411141 n <- getNameFrom (sMN 0 "tacticScript")
11421142 n' <- getNameFrom (sMN 0 "tacticExpr")
@@ -1149,7 +1149,7 @@ elab ist info emode opts fn tm
11491149 focus n
11501150 elab' ina (Just fc') tm
11511151 env <- get_env
1152− runTactical ist (maybe fc' id fc) env (P Bound n' Erased)
1152+ runTactical ist (maybe fc' id fc) env (P Bound n' Erased) ns
11531153 solve
11541154 elab' ina fc x = fail $ "Unelaboratable syntactic form " ++ showTmImpls x
11551155
@@ -1697,10 +1697,10 @@ case_ ind autoSolve ist fn tm = do
16971697 when autoSolve solveAll
16981698
16991699
1700−runTactical :: IState -> FC -> Env -> Term -> ElabD ()
1701−runTactical ist fc env tm = do tm' <- eval tm
1702− runTacTm tm'
1703− return ()
1700+runTactical :: IState -> FC -> Env -> Term -> [String] -> ElabD Term
1701+runTactical ist fc env tm ns = do tm' <- eval tm
1702+ runTacTm tm'
1703+
17041704 where
17051705 eval tm = do ctxt <- get_context
17061706 return $ normaliseAll ctxt env (finalise tm)
@@ -1721,8 +1721,9 @@ runTactical ist fc env tm = do tm' <- eval tm
17211721 let info = CaseInfo True True False -- TODO document and figure out
17221722 clauses' <- forM clauses (\case
17231723 RMkFunClause lhs rhs ->
1724− do lhs' <- fmap fst . lift $ check ctxt [] lhs
1725− rhs' <- fmap fst . lift $ check ctxt [] rhs
1724+ do (lhs', lty) <- lift $ check ctxt [] lhs
1725+ (rhs', rty) <- lift $ check ctxt [] rhs
1726+ lift $ converts ctxt [] lty rty
17261727 return $ Right (lhs', rhs')
17271728 RMkImpossibleClause lhs ->
17281729 do lhs' <- fmap fst . lift $ check ctxt [] lhs
@@ -1812,6 +1813,9 @@ runTactical ist fc env tm = do tm' <- eval tm
18121813 | n == tacN "prim__SourceLocation", [] <- args
18131814 = fmap fst . checkClosed $
18141815 reflectFC fc
1816+ | n == tacN "prim__Namespace", [] <- args
1817+ = fmap fst . checkClosed $
1818+ rawList (RConstant StrType) (map (RConstant . Str) ns)
18151819 | n == tacN "prim__Env", [] <- args
18161820 = do env <- get_env
18171821 fmap fst . checkClosed $ reflectEnv env
@@ -1960,7 +1964,7 @@ runTactical ist fc env tm = do tm' <- eval tm
19601964 datatypes <- get_datatypes
19611965 env <- get_env
19621966 (_, ES (p, aux') _ _) <-
1963− lift $ runElab aux (runTactical ist fc [] script)
1967+ lift $ runElab aux (runTactical ist fc [] script ns)
19641968 (newProof recH ctxt datatypes goalTT)
19651969 let tm_out = getProofTerm (pterm p)
19661970 updateAux $ const aux'
src/Idris/Elab/Value.hs+2−2
@@ -50,7 +50,7 @@ import Data.List.Split (splitOn)
5050
5151import Util.Pretty(pretty, text)
5252
53−-- Elaborate a value, returning any new bindings created (this will only
53+-- | Elaborate a value, returning any new bindings created (this will only
5454-- happen if elaborating as a pattern clause)
5555elabValBind :: ElabInfo -> ElabMode -> Bool -> PTerm -> Idris (Term, Type, [(Name, Type)])
5656elabValBind info aspat norm tm_in
@@ -116,7 +116,7 @@ elabDocTerms info str = do typechecked <- Traversable.mapM decorate str
116116 else Checked tm
117117 | otherwise = Unchecked
118118
119−-- Try running the term directly (as IO ()), then printing it as an Integer
119+-- | Try running the term directly (as IO ()), then printing it as an Integer
120120-- (as a default numeric tye), then printing it as any Showable thing
121121elabExec :: FC -> PTerm -> PTerm
122122elabExec fc tm = runtm (PAlternative FirstSuccess
src/Idris/ElabQuasiquote.hs+2−2
@@ -166,8 +166,8 @@ extractUnquotes n (PUnquote tm)
166166 return (PRef (fileFC "(unquote)") n, [(n, tm)])
167167 | otherwise = fmap (\(tm', ex) -> (PUnquote tm', ex)) $
168168 extractUnquotes (n-1) tm
169−extractUnquotes n (PRunElab fc tm)
170− = fmap (\(tm', ex) -> (PRunElab fc tm', ex)) $ extractUnquotes n tm
169+extractUnquotes n (PRunElab fc tm ns)
170+ = fmap (\(tm', ex) -> (PRunElab fc tm' ns, ex)) $ extractUnquotes n tm
171171extractUnquotes n x = return (x, []) -- no subterms!
172172
173173
src/Idris/Error.hs+1−1
@@ -150,4 +150,4 @@ warnDisamb ist (PUnquote tm) = warnDisamb ist tm
150150warnDisamb ist (PQuoteName _) = return ()
151151warnDisamb ist (PAs _ _ tm) = warnDisamb ist tm
152152warnDisamb ist (PAppImpl tm _) = warnDisamb ist tm
153−warnDisamb ist (PRunElab _ tm) = warnDisamb ist tm
153+warnDisamb ist (PRunElab _ tm _) = warnDisamb ist tm
src/Idris/IBC.hs+6−4
@@ -1625,9 +1625,10 @@ instance Binary PTerm where
16251625 put x2
16261626 PUniverse x1 -> do putWord8 38
16271627 put x1
1628− PRunElab x1 x2 -> do putWord8 39
1629− put x1
1630− put x2
1628+ PRunElab x1 x2 x3 -> do putWord8 39
1629+ put x1
1630+ put x2
1631+ put x3
16311632 PAs x1 x2 x3 -> do putWord8 40
16321633 put x1
16331634 put x2
@@ -1763,7 +1764,8 @@ instance Binary PTerm where
17631764 return (PUniverse x1)
17641765 39 -> do x1 <- get
17651766 x2 <- get
1766− return (PRunElab x1 x2)
1767+ x3 <- get
1768+ return (PRunElab x1 x2 x3)
17671769 40 -> do x1 <- get
17681770 x2 <- get
17691771 x3 <- get
src/Idris/IdrisDoc.hs+1−1
@@ -320,7 +320,7 @@ extractPTermNames (PCoerced p) = extract p
320320extractPTermNames (PDisamb _ p) = extract p
321321extractPTermNames (PUnifyLog p) = extract p
322322extractPTermNames (PNoImplicits p) = extract p
323−extractPTermNames (PRunElab _ p) = extract p
323+extractPTermNames (PRunElab _ p _) = extract p
324324extractPTermNames _ = []
325325
326326-- | Shorter name for extractPTermNames
src/Idris/ParseExpr.hs+5−5
@@ -510,7 +510,7 @@ runElab syn = do try (lchar '%' *> reserved "runElab")
510510 fc <- getFC
511511 tm <- simpleExpr syn
512512 i <- get
513− return $ PRunElab fc tm
513+ return $ PRunElab fc tm (syn_namespace syn)
514514 <?> "new-style tactics expression"
515515
516516{- | Parses a disambiguation expression
@@ -1375,10 +1375,10 @@ tactics =
13751375 , noArgs ["instance"] TCInstance
13761376 , noArgs ["solve"] Solve
13771377 , noArgs ["attack"] Attack
1378− , noArgs ["state"] ProofState
1379− , noArgs ["term"] ProofTerm
1380− , noArgs ["undo"] Undo
1381− , noArgs ["qed"] Qed
1378+ , noArgs ["state", ":state"] ProofState
1379+ , noArgs ["term", ":term"] ProofTerm
1380+ , noArgs ["undo", ":undo"] Undo
1381+ , noArgs ["qed", ":qed"] Qed
13821382 , noArgs ["abandon", ":q"] Abandon
13831383 , noArgs ["skip"] Skip
13841384 , noArgs ["sourceLocation"] SourceFC
src/Idris/Parser.hs+25
@@ -62,6 +62,7 @@ import Data.List
6262import Data.Monoid
6363import Data.Char
6464import Data.Ord
65+import Data.Foldable (asum)
6566import Data.Generics.Uniplate.Data (descendM)
6667import qualified Data.Map as M
6768import qualified Data.HashSet as HS
@@ -1238,6 +1239,30 @@ parseConst st = runparser (fmap fst constant) st "(input)"
12381239parseTactic :: IState -> String -> Result PTactic
12391240parseTactic st = runparser (fullTactic defaultSyntax) st "(input)"
12401241
1242+{- | Parses a do-step from input (used in the elab shell) -}
1243+parseElabShellStep :: IState -> String -> Result (Either ElabShellCmd PDo)
1244+parseElabShellStep ist = runparser (fmap Right (do_ defaultSyntax) <|> fmap Left elabShellCmd) ist "(input)"
1245+ where elabShellCmd = char ':' >>
1246+ (reserved "qed" >> pure EQED ) <|>
1247+ (reserved "abandon" >> pure EAbandon ) <|>
1248+ (reserved "undo" >> pure EUndo ) <|>
1249+ (reserved "state" >> pure EProofState) <|>
1250+ (reserved "term" >> pure EProofTerm ) <|>
1251+ (expressionTactic ["e", "eval"] EEval ) <|>
1252+ (expressionTactic ["t", "type"] ECheck) <|>
1253+ (expressionTactic ["search"] ESearch ) <|>
1254+ (do reserved "doc"
1255+ doc <- (Right . fst <$> constant) <|> (Left . fst <$> fnName)
1256+ eof
1257+ return (EDocStr doc))
1258+ <?> "elab command"
1259+ expressionTactic cmds tactic =
1260+ do asum (map reserved cmds)
1261+ t <- spaced (expr defaultSyntax)
1262+ i <- get
1263+ return $ tactic (desugar defaultSyntax i t)
1264+ spaced parser = indentPropHolds gtProp *> parser
1265+
12411266-- | Parse module header and imports
12421267parseImports :: FilePath -> String -> Idris (Maybe (Docstring ()), [String], [ImportInfo], Maybe Delta)
12431268parseImports fname input
src/Idris/Prover.hs+265−96
@@ -1,5 +1,5 @@
11{-# LANGUAGE PatternGuards #-}
2−module Idris.Prover where
2+module Idris.Prover (prover, showProof, showRunElab) where
33
44import Idris.Core.Elaborate hiding (Tactic(..))
55import Idris.Core.TT
@@ -35,13 +35,14 @@ import Control.DeepSeq
3535import Util.Pretty
3636import Debug.Trace
3737
38−prover :: Bool -> Name -> Idris ()
39−prover lit x =
38+-- | Launch the proof shell
39+prover :: Bool -> Bool -> Name -> Idris ()
40+prover mode lit x =
4041 do ctxt <- getContext
4142 i <- getIState
4243 case lookupTy x ctxt of
4344 [t] -> if elem x (map fst (idris_metavars i))
44− then prove (idris_optimisation i) ctxt lit x t
45+ then prove mode (idris_optimisation i) ctxt lit x t
4546 else ifail $ show x ++ " is not a metavariable"
4647 _ -> fail "No such metavariable"
4748
@@ -53,6 +54,15 @@ showProof lit n ps
5354 where bird = if lit then "> " else ""
5455 break = "\n" ++ bird
5556
57+showRunElab :: Bool -> Name -> [String] -> String
58+showRunElab lit n ps = birdify (displayS (renderPretty 1.0 80 doc) "")
59+ where doc = text (show n) <+> text "=" <+> text "%runElab" <+>
60+ enclose lparen rparen
61+ (text "do" <+> (align $ vsep (map text ps)))
62+ birdify = if lit
63+ then concatMap ("> " ++) . lines
64+ else id
65+
5666proverSettings :: ElabState EState -> Settings Idris
5767proverSettings e = setComplete (proverCompletion (assumptionNames e)) defaultSettings
5868
@@ -64,18 +74,24 @@ assumptionNames e
6474 names ((MN _ _, _) : bs) = names bs
6575 names ((n, _) : bs) = show n : names bs
6676
67−prove :: Ctxt OptInfo -> Context -> Bool -> Name -> Type -> Idris ()
68−prove opt ctxt lit n ty
77+prove :: Bool -> Ctxt OptInfo -> Context -> Bool -> Name -> Type -> Idris ()
78+prove mode opt ctxt lit n ty
6979 = do ps <- fmap (\ist -> initElaborator n ctxt (idris_datatypes ist) ty) getIState
7080 idemodePutSExp "start-proof-mode" n
71− (tm, prf) <- ploop n True ("-" ++ show n) [] (ES (ps, initEState) "" Nothing) Nothing
81+ (tm, prf) <-
82+ if mode
83+ then elabloop n True ("-" ++ show n) [] (ES (ps, initEState) "" Nothing) [] Nothing []
84+ else ploop n True ("-" ++ show n) [] (ES (ps, initEState) "" Nothing) Nothing
7285 iLOG $ "Adding " ++ show tm
7386 i <- getIState
87+ let shower = if mode
88+ then showRunElab
89+ else showProof
7490 case idris_outputmode i of
75− IdeMode _ _ -> idemodePutSExp "end-proof-mode" (n, showProof lit n prf)
76− _ -> iputStrLn $ showProof lit n prf
91+ IdeMode _ _ -> idemodePutSExp "end-proof-mode" (n, shower lit n prf)
92+ _ -> iputStrLn $ shower lit n prf
7793 let proofs = proof_list i
78− putIState (i { proof_list = (n, prf) : proofs })
94+ putIState (i { proof_list = (n, (mode, prf)) : proofs })
7995 let tree = simpleCase False (STerm Erased) False CompileTime (fileFC "proof") [] [] [([], P Ref n ty, tm)]
8096 logLvl 3 (show tree)
8197 (ptm, pty) <- recheckC (fileFC "proof") id [] tm
@@ -117,16 +133,17 @@ elabStep st e = case runStateT eCheck st of
117133 return res
118134 ((_,_,_,_,e,_,_):_) -> lift $ Error e
119135
120−dumpState :: IState -> ProofState -> Idris ()
121−dumpState ist ps | [] <- holes ps =
136+dumpState :: IState -> [(Name, Type, Term)] -> ProofState -> Idris ()
137+dumpState ist menv ps | [] <- holes ps =
122138 do let nm = thname ps
123139 rendered <- iRender $ prettyName True False [] nm <> colon <+> text "No more goals."
124140 iputGoal rendered
125−dumpState ist ps | (h : hs) <- holes ps = do
141+dumpState ist menv ps | (h : hs) <- holes ps = do
126142 let OK ty = goalAtFocus ps
127143 let OK env = envAtFocus ps
128144 let state = prettyOtherGoals hs <> line <>
129145 prettyAssumptions env <> line <>
146+ prettyMetaValues (reverse menv) <>
130147 prettyGoal (zip (assumptionNames env) (repeat False)) ty
131148 rendered <- iRender state
132149 iputGoal rendered
@@ -156,6 +173,21 @@ dumpState ist ps | (h : hs) <- holes ps = do
156173 line <> bindingOf n False <+> colon <+>
157174 align (tPretty bnd (binderTy b)) <> prettyPs ((n, False):bnd) bs
158175
176+ prettyMetaValues [] = empty
177+ prettyMetaValues mvs =
178+ text "---------- Meta-values: ----------" <$$>
179+ prettyMetaValues' [] mvs <> line <> line
180+ prettyMetaValues' _ [] = empty
181+ prettyMetaValues' bnd [mv] = ppMv bnd mv
182+ prettyMetaValues' bnd ((mv@(n, ty, tm)) : mvs) =
183+ ppMv bnd mv <$>
184+ prettyMetaValues' ((n, False):bnd) mvs
185+
186+ ppMv bnd (n, ty, tm) = kwd "let" <+> bindingOf n False <+> colon <+>
187+ tPretty bnd ty <+> text "=" <+> tPretty bnd tm
188+
189+ kwd = annotate AnnKeyword . text
190+
159191 prettyG bnd (Guess t v) = tPretty bnd t <+> text "=?=" <+> tPretty bnd v
160192 prettyG bnd b = tPretty bnd $ binderTy b
161193
@@ -208,11 +240,141 @@ receiveInput h e =
208240 Just (IdeMode.DocsFor str _) -> return (Just (":doc " ++ str))
209241 _ -> return Nothing
210242
243+data ElabShellHistory = ElabStep | LetStep | BothStep
244+
245+undoStep :: [String] -> [(Name, Type, Term)] -> ElabState EState -> ElabShellHistory -> Idris ([String], [(Name, Type, Term)], ElabState EState)
246+undoStep prf env st ElabStep = do (_, st') <- elabStep st loadState
247+ return (init prf, env, st')
248+undoStep prf env st LetStep = return (init prf, tail env, st)
249+undoStep prf env st BothStep = do (_, st') <- elabStep st loadState
250+ return (init prf, tail env, st')
251+
252+undoElab :: [String] -> [(Name, Type, Term)] -> ElabState EState -> [ElabShellHistory] -> Idris ([String], [(Name, Type, Term)], ElabState EState, [ElabShellHistory])
253+undoElab prf env st [] = ifail "Nothing to undo"
254+undoElab prf env st (h:hs) = do (prf', env', st') <- undoStep prf env st h
255+ return (prf', env', st', hs)
256+
257+elabloop :: Name -> Bool -> String -> [String] -> ElabState EState -> [ElabShellHistory] -> Maybe History -> [(Name, Type, Term)] -> Idris (Term, [String])
258+elabloop fn d prompt prf e prev h env
259+ = do ist <- getIState
260+ when d $ dumpState ist env (proof e)
261+ (x, h') <-
262+ case idris_outputmode ist of
263+ RawOutput _ ->
264+ runInputT (proverSettings e) $
265+ do case h of
266+ Just history -> putHistory history
267+ Nothing -> return ()
268+ l <- getInputLine (prompt ++ "> ")
269+ h' <- getHistory
270+ return (l, Just h')
271+ IdeMode _ handle ->
272+ do isetPrompt prompt
273+ i <- receiveInput handle e
274+ return (i, h)
275+ (cmd, step) <- case x of
276+ Nothing -> do iPrintError "" ; ifail "Abandoned"
277+ Just input -> return (parseElabShellStep ist input, input)
278+
279+ -- if we're abandoning, it has to be outside the scope of the catch
280+ case cmd of
281+ Success (Left EAbandon) -> do iPrintError ""; ifail "Abandoned"
282+ _ -> return ()
283+
284+ (d, prev', st, done, prf', env', res) <-
285+ idrisCatch
286+ (case cmd of
287+ Failure err ->
288+ return (False, prev, e, False, prf, env, Left . Msg . show . fixColour (idris_colourRepl ist) $ err)
289+ Success (Left cmd') ->
290+ case cmd' of
291+ EQED -> do hs <- lifte e get_holes
292+ when (not (null hs)) $ ifail "Incomplete proof"
293+ iputStrLn "Proof completed!"
294+ return (False, prev, e, True, prf, env, Right $ iPrintResult "")
295+ EUndo -> do (prf', env', st', prev') <- undoElab prf env e prev
296+ return (True, prev', st', False, prf', env', Right $ iPrintResult "")
297+ EAbandon ->
298+ error "the impossible happened - should have been matched on outer scope"
299+ EProofState -> return (True, prev, e, False, prf, env, Right $ iPrintResult "")
300+ EProofTerm ->
301+ do tm <- lifte e get_term
302+ return (False, prev, e, False, prf, env, Right $ iRenderResult (text "TT:" <+> pprintTT [] tm))
303+ EEval tm -> do (d', st', done, prf', go) <- evalTerm e prf tm
304+ return (d', prev, st', done, prf', env, go)
305+ ECheck (PRef _ n) ->
306+ do (d', st', done, prf', go) <- checkNameType e prf n
307+ return (d', prev, st', done, prf', env, go)
308+ ECheck tm -> do (d', st', done, prf', go) <- checkType e prf tm
309+ return (d', prev, st', done, prf', env, go)
310+ ESearch ty -> do (d', st', done, prf', go) <- search e prf ty
311+ return (d', prev, st', done, prf', env, go)
312+ EDocStr d -> do (d', st', done, prf', go) <- docStr e prf d
313+ return (d', prev, st', done, prf', env, go)
314+ Success (Right cmd') ->
315+ case cmd' of
316+ DoLetP _ _ _ -> ifail "Pattern-matching let not supported here"
317+ DoBindP _ _ _ _ -> ifail "Pattern-matching <- not supported here"
318+ DoLet fc i ifc Placeholder expr ->
319+ do (tm, ty) <- elabVal recinfo ERHS (inLets ist env expr)
320+ ctxt <- getContext
321+ let tm' = normaliseAll ctxt [] tm
322+ ty' = normaliseAll ctxt [] ty
323+ return (True, LetStep:prev, e, False, prf ++ [step], (i, ty', tm' ) : env, Right (iPrintResult ""))
324+ DoLet fc i ifc ty expr ->
325+ do (tm, ty) <- elabVal recinfo ERHS
326+ (PApp NoFC (PRef NoFC (sUN "the"))
327+ [ pexp (inLets ist env ty)
328+ , pexp (inLets ist env expr)
329+ ])
330+ ctxt <- getContext
331+ let tm' = normaliseAll ctxt [] tm
332+ ty' = normaliseAll ctxt [] ty
333+ return (True, LetStep:prev, e, False, prf ++ [step], (i, ty', tm' ) : env, Right (iPrintResult ""))
334+ DoBind fc i ifc expr ->
335+ do (tm, ty) <- elabVal recinfo ERHS (inLets ist env expr)
336+ (_, e') <- elabStep e saveState -- enable :undo
337+ (res, e'') <- elabStep e' $
338+ runTactical ist NoFC [] tm ["Shell"]
339+ ctxt <- getContext
340+ (v, vty) <- tclift $ check ctxt [] (forget res)
341+ let v' = normaliseAll ctxt [] v
342+ vty' = normaliseAll ctxt [] vty
343+ return (True, BothStep:prev, e'', False, prf ++ [step], (i, vty', v') : env, Right (iPrintResult ""))
344+ DoExp fc expr ->
345+ do (tm, ty) <- elabVal recinfo ERHS (inLets ist env expr)
346+ -- TODO: call elaborator with Elab () as goal here
347+ (_, e') <- elabStep e saveState -- enable :undo
348+ (_, e'') <- elabStep e' $
349+ runTactical ist NoFC [] tm ["Shell"]
350+ return (True, ElabStep:prev, e'', False, prf ++ [step], env, Right (iPrintResult "")))
351+ (\err -> return (False, prev, e, False, prf, env, Left err))
352+ idemodePutSExp "write-proof-state" (prf', length prf')
353+ case res of
354+ Left err -> do ist <- getIState
355+ iRenderError $ pprintErr ist err
356+ elabloop fn d prompt prf' st prev' h' env'
357+ Right ok ->
358+ if done then do (tm, _) <- elabStep st get_term
359+ return (tm, prf')
360+ else do ok
361+ elabloop fn d prompt prf' st prev' h' env'
362+
363+ where
364+ -- A bit of a hack: wrap the value up in a let binding, which will
365+ -- normalise away. It would be better to figure out how to call
366+ -- the elaborator with a custom environment here to avoid the
367+ -- delab step.
368+ inLets :: IState -> [(Name, Type, Term)] -> PTerm -> PTerm
369+ inLets ist lets tm = foldr (\(n, ty, v) b -> PLet NoFC n NoFC (delab ist ty) (delab ist v) b) tm (reverse lets)
370+
371+
372+
211373ploop :: Name -> Bool -> String -> [String] -> ElabState EState -> Maybe History -> Idris (Term, [String])
212374ploop fn d prompt prf e h
213375 = do i <- getIState
214376 let autoSolve = opt_autoSolve (idris_options i)
215− when d $ dumpState i (proof e)
377+ when d $ dumpState i [] (proof e)
216378 (x, h') <-
217379 case idris_outputmode i of
218380 RawOutput _ ->
@@ -247,11 +409,11 @@ ploop fn d prompt prf e h
247409 when (not (null hs)) $ ifail "Incomplete proof"
248410 iputStrLn "Proof completed!"
249411 return (False, e, True, prf, Right $ iPrintResult "")
250− Success (TCheck (PRef _ n)) -> checkNameType n
251− Success (TCheck t) -> checkType t
252− Success (TEval t) -> evalTerm t e
253− Success (TDocStr x) -> docStr x
254− Success (TSearch t) -> search t
412+ Success (TCheck (PRef _ n)) -> checkNameType e prf n
413+ Success (TCheck t) -> checkType e prf t
414+ Success (TEval t) -> evalTerm e prf t
415+ Success (TDocStr x) -> docStr e prf x
416+ Success (TSearch t) -> search e prf t
255417 Success tac ->
256418 do (_, e) <- elabStep e saveState
257419 (_, st) <- elabStep e (runTac autoSolve i (Just proverFC) fn tac)
@@ -267,80 +429,87 @@ ploop fn d prompt prf e h
267429 return (tm, prf')
268430 else do ok
269431 ploop fn d prompt prf' st h'
270− where envCtxt env ctxt = foldl (\c (n, b) -> addTyDecl n Bound (binderTy b) c) ctxt env
271− checkNameType n = do
272− ctxt <- getContext
273− ist <- getIState
274− imp <- impShow
275− idrisCatch (do
276− let OK env = envAtFocus (proof e)
277− ctxt' = envCtxt env ctxt
278− bnd = map (\x -> (fst x, False)) env
279− ist' = ist { tt_ctxt = ctxt' }
280− putIState ist'
281− -- Unlike the REPL, metavars have no special treatment, to
282− -- make it easier to see how to prove with them.
283− let action = case lookupNames n ctxt' of
284− [] -> iPrintError $ "No such variable " ++ show n
285− ts -> iPrintFunTypes bnd n (map (\n -> (n, pprintDelabTy ist' n)) ts)
286− putIState ist
287− return (False, e, False, prf, Right action))
288− (\err -> do putIState ist ; ierror err)
289−
290− checkType t = do
291− ist <- getIState
292− ctxt <- getContext
293− idrisCatch (do
294− let OK env = envAtFocus (proof e)
295− ctxt' = envCtxt env ctxt
296− putIState ist { tt_ctxt = ctxt' }
297− (tm, ty) <- elabVal recinfo ERHS t
298− let ppo = ppOptionIst ist
299− ty' = normaliseC ctxt [] ty
300− infixes = idris_infixes ist
301− action = case tm of
302− TType _ ->
303− iPrintTermWithType (prettyImp ppo (PType emptyFC)) type1Doc
304− _ -> let bnd = map (\x -> (fst x, False)) env in
305− iPrintTermWithType (pprintPTerm ppo bnd [] infixes (delab ist tm))
306− (pprintPTerm ppo bnd [] infixes (delab ist ty))
307− putIState ist
308− return (False, e, False, prf, Right action))
309− (\err -> do putIState ist { tt_ctxt = ctxt } ; ierror err)
310−
311− proverFC = FC "(prover shell)" (0, 0) (0, 0)
312−
313− evalTerm t e = withErrorReflection $
314− do ctxt <- getContext
315− ist <- getIState
316− idrisCatch (do
317− let OK env = envAtFocus (proof e)
318− ctxt' = envCtxt env ctxt
319− ist' = ist { tt_ctxt = ctxt' }
320− bnd = map (\x -> (fst x, False)) env
321− putIState ist'
322− (tm, ty) <- elabVal recinfo ERHS t
323− let tm' = force (normaliseAll ctxt' env tm)
324− ty' = force (normaliseAll ctxt' env ty)
325− ppo = ppOption (idris_options ist')
326− infixes = idris_infixes ist
327− tmDoc = pprintPTerm ppo bnd [] infixes (delab ist' tm')
328− tyDoc = pprintPTerm ppo bnd [] infixes (delab ist' ty')
329− action = iPrintTermWithType tmDoc tyDoc
330− putIState ist
331− return (False, e, False, prf, Right action))
332− (\err -> do putIState ist ; ierror err)
333− docStr :: Either Name Const -> Idris (Bool, ElabState EState, Bool, [String], Either Err (Idris ()))
334− docStr (Left n) = do ist <- getIState
335− idrisCatch (case lookupCtxtName n (idris_docstrings ist) of
336− [] -> return (False, e, False, prf,
337− Left . Msg $ "No documentation for " ++ show n)
338− ns -> do toShow <- mapM (showDoc ist) ns
339− return (False, e, False, prf,
340− Right $ iRenderResult (vsep toShow)))
341− (\err -> do putIState ist ; ierror err)
342− where showDoc ist (n, d) = do doc <- getDocs n FullDocs
343− return $ pprintDocs ist doc
344− docStr (Right c) = do ist <- getIState
345− return (False, e, False, prf, Right . iRenderResult $ pprintConstDocs ist c (constDocs c))
346− search t = return (False, e, False, prf, Right $ searchByType [] t)
432+
433+
434+envCtxt env ctxt = foldl (\c (n, b) -> addTyDecl n Bound (binderTy b) c) ctxt env
435+
436+checkNameType :: ElabState EState -> [String] -> Name -> Idris (Bool, ElabState EState, Bool, [String], Either Err (Idris ()))
437+checkNameType e prf n = do
438+ ctxt <- getContext
439+ ist <- getIState
440+ imp <- impShow
441+ idrisCatch (do
442+ let OK env = envAtFocus (proof e)
443+ ctxt' = envCtxt env ctxt
444+ bnd = map (\x -> (fst x, False)) env
445+ ist' = ist { tt_ctxt = ctxt' }
446+ putIState ist'
447+ -- Unlike the REPL, metavars have no special treatment, to
448+ -- make it easier to see how to prove with them.
449+ let action = case lookupNames n ctxt' of
450+ [] -> iPrintError $ "No such variable " ++ show n
451+ ts -> iPrintFunTypes bnd n (map (\n -> (n, pprintDelabTy ist' n)) ts)
452+ putIState ist
453+ return (False, e, False, prf, Right action))
454+ (\err -> do putIState ist ; ierror err)
455+
456+checkType :: ElabState EState -> [String] -> PTerm -> Idris (Bool, ElabState EState, Bool, [String], Either Err (Idris ()))
457+checkType e prf t = do
458+ ist <- getIState
459+ ctxt <- getContext
460+ idrisCatch (do
461+ let OK env = envAtFocus (proof e)
462+ ctxt' = envCtxt env ctxt
463+ putIState ist { tt_ctxt = ctxt' }
464+ (tm, ty) <- elabVal recinfo ERHS t
465+ let ppo = ppOptionIst ist
466+ ty' = normaliseC ctxt [] ty
467+ infixes = idris_infixes ist
468+ action = case tm of
469+ TType _ ->
470+ iPrintTermWithType (prettyImp ppo (PType emptyFC)) type1Doc
471+ _ -> let bnd = map (\x -> (fst x, False)) env in
472+ iPrintTermWithType (pprintPTerm ppo bnd [] infixes (delab ist tm))
473+ (pprintPTerm ppo bnd [] infixes (delab ist ty))
474+ putIState ist
475+ return (False, e, False, prf, Right action))
476+ (\err -> do putIState ist { tt_ctxt = ctxt } ; ierror err)
477+
478+proverFC = FC "(prover shell)" (0, 0) (0, 0)
479+
480+evalTerm :: ElabState EState -> [String] -> PTerm -> Idris (Bool, ElabState EState, Bool, [String], Either Err (Idris ()))
481+evalTerm e prf t = withErrorReflection $
482+ do ctxt <- getContext
483+ ist <- getIState
484+ idrisCatch (do
485+ let OK env = envAtFocus (proof e)
486+ ctxt' = envCtxt env ctxt
487+ ist' = ist { tt_ctxt = ctxt' }
488+ bnd = map (\x -> (fst x, False)) env
489+ putIState ist'
490+ (tm, ty) <- elabVal recinfo ERHS t
491+ let tm' = force (normaliseAll ctxt' env tm)
492+ ty' = force (normaliseAll ctxt' env ty)
493+ ppo = ppOption (idris_options ist')
494+ infixes = idris_infixes ist
495+ tmDoc = pprintPTerm ppo bnd [] infixes (delab ist' tm')
496+ tyDoc = pprintPTerm ppo bnd [] infixes (delab ist' ty')
497+ action = iPrintTermWithType tmDoc tyDoc
498+ putIState ist
499+ return (False, e, False, prf, Right action))
500+ (\err -> do putIState ist ; ierror err)
501+
502+docStr :: ElabState EState -> [String] -> Either Name Const -> Idris (Bool, ElabState EState, Bool, [String], Either Err (Idris ()))
503+docStr e prf (Left n) = do ist <- getIState
504+ idrisCatch (case lookupCtxtName n (idris_docstrings ist) of
505+ [] -> return (False, e, False, prf,
506+ Left . Msg $ "No documentation for " ++ show n)
507+ ns -> do toShow <- mapM (showDoc ist) ns
508+ return (False, e, False, prf,
509+ Right $ iRenderResult (vsep toShow)))
510+ (\err -> do putIState ist ; ierror err)
511+ where showDoc ist (n, d) = do doc <- getDocs n FullDocs
512+ return $ pprintDocs ist doc
513+docStr e prf (Right c) = do ist <- getIState
514+ return (False, e, False, prf, Right . iRenderResult $ pprintConstDocs ist c (constDocs c))
515+search e prf t = return (False, e, False, prf, Right $ searchByType [] t)
src/Idris/REPL.hs+17−11
@@ -296,9 +296,9 @@ runIdeModeCommand h id orig fn mods (IdeMode.Interpret cmd) =
296296 i <- getIState
297297 case parseCmd i "(input)" cmd of
298298 Failure err -> iPrintError $ show (fixColour False err)
299− Success (Right (Prove n')) ->
299+ Success (Right (Prove mode n')) ->
300300 idrisCatch
301− (do process fn (Prove n')
301+ (do process fn (Prove mode n')
302302 isetPrompt (mkPrompt mods)
303303 case idris_outputmode i of
304304 IdeMode n h -> -- signal completion of proof to ide
@@ -1094,16 +1094,20 @@ process fn' (AddProof prf)
10941094 n' <- case prf of
10951095 Nothing -> case proofs of
10961096 [] -> ifail "No proof to add"
1097− ((x, p) : _) -> return x
1097+ ((x, _) : _) -> return x
10981098 Just nm -> return nm
10991099 n <- resolveProof n'
11001100 case lookup n proofs of
11011101 Nothing -> iputStrLn "No proof to add"
1102− Just p -> do let prog' = insertScript (showProof (lit fn) n p) ls
1103− runIO $ writeSource fn (unlines prog')
1104− removeProof n
1105− iputStrLn $ "Added proof " ++ show n
1106− where ls = (lines prog)
1102+ Just (mode, prf) ->
1103+ do let script = if mode
1104+ then showRunElab (lit fn) n prf
1105+ else showProof (lit fn) n prf
1106+ let prog' = insertScript script ls
1107+ runIO $ writeSource fn (unlines prog')
1108+ removeProof n
1109+ iputStrLn $ "Added proof " ++ show n
1110+ where ls = (lines prog)
11071111
11081112process fn (ShowProof n')
11091113 = do i <- getIState
@@ -1111,9 +1115,11 @@ process fn (ShowProof n')
11111115 let proofs = proof_list i
11121116 case lookup n proofs of
11131117 Nothing -> iPrintError "No proof to show"
1114− Just p -> iPrintResult $ showProof False n p
1118+ Just (m, p) -> iPrintResult $ if m
1119+ then showRunElab False n p
1120+ else showProof False n p
11151121
1116−process fn (Prove n')
1122+process fn (Prove mode n')
11171123 = do ctxt <- getContext
11181124 ist <- getIState
11191125 let ns = lookupNames n' ctxt
@@ -1123,7 +1129,7 @@ process fn (Prove n')
11231129 [(n, (_,_,False))] -> return n
11241130 [(_, (_,_,True))] -> ierror (Msg $ "Declarations not solvable using prover")
11251131 ns -> ierror (CantResolveAlts (map fst ns))
1126− prover (lit fn) n
1132+ prover mode (lit fn) n
11271133 -- recheck totality
11281134 i <- getIState
11291135 totcheck (fileFC "(input)", n)
src/Idris/REPLParser.hs+3−1
@@ -63,7 +63,9 @@ parserCommandsForHelp =
6363 , noArgCmd ["e", "edit"] Edit "Edit current file using $EDITOR or $VISUAL"
6464 , noArgCmd ["m", "metavars"] Metavars "Show remaining proof obligations (metavariables)"
6565 , (["p", "prove"], MetaVarArg, "Prove a metavariable"
66− , nameArg Prove)
66+ , nameArg (Prove False))
67+ , (["elab"], MetaVarArg, "Build a metavariable using the elaboration shell"
68+ , nameArg (Prove True))
6769 , (["a", "addproof"], NameArg, "Add proof to source file", cmd_addproof)
6870 , (["rmproof"], NameArg, "Remove proof from proof stack"
6971 , nameArg RmProof)
test/meta003/BadDef.idrnew file+12
@@ -0,0 +1,12 @@
1+module BadDef
2+
3+import Language.Reflection.Elab
4+
5+mkN : String -> TTName
6+mkN n = NS (UN n) ["BadDef"]
7+
8+mkBadDef1 : Elab ()
9+mkBadDef1 = do declareType $ Declare (mkN "bad1") [] `(() -> ())
10+ defineFunction $ DefineFun (mkN "bad1") [MkFunClause `(():()) `("hi")]
11+runBad1 : ()
12+runBad1 = %runElab (mkBadDef1 *> search)
test/meta003/expectednew file+6
@@ -0,0 +1,6 @@
1+BadDef.idr:12:9:
2+When checking right hand side of runBad1:
3+Type mismatch between
4+ ()
5+and
6+ String
test/meta003/runnew file+3
@@ -0,0 +1,3 @@
1+#!/usr/bin/env bash
2+idris $@ --nocolour --check --consolewidth 70 BadDef.idr
3+rm -f *.ibc