{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE Rank2Types #-}
module Synthesizer.LLVM.Generator.Private where

import Synthesizer.LLVM.Private (getPairPtrs, noLocalPtr)

import qualified LLVM.Extra.Memory as Memory
import qualified LLVM.Extra.MaybeContinuation as MaybeCont
import qualified LLVM.Extra.Arithmetic as A
import qualified LLVM.Extra.Tuple as Tuple

import qualified LLVM.Core as LLVM
import LLVM.Core (CodeGenFunction)

import Type.Base.Proxy (Proxy(Proxy))

import Control.Applicative (Applicative, liftA2, pure, (<*>), (<$>))

import Data.Semigroup (Semigroup, (<>))
import Data.Tuple.Strict (mapFst, zipPair)

import qualified Number.Ratio as Ratio
import qualified Algebra.Field as Field
import qualified Algebra.Ring as Ring
import qualified Algebra.Additive as Additive

import qualified Prelude as P
import Prelude hiding (iterate, takeWhile, map, zipWith)


data T a =
   forall global local state.
      (Memory.C global, LLVM.IsSized local, Memory.C state) =>
      Cons (forall r c.
            (Tuple.Phi c) =>
            global ->
            -- pointer to loop local storage
            LLVM.Value (LLVM.Ptr local) ->
            state -> MaybeCont.T r c (a, state))
               -- compute next value
           (forall r. CodeGenFunction r (global, state))
               -- initial state
           (forall r. global -> CodeGenFunction r ())
               -- cleanup


noGlobal ::
   (LLVM.IsSized local, Memory.C state) =>
   (forall r c.
    (Tuple.Phi c) =>
    LLVM.Value (LLVM.Ptr local) -> state -> MaybeCont.T r c (a, state)) ->
   (forall r. CodeGenFunction r state) ->
   T a
noGlobal :: forall local state a.
(IsSized local, C state) =>
(forall r c.
 Phi c =>
 Value (Ptr local) -> state -> T r c (a, state))
-> (forall r. CodeGenFunction r state) -> T a
noGlobal forall r c. Phi c => Value (Ptr local) -> state -> T r c (a, state)
next forall r. CodeGenFunction r state
start = (forall r c.
 Phi c =>
 () -> Value (Ptr local) -> state -> T r c (a, state))
-> (forall r. CodeGenFunction r ((), state))
-> (forall r. () -> CodeGenFunction r ())
-> T a
forall a global local state.
(C global, IsSized local, C state) =>
(forall r c.
 Phi c =>
 global -> Value (Ptr local) -> state -> T r c (a, state))
-> (forall r. CodeGenFunction r (global, state))
-> (forall r. global -> CodeGenFunction r ())
-> T a
Cons ((Value (Ptr local) -> state -> T r c (a, state))
-> () -> Value (Ptr local) -> state -> T r c (a, state)
forall a b. a -> b -> a
const Value (Ptr local) -> state -> T r c (a, state)
forall r c. Phi c => Value (Ptr local) -> state -> T r c (a, state)
next) ((state -> ((), state))
-> CodeGenFunction r state -> CodeGenFunction r ((), state)
forall a b. (a -> b) -> CodeGenFunction r a -> CodeGenFunction r b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((,) ()) CodeGenFunction r state
forall r. CodeGenFunction r state
start) () -> CodeGenFunction r ()
forall a. a -> CodeGenFunction r a
forall r. () -> CodeGenFunction r ()
forall (m :: * -> *) a. Monad m => a -> m a
return

alloca :: (LLVM.IsSized a) => T (LLVM.Value (LLVM.Ptr a))
alloca :: forall a. IsSized a => T (Value (Ptr a))
alloca =
   (forall r c.
 Phi c =>
 Value (Ptr a) -> () -> T r c (Value (Ptr a), ()))
-> (forall r. CodeGenFunction r ()) -> T (Value (Ptr a))
forall local state a.
(IsSized local, C state) =>
(forall r c.
 Phi c =>
 Value (Ptr local) -> state -> T r c (a, state))
-> (forall r. CodeGenFunction r state) -> T a
noGlobal
      (\Value (Ptr a)
ptr () -> (Value (Ptr a), ()) -> T r c (Value (Ptr a), ())
forall a. a -> T r c a
forall (m :: * -> *) a. Monad m => a -> m a
return (Value (Ptr a)
ptr, ()))
      (() -> CodeGenFunction r ()
forall a. a -> CodeGenFunction r a
forall (m :: * -> *) a. Monad m => a -> m a
return ())


iterate ::
   (Memory.C a) =>
   (forall r. a -> CodeGenFunction r a) ->
   (forall r. CodeGenFunction r a) -> T a
iterate :: forall a.
C a =>
(forall r. a -> CodeGenFunction r a)
-> (forall r. CodeGenFunction r a) -> T a
iterate forall r. a -> CodeGenFunction r a
f forall r. CodeGenFunction r a
a =
   (forall r c. Phi c => Value (Ptr (Struct ())) -> a -> T r c (a, a))
-> (forall r. CodeGenFunction r a) -> T a
forall local state a.
(IsSized local, C state) =>
(forall r c.
 Phi c =>
 Value (Ptr local) -> state -> T r c (a, state))
-> (forall r. CodeGenFunction r state) -> T a
noGlobal
      ((a -> T r c (a, a)) -> Value (Ptr (Struct ())) -> a -> T r c (a, a)
forall f. f -> Value (Ptr (Struct ())) -> f
noLocalPtr ((a -> T r c (a, a))
 -> Value (Ptr (Struct ())) -> a -> T r c (a, a))
-> (a -> T r c (a, a))
-> Value (Ptr (Struct ()))
-> a
-> T r c (a, a)
forall a b. (a -> b) -> a -> b
$ \a
s -> (a -> (a, a)) -> T r c a -> T r c (a, a)
forall a b. (a -> b) -> T r c a -> T r c b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((,) a
s) (T r c a -> T r c (a, a)) -> T r c a -> T r c (a, a)
forall a b. (a -> b) -> a -> b
$ CodeGenFunction r a -> T r c a
forall r a z. CodeGenFunction r a -> T r z a
MaybeCont.lift (CodeGenFunction r a -> T r c a) -> CodeGenFunction r a -> T r c a
forall a b. (a -> b) -> a -> b
$ a -> CodeGenFunction r a
forall r. a -> CodeGenFunction r a
f a
s)
      CodeGenFunction r a
forall r. CodeGenFunction r a
a

iterateParam ::
   (Memory.C b, Memory.C a) =>
   (forall r. b -> a -> CodeGenFunction r a) ->
   (forall r. CodeGenFunction r b) ->
   (forall r. CodeGenFunction r a) -> T a
iterateParam :: forall b a.
(C b, C a) =>
(forall r. b -> a -> CodeGenFunction r a)
-> (forall r. CodeGenFunction r b)
-> (forall r. CodeGenFunction r a)
-> T a
iterateParam forall r. b -> a -> CodeGenFunction r a
f forall r. CodeGenFunction r b
b forall r. CodeGenFunction r a
a =
   ((b, a) -> a) -> T (b, a) -> T a
forall a b. (a -> b) -> T a -> T b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (b, a) -> a
forall a b. (a, b) -> b
snd (T (b, a) -> T a) -> T (b, a) -> T a
forall a b. (a -> b) -> a -> b
$ (forall r. (b, a) -> CodeGenFunction r (b, a))
-> (forall r. CodeGenFunction r (b, a)) -> T (b, a)
forall a.
C a =>
(forall r. a -> CodeGenFunction r a)
-> (forall r. CodeGenFunction r a) -> T a
iterate (\(b
bi,a
ai) -> (,) b
bi (a -> (b, a)) -> CodeGenFunction r a -> CodeGenFunction r (b, a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> b -> a -> CodeGenFunction r a
forall r. b -> a -> CodeGenFunction r a
f b
bi a
ai) ((b -> a -> (b, a))
-> CodeGenFunction r b
-> CodeGenFunction r a
-> CodeGenFunction r (b, a)
forall a b c.
(a -> b -> c)
-> CodeGenFunction r a
-> CodeGenFunction r b
-> CodeGenFunction r c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (,) CodeGenFunction r b
forall r. CodeGenFunction r b
b CodeGenFunction r a
forall r. CodeGenFunction r a
a)

takeWhile ::
   (forall r. a -> CodeGenFunction r (LLVM.Value Bool)) -> T a -> T a
takeWhile :: forall a.
(forall r. a -> CodeGenFunction r (Value Bool)) -> T a -> T a
takeWhile forall r. a -> CodeGenFunction r (Value Bool)
p (Cons forall r c.
Phi c =>
global -> Value (Ptr local) -> state -> T r c (a, state)
next forall r. CodeGenFunction r (global, state)
start forall r. global -> CodeGenFunction r ()
stop) = (forall r c.
 Phi c =>
 global -> Value (Ptr local) -> state -> T r c (a, state))
-> (forall r. CodeGenFunction r (global, state))
-> (forall r. global -> CodeGenFunction r ())
-> T a
forall a global local state.
(C global, IsSized local, C state) =>
(forall r c.
 Phi c =>
 global -> Value (Ptr local) -> state -> T r c (a, state))
-> (forall r. CodeGenFunction r (global, state))
-> (forall r. global -> CodeGenFunction r ())
-> T a
Cons
   (\global
global Value (Ptr local)
local state
s0 -> do
      (a
a,state
s1) <- global -> Value (Ptr local) -> state -> T r c (a, state)
forall r c.
Phi c =>
global -> Value (Ptr local) -> state -> T r c (a, state)
next global
global Value (Ptr local)
local state
s0
      Value Bool -> T r c ()
forall z r. Phi z => Value Bool -> T r z ()
MaybeCont.guard (Value Bool -> T r c ()) -> T r c (Value Bool) -> T r c ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< CodeGenFunction r (Value Bool) -> T r c (Value Bool)
forall r a z. CodeGenFunction r a -> T r z a
MaybeCont.lift (a -> CodeGenFunction r (Value Bool)
forall r. a -> CodeGenFunction r (Value Bool)
p a
a)
      (a, state) -> T r c (a, state)
forall a. a -> T r c a
forall (m :: * -> *) a. Monad m => a -> m a
return (a
a,state
s1))
   CodeGenFunction r (global, state)
forall r. CodeGenFunction r (global, state)
start
   global -> CodeGenFunction r ()
forall r. global -> CodeGenFunction r ()
stop


empty :: T a
empty :: forall a. T a
empty = (forall r c.
 Phi c =>
 Value (Ptr (Struct ())) -> () -> T r c (a, ()))
-> (forall r. CodeGenFunction r ()) -> T a
forall local state a.
(IsSized local, C state) =>
(forall r c.
 Phi c =>
 Value (Ptr local) -> state -> T r c (a, state))
-> (forall r. CodeGenFunction r state) -> T a
noGlobal ((() -> T r c (a, ()))
-> Value (Ptr (Struct ())) -> () -> T r c (a, ())
forall f. f -> Value (Ptr (Struct ())) -> f
noLocalPtr ((() -> T r c (a, ()))
 -> Value (Ptr (Struct ())) -> () -> T r c (a, ()))
-> (() -> T r c (a, ()))
-> Value (Ptr (Struct ()))
-> ()
-> T r c (a, ())
forall a b. (a -> b) -> a -> b
$ \ ()
_state -> T r c (a, ())
forall r z a. T r z a
MaybeCont.nothing) (() -> CodeGenFunction r ()
forall a. a -> CodeGenFunction r a
forall (m :: * -> *) a. Monad m => a -> m a
return ())

{- |
Appending many signals is inefficient,
since in cascadingly appended signals the parts are counted in an unary way.
Concatenating infinitely many signals is impossible.
If you want to concatenate a lot of signals,
please render them to lazy storable vectors first.
-}
{-
We might save a little space by using a union
for the states of the first and the second signal generator.
If the concatenated generators allocate memory,
we could also save some memory by calling @startB@
only after the first generator finished.
However, for correct deallocation
we would need to track which of the @start@ blocks
have been executed so far.
This in turn might be difficult in connection with the garbage collector.
-}
append :: (Tuple.Phi a, Tuple.Undefined a) => T a -> T a -> T a
append :: forall a. (Phi a, Undefined a) => T a -> T a -> T a
append (Cons forall r c.
Phi c =>
global -> Value (Ptr local) -> state -> T r c (a, state)
nextA forall r. CodeGenFunction r (global, state)
startA forall r. global -> CodeGenFunction r ()
stopA) (Cons forall r c.
Phi c =>
global -> Value (Ptr local) -> state -> T r c (a, state)
nextB forall r. CodeGenFunction r (global, state)
startB forall r. global -> CodeGenFunction r ()
stopB) = (forall r c.
 Phi c =>
 (global, global)
 -> Value (Ptr (Struct (local, (local, ()))))
 -> (state, state, Value Bool)
 -> T r c (a, (state, state, Value Bool)))
-> (forall r.
    CodeGenFunction r ((global, global), (state, state, Value Bool)))
-> (forall r. (global, global) -> CodeGenFunction r ())
-> T a
forall a global local state.
(C global, IsSized local, C state) =>
(forall r c.
 Phi c =>
 global -> Value (Ptr local) -> state -> T r c (a, state))
-> (forall r. CodeGenFunction r (global, state))
-> (forall r. global -> CodeGenFunction r ())
-> T a
Cons
   (\(global
globalA, global
globalB) Value (Ptr (Struct (local, (local, ()))))
local (state
sa0,state
sb0,Value Bool
phaseB) -> do
      (Value (Ptr local)
localA,Value (Ptr local)
localB) <- Value (Ptr (Struct (local, (local, ()))))
-> T r c (Value (Ptr local), Value (Ptr local))
forall a b r c.
Value (Ptr (Struct (a, (b, ()))))
-> T r c (Value (Ptr a), Value (Ptr b))
getPairPtrs Value (Ptr (Struct (local, (local, ()))))
local
      T r
  (T (a, (state, state, Value Bool)))
  (a, (state, state, Value Bool))
-> T r
     (T (a, (state, state, Value Bool)))
     (a, (state, state, Value Bool))
-> T r c (a, (state, state, Value Bool))
forall z a r.
(Phi z, Undefined a) =>
T r (T a) a -> T r (T a) a -> T r z a
MaybeCont.alternative
         (do
            Value Bool -> T r (T (a, (state, state, Value Bool))) ()
forall z r. Phi z => Value Bool -> T r z ()
MaybeCont.guard (Value Bool -> T r (T (a, (state, state, Value Bool))) ())
-> T r (T (a, (state, state, Value Bool))) (Value Bool)
-> T r (T (a, (state, state, Value Bool))) ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< CodeGenFunction r (Value Bool)
-> T r (T (a, (state, state, Value Bool))) (Value Bool)
forall r a z. CodeGenFunction r a -> T r z a
MaybeCont.lift (Value Bool -> CodeGenFunction r (Value Bool)
forall (value :: * -> *) a r.
(ValueCons value, IsInteger a) =>
value a -> CodeGenFunction r (value a)
LLVM.inv Value Bool
phaseB)
            (a
a,state
sa1) <- global
-> Value (Ptr local)
-> state
-> T r (T (a, (state, state, Value Bool))) (a, state)
forall r c.
Phi c =>
global -> Value (Ptr local) -> state -> T r c (a, state)
nextA global
globalA Value (Ptr local)
localA state
sa0
            (a, (state, state, Value Bool))
-> T r
     (T (a, (state, state, Value Bool)))
     (a, (state, state, Value Bool))
forall a. a -> T r (T (a, (state, state, Value Bool))) a
forall (m :: * -> *) a. Monad m => a -> m a
return (a
a, (state
sa1, state
sb0, Bool -> Value Bool
forall a. IsConst a => a -> Value a
LLVM.valueOf Bool
False)))
         (do
            (a
b,state
sb1) <- global
-> Value (Ptr local)
-> state
-> T r (T (a, (state, state, Value Bool))) (a, state)
forall r c.
Phi c =>
global -> Value (Ptr local) -> state -> T r c (a, state)
nextB global
globalB Value (Ptr local)
localB state
sb0
            (a, (state, state, Value Bool))
-> T r
     (T (a, (state, state, Value Bool)))
     (a, (state, state, Value Bool))
forall a. a -> T r (T (a, (state, state, Value Bool))) a
forall (m :: * -> *) a. Monad m => a -> m a
return (a
b, (state
sa0, state
sb1, Bool -> Value Bool
forall a. IsConst a => a -> Value a
LLVM.valueOf Bool
True))))
   (do
      (global
globalA,state
stateA) <- CodeGenFunction r (global, state)
forall r. CodeGenFunction r (global, state)
startA
      (global
globalB,state
stateB) <- CodeGenFunction r (global, state)
forall r. CodeGenFunction r (global, state)
startB
      ((global, global), (state, state, Value Bool))
-> CodeGenFunction r ((global, global), (state, state, Value Bool))
forall a. a -> CodeGenFunction r a
forall (m :: * -> *) a. Monad m => a -> m a
return ((global
globalA,global
globalB), (state
stateA, state
stateB, Bool -> Value Bool
forall a. IsConst a => a -> Value a
LLVM.valueOf Bool
False)))
   (\(global
globalA,global
globalB) -> global -> CodeGenFunction r ()
forall r. global -> CodeGenFunction r ()
stopB global
globalB CodeGenFunction r ()
-> CodeGenFunction r () -> CodeGenFunction r ()
forall a b.
CodeGenFunction r a -> CodeGenFunction r b -> CodeGenFunction r b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> global -> CodeGenFunction r ()
forall r. global -> CodeGenFunction r ()
stopA global
globalA)

instance (Tuple.Phi a, Tuple.Undefined a) => Semigroup (T a) where
   <> :: T a -> T a -> T a
(<>) = T a -> T a -> T a
forall a. (Phi a, Undefined a) => T a -> T a -> T a
append

instance (Tuple.Phi a, Tuple.Undefined a) => Monoid (T a) where
   mempty :: T a
mempty = T a
forall a. T a
empty
   mappend :: T a -> T a -> T a
mappend = T a -> T a -> T a
forall a. Semigroup a => a -> a -> a
(<>)



instance Functor T where
   fmap :: forall a b. (a -> b) -> T a -> T b
fmap a -> b
f (Cons forall r c.
Phi c =>
global -> Value (Ptr local) -> state -> T r c (a, state)
next forall r. CodeGenFunction r (global, state)
start forall r. global -> CodeGenFunction r ()
stop) = (forall r c.
 Phi c =>
 global -> Value (Ptr local) -> state -> T r c (b, state))
-> (forall r. CodeGenFunction r (global, state))
-> (forall r. global -> CodeGenFunction r ())
-> T b
forall a global local state.
(C global, IsSized local, C state) =>
(forall r c.
 Phi c =>
 global -> Value (Ptr local) -> state -> T r c (a, state))
-> (forall r. CodeGenFunction r (global, state))
-> (forall r. global -> CodeGenFunction r ())
-> T a
Cons
      (\global
global Value (Ptr local)
local state
s -> (a -> b) -> (a, state) -> (b, state)
forall a c b. (a -> c) -> (a, b) -> (c, b)
mapFst a -> b
f ((a, state) -> (b, state)) -> T r c (a, state) -> T r c (b, state)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> global -> Value (Ptr local) -> state -> T r c (a, state)
forall r c.
Phi c =>
global -> Value (Ptr local) -> state -> T r c (a, state)
next global
global Value (Ptr local)
local state
s)
      CodeGenFunction r (global, state)
forall r. CodeGenFunction r (global, state)
start global -> CodeGenFunction r ()
forall r. global -> CodeGenFunction r ()
stop

instance Applicative T where
   pure :: forall a. a -> T a
pure a
a = (forall r c.
 Phi c =>
 Value (Ptr (Struct ())) -> () -> T r c (a, ()))
-> (forall r. CodeGenFunction r ()) -> T a
forall local state a.
(IsSized local, C state) =>
(forall r c.
 Phi c =>
 Value (Ptr local) -> state -> T r c (a, state))
-> (forall r. CodeGenFunction r state) -> T a
noGlobal ((() -> T r c (a, ()))
-> Value (Ptr (Struct ())) -> () -> T r c (a, ())
forall f. f -> Value (Ptr (Struct ())) -> f
noLocalPtr ((() -> T r c (a, ()))
 -> Value (Ptr (Struct ())) -> () -> T r c (a, ()))
-> (() -> T r c (a, ()))
-> Value (Ptr (Struct ()))
-> ()
-> T r c (a, ())
forall a b. (a -> b) -> a -> b
$ \() -> (a, ()) -> T r c (a, ())
forall a. a -> T r c a
forall (m :: * -> *) a. Monad m => a -> m a
return (a
a, ())) (() -> CodeGenFunction r ()
forall a. a -> CodeGenFunction r a
forall (m :: * -> *) a. Monad m => a -> m a
return ())
   Cons forall r c.
Phi c =>
global -> Value (Ptr local) -> state -> T r c (a -> b, state)
nextF forall r. CodeGenFunction r (global, state)
startF forall r. global -> CodeGenFunction r ()
stopF <*> :: forall a b. T (a -> b) -> T a -> T b
<*> Cons forall r c.
Phi c =>
global -> Value (Ptr local) -> state -> T r c (a, state)
nextA forall r. CodeGenFunction r (global, state)
startA forall r. global -> CodeGenFunction r ()
stopA = (forall r c.
 Phi c =>
 (global, global)
 -> Value (Ptr (Struct (local, (local, ()))))
 -> (state, state)
 -> T r c (b, (state, state)))
-> (forall r. CodeGenFunction r ((global, global), (state, state)))
-> (forall r. (global, global) -> CodeGenFunction r ())
-> T b
forall a global local state.
(C global, IsSized local, C state) =>
(forall r c.
 Phi c =>
 global -> Value (Ptr local) -> state -> T r c (a, state))
-> (forall r. CodeGenFunction r (global, state))
-> (forall r. global -> CodeGenFunction r ())
-> T a
Cons
      (\(global
globalF, global
globalA) Value (Ptr (Struct (local, (local, ()))))
local (state
sf0,state
sa0) -> do
         (Value (Ptr local)
localF,Value (Ptr local)
localA) <- Value (Ptr (Struct (local, (local, ()))))
-> T r c (Value (Ptr local), Value (Ptr local))
forall a b r c.
Value (Ptr (Struct (a, (b, ()))))
-> T r c (Value (Ptr a), Value (Ptr b))
getPairPtrs Value (Ptr (Struct (local, (local, ()))))
local
         (a -> b
f,state
sf1) <- global -> Value (Ptr local) -> state -> T r c (a -> b, state)
forall r c.
Phi c =>
global -> Value (Ptr local) -> state -> T r c (a -> b, state)
nextF global
globalF Value (Ptr local)
localF state
sf0
         (a
a,state
sa1) <- global -> Value (Ptr local) -> state -> T r c (a, state)
forall r c.
Phi c =>
global -> Value (Ptr local) -> state -> T r c (a, state)
nextA global
globalA Value (Ptr local)
localA state
sa0
         (b, (state, state)) -> T r c (b, (state, state))
forall a. a -> T r c a
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> b
f a
a, (state
sf1,state
sa1)))
      (((global, state)
 -> (global, state) -> ((global, global), (state, state)))
-> CodeGenFunction r (global, state)
-> CodeGenFunction r (global, state)
-> CodeGenFunction r ((global, global), (state, state))
forall a b c.
(a -> b -> c)
-> CodeGenFunction r a
-> CodeGenFunction r b
-> CodeGenFunction r c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (global, state)
-> (global, state) -> ((global, global), (state, state))
forall a b c d. (a, b) -> (c, d) -> ((a, c), (b, d))
zipPair CodeGenFunction r (global, state)
forall r. CodeGenFunction r (global, state)
startF CodeGenFunction r (global, state)
forall r. CodeGenFunction r (global, state)
startA)
      (\(global
globalF, global
globalA) -> global -> CodeGenFunction r ()
forall r. global -> CodeGenFunction r ()
stopA global
globalA CodeGenFunction r ()
-> CodeGenFunction r () -> CodeGenFunction r ()
forall a b.
CodeGenFunction r a -> CodeGenFunction r b -> CodeGenFunction r b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> global -> CodeGenFunction r ()
forall r. global -> CodeGenFunction r ()
stopF global
globalF)


map :: (forall r. a -> CodeGenFunction r b) -> T a -> T b
map :: forall a b. (forall r. a -> CodeGenFunction r b) -> T a -> T b
map forall r. a -> CodeGenFunction r b
f (Cons forall r c.
Phi c =>
global -> Value (Ptr local) -> state -> T r c (a, state)
next forall r. CodeGenFunction r (global, state)
start forall r. global -> CodeGenFunction r ()
stop) =
   (forall r c.
 Phi c =>
 global -> Value (Ptr local) -> state -> T r c (b, state))
-> (forall r. CodeGenFunction r (global, state))
-> (forall r. global -> CodeGenFunction r ())
-> T b
forall a global local state.
(C global, IsSized local, C state) =>
(forall r c.
 Phi c =>
 global -> Value (Ptr local) -> state -> T r c (a, state))
-> (forall r. CodeGenFunction r (global, state))
-> (forall r. global -> CodeGenFunction r ())
-> T a
Cons
      (\global
global Value (Ptr local)
local state
sa0 -> do
         (a
a,state
sa1) <- global -> Value (Ptr local) -> state -> T r c (a, state)
forall r c.
Phi c =>
global -> Value (Ptr local) -> state -> T r c (a, state)
next global
global Value (Ptr local)
local state
sa0
         b
b <- CodeGenFunction r b -> T r c b
forall r a z. CodeGenFunction r a -> T r z a
MaybeCont.lift (CodeGenFunction r b -> T r c b) -> CodeGenFunction r b -> T r c b
forall a b. (a -> b) -> a -> b
$ a -> CodeGenFunction r b
forall r. a -> CodeGenFunction r b
f a
a
         (b, state) -> T r c (b, state)
forall a. a -> T r c a
forall (m :: * -> *) a. Monad m => a -> m a
return (b
b, state
sa1))
      CodeGenFunction r (global, state)
forall r. CodeGenFunction r (global, state)
start global -> CodeGenFunction r ()
forall r. global -> CodeGenFunction r ()
stop

zipWith :: (forall r. a -> b -> CodeGenFunction r c) -> T a -> T b -> T c
zipWith :: forall a b c.
(forall r. a -> b -> CodeGenFunction r c) -> T a -> T b -> T c
zipWith forall r. a -> b -> CodeGenFunction r c
f T a
as T b
bs = (forall r. (a, b) -> CodeGenFunction r c) -> T (a, b) -> T c
forall a b. (forall r. a -> CodeGenFunction r b) -> T a -> T b
map ((a -> b -> CodeGenFunction r c) -> (a, b) -> CodeGenFunction r c
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry a -> b -> CodeGenFunction r c
forall r. a -> b -> CodeGenFunction r c
f) (T (a, b) -> T c) -> T (a, b) -> T c
forall a b. (a -> b) -> a -> b
$ (a -> b -> (a, b)) -> T a -> T b -> T (a, b)
forall a b c. (a -> b -> c) -> T a -> T b -> T c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (,) T a
as T b
bs

instance (A.Additive a) => Additive.C (T a) where
   zero :: T a
zero = a -> T a
forall a. a -> T a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
forall a. Additive a => a
A.zero
   negate :: T a -> T a
negate = (forall r. a -> CodeGenFunction r a) -> T a -> T a
forall a b. (forall r. a -> CodeGenFunction r b) -> T a -> T b
map a -> CodeGenFunction r a
forall r. a -> CodeGenFunction r a
forall a r. Additive a => a -> CodeGenFunction r a
A.neg
   + :: T a -> T a -> T a
(+) = (forall r. a -> a -> CodeGenFunction r a) -> T a -> T a -> T a
forall a b c.
(forall r. a -> b -> CodeGenFunction r c) -> T a -> T b -> T c
zipWith a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. Additive a => a -> a -> CodeGenFunction r a
A.add
   (-) = (forall r. a -> a -> CodeGenFunction r a) -> T a -> T a -> T a
forall a b c.
(forall r. a -> b -> CodeGenFunction r c) -> T a -> T b -> T c
zipWith a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. Additive a => a -> a -> CodeGenFunction r a
A.sub

instance (A.PseudoRing a, A.IntegerConstant a) => Ring.C (T a) where
   one :: T a
one = a -> T a
forall a. a -> T a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
forall a. IntegerConstant a => a
A.one
   fromInteger :: Integer -> T a
fromInteger Integer
n = a -> T a
forall a. a -> T a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Integer -> a
forall a. IntegerConstant a => Integer -> a
A.fromInteger' Integer
n)
   * :: T a -> T a -> T a
