1module Idris.Prover where
3import Idris.Core.Elaborate hiding (Tactic(..))
5import Idris.Core.Evaluate
6import Idris.Core.CaseTree
7import Idris.Core.Typecheck
10import Idris.Delaborate
16import Idris.Completion
19import Text.Trifecta.Result(Result(..))
21import System.Console.Haskeline
22import System.Console.Haskeline.History
23import Control.Monad.State.Strict
28prover :: Bool -> Name -> Idris ()
32 case lookupTy x ctxt of
33 [t] -> if elem x (map fst (idris_metavars i))
34 then prove ctxt lit x t
35 else ifail $ show x ++ " is not a metavariable"
36 _ -> fail "No such metavariable"
38showProof :: Bool -> Name -> [String] -> String
40 = bird ++ show n ++ " = proof" ++ break ++
41 showSep break (map (\x -> " " ++ x) ps) ++
43 where bird = if lit then "> " else ""
46proverSettings :: ElabState [PDecl] -> Settings Idris
47proverSettings e = setComplete (proverCompletion (assumptionNames e)) defaultSettings
49assumptionNames :: ElabState [PDecl] -> [String]
51 = case envAtFocus (proof e) of
54 names ((MN _ _, _) : bs) = names bs
55 names ((n, _) : bs) = show n : names bs
57prove :: Context -> Bool -> Name -> Type -> Idris ()
59 = do let ps = initElaborator n ctxt ty
60 ideslavePutSExp "start-proof-mode" n
61 (tm, prf) <- ploop True ("-" ++ show n) [] (ES (ps, []) "" Nothing) Nothing
62 iLOG $ "Adding " ++ show tm
63 iputStrLn $ showProof lit n prf
65 ideslavePutSExp "end-proof-mode" n
66 let proofs = proof_list i
67 putIState (i { proof_list = (n, prf) : proofs })
68 let tree = simpleCase False True False CompileTime (fileFC "proof") [] [([], P Ref n ty, tm)]
70 (ptm, pty) <- recheckC (fileFC "proof") [] tm
71 logLvl 5 ("Proof type: " ++ show pty ++ "\n" ++
72 "Expected type:" ++ show ty)
73 case converts ctxt [] ty pty of
75 Error e -> ierror (CantUnify False ty pty e [] 0)
77 updateContext (addCasedef n (CaseInfo True False) False False True False
79 [Right (P Ref n ty, ptm)]
80 [([], P Ref n ty, ptm)]
81 [([], P Ref n ty, ptm)]
82 [([], P Ref n ty, ptm)]
83 [([], P Ref n ty, ptm')] ty)
85elabStep :: ElabState [PDecl] -> ElabD a -> Idris (a, ElabState [PDecl])
86elabStep st e = do case runStateT e st of
87 OK (a, st') -> return (a, st')
90dumpState :: IState -> ProofState -> Idris ()
91dumpState ist (PS nm [] _ _ tm _ _ _ _ _ _ _ _ _ _ _ _ _ _) =
92 iputGoal . render $ pretty nm <> colon <+> text "No more goals."
93dumpState ist ps@(PS nm (h:hs) _ _ tm _ _ _ _ _ _ problems i _ _ ctxy _ _ _) = do
94 let OK ty = goalAtFocus ps
95 let OK env = envAtFocus ps
97 prettyOtherGoals hs $$
98 prettyAssumptions env $$
102 tPretty t = pretty $ delab ist t
105 prettyPs ((MN _ r, _) : bs)
106 | r == txt "rewrite_rule" = prettyPs bs
107 prettyPs ((n, Let t v) : bs) =
108 nest nestingSize (pretty n <+> text "=" <+> tPretty v <> colon <+>
109 tPretty t $$ prettyPs bs)
110 prettyPs ((n, b) : bs) =
111 pretty n <+> colon <+> tPretty (binderTy b) $$ prettyPs bs
113 prettyG (Guess t v) = tPretty t <+> text "=?=" <+> tPretty v
114 prettyG b = tPretty $ binderTy b
117 text "---------- Goal: ----------" $$
118 pretty h <> colon $$ nest nestingSize (prettyG ty)
120 prettyAssumptions env =
121 if length env == 0 then
124 text "---------- Assumptions: ----------" $$
125 nest nestingSize (prettyPs $ reverse env)
127 prettyOtherGoals hs =
128 if length hs == 0 then
131 text "---------- Other goals: ----------" $$
134lifte :: ElabState [PDecl] -> ElabD a -> Idris a
135lifte st e = do (v, _) <- elabStep st e
138receiveInput :: ElabState [PDecl] -> Idris (Maybe String)
142 (sexp, id) <- case parseMessage l of
143 Left err -> ierror err
144 Right (sexp, id) -> return (sexp, id)
145 putIState $ i { idris_outputmode = (IdeSlave id) }
146 case sexpToCommand sexp of
147 Just (REPLCompletions prefix) ->
148 do (unused, compls) <- proverCompletion (assumptionNames e) (reverse prefix, "")
149 let good = SexpList [SymbolAtom "ok", toSExp (map replacement compls, reverse unused)]
150 ideslavePutSExp "return" good
152 Just (Interpret cmd) -> return (Just cmd)
153 Nothing -> return Nothing
155ploop :: Bool -> String -> [String] -> ElabState [PDecl] -> Maybe History -> Idris (Term, [String])
156ploop d prompt prf e h
158 when d $ dumpState i (proof e)
160 case idris_outputmode i of
161 RawOutput -> runInputT (proverSettings e) $
162 -- Manually track the history so that we can use the proof state
164 Just history -> putHistory history
166 l <- getInputLine (prompt ++ "> ")
173 (cmd, step) <- case x of
174 Nothing -> do iPrintError ""; fail "Abandoned"
175 Just input -> do return (parseTactic i input, input)
177 Success Abandon -> do iPrintError ""; fail "Abandoned"
179 (d, st, done, prf') <- idrisCatch
181 Failure err -> do iPrintError (show err)
182 return (False, e, False, prf)
183 Success Undo -> do (_, st) <- elabStep e loadState
185 return (True, st, False, init prf)
186 Success ProofState -> do iPrintResult ""
187 return (True, e, False, prf)
188 Success ProofTerm -> do tm <- lifte e get_term
189 iPrintResult $ "TT: " ++ show tm ++ "\n"
190 return (False, e, False, prf)
191 Success Qed -> do hs <- lifte e get_holes
192 when (not (null hs)) $ ifail "Incomplete proof"
193 iPrintResult "Proof completed!"
194 return (False, e, True, prf)
195 Success tac -> do (_, e) <- elabStep e saveState
196 (_, st) <- elabStep e (runTac True i tac)
197-- trace (show (problems (proof st))) $
199 return (True, st, False, prf ++ [step]))
200 (\err -> do iPrintError (pshow i err)
201 return (False, e, False, prf))
202 ideslavePutSExp "write-proof-state" (prf', length prf')
203 if done then do (tm, _) <- elabStep st get_term
205 else ploop d prompt prf' st h'
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