{- | Module : $Header$ Description : Check the equality of two FlatCurry interfaces Copyright : (c) 2006 , Martin Engelke 2011 - 2014, Björn Peemöller 2014 , Jan Tikovsky License : BSD-3-clause Maintainer : bjp@informatik.uni-kiel.de Stability : experimental Portability : portable -} module Curry.FlatCurry.InterfaceEquivalence (eqInterface) where import Data.List (deleteFirstsBy) import Curry.FlatCurry.Type infix 4 =~=, `eqvSet` -- |Check whether the interfaces of two FlatCurry programs are equivalent. eqInterface :: Prog -> Prog -> Bool eqInterface = (=~=) -- |Type class to express the equivalence of two values class Equiv a where (=~=) :: a -> a -> Bool instance Equiv a => Equiv [a] where [] =~= [] = True (x:xs) =~= (y:ys) = x =~= y && xs =~= ys _ =~= _ = False instance Equiv Char where (=~=) = (==) -- |Equivalence of lists independent of the order. eqvSet :: Equiv a => [a] -> [a] -> Bool xs `eqvSet` ys = null (deleteFirstsBy (=~=) xs ys ++ deleteFirstsBy (=~=) ys xs) instance Equiv Prog where Prog m1 is1 ts1 fs1 os1 =~= Prog m2 is2 ts2 fs2 os2 = m1 == m2 && is1 `eqvSet` is2 && ts1 `eqvSet` ts2 && fs1 `eqvSet` fs2 && os1 `eqvSet` os2 instance Equiv TypeDecl where (=~=) = (==) instance Equiv FuncDecl where Func qn1 ar1 vis1 ty1 r1 =~= Func qn2 ar2 vis2 ty2 r2 = qn1 == qn2 && ar1 == ar2 && vis1 == vis2 && ty1 == ty2 && r1 =~= r2 -- TODO: Check why arguments of rules are not checked for equivalence instance Equiv Rule where Rule _ _ =~= Rule _ _ = True External _ =~= External _ = True _ =~= _ = False instance Equiv OpDecl where (=~=) = (==)