@@ -28,24 +28,25 @@ data Command = Theorem Name Raw
2828 | Print Name
2929 | Tac (Elab ())
3030
31−data ElabState = ES ProofState String (Maybe ElabState)
31+data ElabState aux = ES (ProofState, aux) String (Maybe (ElabState aux))
3232 deriving Show
33−type Elab a = StateT ElabState TC a
33+type Elab' aux a = StateT (ElabState aux) TC a
34+type Elab a = Elab' () a
3435
35−proof :: ElabState -> ProofState
36−proof (ES p _ _) = p
36+proof :: ElabState aux -> ProofState
37+proof (ES (p, _) _ _) = p
3738
38−saveState :: Elab ()
39+saveState :: Elab' aux ()
3940saveState = do e@(ES p s _) <- get
4041 put (ES p s (Just e))
4142
42−loadState :: Elab ()
43+loadState :: Elab' aux ()
4344loadState = do (ES p s e) <- get
4445 case e of
4546 Just st -> put st
4647 _ -> fail "Nothing to undo"
4748
48−erun :: FC -> Elab a -> Elab a
49+erun :: FC -> Elab' aux a -> Elab' aux a
4950erun f elab = do s <- get
5051 case runStateT elab s of
5152 OK (a, s') -> do put s'
@@ -53,82 +54,90 @@ erun f elab = do s <- get
5354 Error (At f e) -> lift $ Error (At f e)
5455 Error e -> lift $ Error (At f e)
5556
56−runElab :: Elab a -> ProofState -> TC (a, ElabState)
57−runElab e ps = runStateT e (ES ps "" Nothing)
57+runElab :: aux -> Elab' aux a -> ProofState -> TC (a, ElabState aux)
58+runElab a e ps = runStateT e (ES (ps, a) "" Nothing)
5859
59−execElab :: Elab a -> ProofState -> TC ElabState
60−execElab e ps = execStateT e (ES ps "" Nothing)
60+execElab :: aux -> Elab' aux a -> ProofState -> TC (ElabState aux)
61+execElab a e ps = execStateT e (ES (ps, a) "" Nothing)
6162
6263initElaborator :: Name -> Context -> Type -> ProofState
6364initElaborator = newProof
6465
65−elaborate :: Context -> Name -> Type -> Elab a -> TC (a, String)
66−elaborate ctxt n ty elab = do let ps = initElaborator n ctxt ty
67− (a, ES ps' str _) <- runElab elab ps
68− return (a, str)
66+elaborate :: Context -> Name -> Type -> aux -> Elab' aux a -> TC (a, String)
67+elaborate ctxt n ty d elab = do let ps = initElaborator n ctxt ty
68+ (a, ES ps' str _) <- runElab d elab ps
69+ return (a, str)
6970
70−processTactic' t = do ES p logs prev <- get
71+updateAux :: (aux -> aux) -> Elab' aux ()
72+updateAux f = do ES (ps, a) l p <- get
73+ put (ES (ps, f a) l p)
74+
75+getAux :: Elab' aux aux
76+getAux = do ES (ps, a) _ _ <- get
77+ return a
78+
79+processTactic' t = do ES (p, a) logs prev <- get
7180 (p', log) <- lift $ processTactic t p
72− put (ES p' (logs ++ log) prev)
81+ put (ES (p', a) (logs ++ log) prev)
7382 return ()
7483
7584-- Some handy gadgets for pulling out bits of state
7685
7786-- get the global context
78−get_context :: Elab Context
87+get_context :: Elab' aux Context
7988get_context = do ES p _ _ <- get
80− return (context p)
89+ return (context (fst p))
8190
8291-- get the proof term
83−get_term :: Elab Term
92+get_term :: Elab' aux Term
8493get_term = do ES p _ _ <- get
85− return (pterm p)
94+ return (pterm (fst p))
8695
8796-- get the local context at the currently in focus hole
88−get_env :: Elab Env
97+get_env :: Elab' aux Env
8998get_env = do ES p _ _ <- get
90− lift $ envAtFocus p
99+ lift $ envAtFocus (fst p)
91100
92−get_holes :: Elab [Name]
101+get_holes :: Elab' aux [Name]
93102get_holes = do ES p _ _ <- get
94− return (holes p)
103+ return (holes (fst p))
95104
96105-- get the current goal type
97−goal :: Elab Type
106+goal :: Elab' aux Type
98107goal = do ES p _ _ <- get
99− b <- lift $ goalAtFocus p
108+ b <- lift $ goalAtFocus (fst p)
100109 return (binderTy b)
101110
102111-- typecheck locally
103−get_type :: Raw -> Elab Type
112+get_type :: Raw -> Elab' aux Type
104113get_type tm = do ctxt <- get_context
105114 env <- get_env
106115 (val, ty) <- lift $ check ctxt env tm
107116 return (finalise ty)
108117
109118-- get holes we've deferred for later definition
110−get_deferred :: Elab [Name]
119+get_deferred :: Elab' aux [Name]
111120get_deferred = do ES p _ _ <- get
112− return (deferred p)
121+ return (deferred (fst p))
113122
114−get_inj :: Elab [(Term, Term, Term)]
123+get_inj :: Elab' aux [(Term, Term, Term)]
115124get_inj = do ES p _ _ <- get
116− return (injective p)
125+ return (injective (fst p))
117126
118−checkInjective :: (Term, Term, Term) -> Elab ()
127+checkInjective :: (Term, Term, Term) -> Elab' aux ()
119128checkInjective (tm, l, r) = if isInjective tm then return ()
120129 else lift $ tfail (NotInjective tm l r)
121130
122131-- get instance argument names
123−get_instances :: Elab [Name]
132+get_instances :: Elab' aux [Name]
124133get_instances = do ES p _ _ <- get
125− return (instances p)
134+ return (instances (fst p))
126135
127136-- given a desired hole name, return a unique hole name
128−unique_hole :: Name -> Elab Name
137+unique_hole :: Name -> Elab' aux Name
129138unique_hole n = do ES p _ _ <- get
130− let bs = bound_in (pterm p) ++ bound_in (ptype p)
131− n' <- uniqueNameCtxt (context p) n (holes p ++ bs)
139+ let bs = bound_in (pterm (fst p)) ++ bound_in (ptype (fst p))
140+ n' <- uniqueNameCtxt (context (fst p)) n (holes (fst p) ++ bs)
132141 return n'
133142 where
134143 bound_in (Bind n b sc) = n : bi b ++ bound_in sc
@@ -139,73 +148,73 @@ unique_hole n = do ES p _ _ <- get
139148 bound_in (App f a) = bound_in f ++ bound_in a
140149 bound_in _ = []
141150
142−uniqueNameCtxt :: Context -> Name -> [Name] -> Elab Name
151+uniqueNameCtxt :: Context -> Name -> [Name] -> Elab' aux Name
143152uniqueNameCtxt ctxt n hs
144153 | n `elem` hs = uniqueNameCtxt ctxt (nextName n) hs
145154 | [_] <- lookupTy Nothing n ctxt = uniqueNameCtxt ctxt (nextName n) hs
146155 | otherwise = return n
147156
148−elog :: String -> Elab ()
157+elog :: String -> Elab' aux ()
149158elog str = do ES p logs prev <- get
150159 put (ES p (logs ++ str ++ "\n") prev)
151160
152161-- The primitives, from ProofState
153162
154−attack :: Elab ()
163+attack :: Elab' aux ()
155164attack = processTactic' Attack
156165
157−claim :: Name -> Raw -> Elab ()
166+claim :: Name -> Raw -> Elab' aux ()
158167claim n t = processTactic' (Claim n t)
159168
160−exact :: Raw -> Elab ()
169+exact :: Raw -> Elab' aux ()
161170exact t = processTactic' (Exact t)
162171
163−fill :: Raw -> Elab ()
172+fill :: Raw -> Elab' aux ()
164173fill t = processTactic' (Fill t)
165174
166−prep_fill :: Name -> [Name] -> Elab ()
175+prep_fill :: Name -> [Name] -> Elab' aux ()
167176prep_fill n ns = processTactic' (PrepFill n ns)
168177
169−complete_fill :: Elab ()
178+complete_fill :: Elab' aux ()
170179complete_fill = processTactic' CompleteFill
171180
172−solve :: Elab ()
181+solve :: Elab' aux ()
173182solve = processTactic' Solve
174183
175−start_unify :: Name -> Elab ()
184+start_unify :: Name -> Elab' aux ()
176185start_unify n = processTactic' (StartUnify n)
177186
178−end_unify :: Elab ()
187+end_unify :: Elab' aux ()
179188end_unify = processTactic' EndUnify
180189
181−regret :: Elab ()
190+regret :: Elab' aux ()
182191regret = processTactic' Regret
183192
184−compute :: Elab ()
193+compute :: Elab' aux ()
185194compute = processTactic' Compute
186195
187−eval_in :: Raw -> Elab ()
196+eval_in :: Raw -> Elab' aux ()
188197eval_in t = processTactic' (EvalIn t)
189198
190−check_in :: Raw -> Elab ()
199+check_in :: Raw -> Elab' aux ()
191200check_in t = processTactic' (CheckIn t)
192201
193−intro :: Maybe Name -> Elab ()
202+intro :: Maybe Name -> Elab' aux ()
194203intro n = processTactic' (Intro n)
195204
196−introTy :: Raw -> Maybe Name -> Elab ()
205+introTy :: Raw -> Maybe Name -> Elab' aux ()
197206introTy ty n = processTactic' (IntroTy ty n)
198207
199−forall :: Name -> Raw -> Elab ()
208+forall :: Name -> Raw -> Elab' aux ()
200209forall n t = processTactic' (Forall n t)
201210
202−letbind :: Name -> Raw -> Raw -> Elab ()
211+letbind :: Name -> Raw -> Raw -> Elab' aux ()
203212letbind n t v = processTactic' (LetBind n t v)
204213
205−rewrite :: Raw -> Elab ()
214+rewrite :: Raw -> Elab' aux ()
206215rewrite tm = processTactic' (Rewrite tm)
207216
208−patvar :: Name -> Elab ()
217+patvar :: Name -> Elab' aux ()
209218patvar n = do env <- get_env
210219 if (n `elem` map fst env) then do apply (Var n) []; solve
211220 else do n' <- case n of
@@ -214,48 +223,48 @@ patvar n = do env <- get_env
214223 NS _ _ -> return n
215224 processTactic' (PatVar n')
216225
217−patbind :: Name -> Elab ()
226+patbind :: Name -> Elab' aux ()
218227patbind n = processTactic' (PatBind n)
219228
220−focus :: Name -> Elab ()
229+focus :: Name -> Elab' aux ()
221230focus n = processTactic' (Focus n)
222231
223−movelast :: Name -> Elab ()
232+movelast :: Name -> Elab' aux ()
224233movelast n = processTactic' (MoveLast n)
225234
226−defer :: Name -> Elab ()
235+defer :: Name -> Elab' aux ()
227236defer n = do n' <- unique_hole n
228237 processTactic' (Defer n')
229238
230−instanceArg :: Name -> Elab ()
239+instanceArg :: Name -> Elab' aux ()
231240instanceArg n = processTactic' (Instance n)
232241
233−proofstate :: Elab ()
242+proofstate :: Elab' aux ()
234243proofstate = processTactic' ProofState
235244
236−reorder_claims :: Name -> Elab ()
245+reorder_claims :: Name -> Elab' aux ()
237246reorder_claims n = processTactic' (Reorder n)
238247
239−qed :: Elab Term
248+qed :: Elab' aux Term
240249qed = do processTactic' QED
241250 ES p _ _ <- get
242− return (pterm p)
251+ return (pterm (fst p))
243252
244−undo :: Elab ()
253+undo :: Elab' aux ()
245254undo = processTactic' Undo
246255
247−prepare_apply :: Raw -> [(Bool, Int)] -> Elab [Name]
256+prepare_apply :: Raw -> [(Bool, Int)] -> Elab' aux [Name]
248257prepare_apply fn imps =
249258 do ty <- get_type fn
250259 ctxt <- get_context
251260 env <- get_env
252261 -- let claims = getArgs ty imps
253262 claims <- mkClaims (normalise ctxt env ty) imps []
254− ES p s prev <- get
263+ ES (p, a) s prev <- get
255264 -- reverse the claims we made so that args go left to right
256265 let n = length (filter not (map fst imps))
257266 let (h : hs) = holes p
258− put (ES (p { holes = h : (reverse (take n hs) ++ drop n hs) }) s prev)
267+ put (ES (p { holes = h : (reverse (take n hs) ++ drop n hs) }, a) s prev)
259268-- case claims of
260269-- [] -> return ()
261270-- (h : _) -> reorder_claims h
@@ -278,7 +287,7 @@ prepare_apply fn imps =
278287 mkMN n@(UN x) = MN 0 x
279288 mkMN (NS n xs) = NS (mkMN n) xs
280289
281−apply :: Raw -> [(Bool, Int)] -> Elab [Name]
290+apply :: Raw -> [(Bool, Int)] -> Elab' aux [Name]
282291apply fn imps =
283292 do args <- prepare_apply fn imps
284293 fill (raw_apply fn (map Var args))
@@ -288,14 +297,14 @@ apply fn imps =
288297 -- so do nothing
289298 ptm <- get_term
290299 let dontunify = [] -- map fst (filter (not.snd) (zip args imps))
291− ES p s prev <- get
300+ ES (p, a) s prev <- get
292301 let (n, hs) = unified p
293302 let unify = (n, filter (\ (n, t) -> not (n `elem` dontunify)) hs)
294− put (ES (p { unified = unify }) s prev)
303+ put (ES (p { unified = unify }, a) s prev)
295304 end_unify
296305 return args
297306
298−apply_elab :: Name -> [Maybe (Int, Elab ())] -> Elab ()
307+apply_elab :: Name -> [Maybe (Int, Elab' aux ())] -> Elab' aux ()
299308apply_elab n args =
300309 do ty <- get_type (Var n)
301310 ctxt <- get_context
@@ -337,7 +346,7 @@ apply_elab n args =
337346 mkMN n@(UN x) = MN 0 x
338347 mkMN (NS n ns) = NS (mkMN n) ns
339348
340−simple_app :: Elab () -> Elab () -> Elab ()
349+simple_app :: Elab' aux () -> Elab' aux () -> Elab' aux ()
341350simple_app fun arg =
342351 do a <- unique_hole (MN 0 "a")
343352 b <- unique_hole (MN 0 "b")
@@ -360,13 +369,13 @@ simple_app fun arg =
360369
361370-- Abstract over an argument of unknown type, giving a name for the hole
362371-- which we'll fill with the argument type too.
363−arg :: Name -> Name -> Elab ()
372+arg :: Name -> Name -> Elab' aux ()
364373arg n tyhole = do ty <- unique_hole tyhole
365374 claim ty RSet
366375 forall n (Var ty)
367376
368377-- Try a tactic, if it fails, try another
369−try :: Elab a -> Elab a -> Elab a
378+try :: Elab' aux a -> Elab' aux a -> Elab' aux a
370379try t1 t2 = do s <- get
371380 case runStateT t1 s of
372381 OK (v, s') -> do put s'
@@ -374,13 +383,13 @@ try t1 t2 = do s <- get
374383 _ -> do put s; t2
375384
376385-- Try a selection of tactics. Exactly one must work, all others must fail
377−tryAll :: [(Elab a, String)] -> Elab a
386+tryAll :: [(Elab' aux a, String)] -> Elab' aux a
378387tryAll xs = tryAll' [] (fail "Nothing to try") (map fst xs)
379388 where
380− tryAll' :: [Elab a] -> -- successes
381− Elab a -> -- last failure
382− [Elab a] -> -- still to try
383− Elab a
389+ tryAll' :: [Elab' aux a] -> -- successes
390+ Elab' aux a -> -- last failure
391+ [Elab' aux a] -> -- still to try
392+ Elab' aux a
384393 tryAll' [res] _ [] = res
385394 tryAll' (_:_) _ [] = fail $ "Couldn't resolve alternative: "
386395 ++ showSep ", " (map snd xs)