@@ -28,24 +28,25 @@ data Command = Theorem Name Raw
28 | Print Name
28 | Print Name
29 | Tac (Elab ())
29 | Tac (Elab ())
31−data ElabState = ES ProofState String (Maybe ElabState)
31+data ElabState aux = ES (ProofState, aux) String (Maybe (ElabState aux))
32 deriving Show
32 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
35−proof :: ElabState -> ProofState
36+proof :: ElabState aux -> ProofState
36−proof (ES p _ _) = p
37+proof (ES (p, _) _ _) = p
38−saveState :: Elab ()
39+saveState :: Elab' aux ()
39saveState = do e@(ES p s _) <- get
40saveState = do e@(ES p s _) <- get
40 put (ES p s (Just e))
41 put (ES p s (Just e))
42−loadState :: Elab ()
43+loadState :: Elab' aux ()
43loadState = do (ES p s e) <- get
44loadState = do (ES p s e) <- get
45 Just st -> put st
46 Just st -> put st
46 _ -> fail "Nothing to undo"
47 _ -> fail "Nothing to undo"
48−erun :: FC -> Elab a -> Elab a
49+erun :: FC -> Elab' aux a -> Elab' aux a
49erun f elab = do s <- get
50erun f elab = do s <- get
50 case runStateT elab s of
51 case runStateT elab s of
51 OK (a, s') -> do put s'
52 OK (a, s') -> do put s'
@@ -53,82 +54,90 @@ erun f elab = do s <- get
53 Error (At f e) -> lift $ Error (At f e)
54 Error (At f e) -> lift $ Error (At f e)
54 Error e -> lift $ Error (At f e)
55 Error e -> lift $ Error (At f e)
56−runElab :: Elab a -> ProofState -> TC (a, ElabState)
57+runElab :: aux -> Elab' aux a -> ProofState -> TC (a, ElabState aux)
57−runElab e ps = runStateT e (ES ps "" Nothing)
58+runElab a e ps = runStateT e (ES (ps, a) "" Nothing)
59−execElab :: Elab a -> ProofState -> TC ElabState
60+execElab :: aux -> Elab' aux a -> ProofState -> TC (ElabState aux)
60−execElab e ps = execStateT e (ES ps "" Nothing)
61+execElab a e ps = execStateT e (ES (ps, a) "" Nothing)
62initElaborator :: Name -> Context -> Type -> ProofState
63initElaborator :: Name -> Context -> Type -> ProofState
63initElaborator = newProof
64initElaborator = newProof
65−elaborate :: Context -> Name -> Type -> Elab a -> TC (a, String)
66+elaborate :: Context -> Name -> Type -> aux -> Elab' aux a -> TC (a, String)
66−elaborate ctxt n ty elab = do let ps = initElaborator n ctxt ty
67+elaborate ctxt n ty d elab = do let ps = initElaborator n ctxt ty
67− (a, ES ps' str _) <- runElab elab ps
68+ (a, ES ps' str _) <- runElab d elab ps
68− return (a, str)
69+ return (a, str)
71+updateAux :: (aux -> aux) -> Elab' aux ()
72+updateAux f = do ES (ps, a) l p <- get
73+ put (ES (ps, f a) l p)
75+getAux :: Elab' aux aux
76+getAux = do ES (ps, a) _ _ <- get
70−processTactic' t = do ES p logs prev <- get
79+processTactic' t = do ES (p, a) logs prev <- get
71 (p', log) <- lift $ processTactic t p
80 (p', log) <- lift $ processTactic t p
72− put (ES p' (logs ++ log) prev)
81+ put (ES (p', a) (logs ++ log) prev)
75-- Some handy gadgets for pulling out bits of state
84-- Some handy gadgets for pulling out bits of state
77-- get the global context
86-- get the global context
78−get_context :: Elab Context
87+get_context :: Elab' aux Context
79get_context = do ES p _ _ <- get
88get_context = do ES p _ _ <- get
80− return (context p)
89+ return (context (fst p))
82-- get the proof term
91-- get the proof term
83−get_term :: Elab Term
92+get_term :: Elab' aux Term
84get_term = do ES p _ _ <- get
93get_term = do ES p _ _ <- get
85− return (pterm p)
94+ return (pterm (fst p))
87-- get the local context at the currently in focus hole
96-- get the local context at the currently in focus hole
88−get_env :: Elab Env
97+get_env :: Elab' aux Env
89get_env = do ES p _ _ <- get
98get_env = do ES p _ _ <- get
90− lift $ envAtFocus p
99+ lift $ envAtFocus (fst p)
92−get_holes :: Elab [Name]
101+get_holes :: Elab' aux [Name]
93get_holes = do ES p _ _ <- get
102get_holes = do ES p _ _ <- get
94− return (holes p)
103+ return (holes (fst p))
96-- get the current goal type
105-- get the current goal type
97−goal :: Elab Type
106+goal :: Elab' aux Type
98goal = do ES p _ _ <- get
107goal = do ES p _ _ <- get
99− b <- lift $ goalAtFocus p
108+ b <- lift $ goalAtFocus (fst p)
100 return (binderTy b)
109 return (binderTy b)
102-- typecheck locally
111-- typecheck locally
103−get_type :: Raw -> Elab Type
112+get_type :: Raw -> Elab' aux Type
104get_type tm = do ctxt <- get_context
113get_type tm = do ctxt <- get_context
105 env <- get_env
114 env <- get_env
106 (val, ty) <- lift $ check ctxt env tm
115 (val, ty) <- lift $ check ctxt env tm
107 return (finalise ty)
116 return (finalise ty)
109-- get holes we've deferred for later definition
118-- get holes we've deferred for later definition
110−get_deferred :: Elab [Name]
119+get_deferred :: Elab' aux [Name]
111get_deferred = do ES p _ _ <- get
120get_deferred = do ES p _ _ <- get
112− return (deferred p)
121+ return (deferred (fst p))
114−get_inj :: Elab [(Term, Term, Term)]
123+get_inj :: Elab' aux [(Term, Term, Term)]
115get_inj = do ES p _ _ <- get
124get_inj = do ES p _ _ <- get
116− return (injective p)
125+ return (injective (fst p))
118−checkInjective :: (Term, Term, Term) -> Elab ()
127+checkInjective :: (Term, Term, Term) -> Elab' aux ()
119checkInjective (tm, l, r) = if isInjective tm then return ()
128checkInjective (tm, l, r) = if isInjective tm then return ()
120 else lift $ tfail (NotInjective tm l r)
129 else lift $ tfail (NotInjective tm l r)
122-- get instance argument names
131-- get instance argument names
123−get_instances :: Elab [Name]
132+get_instances :: Elab' aux [Name]
124get_instances = do ES p _ _ <- get
133get_instances = do ES p _ _ <- get
125− return (instances p)
134+ return (instances (fst p))
127-- given a desired hole name, return a unique hole name
136-- given a desired hole name, return a unique hole name
128−unique_hole :: Name -> Elab Name
137+unique_hole :: Name -> Elab' aux Name
129unique_hole n = do ES p _ _ <- get
138unique_hole n = do ES p _ _ <- get
130− let bs = bound_in (pterm p) ++ bound_in (ptype p)
139+ let bs = bound_in (pterm (fst p)) ++ bound_in (ptype (fst p))
131− n' <- uniqueNameCtxt (context p) n (holes p ++ bs)
140+ n' <- uniqueNameCtxt (context (fst p)) n (holes (fst p) ++ bs)
132 return n'
141 return n'
134 bound_in (Bind n b sc) = n : bi b ++ bound_in sc
143 bound_in (Bind n b sc) = n : bi b ++ bound_in sc
@@ -139,73 +148,73 @@ unique_hole n = do ES p _ _ <- get
139 bound_in (App f a) = bound_in f ++ bound_in a
148 bound_in (App f a) = bound_in f ++ bound_in a
140 bound_in _ = []
149 bound_in _ = []
142−uniqueNameCtxt :: Context -> Name -> [Name] -> Elab Name
151+uniqueNameCtxt :: Context -> Name -> [Name] -> Elab' aux Name
143uniqueNameCtxt ctxt n hs
152uniqueNameCtxt ctxt n hs
144 | n `elem` hs = uniqueNameCtxt ctxt (nextName n) hs
153 | n `elem` hs = uniqueNameCtxt ctxt (nextName n) hs
145 | [_] <- lookupTy Nothing n ctxt = uniqueNameCtxt ctxt (nextName n) hs
154 | [_] <- lookupTy Nothing n ctxt = uniqueNameCtxt ctxt (nextName n) hs
146 | otherwise = return n
155 | otherwise = return n
148−elog :: String -> Elab ()
157+elog :: String -> Elab' aux ()
149elog str = do ES p logs prev <- get
158elog str = do ES p logs prev <- get
150 put (ES p (logs ++ str ++ "\n") prev)
159 put (ES p (logs ++ str ++ "\n") prev)
152-- The primitives, from ProofState
161-- The primitives, from ProofState
154−attack :: Elab ()
163+attack :: Elab' aux ()
155attack = processTactic' Attack
164attack = processTactic' Attack
157−claim :: Name -> Raw -> Elab ()
166+claim :: Name -> Raw -> Elab' aux ()
158claim n t = processTactic' (Claim n t)
167claim n t = processTactic' (Claim n t)
160−exact :: Raw -> Elab ()
169+exact :: Raw -> Elab' aux ()
161exact t = processTactic' (Exact t)
170exact t = processTactic' (Exact t)
163−fill :: Raw -> Elab ()
172+fill :: Raw -> Elab' aux ()
164fill t = processTactic' (Fill t)
173fill t = processTactic' (Fill t)
166−prep_fill :: Name -> [Name] -> Elab ()
175+prep_fill :: Name -> [Name] -> Elab' aux ()
167prep_fill n ns = processTactic' (PrepFill n ns)
176prep_fill n ns = processTactic' (PrepFill n ns)
169−complete_fill :: Elab ()
178+complete_fill :: Elab' aux ()
170complete_fill = processTactic' CompleteFill
179complete_fill = processTactic' CompleteFill
172−solve :: Elab ()
181+solve :: Elab' aux ()
173solve = processTactic' Solve
182solve = processTactic' Solve
175−start_unify :: Name -> Elab ()
184+start_unify :: Name -> Elab' aux ()
176start_unify n = processTactic' (StartUnify n)
185start_unify n = processTactic' (StartUnify n)
178−end_unify :: Elab ()
187+end_unify :: Elab' aux ()
179end_unify = processTactic' EndUnify
188end_unify = processTactic' EndUnify
181−regret :: Elab ()
190+regret :: Elab' aux ()
182regret = processTactic' Regret
191regret = processTactic' Regret
184−compute :: Elab ()
193+compute :: Elab' aux ()
185compute = processTactic' Compute
194compute = processTactic' Compute
187−eval_in :: Raw -> Elab ()
196+eval_in :: Raw -> Elab' aux ()
188eval_in t = processTactic' (EvalIn t)
197eval_in t = processTactic' (EvalIn t)
190−check_in :: Raw -> Elab ()
199+check_in :: Raw -> Elab' aux ()
191check_in t = processTactic' (CheckIn t)
200check_in t = processTactic' (CheckIn t)
193−intro :: Maybe Name -> Elab ()
202+intro :: Maybe Name -> Elab' aux ()
194intro n = processTactic' (Intro n)
203intro n = processTactic' (Intro n)
196−introTy :: Raw -> Maybe Name -> Elab ()
205+introTy :: Raw -> Maybe Name -> Elab' aux ()
197introTy ty n = processTactic' (IntroTy ty n)
206introTy ty n = processTactic' (IntroTy ty n)
199−forall :: Name -> Raw -> Elab ()
208+forall :: Name -> Raw -> Elab' aux ()
200forall n t = processTactic' (Forall n t)
209forall n t = processTactic' (Forall n t)
202−letbind :: Name -> Raw -> Raw -> Elab ()
211+letbind :: Name -> Raw -> Raw -> Elab' aux ()
203letbind n t v = processTactic' (LetBind n t v)
212letbind n t v = processTactic' (LetBind n t v)
205−rewrite :: Raw -> Elab ()
214+rewrite :: Raw -> Elab' aux ()
206rewrite tm = processTactic' (Rewrite tm)
215rewrite tm = processTactic' (Rewrite tm)
208−patvar :: Name -> Elab ()
217+patvar :: Name -> Elab' aux ()
209patvar n = do env <- get_env
218patvar n = do env <- get_env
210 if (n `elem` map fst env) then do apply (Var n) []; solve
219 if (n `elem` map fst env) then do apply (Var n) []; solve
211 else do n' <- case n of
220 else do n' <- case n of
@@ -214,48 +223,48 @@ patvar n = do env <- get_env
214 NS _ _ -> return n
223 NS _ _ -> return n
215 processTactic' (PatVar n')
224 processTactic' (PatVar n')
217−patbind :: Name -> Elab ()
226+patbind :: Name -> Elab' aux ()
218patbind n = processTactic' (PatBind n)
227patbind n = processTactic' (PatBind n)
220−focus :: Name -> Elab ()
229+focus :: Name -> Elab' aux ()
221focus n = processTactic' (Focus n)
230focus n = processTactic' (Focus n)
223−movelast :: Name -> Elab ()
232+movelast :: Name -> Elab' aux ()
224movelast n = processTactic' (MoveLast n)
233movelast n = processTactic' (MoveLast n)
226−defer :: Name -> Elab ()
235+defer :: Name -> Elab' aux ()
227defer n = do n' <- unique_hole n
236defer n = do n' <- unique_hole n
228 processTactic' (Defer n')
237 processTactic' (Defer n')
230−instanceArg :: Name -> Elab ()
239+instanceArg :: Name -> Elab' aux ()
231instanceArg n = processTactic' (Instance n)
240instanceArg n = processTactic' (Instance n)
233−proofstate :: Elab ()
242+proofstate :: Elab' aux ()
234proofstate = processTactic' ProofState
243proofstate = processTactic' ProofState
236−reorder_claims :: Name -> Elab ()
245+reorder_claims :: Name -> Elab' aux ()
237reorder_claims n = processTactic' (Reorder n)
246reorder_claims n = processTactic' (Reorder n)
239−qed :: Elab Term
248+qed :: Elab' aux Term
240qed = do processTactic' QED
249qed = do processTactic' QED
241 ES p _ _ <- get
250 ES p _ _ <- get
242− return (pterm p)
251+ return (pterm (fst p))
244−undo :: Elab ()
253+undo :: Elab' aux ()
245undo = processTactic' Undo
254undo = processTactic' Undo
247−prepare_apply :: Raw -> [(Bool, Int)] -> Elab [Name]
256+prepare_apply :: Raw -> [(Bool, Int)] -> Elab' aux [Name]
248prepare_apply fn imps =
257prepare_apply fn imps =
249 do ty <- get_type fn
258 do ty <- get_type fn
250 ctxt <- get_context
259 ctxt <- get_context
251 env <- get_env
260 env <- get_env
252 -- let claims = getArgs ty imps
261 -- let claims = getArgs ty imps
253 claims <- mkClaims (normalise ctxt env ty) imps []
262 claims <- mkClaims (normalise ctxt env ty) imps []
254− ES p s prev <- get
263+ ES (p, a) s prev <- get
255 -- reverse the claims we made so that args go left to right
264 -- reverse the claims we made so that args go left to right
256 let n = length (filter not (map fst imps))
265 let n = length (filter not (map fst imps))
257 let (h : hs) = holes p
266 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)
259-- case claims of
268-- case claims of
260-- [] -> return ()
269-- [] -> return ()
261-- (h : _) -> reorder_claims h
270-- (h : _) -> reorder_claims h
@@ -278,7 +287,7 @@ prepare_apply fn imps =
278 mkMN n@(UN x) = MN 0 x
287 mkMN n@(UN x) = MN 0 x
279 mkMN (NS n xs) = NS (mkMN n) xs
288 mkMN (NS n xs) = NS (mkMN n) xs
281−apply :: Raw -> [(Bool, Int)] -> Elab [Name]
290+apply :: Raw -> [(Bool, Int)] -> Elab' aux [Name]
282apply fn imps =
291apply fn imps =
283 do args <- prepare_apply fn imps
292 do args <- prepare_apply fn imps
284 fill (raw_apply fn (map Var args))
293 fill (raw_apply fn (map Var args))
@@ -288,14 +297,14 @@ apply fn imps =
288 -- so do nothing
297 -- so do nothing
289 ptm <- get_term
298 ptm <- get_term
290 let dontunify = [] -- map fst (filter (not.snd) (zip args imps))
299 let dontunify = [] -- map fst (filter (not.snd) (zip args imps))
291− ES p s prev <- get
300+ ES (p, a) s prev <- get
292 let (n, hs) = unified p
301 let (n, hs) = unified p
293 let unify = (n, filter (\ (n, t) -> not (n `elem` dontunify)) hs)
302 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)
295 end_unify
304 end_unify
296 return args
305 return args
298−apply_elab :: Name -> [Maybe (Int, Elab ())] -> Elab ()
307+apply_elab :: Name -> [Maybe (Int, Elab' aux ())] -> Elab' aux ()
299apply_elab n args =
308apply_elab n args =
300 do ty <- get_type (Var n)
309 do ty <- get_type (Var n)
301 ctxt <- get_context
310 ctxt <- get_context
@@ -337,7 +346,7 @@ apply_elab n args =
337 mkMN n@(UN x) = MN 0 x
346 mkMN n@(UN x) = MN 0 x
338 mkMN (NS n ns) = NS (mkMN n) ns
347 mkMN (NS n ns) = NS (mkMN n) ns
340−simple_app :: Elab () -> Elab () -> Elab ()
349+simple_app :: Elab' aux () -> Elab' aux () -> Elab' aux ()
341simple_app fun arg =
350simple_app fun arg =
342 do a <- unique_hole (MN 0 "a")
351 do a <- unique_hole (MN 0 "a")
343 b <- unique_hole (MN 0 "b")
352 b <- unique_hole (MN 0 "b")
@@ -360,13 +369,13 @@ simple_app fun arg =
361-- Abstract over an argument of unknown type, giving a name for the hole
370-- Abstract over an argument of unknown type, giving a name for the hole
362-- which we'll fill with the argument type too.
371-- which we'll fill with the argument type too.
363−arg :: Name -> Name -> Elab ()
372+arg :: Name -> Name -> Elab' aux ()
364arg n tyhole = do ty <- unique_hole tyhole
373arg n tyhole = do ty <- unique_hole tyhole
365 claim ty RSet
374 claim ty RSet
366 forall n (Var ty)
375 forall n (Var ty)
368-- Try a tactic, if it fails, try another
377-- 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
370try t1 t2 = do s <- get
379try t1 t2 = do s <- get
371 case runStateT t1 s of
380 case runStateT t1 s of
372 OK (v, s') -> do put s'
381 OK (v, s') -> do put s'
@@ -374,13 +383,13 @@ try t1 t2 = do s <- get
374 _ -> do put s; t2
383 _ -> do put s; t2
376-- Try a selection of tactics. Exactly one must work, all others must fail
385-- 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
378tryAll xs = tryAll' [] (fail "Nothing to try") (map fst xs)
387tryAll xs = tryAll' [] (fail "Nothing to try") (map fst xs)
380− tryAll' :: [Elab a] -> -- successes
389+ tryAll' :: [Elab' aux a] -> -- successes
381− Elab a -> -- last failure
390+ Elab' aux a -> -- last failure
382− [Elab a] -> -- still to try
391+ [Elab' aux a] -> -- still to try
383− Elab a
392+ Elab' aux a
384 tryAll' [res] _ [] = res
393 tryAll' [res] _ [] = res
385 tryAll' (_:_) _ [] = fail $ "Couldn't resolve alternative: "
394 tryAll' (_:_) _ [] = fail $ "Couldn't resolve alternative: "
386 ++ showSep ", " (map snd xs)
395 ++ showSep ", " (map snd xs)