@@ -7,7 +7,7 @@ evaluation/checking inside the proof system, etc.
77
88module Idris.Core.ProofTerm(ProofTerm, Goal(..), mkProofTerm, getProofTerm,
99 updateSolved, updateSolvedTerm, updateSolvedTerm',
10− bound_in, bound_in_term, refocus,
10+ bound_in, bound_in_term, refocus, updsubst,
1111 Hole, RunTactic',
1212 goal, atHole) where
1313
@@ -73,6 +73,7 @@ findHole :: Name -> Env -> Term -> Maybe (TermPath, Env, Term)
7373findHole n env t = fh' env Top t where
7474 fh' env path tm@(Bind x h sc)
7575 | hole h && n == x = Just (path, env, tm)
76+ fh' env path (App Complete _ _) = Nothing
7677 fh' env path (App s f a)
7778 | Just (p, env', tm) <- fh' env path a = Just (AppR s f p, env', tm)
7879 | Just (p, env', tm) <- fh' env path f = Just (AppL s p a, env', tm)
@@ -156,15 +157,16 @@ updateSolvedTerm' xs x = updateSolved' xs x where
156157 updateSolved' xs (Bind n (Hole ty) t)
157158 | Just v <- lookup n xs
158159 = case xs of
159− [_] -> (subst n v t, True) -- some may be Vs! Can't assume
160+ [_] -> (updsubst n v t, True) -- some may be Vs! Can't assume
160161 -- explicit names
161162 _ -> let (t', _) = updateSolved' xs t in
162− (subst n v t', True)
163+ (updsubst n v t', True)
163164 updateSolved' xs tm@(Bind n b t)
164165 | otherwise = let (t', ut) = updateSolved' xs t
165166 (b', ub) = updateSolvedB' xs b in
166167 if ut || ub then (Bind n b' t', True)
167168 else (tm, False)
169+ updateSolved' xs t@(App Complete f a) = (t, False)
168170 updateSolved' xs t@(App s f a)
169171 = let (f', uf) = updateSolved' xs f
170172 (a', ua) = updateSolved' xs a in
@@ -198,6 +200,49 @@ updateSolvedTerm' xs x = updateSolved' xs x where
198200 noneOfB ns b = noneOf ns (binderTy b)
199201 noneOf ns _ = True
200202
203+-- | As 'subst', in TT, but takes advantage of knowing not to substitute
204+-- under Complete applications.
205+updsubst :: Eq n => n {-^ The id to replace -} ->
206+ TT n {-^ The replacement term -} ->
207+ TT n {-^ The term to replace in -} ->
208+ TT n
209+-- subst n v tm = instantiate v (pToV n tm)
210+updsubst n v tm = fst $ subst' 0 tm
211+ where
212+ -- keep track of updates to save allocations - this is a big win on
213+ -- large terms in particular
214+ -- ('Maybe' would be neater here, but >>= is not the right combinator.
215+ -- Feel free to tidy up, as long as it still saves allocating when no
216+ -- substitution happens...)
217+ subst' i (V x) | i == x = (v, True)
218+ subst' i (P _ x _) | n == x = (v, True)
219+ subst' i t@(P nt x ty)
220+ = let (ty', ut) = subst' i ty in
221+ if ut then (P nt x ty', True) else (t, False)
222+ subst' i t@(Bind x b sc) | x /= n
223+ = let (b', ub) = substB' i b
224+ (sc', usc) = subst' (i+1) sc in
225+ if ub || usc then (Bind x b' sc', True) else (t, False)
226+ subst' i t@(App Complete f a) = (t, False)
227+ subst' i t@(App s f a) = let (f', uf) = subst' i f
228+ (a', ua) = subst' i a in
229+ if uf || ua then (App s f' a', True) else (t, False)
230+ subst' i t@(Proj x idx) = let (x', u) = subst' i x in
231+ if u then (Proj x' idx, u) else (t, False)
232+ subst' i t = (t, False)
233+
234+ substB' i b@(Let t v) = let (t', ut) = subst' i t
235+ (v', uv) = subst' i v in
236+ if ut || uv then (Let t' v', True)
237+ else (b, False)
238+ substB' i b@(Guess t v) = let (t', ut) = subst' i t
239+ (v', uv) = subst' i v in
240+ if ut || uv then (Guess t' v', True)
241+ else (b, False)
242+ substB' i b = let (ty', u) = subst' i (binderTy b) in
243+ if u then (b { binderTy = ty' }, u) else (b, False)
244+
245+
201246-- | Apply solutions to an environment.
202247updateEnv :: [(Name, Term)] -> Env -> Env
203248updateEnv [] e = e
@@ -208,6 +253,8 @@ updateEnv ns ((n, b) : env) = (n, fmap (updateSolvedTerm ns) b) : updateEnv ns e
208253updateSolvedPath :: [(Name, Term)] -> TermPath -> TermPath
209254updateSolvedPath [] t = t
210255updateSolvedPath ns Top = Top
256+updateSolvedPath ns t@(AppL Complete _ _) = t
257+updateSolvedPath ns t@(AppR Complete _ _) = t
211258updateSolvedPath ns (AppL s p r) = AppL s (updateSolvedPath ns p) (updateSolvedTerm ns r)
212259updateSolvedPath ns (AppR s l p) = AppR s (updateSolvedTerm ns l) (updateSolvedPath ns p)
213260updateSolvedPath ns (InBind n b sc)
@@ -246,6 +293,7 @@ goal h pt@(PT path env sub ups)
246293 g env (Bind n b sc) | hole b && same h n = return $ GD env b
247294 | otherwise
248295 = g ((n, b):env) sc `mplus` gb env b
296+ g env (App Complete f a) = fail "Can't find hole"
249297 g env (App _ f a) = g env a `mplus` g env f
250298 g env t = fail "Can't find hole"
251299