{-# 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.Function ((&))
import Data.Equality.Graph.Lens
import Data.Equality.Language
import Data.Equality.Graph.Internal (EGraph)
import Data.Equality.Graph.Classes
class Eq domain => Analysis domain (l :: Type -> Type) where
makeA :: l domain -> domain
joinA :: domain -> domain -> domain
modifyA :: ClassId
-> EGraph domain l
-> EGraph domain l
modifyA ClassId
_ = EGraph domain l -> EGraph domain l
forall a. a -> a
id
{-# 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 :: ClassId -> EGraph (a, b) l -> EGraph (a, b) l
modifyA :: ClassId -> EGraph (a, b) l -> EGraph (a, b) l
modifyA ClassId
c EGraph (a, b) l
egr =
let egra :: EGraph a l
egra = forall domain (l :: * -> *).
Analysis domain l =>
ClassId -> EGraph domain l -> EGraph domain l
modifyA @a ClassId
c (EGraph (a, b) l
egr EGraph (a, b) l -> (EGraph (a, b) l -> EGraph a l) -> EGraph a l
forall a b. a -> (a -> b) -> b
& (EClass (a, b) l -> Identity (EClass a l))
-> EGraph (a, b) l -> Identity (EGraph a l)
forall a (l :: * -> *) b (f :: * -> *).
Applicative f =>
(EClass a l -> f (EClass b l)) -> EGraph a l -> f (EGraph b l)
_classes((EClass (a, b) l -> Identity (EClass a l))
-> EGraph (a, b) l -> Identity (EGraph a l))
-> (((a, b) -> Identity a)
-> EClass (a, b) l -> Identity (EClass a l))
-> ((a, b) -> Identity a)
-> EGraph (a, b) l
-> Identity (EGraph a l)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.((a, b) -> Identity a) -> EClass (a, b) l -> Identity (EClass a l)
forall domain (l :: * -> *) domain' (f :: * -> *).
Functor f =>
(domain -> f domain') -> EClass domain l -> f (EClass domain' l)
_data (((a, b) -> Identity a)
-> EGraph (a, b) l -> Identity (EGraph a l))
-> ((a, b) -> a) -> EGraph (a, b) l -> EGraph a l
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ (a, b) -> a
forall a b. (a, b) -> a
fst)
egrb :: EGraph b l
egrb = forall domain (l :: * -> *).
Analysis domain l =>
ClassId -> EGraph domain l -> EGraph domain l
modifyA @b ClassId
c (EGraph (a, b) l
egr EGraph (a, b) l -> (EGraph (a, b) l -> EGraph b l) -> EGraph b l
forall a b. a -> (a -> b) -> b
& (EClass (a, b) l -> Identity (EClass b l))
-> EGraph (a, b) l -> Identity (EGraph b l)
forall a (l :: * -> *) b (f :: * -> *).
Applicative f =>
(EClass a l -> f (EClass b l)) -> EGraph a l -> f (EGraph b l)
_classes((EClass (a, b) l -> Identity (EClass b l))
-> EGraph (a, b) l -> Identity (EGraph b l))
-> (((a, b) -> Identity b)
-> EClass (a, b) l -> Identity (EClass b l))
-> ((a, b) -> Identity b)
-> EGraph (a, b) l
-> Identity (EGraph b l)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.((a, b) -> Identity b) -> EClass (a, b) l -> Identity (EClass b l)
forall domain (l :: * -> *) domain' (f :: * -> *).
Functor f =>
(domain -> f domain') -> EClass domain l -> f (EClass domain' l)
_data (((a, b) -> Identity b)
-> EGraph (a, b) l -> Identity (EGraph b l))
-> ((a, b) -> b) -> EGraph (a, b) l -> EGraph b l
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ (a, b) -> b
forall a b. (a, b) -> b
snd)
ca :: EClass a l
ca = EGraph a l
egra EGraph a l -> Lens' (EGraph a l) (EClass a l) -> EClass a l
forall s a. s -> Lens' s a -> a
^.ClassId -> Lens' (EGraph a l) (EClass a l)
forall a (l :: * -> *). ClassId -> Lens' (EGraph a l) (EClass a l)
_class ClassId
c
cb :: EClass b l
cb = EGraph b l
egrb EGraph b l -> Lens' (EGraph b l) (EClass b l) -> EClass b l
forall s a. s -> Lens' s a -> a
^.ClassId -> Lens' (EGraph b l) (EClass b l)
forall a (l :: * -> *). ClassId -> Lens' (EGraph a l) (EClass a l)
_class ClassId
c
in
EGraph (a, b) l
egr EGraph (a, b) l
-> (EGraph (a, b) l -> EGraph (a, b) l) -> EGraph (a, b) l
forall a b. a -> (a -> b) -> b
&
ClassId
-> forall {f :: * -> *}.
Functor f =>
(EClass (a, b) l -> f (EClass (a, b) l))
-> EGraph (a, b) l -> f (EGraph (a, b) l)
forall a (l :: * -> *). ClassId -> Lens' (EGraph a l) (EClass a l)
_class ClassId
c (forall {f :: * -> *}.
Functor f =>
(EClass (a, b) l -> f (EClass (a, b) l))
-> EGraph (a, b) l -> f (EGraph (a, b) l))
-> EClass (a, b) l -> EGraph (a, b) l -> EGraph (a, b) l
forall s a. Lens' s a -> a -> s -> s
.~ (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 ClassId
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))