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)
89elabStep :: ElabState [PDecl] -> ElabD a -> Idris (a, ElabState [PDecl])
90elabStep st e = case runStateT eCheck st of
91 OK (a, st') -> return (a, st')
93 where eCheck = do res <- e
96 lift $ check ctxt [] (forget tm)
99dumpState :: IState -> ProofState -> Idris ()
100dumpState ist (PS nm [] _ _ tm _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) =
101 do rendered <- iRender $ prettyName False [] nm <> colon <+> text "No more goals."
103dumpState ist ps@(PS nm (h:hs) _ _ tm _ _ _ _ _ _ problems i _ _ ctxy _ _ _ _) = do
104 let OK ty = goalAtFocus ps
105 let OK env = envAtFocus ps
106 let state = prettyOtherGoals hs <> line <>
107 prettyAssumptions env <> line <>
108 prettyGoal (zip (assumptionNames env) (repeat False)) ty
109 rendered <- iRender state
113 showImplicits = opt_showimp (idris_options ist)
115 tPretty bnd t = pprintPTerm showImplicits bnd [] $ delab ist t
117 assumptionNames :: Env -> [Name]
118 assumptionNames = map fst
120 prettyPs :: [(Name, Bool)] -> Env -> Doc OutputAnnotation
121 prettyPs bnd [] = empty
122 prettyPs bnd ((n@(MN _ r), _) : bs)
123 | r == txt "rewrite_rule" = prettyPs ((n, False):bnd) bs
124 prettyPs bnd ((n, Let t v) : bs) =
125 nest nestingSize (bindingOf n False <+> text "=" <+> tPretty bnd v <> colon <+>
126 tPretty ((n, False):bnd) t <> line <> prettyPs ((n, False):bnd) bs)
127 prettyPs bnd ((n, b) : bs) =
128 line <> bindingOf n False <+> colon <+> align (tPretty bnd (binderTy b)) <> prettyPs ((n, False):bnd) bs
130 prettyG bnd (Guess t v) = tPretty bnd t <+> text "=?=" <+> tPretty bnd v
131 prettyG bnd b = tPretty bnd $ binderTy b
134 text "---------- Goal: ----------" <$$>
135 bindingOf h False <+> colon <+> align (prettyG bnd ty)
137 prettyAssumptions env =
138 if length env == 0 then
141 text "---------- Assumptions: ----------" <>
142 nest nestingSize (prettyPs [] $ reverse env)
144 prettyOtherGoals hs =
145 if length hs == 0 then
148 text "---------- Other goals: ----------" <$$>
149 nest nestingSize (align . cat . punctuate (text ",") . map (flip bindingOf False) $ hs)
151lifte :: ElabState [PDecl] -> ElabD a -> Idris a
152lifte st e = do (v, _) <- elabStep st e
155receiveInput :: ElabState [PDecl] -> Idris (Maybe String)
159 (sexp, id) <- case parseMessage l of
160 Left err -> ierror err
161 Right (sexp, id) -> return (sexp, id)
162 putIState $ i { idris_outputmode = (IdeSlave id) }
163 case sexpToCommand sexp of
164 Just (REPLCompletions prefix) ->
165 do (unused, compls) <- proverCompletion (assumptionNames e) (reverse prefix, "")
166 let good = SexpList [SymbolAtom "ok", toSExp (map replacement compls, reverse unused)]
167 ideslavePutSExp "return" good
169 Just (Interpret cmd) -> return (Just cmd)
170 Nothing -> return Nothing
172ploop :: Name -> Bool -> String -> [String] -> ElabState [PDecl] -> Maybe History -> Idris (Term, [String])
173ploop fn d prompt prf e h
175 let autoSolve = opt_autoSolve (idris_options i)
176 when d $ dumpState i (proof e)
178 case idris_outputmode i of
179 RawOutput -> runInputT (proverSettings e) $
180 -- Manually track the history so that we can use the proof state
182 Just history -> putHistory history
184 l <- getInputLine (prompt ++ "> ")
191 (cmd, step) <- case x of
192 Nothing -> do iPrintError ""; ifail "Abandoned"
193 Just input -> do return (parseTactic i input, input)
195 Success Abandon -> do iPrintError ""; ifail "Abandoned"
197 (d, st, done, prf') <- idrisCatch
199 Failure err -> do iPrintError (show err)
200 return (False, e, False, prf)
201 Success Undo -> do (_, st) <- elabStep e loadState
203 return (True, st, False, init prf)
204 Success ProofState -> do iPrintResult ""
205 return (True, e, False, prf)
206 Success ProofTerm -> do tm <- lifte e get_term
207 iPrintResult $ "TT: " ++ show tm ++ "\n"
208 return (False, e, False, prf)
209 Success Qed -> do hs <- lifte e get_holes
210 when (not (null hs)) $ ifail "Incomplete proof"
211 iPrintResult "Proof completed!"
212 return (False, e, True, prf)
213 Success (TCheck (PRef _ n)) ->
214 do ctxt <- getContext
218 let h = idris_outh ist
219 OK env = envAtFocus (proof e)
220 ctxt' = envCtxt env ctxt
221 bnd = map (\x -> (fst x, False)) env
222 ist' = ist { tt_ctxt = ctxt' }
224 -- Unlike the REPL, metavars have no special treatment, to
225 -- make it easier to see how to prove with them.
226 case lookupNames n ctxt' of
227 [] -> ihPrintError h $ "No such variable " ++ show n
228 ts -> ihPrintFunTypes h bnd n (map (\n -> (n, delabTy ist' n)) ts)
230 return (False, e, False, prf))
231 (\err -> do putIState ist ; ierror err)
232 Success (TCheck t) ->
236 let OK env = envAtFocus (proof e)
237 ctxt' = envCtxt env ctxt
238 putIState ist { tt_ctxt = ctxt' }
239 (tm, ty) <- elabVal toplevel False t
240 let imp = opt_showimp (idris_options ist)
241 ty' = normaliseC ctxt [] ty
245 ihPrintTermWithType h (prettyImp imp PType) type1Doc
246 _ -> let bnd = map (\x -> (fst x, False)) env in
247 ihPrintTermWithType h (pprintPTerm imp bnd [] (delab ist tm))
248 (pprintPTerm imp bnd [] (delab ist ty))
250 return (False, e, False, prf))
251 (\err -> do putIState ist { tt_ctxt = ctxt } ; ierror err)
252 Success (TEval t) -> withErrorReflection $
253 do ctxt <- getContext
256 let OK env = envAtFocus (proof e)
257 ctxt' = envCtxt env ctxt
258 ist' = ist { tt_ctxt = ctxt' }
259 bnd = map (\x -> (fst x, False)) env
261 (tm, ty) <- elabVal toplevel False t
262 let tm' = force (normaliseAll ctxt' env tm)
263 ty' = force (normaliseAll ctxt' env ty)
264 imp = opt_showimp (idris_options ist')
265 tmDoc = pprintPTerm imp bnd [] (delab ist' tm')
266 tyDoc = pprintPTerm imp bnd [] (delab ist' ty')
267 ihPrintTermWithType (idris_outh ist') tmDoc tyDoc
269 return (False, e, False, prf))
270 (\err -> do putIState ist ; ierror err)
271 Success tac -> do (_, e) <- elabStep e saveState
272 (_, st) <- elabStep e (runTac autoSolve i fn tac)
273-- trace (show (problems (proof st))) $
275 return (True, st, False, prf ++ [step]))
276 (\err -> do iPrintError (pshow i err)
277 return (False, e, False, prf))
278 ideslavePutSExp "write-proof-state" (prf', length prf')
279 if done then do (tm, _) <- elabStep st get_term
281 else ploop fn d prompt prf' st h'
282 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