@@ -2,7 +2,7 @@
22 PatternGuards #-}
33
44module Core.Evaluate(normalise, normaliseC, normaliseAll,
5− simplify, specialise, hnf,
5+ simplify, specialise, hnf, convEq, convEq',
66 Def(..), Accessibility(..), Totality(..), PReason(..),
77 Context, initContext, ctxtAlist, uconstraints, next_tvar,
88 addToCtxt, setAccess, setTotal, addCtxtDef, addTyDecl, addDatatype,
@@ -424,6 +424,56 @@ eval_hnf ctxt statics genv tm = ev [] tm where
424424 getValArgs (HApp t env args) = (t, env, args)
425425 getValArgs t = (t, [], [])
426426
427+convEq' ctxt x y = evalStateT (convEq ctxt x y) (0, [])
428+
429+convEq :: Context -> TT Name -> TT Name -> StateT UCs TC Bool
430+convEq ctxt = ceq [] where
431+ ceq :: [(Name, Name)] -> TT Name -> TT Name -> StateT UCs TC Bool
432+ ceq ps (P xt x _) (P yt y _)
433+ | (xt == yt && x ==y ) || (x, y) `elem` ps || (y,x) `elem` ps = return True
434+ | otherwise = sameDefs ps x y
435+ ceq ps (V x) (V y) = return (x == y)
436+ ceq ps (Bind _ xb xs) (Bind _ yb ys)
437+ = liftM2 (&&) (ceqB ps xb yb) (ceq ps xs ys)
438+ where
439+ ceqB ps (Let v t) (Let v' t') = liftM2 (&&) (ceq ps v v') (ceq ps t t')
440+ ceqB ps (Guess v t) (Guess v' t') = liftM2 (&&) (ceq ps v v') (ceq ps t t')
441+ ceqB ps b b' = ceq ps (binderTy b) (binderTy b')
442+ ceq ps (App fx ax) (App fy ay) = liftM2 (&&) (ceq ps fx fy) (ceq ps ax ay)
443+ ceq ps (Constant x) (Constant y) = return (x == y)
444+ ceq ps (Set x) (Set y) = do (v, cs) <- get
445+ put (v, ULE x y : cs)
446+ return True
447+ ceq ps Erased _ = return True
448+ ceq ps _ Erased = return True
449+ ceq ps _ _ = return False
450+
451+ caseeq ps (Case n cs) (Case n' cs') = caseeqA ((n,n'):ps) cs cs'
452+ where
453+ caseeqA ps (ConCase x i as sc : rest) (ConCase x' i' as' sc' : rest')
454+ = do q1 <- caseeq (zip as as' ++ ps) sc sc'
455+ q2 <- caseeqA ps rest rest'
456+ return $ x == x' && i == i' && q1 && q2
457+ caseeqA ps (ConstCase x sc : rest) (ConstCase x' sc' : rest')
458+ = do q1 <- caseeq ps sc sc'
459+ q2 <- caseeqA ps rest rest'
460+ return $ x == x' && q1 && q2
461+ caseeqA ps (DefaultCase sc : rest) (DefaultCase sc' : rest')
462+ = liftM2 (&&) (caseeq ps sc sc') (caseeqA ps rest rest')
463+ caseeqA ps [] [] = return True
464+ caseeqA ps _ _ = return False
465+ caseeq ps (STerm x) (STerm y) = ceq ps x y
466+ caseeq ps (UnmatchedCase _) (UnmatchedCase _) = return True
467+ caseeq ps _ _ = return False
468+
469+ sameDefs ps x y = case (lookupDef Nothing x ctxt, lookupDef Nothing y ctxt) of
470+ ([Function _ xdef], [Function _ ydef])
471+ -> ceq ((x,y):ps) xdef ydef
472+ ([CaseOp _ _ _ _ xdef _ _],
473+ [CaseOp _ _ _ _ ydef _ _])
474+ -> caseeq ((x,y):ps) xdef ydef
475+ _ -> return False
476+
427477-- SPECIALISATION -----------------------------------------------------------
428478-- We need too much control to be able to do this by tweaking the main
429479-- evaluator