@@ -1,6 +1,6 @@
1{-# LANGUAGE PatternGuards #-}
1{-# LANGUAGE PatternGuards #-}
3−module Core.Unify(unify, Fails) where
3+module Core.Unify(match_unify, unify, Fails) where
5import Core.TT
5import Core.TT
6import Core.Evaluate
6import Core.Evaluate
@@ -27,6 +27,66 @@ data UResult a = UOK a
27 | UPartOK a
27 | UPartOK a
28 | UFail Err
28 | UFail Err
30+-- Solve metavariables by matching terms against each other
31+-- Not really unification, of course!
33+match_unify :: Context -> Env -> TT Name -> TT Name -> [Name] -> [Name] ->
35+match_unify ctxt env topx topy dont holes =
36+-- trace ("Matching " ++ show (topx, topy)) $
37+ case runStateT (un [] topx topy) (UI 0 []) of
38+ OK (v, UI _ fails) -> return (filter notTrivial v)
41+ un names (P _ x _) tm
42+ | holeIn env x || x `elem` holes
43+ = do sc 1; checkCycle (x, tm)
44+ un names tm (P _ y _)
45+ | holeIn env y || y `elem` holes
46+ = do sc 1; checkCycle (y, tm)
48+ | OK True <- convEq' ctxt x y = do sc 1; return []
49+ un bnames (V i) (P _ x _)
50+ | fst (bnames!!i) == x || snd (bnames!!i) == x = do sc 1; return []
51+ un bnames (P _ x _) (V i)
52+ | fst (bnames!!i) == x || snd (bnames!!i) == x = do sc 1; return []
53+ un names (App fx ax) (App fy ay)
54+ = do hf <- un names fx fy
59+ -- TODO: there's an annoying amount of repetition between this and the
60+ -- main unification function. Consider lifting it out.
62+ sc i = do UI s f <- get
65+ unifyFail x y = do UI s f <- get
66+ let r = recoverable x y
67+ let err = CantUnify r
68+ topx topy (CantUnify r x y (Msg "") [] s) (errEnv env) s
69+ put (UI s ((x, y, env, err) : f))
71+ combine bnames as [] = return as
72+ combine bnames as ((n, t) : bs)
73+ = case lookup n as of
74+ Nothing -> combine bnames (as ++ [(n,t)]) bs
75+ Just t' -> do ns <- un bnames t t'
76+ -- make sure there's n mapping from n in ns
77+ let ns' = filter (\ (x, _) -> x/=n) ns
79+ combine bnames as (ns' ++ bs)
81+ checkCycle p@(x, P _ _ _) = return [p]
83+ | not (x `elem` freeNames tm) = return [(x, tm)]
84+ | otherwise = lift $ tfail (InfiniteUnify x tm (errEnv env))
86+notTrivial (x, P _ x' _) = x /= x'
30unify :: Context -> Env -> TT Name -> TT Name -> [Name] -> [Name] ->
90unify :: Context -> Env -> TT Name -> TT Name -> [Name] -> [Name] ->
31 TC ([(Name, TT Name)], Fails)
91 TC ([(Name, TT Name)], Fails)
32unify ctxt env topx topy dont holes =
92unify ctxt env topx topy dont holes =
@@ -45,9 +105,6 @@ unify ctxt env topx topy dont holes =
45-- Error e@(CantUnify False _ _ _ _ _) -> tfail e
105-- Error e@(CantUnify False _ _ _ _ _) -> tfail e
46 Error e -> tfail e
106 Error e -> tfail e
48− notTrivial (x, P _ x' _) = x /= x'
51 headDiff (P (DCon _ _) x _) (P (DCon _ _) y _) = x /= y
108 headDiff (P (DCon _ _) x _) (P (DCon _ _) y _) = x /= y
52 headDiff (P (TCon _ _) x _) (P (TCon _ _) y _) = x /= y
109 headDiff (P (TCon _ _) x _) (P (TCon _ _) y _) = x /= y
53 headDiff _ _ = False
110 headDiff _ _ = False
@@ -311,6 +368,7 @@ unify ctxt env topx topy dont holes =
311 | not (x `elem` freeNames tm) = return [(x, tm)]
368 | not (x `elem` freeNames tm) = return [(x, tm)]
312 | otherwise = lift $ tfail (InfiniteUnify x tm (errEnv env))
369 | otherwise = lift $ tfail (InfiniteUnify x tm (errEnv env))
314 combineArgs bnames args = ca [] args where
372 combineArgs bnames args = ca [] args where
315 ca acc [] = return acc
373 ca acc [] = return acc
316 ca acc (x : xs) = do x' <- combine bnames acc x
374 ca acc (x : xs) = do x' <- combine bnames acc x
@@ -326,30 +384,30 @@ unify ctxt env topx topy dont holes =
327 combine bnames as (ns' ++ bs)
385 combine bnames as (ns' ++ bs)
329− -- If there are any clashes of constructors, deem it unrecoverable, otherwise some
387+-- If there are any clashes of constructors, deem it unrecoverable, otherwise some
330− -- more work may help.
388+-- more work may help.
331− -- FIXME: Depending on how overloading gets used, this may cause problems. Better
389+-- FIXME: Depending on how overloading gets used, this may cause problems. Better
332− -- rethink overloading properly...
390+-- rethink overloading properly...
334− recoverable (P (DCon _ _) x _) (P (DCon _ _) y _)
392+recoverable (P (DCon _ _) x _) (P (DCon _ _) y _)
335− | x == y = True
393+ | x == y = True
336− | otherwise = False
394+ | otherwise = False
337− recoverable (P (TCon _ _) x _) (P (TCon _ _) y _)
395+recoverable (P (TCon _ _) x _) (P (TCon _ _) y _)
338− | x == y = True
396+ | x == y = True
339− | otherwise = False
397+ | otherwise = False
340− recoverable (Constant _) (P (DCon _ _) y _) = False
398+recoverable (Constant _) (P (DCon _ _) y _) = False
341− recoverable (P (DCon _ _) x _) (Constant _) = False
399+recoverable (P (DCon _ _) x _) (Constant _) = False
342− recoverable (Constant _) (P (TCon _ _) y _) = False
400+recoverable (Constant _) (P (TCon _ _) y _) = False
343− recoverable (P (TCon _ _) x _) (Constant _) = False
401+recoverable (P (TCon _ _) x _) (Constant _) = False
344− recoverable (P (DCon _ _) x _) (P (TCon _ _) y _) = False
402+recoverable (P (DCon _ _) x _) (P (TCon _ _) y _) = False
345− recoverable (P (TCon _ _) x _) (P (DCon _ _) y _) = False
403+recoverable (P (TCon _ _) x _) (P (DCon _ _) y _) = False
346− recoverable p@(Constant _) (App f a) = recoverable p f
404+recoverable p@(Constant _) (App f a) = recoverable p f
347− recoverable (App f a) p@(Constant _) = recoverable f p
405+recoverable (App f a) p@(Constant _) = recoverable f p
348− recoverable p@(P _ n _) (App f a) = recoverable p f
406+recoverable p@(P _ n _) (App f a) = recoverable p f
349-- recoverable (App f a) p@(P _ _ _) = recoverable f p
407-- recoverable (App f a) p@(P _ _ _) = recoverable f p
350− recoverable (App f a) (App f' a')
408+recoverable (App f a) (App f' a')
351− = recoverable f f' -- && recoverable a a'
409+ = recoverable f f' -- && recoverable a a'
352− recoverable _ _ = True
410+recoverable _ _ = True
354errEnv = map (\(x, b) -> (x, binderTy b))
412errEnv = map (\(x, b) -> (x, binderTy b))