(*) = (forall r. a -> a -> CodeGenFunction r a) -> T a -> T a -> T a
forall a b c.
(forall r. a -> b -> CodeGenFunction r c) -> T a -> T b -> T c
zipWith a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. PseudoRing a => a -> a -> CodeGenFunction r a
A.mul

instance (A.Field a, A.RationalConstant a) => Field.C (T a) where
   fromRational' :: Rational -> T a
fromRational' Rational
x = a -> T a
forall a. a -> T a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Rational -> a
forall a. RationalConstant a => Rational -> a
A.fromRational' (Rational -> a) -> Rational -> a
forall a b. (a -> b) -> a -> b
$ Rational -> Rational
forall a. Integral a => T a -> Ratio a
Ratio.toRational98 Rational
x)
   / :: T a -> T a -> T a
(/) = (forall r. a -> a -> CodeGenFunction r a) -> T a -> T a -> T a
forall a b c.
(forall r. a -> b -> CodeGenFunction r c) -> T a -> T b -> T c
zipWith a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. Field a => a -> a -> CodeGenFunction r a
A.fdiv


instance (A.PseudoRing a, A.Real a, A.IntegerConstant a) => P.Num (T a) where
   fromInteger :: Integer -> T a
fromInteger Integer
n = a -> T a
forall a. a -> T a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Integer -> a
forall a. IntegerConstant a => Integer -> a
A.fromInteger' Integer
n)
   negate :: T a -> T a
