{-|
module      :  Data.Number.Flint.Acb.Modular.Instances
copyright   :  (c) 2022 Hartmut Monien
license     :  GNU GPL, version 2 or above (see LICENSE)
maintainer  :  hmonien@uni-bonn.de
-}

module Data.Number.Flint.Acb.Modular.Instances where

import System.IO.Unsafe

import Foreign.C.String
import Foreign.Marshal.Alloc (free)

import Data.Group

import Data.Number.Flint.Acb.Modular

instance Show PSL2Z where
  show :: PSL2Z -> String
show PSL2Z
x = IO String -> String
forall a. IO a -> a
unsafePerformIO (IO String -> String) -> IO String -> String
forall a b. (a -> b) -> a -> b
$ do
    (PSL2Z
_, CString
cs) <- PSL2Z -> (Ptr CPSL2Z -> IO CString) -> IO (PSL2Z, CString)
forall {a}. PSL2Z -> (Ptr CPSL2Z -> IO a) -> IO (PSL2Z, a)
withPSL2Z PSL2Z
x Ptr CPSL2Z -> IO CString
psl2z_get_str
    String
s <- CString -> IO String
peekCString CString
cs
    CString -> IO ()
forall a. Ptr a -> IO ()
free CString
cs
    String -> IO String
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return String
s

instance Eq PSL2Z where
  == :: PSL2Z -> PSL2Z -> Bool
(==) PSL2Z
x PSL2Z
y =  (PSL2Z, Bool) -> Bool
forall a b. (a, b) -> b
snd ((PSL2Z, Bool) -> Bool) -> (PSL2Z, Bool) -> Bool
forall a b. (a -> b) -> a -> b
$ (PSL2Z, (PSL2Z, Bool)) -> (PSL2Z, Bool)
forall a b. (a, b) -> b
snd ((PSL2Z, (PSL2Z, Bool)) -> (PSL2Z, Bool))
-> (PSL2Z, (PSL2Z, Bool)) -> (PSL2Z, Bool)
forall a b. (a -> b) -> a -> b
$ IO (PSL2Z, (PSL2Z, Bool)) -> (PSL2Z, (PSL2Z, Bool))
forall a. IO a -> a
unsafePerformIO (IO (PSL2Z, (PSL2Z, Bool)) -> (PSL2Z, (PSL2Z, Bool)))
-> IO (PSL2Z, (PSL2Z, Bool)) -> (PSL2Z, (PSL2Z, Bool))
forall a b. (a -> b) -> a -> b
$ do
    PSL2Z
-> (Ptr CPSL2Z -> IO (PSL2Z, Bool)) -> IO (PSL2Z, (PSL2Z, Bool))
forall {a}. PSL2Z -> (Ptr CPSL2Z -> IO a) -> IO (PSL2Z, a)
withPSL2Z PSL2Z
x ((Ptr CPSL2Z -> IO (PSL2Z, Bool)) -> IO (PSL2Z, (PSL2Z, Bool)))
-> (Ptr CPSL2Z -> IO (PSL2Z, Bool)) -> IO (PSL2Z, (PSL2Z, Bool))
forall a b. (a -> b) -> a -> b
$ \Ptr CPSL2Z
x -> do
      PSL2Z -> (Ptr CPSL2Z -> IO Bool) -> IO (PSL2Z, Bool)
forall {a}. PSL2Z -> (Ptr CPSL2Z -> IO a) -> IO (PSL2Z, a)
withPSL2Z PSL2Z
y ((Ptr CPSL2Z -> IO Bool) -> IO (PSL2Z, Bool))
-> (Ptr CPSL2Z -> IO Bool) -> IO (PSL2Z, Bool)
forall a b. (a -> b) -> a -> b
$ \Ptr CPSL2Z
y -> do
        CInt
flag <- Ptr CPSL2Z -> Ptr CPSL2Z -> IO CInt
psl2z_equal Ptr CPSL2Z
x Ptr CPSL2Z
y
        Bool -> IO Bool
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> IO Bool) -> Bool -> IO Bool
forall a b. (a -> b) -> a -> b
$ CInt
flag CInt -> CInt -> Bool
forall a. Eq a => a -> a -> Bool
== CInt
1
        
instance Monoid PSL2Z where
  mempty :: PSL2Z
mempty = IO PSL2Z -> PSL2Z
forall a. IO a -> a
unsafePerformIO (IO PSL2Z -> PSL2Z) -> IO PSL2Z -> PSL2Z
forall a b. (a -> b) -> a -> b
$ do
    PSL2Z
result <- IO PSL2Z
newPSL2Z
    PSL2Z -> IO PSL2Z
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return PSL2Z
result
  
instance Semigroup PSL2Z where
  <> :: PSL2Z -> PSL2Z -> PSL2Z
(<>) PSL2Z
x PSL2Z
y = (PSL2Z, (PSL2Z, (PSL2Z, ()))) -> PSL2Z
forall a b. (a, b) -> a
fst ((PSL2Z, (PSL2Z, (PSL2Z, ()))) -> PSL2Z)
-> (PSL2Z, (PSL2Z, (PSL2Z, ()))) -> PSL2Z
forall a b. (a -> b) -> a -> b
$ IO (PSL2Z, (PSL2Z, (PSL2Z, ()))) -> (PSL2Z, (PSL2Z, (PSL2Z, ())))
forall a. IO a -> a
unsafePerformIO (IO (PSL2Z, (PSL2Z, (PSL2Z, ()))) -> (PSL2Z, (PSL2Z, (PSL2Z, ()))))
-> IO (PSL2Z, (PSL2Z, (PSL2Z, ())))
-> (PSL2Z, (PSL2Z, (PSL2Z, ())))
forall a b. (a -> b) -> a -> b
$ do
    (Ptr CPSL2Z -> IO (PSL2Z, (PSL2Z, ())))
