2155N/ADescription : choose a minimal type for overloaded terms
2155N/ACopyright : (c) Christian Maeder and Uni Bremen 2003
2155N/AMaintainer : Christian.Maeder@dfki.de
2155N/Aq2p :: (a, b, c, d) -> (c, d)
2155N/AtypeNub :: Env -> (a -> (Type, Term)) -> [a] -> [a]
2155N/A comp (ty1, t1) (ty2, t2) = eqTerm e t1 t2 &&
2155N/AeqTerm :: Env -> Term -> Term -> Bool
2155N/AeqTerm e t1 t2 = case (t1, t2) of
2155N/A (TypedTerm t _ _ _, _) -> eqTerm e t t2
2155N/A (_, TypedTerm t _ _ _) -> eqTerm e t1 t
2155N/A (QualVar (VarDecl v1 _s1 _ _), QualVar (VarDecl v2 _s2 _ _)) ->
2155N/A (QualOp _ i1 s1 _ _ _, QualOp _ i2 s2 _ _ _) -> i1 == i2
2155N/A && haveCommonSupertype e s1 s2
2155N/A (ApplTerm tf1 ta1 _, ApplTerm tf2 ta2 _) ->
2155N/A eqTerm e tf1 tf2 && eqTerm e ta1 ta2
2155N/A (TupleTerm ts1 _, TupleTerm ts2 _) ->
2155N/A length ts1 == length ts2 && and (zipWith (eqTerm e) ts1 ts2)
2155N/A (QuantifiedTerm q1 vs1 f1 _, QuantifiedTerm q2 vs2 f2 _) ->
2155N/A (q1, vs1) == (q2, vs2) && eqTerm e f1 f2
2155N/A (LambdaTerm ps1 p1 f1 _, LambdaTerm ps2 p2 f2 _) ->
2155N/A and (zipWith (eqTerm e) ps1 ps2) && p1 == p2 && eqTerm e f1 f2
2155N/A && length ps1 == length ps2
2155N/A (CaseTerm f1 e1 _, CaseTerm f2 e2 _) ->
2155N/A eqTerm e f1 f2 && length e1 == length e2
2155N/A && and (zipWith (eqProgEq e) e1 e2)
2155N/A (LetTerm _ e1 f1 _, LetTerm _ e2 f2 _) ->
2155N/A eqTerm e f1 f2 && length e1 == length e2
2155N/A && and (zipWith (eqProgEq e) e1 e2)
eqProgEq :: Env -> ProgEq -> ProgEq -> Bool
eqProgEq e (ProgEq p1 t1 _) (ProgEq p2 t2 _) = eqTerm e p1 p2 && eqTerm e t1 t2
addToEnv :: (Type, VarKind) -> Env -> Env
addToEnv (ty, vk) e = case ty of
TypeName i rk c | c > 0 ->
execState (addLocalTypeVar False (TypeVarDefn NonVar vk rk c) i) e
haveCommonSupertype :: Env -> TypeScheme -> TypeScheme -> Bool
haveCommonSupertype e s = isJust . getCommonSupertype e s
getCommonSupertype :: Env -> TypeScheme -> TypeScheme -> Maybe TypeTriple
getCommonSupertype e s1 s2 =
evalState (toEnvState $ haveCommonSupertypeE e s1 s2) e
type TypeTriple = (Type, [Type], Type, [Type], [TypeArg], Type)
haveCommonSupertypeE :: Env -> TypeScheme -> TypeScheme
-> State Int (Maybe TypeTriple)
haveCommonSupertypeE eIn s1 s2 = do
cst <- mkSingleSubst (genName "commonSupertype", rStar)
e = foldr addToEnv eIn $ (cst, VarKind universe) : l1 ++ l2
Result _ mr <- shapeRelAndSimplify False e cs (Just cst)
Just (sbst, rcs) -> let (qs, subC) = partitionC rcs
in case reduceCommonSubtypes
doSubst = subst $ compSubst sbst msb
[ty, ty1, ty2] = map doSubst [cst, t1, t2]
fvs = foldr1
List.union $ map freeTVars [ty1, ty2, ty]
comp a b = compare (fst a) $ fst b
newArgs = map ( \ (_, (i, _)) -> case
Map.lookup i tvs of
Nothing -> error $ "generalizeS " ++ show (i, ty)
++ "\n" ++ showDoc (s1, s2) ""
Just (TypeVarDefn v vk rk c) ->
TypeArg i v vk rk c Other nullRange) svs
genArgs = generalize newArgs
[gty, gty1, gty2] = map genArgs [ty, ty1, ty2]
gl1 = map (genArgs . doSubst . fst) l1
gl2 = map (genArgs . doSubst . fst) l2
in Just (gty1, gl1, gty2, gl2, genTypeArgs newArgs, gty)
reduceCommonSubtypes ::
Rel.Rel Type -> [(Type, Type)] -> Maybe Subst
reduceCommonSubtypes e l = let
mygroup = groupBy ( \ (a, b) (c, d) -> case (a, b, d) of
(TypeName _ _ n, TypeName _ _ 0, TypeName _ _ 0)
mypart = partition ( \ s -> case s of
[] -> error "reduceCommonSubtypes1"
(csubts, rest) = mypart $ mygroup l
swap = map $ \ (a, b) -> (b, a)
(csuperts, rest2) = mypart $ mygroup $ sort $ swap (concat rest)
(a, _) : _ -> (a, map snd s)
_ -> error "reduceCommonSubtypes2"
subM = mapM (commonSubtype e True . mkPair) csubts
superM = mapM (commonSubtype e False . mkPair) csuperts
in case (concat rest2, subM, superM) of
commonSubtype ::
Rel.Rel Type -> Bool -> (Type, [Type]) -> Maybe (Int, Type)
commonSubtype trel b (ty, l) =
TypeName _ _ n | not (
Set.null tySet) && n > 0