1{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, PatternGuards #-}
3{- Implements a proof state, some primitive tactics for manipulating
4 proofs, and some high level commands for introducing new theorems,
5 evaluation/checking inside the proof system, etc. --}
7module Core.ProofState(ProofState(..), newProof, envAtFocus, goalAtFocus,
8 Tactic(..), Goal(..), processTactic,
9 dropGiven, keepGiven) where
16import Control.Monad.State
17import Control.Applicative hiding (empty)
23data ProofState = PS { thname :: Name,
24 holes :: [Name], -- holes still to be solved
25 usedns :: [Name], -- used names, don't use again
26 nextname :: Int, -- name supply
27 pterm :: Term, -- current proof term
28 ptype :: Type, -- original goal
29 dontunify :: [Name], -- explicitly given by programmer, leave it
30 unified :: (Name, [(Name, Term)]),
31 notunified :: [(Name, Term)],
32 solved :: Maybe (Name, Term),
35 deferred :: [Name], -- names we'll need to define
36 instances :: [Name], -- instance arguments (for type classes)
37 previous :: Maybe ProofState, -- for undo
44data Goal = GD { premises :: Env,
45 goalType :: Binder Term
54 | PrepFill Name [Name]
65 | IntroTy Raw (Maybe Name)
67 | LetBind Name Raw Raw
73 | DeferType Name Raw [Name]
82-- Some utilites on proof and tactic states
84instance Show ProofState where
85 show (PS nm [] _ _ tm _ _ _ _ _ _ _ _ _ _ _ _ _ _)
86 = show nm ++ ": no more goals"
87 show (PS nm (h:hs) _ _ tm _ _ _ _ _ _ _ i _ _ ctxt _ _ _)
88 = let OK g = goal (Just h) tm
90 "Other goals: " ++ show hs ++ "\n" ++
91 showPs wkenv (reverse wkenv) ++ "\n" ++
92 "-------------------------------- (" ++ show nm ++
94 show h ++ " : " ++ showG wkenv (goalType g) ++ "\n"
95 where showPs env [] = ""
96 showPs env ((n, Let t v):bs)
97 = " " ++ show n ++ " : " ++
98 showEnv env ({- normalise ctxt env -} t) ++ " = " ++
99 showEnv env ({- normalise ctxt env -} v) ++
100 "\n" ++ showPs env bs
101 showPs env ((n, b):bs)
102 = " " ++ show n ++ " : " ++
103 showEnv env ({- normalise ctxt env -} (binderTy b)) ++
104 "\n" ++ showPs env bs
105 showG ps (Guess t v) = showEnv ps ({- normalise ctxt ps -} t) ++
106 " =?= " ++ showEnv ps v
107 showG ps b = showEnv ps (binderTy b)
109instance Pretty ProofState where
110 pretty (PS nm [] _ _ trm _ _ _ _ _ _ _ _ _ _ _ _ _ _) =
111 if size nm > breakingSize then
112 pretty nm <> colon $$ nest nestingSize (text " no more goals.")
114 pretty nm <> colon <+> text " no more goals."
115 pretty p@(PS nm (h:hs) _ _ tm _ _ _ _ _ _ _ i _ _ ctxt _ _ _) =
116 let OK g = goal (Just h) tm in
117 let wkEnv = premises g in
118 text "Other goals" <+> colon <+> pretty hs $$
119 prettyPs wkEnv (reverse wkEnv) $$
120 text "---------- " <+> text "Focussing on" <> colon <+> pretty nm <+> text " ----------" $$
121 pretty h <+> colon <+> prettyGoal wkEnv (goalType g)
123 prettyGoal ps (Guess t v) =
124 if size v > breakingSize then
125 prettyEnv ps t <+> text "=?=" $$
126 nest nestingSize (prettyEnv ps v)
128 prettyEnv ps t <+> text "=?=" <+> prettyEnv ps v
129 prettyGoal ps b = prettyEnv ps $ binderTy b
131 prettyPs env [] = empty
132 prettyPs env ((n, Let t v):bs) =
133 nest nestingSize (pretty n <+> colon <+>
134 if size v > breakingSize then
135 prettyEnv env t <+> text "=" $$
136 nest nestingSize (prettyEnv env v) $$
137 nest nestingSize (prettyPs env bs)
139 prettyEnv env t <+> text "=" <+> prettyEnv env v $$
140 nest nestingSize (prettyPs env bs))
141 prettyPs env ((n, b):bs) =
142 if size (binderTy b) > breakingSize then
143 nest nestingSize (pretty n <+> colon <+> prettyEnv env (binderTy b) <+> prettyPs env bs)
145 nest nestingSize (pretty n <+> colon <+> prettyEnv env (binderTy b) $$
146 nest nestingSize (prettyPs env bs))
149same (Just x) n = x == n
152hole (Guess _ _) = True
155holeName i = MN i "hole"
157qshow :: Fails -> String
158qshow fs = show (map (\ (x, y, _, _) -> (x, y)) fs)
160match_unify' :: Context -> Env -> TT Name -> TT Name ->
161 StateT TState TC [(Name, TT Name)]
162match_unify' ctxt env topx topy =
164 let dont = dontunify ps
165 u <- lift $ match_unify ctxt env topx topy dont (holes ps)
166 let (h, ns) = unified ps
167 put (ps { unified = (h, u ++ ns) })
170unify' :: Context -> Env -> TT Name -> TT Name ->
171 StateT TState TC [(Name, TT Name)]
172unify' ctxt env topx topy =
174 let dont = dontunify ps
175 (u, fails) <- -- trace ("Trying " ++ show (topx, topy)) $
176 lift $ unify ctxt env topx topy dont (holes ps)
177 traceWhen (unifylog ps)
178 ("Unified " ++ show (topx, topy) ++ " without " ++ show dont ++
179 " in " ++ show env ++
180 "\n" ++ show u ++ "\n" ++ qshow fails ++ "\nCurrent problems:\n"
181 ++ qshow (problems ps) ++ "\n" ++ show (holes ps) ++ "\n"
188 let (h, ns) = unified ps
189 let (ns', probs') = updateProblems (context ps) (u ++ ns)
193 put (ps { problems = probs',
194 unified = (h, ns') })
197getName :: Monad m => String -> StateT TState m Name
198getName tag = do ps <- get
200 put (ps { nextname = n+1 })
203action :: Monad m => (ProofState -> ProofState) -> StateT TState m ()
204action a = do ps <- get
207addLog :: Monad m => String -> StateT TState m ()
208addLog str = action (\ps -> ps { plog = plog ps ++ str ++ "\n" })
210newProof :: Name -> Context -> Type -> ProofState
211newProof n ctxt ty = let h = holeName 0
213 PS n [h] [] 1 (Bind h (Hole ty')
214 (P Bound h ty')) ty [] (h, []) []
217 Nothing ctxt "" False False
219type TState = ProofState -- [TacticAction])
220type RunTactic = Context -> Env -> Term -> StateT TState TC Term
221type Hole = Maybe Name -- Nothing = default hole, first in list in proof state
223envAtFocus :: ProofState -> TC Env
225 | not $ null (holes ps) = do g <- goal (Just (head (holes ps))) (pterm ps)
227 | otherwise = fail "No holes"
229goalAtFocus :: ProofState -> TC (Binder Type)
231 | not $ null (holes ps) = do g <- goal (Just (head (holes ps))) (pterm ps)
233 | otherwise = error $ "No goal in " ++ show (holes ps) ++ show (pterm ps)
235goal :: Hole -> Term -> TC Goal
236goal h tm = g [] tm where
237 g env (Bind n b sc) | hole b && same h n = return $ GD env b
239 = gb env b `mplus` g ((n, b):env) sc
240 g env (App f a) = g env f `mplus` g env a
241 g env t = fail "Can't find hole"
243 gb env (Let t v) = g env t `mplus` g env v
244 gb env (Guess t v) = g env t `mplus` g env v
245 gb env t = g env (binderTy t)
247tactic :: Hole -> RunTactic -> StateT TState TC ()
248tactic h f = do ps <- get
249 tm' <- atH (context ps) [] (pterm ps)
250 ps <- get -- might have changed while processing
251 put (ps { pterm = tm' })
253 atH c env binder@(Bind n b sc)
254 | hole b && same h n = f c env binder
256 = liftM2 (Bind n) (atHb c env b) (atH c ((n, b) : env) sc)
257 atH c env (App f a) = liftM2 App (atH c env f) (atH c env a)
258 atH c env t = return t
260 atHb c env (Let t v) = liftM2 Let (atH c env t) (atH c env v)
261 atHb c env (Guess t v) = liftM2 Guess (atH c env t) (atH c env v)
262 atHb c env t = do ty' <- atH c env (binderTy t)
263 return $ t { binderTy = ty' }
266attack ctxt env (Bind x (Hole t) sc)
267 = do h <- getName "hole"
268 action (\ps -> ps { holes = h : holes ps })
269 return $ Bind x (Guess t (newtm h)) sc
271 newtm h = Bind h (Hole t) (P Bound h t)
272attack ctxt env _ = fail "Not an attackable hole"
274claim :: Name -> Raw -> RunTactic
275claim n ty ctxt env t =
276 do (tyv, tyt) <- lift $ check ctxt env ty
277 lift $ isType ctxt env tyt
278 action (\ps -> let (g:gs) = holes ps in
279 ps { holes = g : n : gs } )
280 return $ Bind n (Hole tyv) t -- (weakenTm 1 t)
282reorder_claims :: RunTactic
283reorder_claims ctxt env t
284 = -- trace (showSep "\n" (map show (scvs t))) $
285 let (bs, sc) = scvs t []
286 newbs = reverse (sortB (reverse bs)) in
287 traceWhen (bs /= newbs) (show bs ++ "\n ==> \n" ++ show newbs) $
288 return (bindAll newbs sc)
289 where scvs (Bind n b@(Hole _) sc) acc = scvs sc ((n, b):acc)
290 scvs sc acc = (reverse acc, sc)
292 sortB :: [(Name, Binder (TT Name))] -> [(Name, Binder (TT Name))]
294 sortB (x:xs) | all (noOcc x) xs = x : sortB xs
295 | otherwise = sortB (insertB x xs)
298 insertB x (y:ys) | all (noOcc x) (y:ys) = x : y : ys
299 | otherwise = y : insertB x ys
301 noOcc (n, _) (_, Let t v) = noOccurrence n t && noOccurrence n v
302 noOcc (n, _) (_, Guess t v) = noOccurrence n t && noOccurrence n v
303 noOcc (n, _) (_, b) = noOccurrence n (binderTy b)
305focus :: Name -> RunTactic
306focus n ctxt env t = do action (\ps -> let hs = holes ps in
308 then ps { holes = n : (hs \\ [n]) }
313movelast :: Name -> RunTactic
314movelast n ctxt env t = do action (\ps -> let hs = holes ps in
316 then ps { holes = (hs \\ [n]) ++ [n] }
320instanceArg :: Name -> RunTactic
321instanceArg n ctxt env (Bind x (Hole t) sc)
322 = do action (\ps -> let hs = holes ps
324 ps { holes = (hs \\ [x]) ++ [x],
326 return (Bind x (Hole t) sc)
328setinj :: Name -> RunTactic
329setinj n ctxt env (Bind x (Hole t) sc)
330 = do action (\ps -> let is = injective ps in
331 ps { injective = n : is })
332 return (Bind x (Hole t) sc)
334defer :: Name -> RunTactic
335defer n ctxt env (Bind x (Hole t) (P nt x' ty)) | x == x' =
336 do action (\ps -> let hs = holes ps in
337 ps { holes = hs \\ [x] })
338 return (Bind n (GHole (mkTy (reverse env) t))
339 (mkApp (P Ref n ty) (map getP (reverse env))))
342 mkTy ((n,b) : bs) t = Bind n (Pi (binderTy b)) (mkTy bs t)
344 getP (n, b) = P Bound n (binderTy b)
346-- as defer, but build the type and application explicitly
347deferType :: Name -> Raw -> [Name] -> RunTactic
348deferType n fty_in args ctxt env (Bind x (Hole t) (P nt x' ty)) | x == x' =
349 do (fty, _) <- lift $ check ctxt env fty_in
350 action (\ps -> let hs = holes ps
352 ps { holes = hs \\ [x],
354 return (Bind n (GHole fty)
355 (mkApp (P Ref n ty) (map getP args)))
357 getP n = case lookup n env of
358 Just b -> P Bound n (binderTy b)
359 Nothing -> error ("deferType can't find " ++ show n)
362regret ctxt env (Bind x (Hole t) sc) | noOccurrence x sc =
363 do action (\ps -> let hs = holes ps in
364 ps { holes = hs \\ [x] })
366regret ctxt env (Bind x (Hole t) _) = fail $ show x ++ " : " ++ show t ++ " is not solved"
368exact :: Raw -> RunTactic
369exact guess ctxt env (Bind x (Hole ty) sc) =
370 do (val, valty) <- lift $ check ctxt env guess
371 lift $ converts ctxt env valty ty
372 return $ Bind x (Guess ty val) sc
373exact _ _ _ _ = fail "Can't fill here."
375-- As exact, but attempts to solve other goals by unification
377fill :: Raw -> RunTactic
378fill guess ctxt env (Bind x (Hole ty) sc) =
379 do (val, valty) <- lift $ check ctxt env guess
380-- let valtyn = normalise ctxt env valty
381-- let tyn = normalise ctxt env ty
382 ns <- unify' ctxt env valty ty
384 let (uh, uns) = unified ps
385-- put (ps { unified = (uh, uns ++ ns) })
386-- addLog (show (uh, uns ++ ns))
387 return $ Bind x (Guess ty val) sc
388fill _ _ _ _ = fail "Can't fill here."
390-- As fill, but attempts to solve other goals by matching
392match_fill :: Raw -> RunTactic
393match_fill guess ctxt env (Bind x (Hole ty) sc) =
394 do (val, valty) <- lift $ check ctxt env guess
395-- let valtyn = normalise ctxt env valty
396-- let tyn = normalise ctxt env ty
397 ns <- match_unify' ctxt env valty ty
399 let (uh, uns) = unified ps
400-- put (ps { unified = (uh, uns ++ ns) })
401-- addLog (show (uh, uns ++ ns))
402 return $ Bind x (Guess ty val) sc
403match_fill _ _ _ _ = fail "Can't fill here."
405prep_fill :: Name -> [Name] -> RunTactic
406prep_fill f as ctxt env (Bind x (Hole ty) sc) =
407 do let val = mkApp (P Ref f Erased) (map (\n -> P Ref n Erased) as)
408 return $ Bind x (Guess ty val) sc
409prep_fill f as ctxt env t = fail $ "Can't prepare fill at " ++ show t
411complete_fill :: RunTactic
412complete_fill ctxt env (Bind x (Guess ty val) sc) =
413 do let guess = forget val
414 (val', valty) <- lift $ check ctxt env guess
415 ns <- unify' ctxt env valty ty
417 let (uh, uns) = unified ps
418-- put (ps { unified = (uh, uns ++ ns) })
419 return $ Bind x (Guess ty val) sc
420complete_fill ctxt env t = fail $ "Can't complete fill at " ++ show t
422-- When solving something in the 'dont unify' set, we should check
423-- that the guess we are solving it with unifies with the thing unification
424-- found for it, if anything.
427solve ctxt env (Bind x (Guess ty val) sc)
428 | True = do ps <- get
429 let (uh, uns) = unified ps
430 case lookup x (notunified ps) of
431 Just tm -> do -- trace ("AVOIDED " ++ show (x, tm, val)) $
433 unify' ctxt env tm val
435 action (\ps -> ps { holes = holes ps \\ [x],
436 solved = Just (x, val),
437-- problems = solveInProblems
438-- x val (problems ps),
439 -- dontunify = dontunify ps \\ [x],
440 -- unified = (uh, uns ++ [(x, val)]),
441 instances = instances ps \\ [x] })
442 return $ {- Bind x (Let ty val) sc -}
443 instantiate val (pToV x sc)
444 | otherwise = lift $ tfail $ IncompleteTerm val
445solve _ _ h@(Bind x t sc)
447 fail $ "Not a guess " ++ show h ++ "\n" ++ show (holes ps, pterm ps)
449introTy :: Raw -> Maybe Name -> RunTactic
450introTy ty mn ctxt env (Bind x (Hole t) (P _ x' _)) | x == x' =
451 do let n = case mn of
455 x@(Bind y (Pi s) _) -> x
457 (tyv, tyt) <- lift $ check ctxt env ty
458-- ns <- lift $ unify ctxt env tyv t'
460 Bind y (Pi s) t -> let t' = instantiate (P Bound n s) (pToV y t) in
461 do ns <- unify' ctxt env s tyv
463 let (uh, uns) = unified ps
464-- put (ps { unified = (uh, uns ++ ns) })
465 return $ Bind n (Lam tyv) (Bind x (Hole t') (P Bound x t'))
466 _ -> lift $ tfail $ CantIntroduce t'
467introTy ty n ctxt env _ = fail "Can't introduce here."
469intro :: Maybe Name -> RunTactic
470intro mn ctxt env (Bind x (Hole t) (P _ x' _)) | x == x' =
471 do let n = case mn of
475 x@(Bind y (Pi s) _) -> x
478 Bind y (Pi s) t -> -- trace ("in type " ++ show t') $
479 let t' = instantiate (P Bound n s) (pToV y t) in
480 return $ Bind n (Lam s) (Bind x (Hole t') (P Bound x t'))
481 _ -> lift $ tfail $ CantIntroduce t'
482intro n ctxt env _ = fail "Can't introduce here."
484forall :: Name -> Raw -> RunTactic
485forall n ty ctxt env (Bind x (Hole t) (P _ x' _)) | x == x' =
486 do (tyv, tyt) <- lift $ check ctxt env ty
487 unify' ctxt env tyt (TType (UVar 0))
488 return $ Bind n (Pi tyv) (Bind x (Hole t) (P Bound x t))
489forall n ty ctxt env _ = fail "Can't pi bind here"
491patvar :: Name -> RunTactic
492patvar n ctxt env (Bind x (Hole t) sc) =
493 do action (\ps -> ps { holes = holes ps \\ [x] })
494 return $ Bind n (PVar t) (instantiate (P Bound n t) (pToV x sc))
495patvar n ctxt env tm = fail $ "Can't add pattern var at " ++ show tm
497letbind :: Name -> Raw -> Raw -> RunTactic
498letbind n ty val ctxt env (Bind x (Hole t) (P _ x' _)) | x == x' =
499 do (tyv, tyt) <- lift $ check ctxt env ty
500 (valv, valt) <- lift $ check ctxt env val
501 lift $ isType ctxt env tyt
502 return $ Bind n (Let tyv valv) (Bind x (Hole t) (P Bound x t))
503letbind n ty val ctxt env _ = fail "Can't let bind here"
505rewrite :: Raw -> RunTactic
506rewrite tm ctxt env (Bind x (Hole t) xp@(P _ x' _)) | x == x' =
507 do (tmv, tmt) <- lift $ check ctxt env tm
508 let tmt' = normalise ctxt env tmt
510 (P _ (UN "=") _, [lt,rt,l,r]) ->
511 do let p = Bind rname (Lam lt) (mkP (P Bound rname lt) r l t)
512 let newt = mkP l r l t
513 let sc = forget $ (Bind x (Hole newt)
514 (mkApp (P Ref (UN "replace") (TType (UVal 0)))
515 [lt, l, r, p, tmv, xp]))
516 (scv, sct) <- lift $ check ctxt env sc
518 _ -> fail "Not an equality type"
520 -- to make the P for rewrite, replace syntactic occurrences of l in ty with
521 -- an x, and put \x : lt in front
522 mkP lt l r ty | l == ty = lt
523 mkP lt l r (App f a) = let f' = if (r /= f) then mkP lt l r f else f
524 a' = if (r /= a) then mkP lt l r a else a in
526 mkP lt l r (Bind n b sc)
528 sc' = if (r /= sc) then mkP lt l r sc else sc in
530 where mkPB (Let t v) = let t' = if (r /= t) then mkP lt l r t else t
531 v' = if (r /= v) then mkP lt l r v else v in
533 mkPB b = let ty = binderTy b
534 ty' = if (r /= ty) then mkP lt l r ty else ty in
538 rname = MN 0 "replaced"
539rewrite _ _ _ _ = fail "Can't rewrite here"
541patbind :: Name -> RunTactic
542patbind n ctxt env (Bind x (Hole t) (P _ x' _)) | x == x' =
543 do let t' = case t of
544 x@(Bind y (PVTy s) t) -> x
547 Bind y (PVTy s) t -> let t' = instantiate (P Bound n s) (pToV y t) in
548 return $ Bind n (PVar s) (Bind x (Hole t') (P Bound x t'))
549 _ -> fail "Nothing to pattern bind"
550patbind n ctxt env _ = fail "Can't pattern bind here"
553compute ctxt env (Bind x (Hole ty) sc) =
554 do return $ Bind x (Hole (normalise ctxt env ty)) sc
555compute ctxt env t = return t
557hnf_compute :: RunTactic
558hnf_compute ctxt env (Bind x (Hole ty) sc) =
559 do let ty' = hnf ctxt env ty in
560-- trace ("HNF " ++ show (ty, ty')) $
561 return $ Bind x (Hole ty') sc
562hnf_compute ctxt env t = return t
564check_in :: Raw -> RunTactic
565check_in t ctxt env tm =
566 do (val, valty) <- lift $ check ctxt env t
567 addLog (showEnv env val ++ " : " ++ showEnv env valty)
570eval_in :: Raw -> RunTactic
571eval_in t ctxt env tm =
572 do (val, valty) <- lift $ check ctxt env t
573 let val' = normalise ctxt env val
574 let valty' = normalise ctxt env valty
575 addLog (showEnv env val ++ " : " ++
577-- " in " ++ show env ++
579 showEnv env val' ++ " : " ++
583start_unify :: Name -> RunTactic
584start_unify n ctxt env tm = do -- action (\ps -> ps { unified = (n, []) })
587tmap f (a, b, c) = (f a, b, c)
589solve_unified :: RunTactic
590solve_unified ctxt env tm =
592 let (_, ns) = unified ps
593 let unify = dropGiven (dontunify ps) ns (holes ps)
594 action (\ps -> ps { holes = holes ps \\ map fst unify })
595 action (\ps -> ps { pterm = updateSolved unify (pterm ps) })
596 return (updateSolved unify tm)
599dropGiven du [] hs = []
600dropGiven du ((n, P Bound t ty) : us) hs
601 | n `elem` du && not (t `elem` du)
602 && n `elem` hs && t `elem` hs
603 = (t, P Bound n ty) : dropGiven du us hs
604dropGiven du (u@(n, _) : us) hs
605 | n `elem` du = dropGiven du us hs
606-- dropGiven du (u@(_, P a n ty) : us) | n `elem` du = dropGiven du us
607dropGiven du (u : us) hs = u : dropGiven du us hs
609keepGiven du [] hs = []
610keepGiven du ((n, P Bound t ty) : us) hs
611 | n `elem` du && not (t `elem` du)
612 && n `elem` hs && t `elem` hs
614keepGiven du (u@(n, _) : us) hs
615 | n `elem` du = u : keepGiven du us hs
616keepGiven du (u : us) hs = keepGiven du us hs
618updateSolved xs x = -- trace ("Updating " ++ show xs ++ " in " ++ show x) $
620updateSolved' xs (Bind n (Hole ty) t)
621 | Just v <- lookup n xs = instantiate v (pToV n (updateSolved' xs t))
622updateSolved' xs (Bind n b t)
623 | otherwise = Bind n (fmap (updateSolved' xs) b) (updateSolved' xs t)
624updateSolved' xs (App f a) = App (updateSolved' xs f) (updateSolved' xs a)
625updateSolved' xs (P _ n _)
626 | Just v <- lookup n xs = v
627updateSolved' xs t = t
630updateEnv ns ((n, b) : env) = (n, fmap (updateSolved ns) b) : updateEnv ns env
632updateError ns (CantUnify b l r e xs sc)
633 = CantUnify b (updateSolved ns l) (updateSolved ns r) (updateError ns e) xs sc
636solveInProblems x val [] = []
637solveInProblems x val ((l, r, env, err) : ps)
638 = ((instantiate val (pToV x l), instantiate val (pToV x r),
639 updateEnv [(x, val)] env, err) : solveInProblems x val ps)
641updateProblems ctxt ns ps inj holes = up ns ps where
643 up ns ((x, y, env, err) : ps) =
644 let x' = updateSolved ns x
645 y' = updateSolved ns y
646 err' = updateError ns err
647 env' = updateEnv ns env in
648 case unify ctxt env' x' y' inj holes of
649 OK (v, []) -> -- trace ("Added " ++ show v ++ " from " ++ show (x', y')) $
651 _ -> let (ns', ps') = up ns ps in
652 (ns', (x',y',env',err') : ps')
654processTactic :: Tactic -> ProofState -> TC (ProofState, String)
655processTactic QED ps = case holes ps of
656 [] -> do let tm = {- normalise (context ps) [] -} (pterm ps)
657 (tm', ty', _) <- recheck (context ps) [] (forget tm) tm
658 return (ps { done = True, pterm = tm' },
659 "Proof complete: " ++ showEnv [] tm')
660 _ -> fail "Still holes to fill."
661processTactic ProofState ps = return (ps, showEnv [] (pterm ps))
662processTactic Undo ps = case previous ps of
663 Nothing -> fail "Nothing to undo."
664 Just pold -> return (pold, "")
665processTactic EndUnify ps
666 = let (h, ns_in) = unified ps
667 ns = dropGiven (dontunify ps) ns_in (holes ps)
668 ns' = map (\ (n, t) -> (n, updateSolved ns t)) ns
669 (ns'', probs') = updateProblems (context ps) ns' (problems ps)
670 (injective ps) (holes ps)
671 tm' = -- trace ("Updating " ++ show ns_in ++ "\n" ++ show ns'') $ -- ++ " in " ++ show (pterm ps)) $
672 updateSolved ns'' (pterm ps) in
673 return (ps { pterm = tm',
676 holes = holes ps \\ map fst ns'' }, "")
677processTactic (Reorder n) ps
678 = do ps' <- execStateT (tactic (Just n) reorder_claims) ps
679 return (ps' { previous = Just ps, plog = "" }, plog ps')
682 [] -> fail "Nothing to fill in."
683 (h:_) -> do ps' <- execStateT (process t h) ps
684 let pterm' = case solved ps' of
685 Just s -> updateSolved [s] (pterm ps')
689 Just s -> updateProblems (context ps')
693 _ -> ([], problems ps')
694 -- rechecking problems may find more solutions, so
696 let pterm'' = updateSolved ns' pterm'
697 return (ps' { pterm = pterm'',
700 previous = Just ps, plog = "",
701 holes = holes ps' \\ (map fst ns')}, plog ps')
703process :: Tactic -> Name -> StateT TState TC ()
706 let (h, _) = unified ps
707 tactic (Just h) solve_unified
708process t h = tactic (Just h) (mktac t)
709 where mktac Attack = attack
710 mktac (Claim n r) = claim n r
711 mktac (Exact r) = exact r
712 mktac (Fill r) = fill r
713 mktac (MatchFill r) = match_fill r
714 mktac (PrepFill n ns) = prep_fill n ns
715 mktac CompleteFill = complete_fill
716 mktac Regret = regret
718 mktac (StartUnify n) = start_unify n
719 mktac Compute = compute
720 mktac HNF_Compute = hnf_compute
721 mktac (Intro n) = intro n
722 mktac (IntroTy ty n) = introTy ty n
723 mktac (Forall n t) = forall n t
724 mktac (LetBind n t v) = letbind n t v
725 mktac (Rewrite t) = rewrite t
726 mktac (PatVar n) = patvar n
727 mktac (PatBind n) = patbind n
728 mktac (CheckIn r) = check_in r
729 mktac (EvalIn r) = eval_in r
730 mktac (Focus n) = focus n
731 mktac (Defer n) = defer n
732 mktac (DeferType n t a) = deferType n t a
733 mktac (Instance n) = instanceArg n
734 mktac (SetInjective n) = setinj n
735 mktac (MoveLast n) = movelast n
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