{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DeriveAnyClass #-}
module Nominal.Atomic where
import GHC.Generics
import Nominal.ConcreteNames
import Nominal.Atom
import Nominal.Nominal
import Nominal.NominalSupport
import Nominal.NominalShow
import Nominal.Bindable
import Nominal.Unsafe
class (Nominal a, NominalSupport a, Eq a, Ord a, Show a, Bindable a) => Atomic a where
to_atom :: a -> Atom
from_atom :: Atom -> a
names :: a -> NameGen
instance Atomic Atom where
to_atom :: Atom -> Atom
to_atom = Atom -> Atom
forall a. a -> a
id
from_atom :: Atom -> Atom
from_atom = Atom -> Atom
forall a. a -> a
id
names :: Atom -> NameGen
names Atom
a = NameGen
default_namegen
atomic_show :: (Atomic a) => a -> String
atomic_show :: forall a. Atomic a => a -> String
atomic_show a
a = Atom -> String
atom_show (a -> Atom
forall a. Atomic a => a -> Atom
to_atom a
a)
with_fresh :: (Atomic a) => (a -> t) -> t
with_fresh :: forall a t. Atomic a => (a -> t) -> t
with_fresh a -> t
k = NameSuggestion -> (a -> t) -> t
forall a t. Atomic a => NameSuggestion -> (a -> t) -> t
with_fresh_namelist [] a -> t
k
with_fresh_named :: (Atomic a) => String -> (a -> t) -> t
with_fresh_named :: forall a t. Atomic a => String -> (a -> t) -> t
with_fresh_named String
n = IO a -> (a -> t) -> t
forall a b. IO a -> (a -> b) -> b
unsafe_with (String -> IO a
forall a. Atomic a => String -> IO a
fresh_named String
n)
with_fresh_namelist :: (Atomic a) => NameSuggestion -> (a -> t) -> t
with_fresh_namelist :: forall a t. Atomic a => NameSuggestion -> (a -> t) -> t
with_fresh_namelist NameSuggestion
ns a -> t
k =
NameGen -> (Atom -> t) -> t
forall a. NameGen -> (Atom -> a) -> a
with_fresh_atom NameGen
ng (\Atom
a -> a -> t
k (Atom -> a
forall a. Atomic a => Atom -> a
from_atom Atom
a))
where
NameGen NameSuggestion
ns1 NameSuggestion -> NameSuggestion
ex = a -> NameGen
forall a. Atomic a => a -> NameGen
names ((a -> t) -> a
forall a t. (a -> t) -> a
un a -> t
k)
ns2 :: NameSuggestion
ns2 = if NameSuggestion -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null NameSuggestion
ns then NameSuggestion
ns1 else NameSuggestion
ns
ng :: NameGen
ng = NameSuggestion -> (NameSuggestion -> NameSuggestion) -> NameGen
NameGen NameSuggestion
ns2 NameSuggestion -> NameSuggestion
ex
un :: (a -> t) -> a
un :: forall a t. (a -> t) -> a
un = (a -> t) -> a
forall a. HasCallStack => a
undefined
fresh :: (Atomic a) => IO a
fresh :: forall a. Atomic a => IO a
fresh = NameSuggestion -> IO a
forall a. Atomic a => NameSuggestion -> IO a
fresh_namelist []
fresh_named :: (Atomic a) => String -> IO a
fresh_named :: forall a. Atomic a => String -> IO a
fresh_named String
n = IO a
result
where
result :: IO a
result = do
Atom
a <- String -> NameGen -> IO Atom
fresh_atom_named String
n NameGen
ng
a -> IO a
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Atom -> a
forall a. Atomic a => Atom -> a
from_atom Atom
a)
NameGen NameSuggestion
ns NameSuggestion -> NameSuggestion
ex = a -> NameGen
forall a. Atomic a => a -> NameGen
names (IO a -> a
forall a. IO a -> a
un IO a
result)
ng :: NameGen
ng = NameSuggestion -> (NameSuggestion -> NameSuggestion) -> NameGen
NameGen [String
n] NameSuggestion -> NameSuggestion
ex
un :: IO a -> a
un :: forall a. IO a -> a
un = IO a -> a
forall a. HasCallStack => a
undefined
fresh_namelist :: (Atomic a) => NameSuggestion -> IO a
fresh_namelist :: forall a. Atomic a => NameSuggestion -> IO a
fresh_namelist NameSuggestion
ns = IO a
result
where
result :: IO a
result = do
Atom
a <- NameGen -> IO Atom
fresh_atom NameGen
ng
a -> IO a
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Atom -> a
forall a. Atomic a => Atom -> a
from_atom Atom
a)
NameGen NameSuggestion
ns1 NameSuggestion -> NameSuggestion
ex = a -> NameGen
forall a. Atomic a => a -> NameGen
names (IO a -> a
forall a. IO a -> a
un IO a
result)
ns2 :: NameSuggestion
ns2 = if NameSuggestion -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null NameSuggestion
ns then NameSuggestion
ns1 else NameSuggestion
ns
ng :: NameGen
ng = NameSuggestion -> (NameSuggestion -> NameSuggestion) -> NameGen
NameGen NameSuggestion
ns2 NameSuggestion -> NameSuggestion
ex
un :: IO a -> a
un :: forall a. IO a -> a
un = IO a -> a
forall a. HasCallStack => a
undefined
bind :: (Atomic a, Nominal t) => (a -> t) -> Bind a t
bind :: forall a t. (Atomic a, Nominal t) => (a -> t) -> Bind a t
bind a -> t
f = (a -> Bind a t) -> Bind a t
forall a t. Atomic a => (a -> t) -> t
with_fresh (\a
x -> a
x a -> t -> Bind a t
forall b a. (Nominal b, Bindable a) => a -> b -> Bind a b
:. a -> t
f a
x)
bind_named :: (Atomic a, Nominal t) => String -> (a -> t) -> Bind a t
bind_named :: forall a t. (Atomic a, Nominal t) => String -> (a -> t) -> Bind a t
bind_named String
n a -> t
f = String -> (a -> Bind a t) -> Bind a t
forall a t. Atomic a => String -> (a -> t) -> t
with_fresh_named String
n (\a
x -> a
x a -> t -> Bind a t
forall b a. (Nominal b, Bindable a) => a -> b -> Bind a b
:. a -> t
f a
x)
bind_namelist :: (Atomic a, Nominal t) => NameSuggestion -> (a -> t) -> Bind a t
bind_namelist :: forall a t.
(Atomic a, Nominal t) =>
NameSuggestion -> (a -> t) -> Bind a t
bind_namelist NameSuggestion
ns a -> t
f = NameSuggestion -> (a -> Bind a t) -> Bind a t
forall a t. Atomic a => NameSuggestion -> (a -> t) -> t
with_fresh_namelist NameSuggestion
ns (\a
x -> a
x a -> t -> Bind a t
forall b a. (Nominal b, Bindable a) => a -> b -> Bind a b
:. a -> t
f a
x)
to_bindatom :: (Atomic a, Nominal t) => Bind a t -> BindAtom t
to_bindatom :: forall a t. (Atomic a, Nominal t) => Bind a t -> BindAtom t
to_bindatom (a
a :. t
t) = Atom -> t -> BindAtom t
forall t. Atom -> t -> BindAtom t
atom_abst (a -> Atom
forall a. Atomic a => a -> Atom
to_atom a
a) t
t
from_bindatom :: (Atomic a, Nominal t) => BindAtom t -> Bind a t
from_bindatom :: forall a t. (Atomic a, Nominal t) => BindAtom t -> Bind a t
from_bindatom BindAtom t
body = BindAtom t -> (Atom -> t -> Bind a t) -> Bind a t
forall t s. Nominal t => BindAtom t -> (Atom -> t -> s) -> s
atom_open BindAtom t
body ((Atom -> t -> Bind a t) -> Bind a t)
-> (Atom -> t -> Bind a t) -> Bind a t
forall a b. (a -> b) -> a -> b
$ \Atom
a t
t -> (Atom -> a
forall a. Atomic a => Atom -> a
from_atom Atom
a a -> t -> Bind a t
forall b a. (Nominal b, Bindable a) => a -> b -> Bind a b
:. t
t)
merge :: (Atomic a, Nominal t, Nominal s) => Bind a t -> Bind a s -> Bind a (t,s)
merge :: forall a t s.
(Atomic a, Nominal t, Nominal s) =>
Bind a t -> Bind a s -> Bind a (t, s)
merge Bind a t
at Bind a s
as = BindAtom (t, s) -> Bind a (t, s)
forall a t. (Atomic a, Nominal t) => BindAtom t -> Bind a t
from_bindatom (BindAtom t -> BindAtom s -> BindAtom (t, s)
forall t s.
(Nominal t, Nominal s) =>
BindAtom t -> BindAtom s -> BindAtom (t, s)
atom_merge (Bind a t -> BindAtom t
forall a t. (Atomic a, Nominal t) => Bind a t -> BindAtom t
to_bindatom Bind a t
at) (Bind a s -> BindAtom s
forall a t. (Atomic a, Nominal t) => Bind a t -> BindAtom t
to_bindatom Bind a s
as))
class AtomKind a where
suggested_names :: a -> NameSuggestion
suggested_names a
a = NameSuggestion
default_names
expand_names :: a -> NameSuggestion -> [String]
expand_names a
a = NameSuggestion -> NameSuggestion
expand_default
newtype AtomOfKind a = AtomOfKind Atom
deriving (AtomOfKind a -> AtomOfKind a -> Bool
(AtomOfKind a -> AtomOfKind a -> Bool)
-> (AtomOfKind a -> AtomOfKind a -> Bool) -> Eq (AtomOfKind a)
forall a. AtomOfKind a -> AtomOfKind a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. AtomOfKind a -> AtomOfKind a -> Bool
== :: AtomOfKind a -> AtomOfKind a -> Bool
$c/= :: forall a. AtomOfKind a -> AtomOfKind a -> Bool
/= :: AtomOfKind a -> AtomOfKind a -> Bool
Eq, Eq (AtomOfKind a)
Eq (AtomOfKind a) =>
(AtomOfKind a -> AtomOfKind a -> Ordering)
-> (AtomOfKind a -> AtomOfKind a -> Bool)
-> (AtomOfKind a -> AtomOfKind a -> Bool)
-> (AtomOfKind a -> AtomOfKind a -> Bool)
-> (AtomOfKind a -> AtomOfKind a -> Bool)
-> (AtomOfKind a -> AtomOfKind a -> AtomOfKind a)
-> (AtomOfKind a -> AtomOfKind a -> AtomOfKind a)
-> Ord (AtomOfKind a)
AtomOfKind a -> AtomOfKind a -> Bool
AtomOfKind a -> AtomOfKind a -> Ordering
AtomOfKind a -> AtomOfKind a -> AtomOfKind a
forall a. Eq (AtomOfKind a)
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. AtomOfKind a -> AtomOfKind a -> Bool
forall a. AtomOfKind a -> AtomOfKind a -> Ordering
forall a. AtomOfKind a -> AtomOfKind a -> AtomOfKind a
$ccompare :: forall a. AtomOfKind a -> AtomOfKind a -> Ordering
compare :: AtomOfKind a -> AtomOfKind a -> Ordering
$c< :: forall a. AtomOfKind a -> AtomOfKind a -> Bool
< :: AtomOfKind a -> AtomOfKind a -> Bool
$c<= :: forall a. AtomOfKind a -> AtomOfKind a -> Bool
<= :: AtomOfKind a -> AtomOfKind a -> Bool
$c> :: forall a. AtomOfKind a -> AtomOfKind a -> Bool
> :: AtomOfKind a -> AtomOfKind a -> Bool
$c>= :: forall a. AtomOfKind a -> AtomOfKind a -> Bool
>= :: AtomOfKind a -> AtomOfKind a -> Bool
$cmax :: forall a. AtomOfKind a -> AtomOfKind a -> AtomOfKind a
max :: AtomOfKind a -> AtomOfKind a -> AtomOfKind a
$cmin :: forall a. AtomOfKind a -> AtomOfKind a -> AtomOfKind a
min :: AtomOfKind a -> AtomOfKind a -> AtomOfKind a
Ord, (forall x. AtomOfKind a -> Rep (AtomOfKind a) x)
-> (forall x. Rep (AtomOfKind a) x -> AtomOfKind a)
-> Generic (AtomOfKind a)
forall x. Rep (AtomOfKind a) x -> AtomOfKind a
forall x. AtomOfKind a -> Rep (AtomOfKind a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (AtomOfKind a) x -> AtomOfKind a
forall a x. AtomOfKind a -> Rep (AtomOfKind a) x
$cfrom :: forall a x. AtomOfKind a -> Rep (AtomOfKind a) x
from :: forall x. AtomOfKind a -> Rep (AtomOfKind a) x
$cto :: forall a x. Rep (AtomOfKind a) x -> AtomOfKind a
to :: forall x. Rep (AtomOfKind a) x -> AtomOfKind a
Generic, Nominal (AtomOfKind a)
Nominal (AtomOfKind a) =>
(AtomOfKind a -> NominalBinder (AtomOfKind a))
-> Bindable (AtomOfKind a)
AtomOfKind a -> NominalBinder (AtomOfKind a)
forall a. Nominal a => (a -> NominalBinder a) -> Bindable a
forall a. AtomKind a => Nominal (AtomOfKind a)
forall a.
AtomKind a =>
AtomOfKind a -> NominalBinder (AtomOfKind a)
$cbinding :: forall a.
AtomKind a =>
AtomOfKind a -> NominalBinder (AtomOfKind a)
binding :: AtomOfKind a -> NominalBinder (AtomOfKind a)
Bindable)
instance (AtomKind a) => Nominal (AtomOfKind a) where
NominalPermutation
π • :: NominalPermutation -> AtomOfKind a -> AtomOfKind a
• (AtomOfKind Atom
a) = Atom -> AtomOfKind a
forall a. Atom -> AtomOfKind a
AtomOfKind (NominalPermutation
π NominalPermutation -> Atom -> Atom
forall t. Nominal t => NominalPermutation -> t -> t
• Atom
a)
instance (AtomKind a) => NominalSupport (AtomOfKind a) where
support :: AtomOfKind a -> Support
support (AtomOfKind Atom
a) = Atom -> Support
forall t. NominalSupport t => t -> Support
support Atom
a
instance (AtomKind a) => NominalShow (AtomOfKind a) where
showsPrecSup :: Support -> Int -> AtomOfKind a -> ShowS
showsPrecSup Support
sup Int
d AtomOfKind a
t = String -> ShowS
showString (AtomOfKind a -> String
forall a. Atomic a => a -> String
atomic_show AtomOfKind a
t)
instance (AtomKind a) => Show (AtomOfKind a) where
show :: AtomOfKind a -> String
show = AtomOfKind a -> String
forall a. Atomic a => a -> String
atomic_show
instance (AtomKind a) => Atomic (AtomOfKind a) where
to_atom :: AtomOfKind a -> Atom
to_atom (AtomOfKind Atom
a) = Atom
a
from_atom :: Atom -> AtomOfKind a
from_atom Atom
a = Atom -> AtomOfKind a
forall a. Atom -> AtomOfKind a
AtomOfKind Atom
a
names :: AtomOfKind a -> NameGen
names AtomOfKind a
f = AtomOfKind a -> NameGen
forall a. AtomKind a => AtomOfKind a -> NameGen
atomofkind_names AtomOfKind a
f
atomofkind_names :: (AtomKind a) => AtomOfKind a -> NameGen
atomofkind_names :: forall a. AtomKind a => AtomOfKind a -> NameGen
atomofkind_names AtomOfKind a
f = NameSuggestion -> (NameSuggestion -> NameSuggestion) -> NameGen
NameGen NameSuggestion
ns NameSuggestion -> NameSuggestion
ex
where
ns :: NameSuggestion
ns = a -> NameSuggestion
forall a. AtomKind a => a -> NameSuggestion
suggested_names (AtomOfKind a -> a
forall a. AtomOfKind a -> a
un AtomOfKind a
f)
ex :: NameSuggestion -> NameSuggestion
ex = a -> NameSuggestion -> NameSuggestion
forall a. AtomKind a => a -> NameSuggestion -> NameSuggestion
expand_names (AtomOfKind a -> a
forall a. AtomOfKind a -> a
un AtomOfKind a
f)
un :: AtomOfKind a -> a
un :: forall a. AtomOfKind a -> a
un = AtomOfKind a -> a
forall a. HasCallStack => a
undefined