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 . renderPretty 0.7 breakingSize $
93 prettyName False [] nm <> colon <+> text "No more goals."
94dumpState ist ps@(PS nm (h:hs) _ _ tm _ _ _ _ _ _ problems i _ _ ctxy _ _ _) = do
95 let OK ty = goalAtFocus ps
96 let OK env = envAtFocus ps
97 iputGoal . renderPretty 0.7 breakingSize $
98 prettyOtherGoals hs <> line <>
99 prettyAssumptions env <> line <>
100 prettyGoal (zip (assumptionNames env) (repeat False)) ty
103 tPretty bnd t = pprintPTerm True bnd $ delab ist t
105 assumptionNames :: Env -> [Name]
106 assumptionNames = map fst
108 prettyPs :: [(Name, Bool)] -> Env -> Doc OutputAnnotation
109 prettyPs bnd [] = empty
110 prettyPs bnd ((n@(MN _ r), _) : bs)
111 | r == txt "rewrite_rule" = prettyPs ((n, False):bnd) bs
112 prettyPs bnd ((n, Let t v) : bs) =
113 nest nestingSize (bindingOf n False <+> text "=" <+> tPretty bnd v <> colon <+>
114 tPretty ((n, False):bnd) t <> line <> prettyPs ((n, False):bnd) bs)
115 prettyPs bnd ((n, b) : bs) =
116 line <> bindingOf n False <+> colon <+> tPretty bnd (binderTy b) <> prettyPs ((n, False):bnd) bs
118 prettyG bnd (Guess t v) = tPretty bnd t <+> text "=?=" <+> tPretty bnd v
119 prettyG bnd b = tPretty bnd $ binderTy b
122 text "---------- Goal: ----------" <$$>
123 bindingOf h False <+> colon <+> nest nestingSize (prettyG bnd ty)
125 prettyAssumptions env =
126 if length env == 0 then
129 text "---------- Assumptions: ----------" <>
130 nest nestingSize (prettyPs [] $ reverse env)
132 prettyOtherGoals hs =
133 if length hs == 0 then
136 text "---------- Other goals: ----------" <$$>
137 nest nestingSize (align . cat . punctuate (text ",") . map (flip bindingOf False) $ hs)
139lifte :: ElabState [PDecl] -> ElabD a -> Idris a
140lifte st e = do (v, _) <- elabStep st e
143receiveInput :: ElabState [PDecl] -> Idris (Maybe String)
147 (sexp, id) <- case parseMessage l of
148 Left err -> ierror err
149 Right (sexp, id) -> return (sexp, id)
150 putIState $ i { idris_outputmode = (IdeSlave id) }
151 case sexpToCommand sexp of
152 Just (REPLCompletions prefix) ->
153 do (unused, compls) <- proverCompletion (assumptionNames e) (reverse prefix, "")
154 let good = SexpList [SymbolAtom "ok", toSExp (map replacement compls, reverse unused)]
155 ideslavePutSExp "return" good
157 Just (Interpret cmd) -> return (Just cmd)
158 Nothing -> return Nothing
160ploop :: Bool -> String -> [String] -> ElabState [PDecl] -> Maybe History -> Idris (Term, [String])
161ploop d prompt prf e h
163 when d $ dumpState i (proof e)
165 case idris_outputmode i of
166 RawOutput -> runInputT (proverSettings e) $
167 -- Manually track the history so that we can use the proof state
169 Just history -> putHistory history
171 l <- getInputLine (prompt ++ "> ")
178 (cmd, step) <- case x of
179 Nothing -> do iPrintError ""; fail "Abandoned"
180 Just input -> do return (parseTactic i input, input)
182 Success Abandon -> do iPrintError ""; fail "Abandoned"
184 (d, st, done, prf') <- idrisCatch
186 Failure err -> do iPrintError (show err)
187 return (False, e, False, prf)
188 Success Undo -> do (_, st) <- elabStep e loadState
190 return (True, st, False, init prf)
191 Success ProofState -> do iPrintResult ""
192 return (True, e, False, prf)
193 Success ProofTerm -> do tm <- lifte e get_term
194 iPrintResult $ "TT: " ++ show tm ++ "\n"
195 return (False, e, False, prf)
196 Success Qed -> do hs <- lifte e get_holes
197 when (not (null hs)) $ ifail "Incomplete proof"
198 iPrintResult "Proof completed!"
199 return (False, e, True, prf)
200 Success tac -> do (_, e) <- elabStep e saveState
201 (_, st) <- elabStep e (runTac True i tac)
202-- trace (show (problems (proof st))) $
204 return (True, st, False, prf ++ [step]))
205 (\err -> do iPrintError (pshow i err)
206 return (False, e, False, prf))
207 ideslavePutSExp "write-proof-state" (prf', length prf')
208 if done then do (tm, _) <- elabStep st get_term
210 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