-> IO (PSL2Z, (PSL2Z, (PSL2Z, ())))
forall {a}. (Ptr CPSL2Z -> IO a) -> IO (PSL2Z, a)
withNewPSL2Z ((Ptr CPSL2Z -> IO (PSL2Z, (PSL2Z, ())))
 -> IO (PSL2Z, (PSL2Z, (PSL2Z, ()))))
-> (Ptr CPSL2Z -> IO (PSL2Z, (PSL2Z, ())))
-> IO (PSL2Z, (PSL2Z, (PSL2Z, ())))
forall a b. (a -> b) -> a -> b
$ \Ptr CPSL2Z
result -> do 
      PSL2Z -> (Ptr CPSL2Z -> IO (PSL2Z, ())) -> IO (PSL2Z, (PSL2Z, ()))
forall {a}. PSL2Z -> (Ptr CPSL2Z -> IO a) -> IO (PSL2Z, a)
withPSL2Z PSL2Z
x ((Ptr CPSL2Z -> IO (PSL2Z, ())) -> IO (PSL2Z, (PSL2Z, ())))
-> (Ptr CPSL2Z -> IO (PSL2Z, ())) -> IO (PSL2Z, (PSL2Z, ()))
forall a b. (a -> b) -> a -> b
$ \Ptr CPSL2Z
x -> do
        PSL2Z -> (Ptr CPSL2Z -> IO ()) -> IO (PSL2Z, ())
forall {a}. PSL2Z -> (Ptr CPSL2Z -> IO a) -> IO (PSL2Z, a)
withPSL2Z PSL2Z
y ((Ptr CPSL2Z -> IO ()) -> IO (PSL2Z, ()))
-> (Ptr CPSL2Z -> IO ()) -> IO (PSL2Z, ())
forall a b. (a -> b) -> a -> b
$ \Ptr CPSL2Z
y -> do
          Ptr CPSL2Z -> Ptr CPSL2Z -> Ptr CPSL2Z -> IO ()
psl2z_mul Ptr CPSL2Z
result Ptr CPSL2Z
x Ptr CPSL2Z
y
          
instance Group PSL2Z where
  invert :: PSL2Z -> PSL2Z
invert PSL2Z
x = (PSL2Z, (PSL2Z, ())) -> PSL2Z
forall a b. (a, b) -> a
fst ((PSL2Z, (PSL2Z, ())) -> PSL2Z) -> (PSL2Z, (PSL2Z, ())) -> PSL2Z
forall a b. (a -> b) -> a -> b
$ IO (PSL2Z, (PSL2Z, ())) -> (PSL2Z, (PSL2Z, ()))
forall a. IO a -> a
unsafePerformIO (IO (PSL2Z, (PSL2Z, ())) -> (PSL2Z, (PSL2Z, ())))
-> IO (PSL2Z, (PSL2Z, ())) -> (PSL2Z, (PSL2Z, ()))
forall a b. (a -> b) -> a -> b
$ do
    (Ptr CPSL2Z -> IO (PSL2Z, ())) -> IO (PSL2Z, (PSL2Z, ()))
forall {a}. (Ptr CPSL2Z -> IO a) -> IO (PSL2Z, a)
withNewPSL2Z ((Ptr CPSL2Z -> IO (PSL2Z, ())) -> IO (PSL2Z, (PSL2Z, ())))
-> (Ptr CPSL2Z -> IO (PSL2Z, ())) -> IO (PSL2Z, (PSL2Z, ()))
forall a b. (a -> b) -> a -> b
$ \Ptr CPSL2Z
result -> do
      PSL2Z -> (Ptr CPSL2Z -> IO ()) -> IO (PSL2Z, ())
forall {a}. PSL2Z -> (Ptr CPSL2Z -> IO a) -> IO (PSL2Z, a)
withPSL2Z PSL2Z
x ((Ptr CPSL2Z -> IO ()) -> IO (PSL2Z, ()))
-> (Ptr CPSL2Z -> IO ()) -> IO (PSL2Z, ())
forall a b. (a -> b) -> a -> b
$ \Ptr CPSL2Z
x -> do
        Ptr CPSL2Z -> Ptr CPSL2Z -> IO ()
psl2z_inv Ptr CPSL2Z
result Ptr CPSL2Z
x

instance Show PSL2ZWord where
  show :: PSL2ZWord -> String
show PSL2ZWord
x = IO String -> String
forall a. IO a -> a
unsafePerformIO (IO String -> String) -> IO String -> String
forall a b. (a -> b) -> a -> b
$ do
    (PSL2ZWord
_, CString
cs) <- PSL2ZWord
-> (Ptr CPSL2ZWord -> IO CString) -> IO (PSL2ZWord, CString)
forall {a}.
PSL2ZWord -> (Ptr CPSL2ZWord -> IO a) -> IO (PSL2ZWord, a)
withPSL2ZWord PSL2ZWord
x Ptr CPSL2ZWord -> IO CString
psl2z_word_get_str_pretty
    String
s <- CString -> IO String
peekCString CString
cs
    CString -> IO ()
forall a. Ptr a -> IO ()
free CString
cs
    String -> IO String
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return String
s