negate = (forall r. a -> CodeGenFunction r a) -> T a -> T a
forall a b. (forall r. a -> CodeGenFunction r b) -> T a -> T b
map a -> CodeGenFunction r a
forall r. a -> CodeGenFunction r a
forall a r. Additive a => a -> CodeGenFunction r a
A.neg
   + :: T a -> T a -> T a
(+) = (forall r. a -> a -> CodeGenFunction r a) -> T a -> T a -> T a
forall a b c.
(forall r. a -> b -> CodeGenFunction r c) -> T a -> T b -> T c
zipWith a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. Additive a => a -> a -> CodeGenFunction r a
A.add
   (-) = (forall r. a -> a -> CodeGenFunction r a) -> T a -> T a -> T a
forall a b c.
(forall r. a -> b -> CodeGenFunction r c) -> T a -> T b -> T c
zipWith a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. Additive a => a -> a -> CodeGenFunction r a
A.sub
   * :: T a -> T a -> T a
(*) = (forall r. a -> a -> CodeGenFunction r a) -> T a -> T a -> T a
forall a b c.
(forall r. a -> b -> CodeGenFunction r c) -> T a -> T b -> T c
zipWith a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. PseudoRing a => a -> a -> CodeGenFunction r a
A.mul
   abs :: T a -> T a
