Subversion

Galculator

?curdirlinks? - Rev 7

?prevdifflink? - Blame



{-# LANGUAGE FlexibleContexts #-}
{-# OPTIONS_GHC -Wall #-}
 
-------------------------------------------------------------------------------

{- |
Module      :  Language.Type.Unification
Description :  Unification algorithm for the polymorphic type representation.
Copyright   :  (c) Paulo Silva
License     :  LGPL
 
Maintainer  :  paufil@di.uminho.pt
Stability   :  experimental
Portability :  portable
 
-}


-------------------------------------------------------------------------------
 
module Language.Type.Unification  (
 unify
 )   where

import Control.GalcError
import Control.Monad.Error
import Data.Existential
import Language.Type.Constraint
import Language.Type.Equality
import Language.Type.Syntax
import Language.Type.Utils
import Prelude hiding (all,fail)

-------------------------------------------------------------------------------

unify :: (MonadError GalcError m)
      => [Constraint] -> m [Constraint]
unify [] = return []
unify ((s :=: t):c)
  | isTVar s && isTVar t && beq s t =              -- delete rule (variables)
      unify c
  | isBasicType s && isBasicType t && beq s t =    -- delete rule (base types)
      unify c
  | isTVar t && not (isTVar s) =                     -- orient rule
      unify $ (t :=: s):c
  | isConstructor s && isConstructor t = do          -- decompose rule
      cns <- decompose s t
      unify $ cns++c
  | isTVar s && not (occursIn s t) = do              -- eliminate rule
      c' <- substitution [s :=: t] c
      sbs <- unify c'
      Hide t' <- typeRewriteE sbs t
      return $ (s :=: t'):sbs
  | otherwise =
      throwError $ UnificationError (show s, show t)  -- typing error

-------------------------------------------------------------------------------

substitution :: MonadError GalcError m
             => [Constraint] -> [Constraint] -> m [Constraint]
substitution subst = mapM aux
  where aux (t1 :=: t2) = do
          Hide t1' <- typeRewriteE subst t1
          Hide t2' <- typeRewriteE subst t2
          return $ t1' :=: t2'

-------------------------------------------------------------------------------

decompose :: MonadError GalcError m => Type a -> Type b -> m [Constraint]
decompose (Prod a b) (Prod a' b') = return [a :=: a', b :=: b']
decompose (Either a b) (Either a' b') = return [a :=: a', b :=: b']
decompose (Maybe a) (Maybe a') = return [a :=: a']
decompose (List a) (List a') = return [a :=: a']
decompose (Set a) (Set a') = return [a :=: a']
decompose (Map a b) (Map a' b') = return [a :=: a', b :=: b']
decompose (Fun a b) (Fun a' b') = return [a :=: a', b :=: b']
decompose (Rel a b) (Rel a' b') = return [a :=: a', b :=: b']
decompose (Ord a) (Ord a') = return [a :=: a']
decompose (GC a b) (GC a' b') = return [a :=: a', b :=: b']
decompose t1 t2 = throwError $ DecomposeError (show t1) (show t2)

-------------------------------------------------------------------------------

 

Theme by Vikram Singh | Powered by WebSVN v2.3.3