1module Idris.Prover where
3import Idris.Core.Elaborate hiding (Tactic(..))
5import Idris.Core.Evaluate
6import Idris.Core.CaseTree
7import Idris.Core.Typecheck
10import Idris.AbsSyntaxTree
11import Idris.Delaborate
14import Idris.Parser hiding (params)
17import Idris.Completion
21import Text.Trifecta.Result(Result(..))
23import System.Console.Haskeline
24import System.Console.Haskeline.History
25import Control.Monad.State.Strict
31prover :: Bool -> Name -> Idris ()
35 case lookupTy x ctxt of
36 [t] -> if elem x (map fst (idris_metavars i))
37 then prove (idris_optimisation i) ctxt lit x t
38 else ifail $ show x ++ " is not a metavariable"
39 _ -> fail "No such metavariable"
41showProof :: Bool -> Name -> [String] -> String
43 = bird ++ show n ++ " = proof" ++ break ++
44 showSep break (map (\x -> " " ++ x) ps) ++
46 where bird = if lit then "> " else ""
49proverSettings :: ElabState [PDecl] -> Settings Idris
50proverSettings e = setComplete (proverCompletion (assumptionNames e)) defaultSettings
52assumptionNames :: ElabState [PDecl] -> [String]
54 = case envAtFocus (proof e) of
57 names ((MN _ _, _) : bs) = names bs
58 names ((n, _) : bs) = show n : names bs
60prove :: Ctxt OptInfo -> Context -> Bool -> Name -> Type -> Idris ()
61prove opt ctxt lit n ty
62 = do let ps = initElaborator n ctxt ty
63 ideslavePutSExp "start-proof-mode" n
64 (tm, prf) <- ploop n True ("-" ++ show n) [] (ES (ps, []) "" Nothing) Nothing
65 iLOG $ "Adding " ++ show tm
66 iputStrLn $ showProof lit n prf
68 ideslavePutSExp "end-proof-mode" n
69 let proofs = proof_list i
70 putIState (i { proof_list = (n, prf) : proofs })
71 let tree = simpleCase False True False CompileTime (fileFC "proof") [] [] [([], P Ref n ty, tm)]
73 (ptm, pty) <- recheckC (fileFC "proof") [] tm
74 logLvl 5 ("Proof type: " ++ show pty ++ "\n" ++
75 "Expected type:" ++ show ty)
76 case converts ctxt [] ty pty of
78 Error e -> ierror (CantUnify False ty pty e [] 0)
80 updateContext (addCasedef n (CaseInfo True False) False False True False
81 [] [] -- argtys, inaccArgs
82 [Right (P Ref n ty, ptm)]
83 [([], P Ref n ty, ptm)]
84 [([], P Ref n ty, ptm)]
85 [([], P Ref n ty, ptm)]
86 [([], P Ref n ty, ptm')] ty)
88elabStep :: ElabState [PDecl] -> ElabD a -> Idris (a, ElabState [PDecl])
89elabStep st e = do case runStateT e st of
90 OK (a, st') -> return (a, st')
93dumpState :: IState -> ProofState -> Idris ()
94dumpState ist (PS nm [] _ _ tm _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) =
95 do rendered <- iRender $ prettyName False [] nm <> colon <+> text "No more goals."
97dumpState ist ps@(PS nm (h:hs) _ _ tm _ _ _ _ _ _ problems i _ _ ctxy _ _ _ _) = do
98 let OK ty = goalAtFocus ps
99 let OK env = envAtFocus ps
100 let state = prettyOtherGoals hs <> line <>
101 prettyAssumptions env <> line <>
102 prettyGoal (zip (assumptionNames env) (repeat False)) ty
103 rendered <- iRender state
107 showImplicits = opt_showimp (idris_options ist)
109 tPretty bnd t = pprintPTerm showImplicits bnd [] $ delab ist t
111 assumptionNames :: Env -> [Name]
112 assumptionNames = map fst
114 prettyPs :: [(Name, Bool)] -> Env -> Doc OutputAnnotation
115 prettyPs bnd [] = empty
116 prettyPs bnd ((n@(MN _ r), _) : bs)
117 | r == txt "rewrite_rule" = prettyPs ((n, False):bnd) bs
118 prettyPs bnd ((n, Let t v) : bs) =
119 nest nestingSize (bindingOf n False <+> text "=" <+> tPretty bnd v <> colon <+>
120 tPretty ((n, False):bnd) t <> line <> prettyPs ((n, False):bnd) bs)
121 prettyPs bnd ((n, b) : bs) =
122 line <> bindingOf n False <+> colon <+> align (tPretty bnd (binderTy b)) <> prettyPs ((n, False):bnd) bs
124 prettyG bnd (Guess t v) = tPretty bnd t <+> text "=?=" <+> tPretty bnd v
125 prettyG bnd b = tPretty bnd $ binderTy b
128 text "---------- Goal: ----------" <$$>
129 bindingOf h False <+> colon <+> align (prettyG bnd ty)
131 prettyAssumptions env =
132 if length env == 0 then
135 text "---------- Assumptions: ----------" <>
136 nest nestingSize (prettyPs [] $ reverse env)
138 prettyOtherGoals hs =
139 if length hs == 0 then
142 text "---------- Other goals: ----------" <$$>
143 nest nestingSize (align . cat . punctuate (text ",") . map (flip bindingOf False) $ hs)
145lifte :: ElabState [PDecl] -> ElabD a -> Idris a
146lifte st e = do (v, _) <- elabStep st e
149receiveInput :: ElabState [PDecl] -> Idris (Maybe String)
153 (sexp, id) <- case parseMessage l of
154 Left err -> ierror err
155 Right (sexp, id) -> return (sexp, id)
156 putIState $ i { idris_outputmode = (IdeSlave id) }
157 case sexpToCommand sexp of
158 Just (REPLCompletions prefix) ->
159 do (unused, compls) <- proverCompletion (assumptionNames e) (reverse prefix, "")
160 let good = SexpList [SymbolAtom "ok", toSExp (map replacement compls, reverse unused)]
161 ideslavePutSExp "return" good
163 Just (Interpret cmd) -> return (Just cmd)
164 Nothing -> return Nothing
166ploop :: Name -> Bool -> String -> [String] -> ElabState [PDecl] -> Maybe History -> Idris (Term, [String])
167ploop fn d prompt prf e h
169 let autoSolve = opt_autoSolve (idris_options i)
170 when d $ dumpState i (proof e)
172 case idris_outputmode i of
173 RawOutput -> runInputT (proverSettings e) $
174 -- Manually track the history so that we can use the proof state
176 Just history -> putHistory history
178 l <- getInputLine (prompt ++ "> ")
185 (cmd, step) <- case x of
186 Nothing -> do iPrintError ""; ifail "Abandoned"
187 Just input -> do return (parseTactic i input, input)
189 Success Abandon -> do iPrintError ""; ifail "Abandoned"
191 (d, st, done, prf') <- idrisCatch
193 Failure err -> do iPrintError (show err)
194 return (False, e, False, prf)
195 Success Undo -> do (_, st) <- elabStep e loadState
197 return (True, st, False, init prf)
198 Success ProofState -> do iPrintResult ""
199 return (True, e, False, prf)
200 Success ProofTerm -> do tm <- lifte e get_term
201 iPrintResult $ "TT: " ++ show tm ++ "\n"
202 return (False, e, False, prf)
203 Success Qed -> do hs <- lifte e get_holes
204 when (not (null hs)) $ ifail "Incomplete proof"
205 iPrintResult "Proof completed!"
206 return (False, e, True, prf)
207 Success (TCheck (PRef _ n)) ->
208 do ctxt <- getContext
212 let h = idris_outh ist
213 OK env = envAtFocus (proof e)
214 ctxt' = envCtxt env ctxt
215 bnd = map (\x -> (fst x, False)) env
216 ist' = ist { tt_ctxt = ctxt' }
218 -- Unlike the REPL, metavars have no special treatment, to
219 -- make it easier to see how to prove with them.
220 case lookupNames n ctxt' of
221 [] -> ihPrintError h $ "No such variable " ++ show n
222 ts -> ihPrintFunTypes h bnd n (map (\n -> (n, delabTy ist' n)) ts)
224 return (False, e, False, prf))
225 (\err -> do putIState ist ; ierror err)
226 Success (TCheck t) ->
230 let OK env = envAtFocus (proof e)
231 ctxt' = envCtxt env ctxt
232 putIState ist { tt_ctxt = ctxt' }
233 (tm, ty) <- elabVal toplevel False t
234 let imp = opt_showimp (idris_options ist)
235 ty' = normaliseC ctxt [] ty
239 ihPrintTermWithType h (prettyImp imp PType) type1Doc
240 _ -> let bnd = map (\x -> (fst x, False)) env in
241 ihPrintTermWithType h (pprintPTerm imp bnd [] (delab ist tm))
242 (pprintPTerm imp bnd [] (delab ist ty))
244 return (False, e, False, prf))
245 (\err -> do putIState ist { tt_ctxt = ctxt } ; ierror err)
246 Success (TEval t) -> withErrorReflection $
247 do ctxt <- getContext
250 let OK env = envAtFocus (proof e)
251 ctxt' = envCtxt env ctxt
252 ist' = ist { tt_ctxt = ctxt' }
253 bnd = map (\x -> (fst x, False)) env
255 (tm, ty) <- elabVal toplevel False t
256 let tm' = force (normaliseAll ctxt' env tm)
257 ty' = force (normaliseAll ctxt' env ty)
258 imp = opt_showimp (idris_options ist')
259 tmDoc = pprintPTerm imp bnd [] (delab ist' tm')
260 tyDoc = pprintPTerm imp bnd [] (delab ist' ty')
261 ihPrintTermWithType (idris_outh ist') tmDoc tyDoc
263 return (False, e, False, prf))
264 (\err -> do putIState ist ; ierror err)
265 Success tac -> do (_, e) <- elabStep e saveState
266 (_, st) <- elabStep e (runTac autoSolve i fn tac)
267-- trace (show (problems (proof st))) $
269 return (True, st, False, prf ++ [step]))
270 (\err -> do iPrintError (pshow i err)
271 return (False, e, False, prf))
272 ideslavePutSExp "write-proof-state" (prf', length prf')
273 if done then do (tm, _) <- elabStep st get_term
275 else ploop fn d prompt prf' st h'
276 where envCtxt env ctxt = foldl (\c (n, b) -> addTyDecl n Bound (binderTy b) c) ctxt env
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