@@ -48,10 +48,10 @@ match_unify ctxt env topx topy dont holes =
49 un names (P _ x _) tm
49 un names (P _ x _) tm
50 | holeIn env x || x `elem` holes
50 | holeIn env x || x `elem` holes
51− = do sc 1; checkCycle (x, tm)
51+ = do sc 1; checkCycle names (x, tm)
52 un names tm (P _ y _)
52 un names tm (P _ y _)
53 | holeIn env y || y `elem` holes
53 | holeIn env y || y `elem` holes
54− = do sc 1; checkCycle (y, tm)
54+ = do sc 1; checkCycle names (y, tm)
55 un bnames (V i) (P _ x _)
55 un bnames (V i) (P _ x _)
56 | fst (bnames!!i) == x || snd (bnames!!i) == x = do sc 1; return []
56 | fst (bnames!!i) == x || snd (bnames!!i) == x = do sc 1; return []
57 un bnames (P _ x _) (V i)
57 un bnames (P _ x _) (V i)
@@ -93,11 +93,19 @@ match_unify ctxt env topx topy dont holes =
94 combine bnames as (ns' ++ bs)
94 combine bnames as (ns' ++ bs)
96− checkCycle p@(x, P _ _ _) = return [p]
96+ checkCycle ns p@(x, P _ _ _) = return [p]
97− checkCycle (x, tm)
97+ checkCycle ns (x, tm)
98− | not (x `elem` freeNames tm) = return [(x, tm)]
98+ | not (x `elem` freeNames tm) = checkScope ns (x, tm)
99 | otherwise = lift $ tfail (InfiniteUnify x tm (errEnv env))
99 | otherwise = lift $ tfail (InfiniteUnify x tm (errEnv env))
101+ checkScope ns (x, tm) =
102+ case boundVs (envPos x 0 env) tm of
103+ [] -> return [(x, tm)]
104+ (i:_) -> lift $ tfail (UnifyScope x (fst (ns!!i))
105+ (inst ns tm) (errEnv env))
106+ where inst [] tm = tm
107+ inst ((n, _) : ns) tm = inst ns (substV (P Bound n Erased) tm)
101notTrivial (x, P _ x' _) = x /= x'
109notTrivial (x, P _ x' _) = x /= x'
102notTrivial _ = True
110notTrivial _ = True
@@ -195,7 +203,7 @@ unify ctxt env topx topy dont holes =
195-- put (UI s ((tm, topx, topy) : i) f)
203-- put (UI s ((tm, topx, topy) : i) f)
196 then unifyTmpFail xtm tm
204 then unifyTmpFail xtm tm
197 else do sc 1
205 else do sc 1
198− checkCycle (x, tm)
206+ checkCycle bnames (x, tm)
199 | not (injective xtm) && injective tm = unifyFail xtm tm
207 | not (injective xtm) && injective tm = unifyFail xtm tm
200 un' fn bnames tm ytm@(P _ y _)
208 un' fn bnames tm ytm@(P _ y _)
201 | holeIn env y || y `elem` holes
209 | holeIn env y || y `elem` holes
@@ -206,7 +214,7 @@ unify ctxt env topx topy dont holes =
206-- put (UI s ((tm, topx, topy) : i) f)
214-- put (UI s ((tm, topx, topy) : i) f)
207 then unifyTmpFail tm ytm
215 then unifyTmpFail tm ytm
208 else do sc 1
216 else do sc 1
209− checkCycle (y, tm)
217+ checkCycle bnames (y, tm)
210 | not (injective ytm) && injective tm = unifyFail ytm tm
218 | not (injective ytm) && injective tm = unifyFail ytm tm
211 un' fn bnames (V i) (P _ x _)
219 un' fn bnames (V i) (P _ x _)
212 | fst (bnames!!i) == x || snd (bnames!!i) == x = do sc 1; return []
220 | fst (bnames!!i) == x || snd (bnames!!i) == x = do sc 1; return []
@@ -398,11 +406,18 @@ unify ctxt env topx topy dont holes =
398 put (UI s ((binderTy x, binderTy y, env, err) : f))
406 put (UI s ((binderTy x, binderTy y, env, err) : f))
399 return [] -- lift $ tfail err
407 return [] -- lift $ tfail err
401− checkCycle p@(x, P _ _ _) = return [p]
409+ checkCycle ns p@(x, P _ _ _) = return [p]
402− checkCycle (x, tm)
410+ checkCycle ns (x, tm)
403− | not (x `elem` freeNames tm) = return [(x, tm)]
411+ | not (x `elem` freeNames tm) = checkScope ns (x, tm)
404 | otherwise = lift $ tfail (InfiniteUnify x tm (errEnv env))
412 | otherwise = lift $ tfail (InfiniteUnify x tm (errEnv env))
414+ checkScope ns (x, tm) =
415+ case boundVs (envPos x 0 env) tm of
416+ [] -> return [(x, tm)]
417+ (i:_) -> lift $ tfail (UnifyScope x (fst (ns!!i))
418+ (inst ns tm) (errEnv env))
419+ where inst [] tm = tm
420+ inst ((n, _) : ns) tm = inst ns (substV (P Bound n Erased) tm)
407 combineArgs bnames args = ca [] args where
422 combineArgs bnames args = ca [] args where
408 ca acc [] = return acc
423 ca acc [] = return acc
@@ -419,6 +434,20 @@ unify ctxt env topx topy dont holes =
420 combine bnames as (ns' ++ bs)
435 combine bnames as (ns' ++ bs)
437+boundVs :: Int -> Term -> [Int]
438+boundVs i (V j) | j <= i = []
440+boundVs i (Bind n b sc) = boundVs (i + 1) sc
441+boundVs i (App f x) = let fs = boundVs i f
447+envPos x i ((y, _) : ys) | x == y = i
448+ | otherwise = envPos x (i + 1) ys
422-- If there are any clashes of constructors, deem it unrecoverable, otherwise some
451-- If there are any clashes of constructors, deem it unrecoverable, otherwise some
423-- more work may help.
452-- more work may help.
424-- FIXME: Depending on how overloading gets used, this may cause problems. Better
453-- FIXME: Depending on how overloading gets used, this may cause problems. Better