{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ImpredicativeTypes #-}
module Data.Equality.Analysis where
import Data.Kind (Type)
import Control.Arrow ((***))
import Data.Equality.Utils
import Data.Equality.Language
import Data.Equality.Graph.Classes
class Eq domain => Analysis domain (l :: Type -> Type) where
makeA :: l domain -> domain
joinA :: domain -> domain -> domain
modifyA :: EClass domain l -> (EClass domain l, [Fix l])
modifyA EClass domain l
c = (EClass domain l
c, [])
{-# INLINE modifyA #-}
instance forall l. Analysis () l where
makeA :: l () -> ()
makeA l ()
_ = ()
joinA :: () -> () -> ()
joinA = () -> () -> ()
forall a. Semigroup a => a -> a -> a
(<>)
instance (Language l, Analysis a l, Analysis b l) => Analysis (a, b) l where
makeA :: l (a, b) -> (a, b)
makeA :: l (a, b) -> (a, b)
makeA l (a, b)
g = (forall domain (l :: * -> *).
Analysis domain l =>
l domain -> domain
makeA @a ((a, b) -> a
forall a b. (a, b) -> a
fst ((a, b) -> a) -> l (a, b) -> l a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> l (a, b)
g), forall domain (l :: * -> *).
Analysis domain l =>
l domain -> domain
makeA @b ((a, b) -> b
forall a b. (a, b) -> b
snd ((a, b) -> b) -> l (a, b) -> l b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> l (a, b)
g))
joinA :: (a,b) -> (a,b) -> (a,b)
joinA :: (a, b) -> (a, b) -> (a, b)
joinA (a
x,b
y) = forall domain (l :: * -> *).
Analysis domain l =>
domain -> domain -> domain
joinA @a @l a
x (a -> a) -> (b -> b) -> (a, b) -> (a, b)
forall b c b' c'. (b -> c) -> (b' -> c') -> (b, b') -> (c, c')
forall (a :: * -> * -> *) b c b' c'.
Arrow a =>
a b c -> a b' c' -> a (b, b') (c, c')
*** forall domain (l :: * -> *).
Analysis domain l =>
domain -> domain -> domain
joinA @b @l b
y
modifyA :: EClass (a, b) l -> (EClass (a, b) l, [Fix l])
modifyA :: EClass (a, b) l -> (EClass (a, b) l, [Fix l])
modifyA EClass (a, b) l
c =
let (EClass a l
ca, [Fix l]
la) = forall domain (l :: * -> *).
Analysis domain l =>
EClass domain l -> (EClass domain l, [Fix l])
modifyA @a (EClass (a, b) l
c { eClassData :: a
eClassData = (a, b) -> a
forall a b. (a, b) -> a
fst (EClass (a, b) l -> (a, b)
forall analysis_domain (language :: * -> *).
EClass analysis_domain language -> analysis_domain
eClassData EClass (a, b) l
c) })
(EClass b l
cb, [Fix l]
lb) = forall domain (l :: * -> *).
Analysis domain l =>
EClass domain l -> (EClass domain l, [Fix l])
modifyA @b (EClass (a, b) l
c { eClassData :: b
eClassData = (a, b) -> b
forall a b. (a, b) -> b
snd (EClass (a, b) l -> (a, b)
forall analysis_domain (language :: * -> *).
EClass analysis_domain language -> analysis_domain
eClassData EClass (a, b) l
c) })
in ( ClassId
-> Set (ENode l)
-> (a, b)
-> SList (ClassId, ENode l)
-> EClass (a, b) l
forall analysis_domain (language :: * -> *).
ClassId
-> Set (ENode language)
-> analysis_domain
-> SList (ClassId, ENode language)
-> EClass analysis_domain language
EClass (EClass (a, b) l -> ClassId
forall analysis_domain (language :: * -> *).
EClass analysis_domain language -> ClassId
eClassId EClass (a, b) l
c) (EClass a l -> Set (ENode l)
forall analysis_domain (language :: * -> *).
EClass analysis_domain language -> Set (ENode language)
eClassNodes EClass a l
ca Set (ENode l) -> Set (ENode l) -> Set (ENode l)
forall a. Semigroup a => a -> a -> a
<> EClass b l -> Set (ENode l)
forall analysis_domain (language :: * -> *).
EClass analysis_domain language -> Set (ENode language)
eClassNodes EClass b l
cb) (EClass a l -> a
forall analysis_domain (language :: * -> *).
EClass analysis_domain language -> analysis_domain
eClassData EClass a l
ca, EClass b l -> b
forall analysis_domain (language :: * -> *).
EClass analysis_domain language -> analysis_domain
eClassData EClass b l
cb) (EClass a l -> SList (ClassId, ENode l)
forall analysis_domain (language :: * -> *).
EClass analysis_domain language -> SList (ClassId, ENode language)
eClassParents EClass a l
ca SList (ClassId, ENode l)
-> SList (ClassId, ENode l) -> SList (ClassId, ENode l)
forall a. Semigroup a => a -> a -> a
<> EClass b l -> SList (ClassId, ENode l)
forall analysis_domain (language :: * -> *).
EClass analysis_domain language -> SList (ClassId, ENode language)
eClassParents EClass b l
cb)
, [Fix l]
la [Fix l] -> [Fix l] -> [Fix l]
forall a. Semigroup a => a -> a -> a
<> [Fix l]
lb
)