@@ -34,6 +34,7 @@ data Command = Theorem Name Raw
3434data Tactic = Attack
3535 | Claim Name Raw
3636 | Fill Raw
37+ | UnifyFill Raw
3738 | Regret
3839 | Solve
3940 | Compute
@@ -49,6 +50,7 @@ data TacticAction = AddGoal Name -- add a new goal, solve immediately
4950 | NextGoal Name -- add a new goal, solve it after current one
5051 | FocusGoal Name -- focus on this goal next
5152 | Solved Name
53+ | AlsoSolved Name Term -- goals solved by unification
5254 | Log String
5355
5456-- Some utilites on proof and tactic states
@@ -162,6 +164,20 @@ fill guess ctxt env (Bind x (Hole ty) sc) =
162164 return $ Bind x (Guess ty val) sc
163165fill _ _ _ _ = fail "Can't fill here."
164166
167+-- As fill, but attempts to solve other goals by unification
168+
169+unify_fill :: Raw -> RunTactic
170+unify_fill guess ctxt env (Bind x (Hole ty) sc) =
171+ do (val, valty) <- lift $ check ctxt env guess
172+ ns <- lift $ unify ctxt env valty ty
173+ solve_all ns
174+ return $ Bind x (Guess ty val) sc
175+ where
176+ solve_all [] = return ()
177+ solve_all ((n, tm): ns) = do action (AlsoSolved n tm)
178+ solve_all ns
179+unify_fill _ _ _ _ = fail "Can't fill here."
180+
165181solve :: RunTactic
166182solve ctxt env (Bind x (Guess ty val) sc)
167183 | pureTerm val = do action (Solved x)
@@ -209,13 +225,15 @@ processTactic QED ps = case holes ps of
209225 "Proof complete: " ++ showEnv [] tm)
210226 _ -> Error "Still holes to fill."
211227processTactic ProofState ps = return (ps, showEnv [] (pterm ps))
212−processTactic t ps = case holes ps of
213− [] -> Error "Nothing to fill in."
214− (h:_) -> do let n = nextname ps
215− (ps',(n', actions)) <- runStateT (process t h ps) (n, [])
216− return (ps' { nextname = n',
217− holes = goals (holes ps') actions },
218− logs actions)
228+processTactic t ps
229+ = case holes ps of
230+ [] -> Error "Nothing to fill in."
231+ (h:_) -> do let n = nextname ps
232+ (ps', (n', actions)) <- runStateT (process t h ps) (n, [])
233+ return (ps' { nextname = n',
234+ pterm = updateSolved (getSolved actions) (pterm ps'),
235+ holes = goals (holes ps') actions },
236+ logs actions)
219237 where logs [] = ""
220238 logs (Log x : xs) = x ++ "\n" ++ logs xs
221239 logs (_ : xs) = logs xs
@@ -225,18 +243,31 @@ processTactic t ps = case holes ps of
225243 goals (g:gs) (NextGoal n : xs) = goals (g : n : gs) xs
226244 goals g (FocusGoal n : xs) = goals (n : (g \\ [n])) xs
227245 goals g (Solved n : xs) = goals (g \\ [n]) xs
246+ goals g (AlsoSolved n tm : xs) = goals (g \\ [n]) xs
228247 goals g (_ : xs) = goals g xs
229248
249+ getSolved [] = []
250+ getSolved (AlsoSolved n tm : xs) = (n, tm) : getSolved xs
251+ getSolved (_ : xs) = getSolved xs
252+
253+ updateSolved xs (Bind n b t)
254+ | Just v <- lookup n xs = Bind n (Let (binderTy b) v) (updateSolved xs t)
255+ | otherwise = Bind n (fmap (updateSolved xs) b) (updateSolved xs t)
256+ updateSolved xs (App f a) = App (updateSolved xs f) (updateSolved xs a)
257+ updateSolved xs t = t
258+
259+
230260
231261process :: Tactic -> Name -> ProofState -> StateT TState TC ProofState
232262process t h ps = tactic (Just h) ps (context ps) (mktac t)
233− where mktac Attack = attack
234− mktac (Claim n r) = claim n r
235− mktac (Fill r) = fill r
236− mktac Regret = regret
237− mktac Solve = solve
238− mktac Compute = compute
239− mktac (Intro n) = intro n
240− mktac (CheckIn r) = check_in r
241− mktac (EvalIn r) = eval_in r
242− mktac (Focus n) = focus n
263+ where mktac Attack = attack
264+ mktac (Claim n r) = claim n r
265+ mktac (Fill r) = fill r
266+ mktac (UnifyFill r) = unify_fill r
267+ mktac Regret = regret
268+ mktac Solve = solve
269+ mktac Compute = compute
270+ mktac (Intro n) = intro n
271+ mktac (CheckIn r) = check_in r
272+ mktac (EvalIn r) = eval_in r
273+ mktac (Focus n) = focus n