abs = (forall r. a -> CodeGenFunction r a) -> T a -> T a
forall a b. (forall r. a -> CodeGenFunction r b) -> T a -> T b
map a -> CodeGenFunction r a
forall r. a -> CodeGenFunction r a
forall a r. Real a => a -> CodeGenFunction r a
A.abs
   signum :: T a -> T a
signum = (forall r. a -> CodeGenFunction r a) -> T a -> T a
forall a b. (forall r. a -> CodeGenFunction r b) -> T a -> T b
map a -> CodeGenFunction r a
forall r. a -> CodeGenFunction r a
forall a r. Real a => a -> CodeGenFunction r a
A.signum

instance (A.Field a, A.Real a, A.RationalConstant a) => P.Fractional (T a) where
   fromRational :: Rational -> T a
fromRational Rational
x = a -> T a
forall a. a -> T a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Rational -> a
forall a. RationalConstant a => Rational -> a
A.fromRational' Rational
x)
   / :: T a -> T a -> T a
(/) = (forall r. a -> a -> CodeGenFunction r a) -> T a -> T a -> T a
forall a b c.
(forall r. a -> b -> CodeGenFunction r c) -> T a -> T b -> T c
zipWith a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. Field a => a -> a -> CodeGenFunction r a
A.fdiv



arraySize :: value (array n a) -> Proxy n
arraySize :: forall (value :: * -> *) (array :: * -> * -> *) n a.
value (array n a) -> Proxy n
arraySize value (array n a)
_ = Proxy n
forall a. Proxy a
Proxy