freshs :: Nominal a => a -> [Name]
freshs = gensyms . support
unions :: Eq a => [[a]] -> [a]
unions = foldr union []
unionsMap :: Eq b => (a -> [b]) -> [a] -> [b]
unionsMap f = unions . map f
newtype Nameless a = Nameless { unNameless :: a }
deriving (Eq, Ord)
instance Nominal (Nameless a) where
support _ = []
act x _ = x
swap x _ = x
instance Nominal () where
support () = []
act () _ = ()
swap () _ = ()
instance (Nominal a, Nominal b) => Nominal (a, b) where
support (a, b) = support a `union` support b
act (a,b) f = (act a f,act b f)
swap (a,b) n = (swap a n,swap b n)
instance (Nominal a, Nominal b, Nominal c) => Nominal (a, b, c) where
support (a,b,c) = unions [support a, support b, support c]
act (a,b,c) f = (act a f,act b f,act c f)
swap (a,b,c) n = (swap a n,swap b n,swap c n)
instance (Nominal a, Nominal b, Nominal c, Nominal d) =>
Nominal (a, b, c, d) where
support (a,b,c,d) = unions [support a, support b, support c, support d]
act (a,b,c,d) f = (act a f,act b f,act c f,act d f)
swap (a,b,c,d) n = (swap a n,swap b n,swap c n,swap d n)
instance (Nominal a, Nominal b, Nominal c, Nominal d, Nominal e) =>
Nominal (a, b, c, d, e) where
support (a,b,c,d,e) =
unions [support a, support b, support c, support d, support e]
act (a,b,c,d,e) f = (act a f,act b f,act c f,act d f, act e f)
swap (a,b,c,d,e) n =
(swap a n,swap b n,swap c n,swap d n,swap e n)
instance (Nominal a, Nominal b, Nominal c, Nominal d, Nominal e, Nominal h) =>
Nominal (a, b, c, d, e, h) where
support (a,b,c,d,e,h) =
unions [support a, support b, support c, support d, support e, support h]
act (a,b,c,d,e,h) f = (act a f,act b f,act c f,act d f, act e f, act h f)
swap (a,b,c,d,e,h) n =
(swap a n,swap b n,swap c n,swap d n,swap e n,swap h n)
instance Nominal a => Nominal [a] where
support xs = unions (map support xs)
act xs f = [ act x f | x <- xs ]
swap xs n = [ swap x n | x <- xs ]
instance Nominal a => Nominal (Maybe a) where
support = maybe [] support
act v f = fmap (`act` f) v
swap a n = fmap (`swap` n) a
instance Nominal Formula where
support (Dir _) = []
support (Atom i) = [i]
support (NegAtom i) = [i]
support (phi :/\: psi) = support phi `union` support psi
support (phi :\/: psi) = support phi `union` support psi
act (Dir b) (i,phi) = Dir b
act (Atom j) (i,phi) | i == j = phi
| otherwise = Atom j
act (NegAtom j) (i,phi) | i == j = negFormula phi
| otherwise = NegAtom j
act (psi1 :/\: psi2) (i,phi) = act psi1 (i,phi) `andFormula` act psi2 (i,phi)
act (psi1 :\/: psi2) (i,phi) = act psi1 (i,phi) `orFormula` act psi2 (i,phi)
swap (Dir b) (i,j) = Dir b
swap (Atom k) (i,j)| k == i = Atom j
| k == j = Atom i
| otherwise = Atom k
swap (NegAtom k) (i,j)| k == i = NegAtom j
| k == j = NegAtom i
| otherwise = NegAtom k
swap (psi1 :/\: psi2) (i,j) = swap psi1 (i,j) :/\: swap psi2 (i,j)
swap (psi1 :\/: psi2) (i,j) = swap psi1 (i,j) :\/: swap psi2 (i,j)
face :: Nominal a => a -> Face -> a
face = foldrWithKey (\i d a -> act a (i,Dir d))