{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
module Synthesizer.LLVM.Generator.Core where

import qualified Synthesizer.LLVM.Causal.Private as Causal
import qualified Synthesizer.LLVM.Generator.Private as Sig
import qualified Synthesizer.LLVM.Random as Rnd

import Synthesizer.Causal.Class (($*))

import qualified LLVM.DSL.Expression as Expr
import LLVM.DSL.Expression (Exp)

import qualified LLVM.Extra.Multi.Value.Marshal as Marshal
import qualified LLVM.Extra.Multi.Value as MultiValue
import qualified LLVM.Extra.Arithmetic as A

import Control.Applicative ((<$>))

import Data.Word (Word32)

import NumericPrelude.Numeric
import NumericPrelude.Base hiding (map, iterate, takeWhile, tail)



type MV a = Sig.T (MultiValue.T a)

iterate :: (Marshal.C a) => (Exp a -> Exp a) -> Exp a -> MV a
iterate :: forall a. C a => (Exp a -> Exp a) -> Exp a -> MV a
iterate Exp a -> Exp a
f Exp a
a = (forall r. T a -> CodeGenFunction r (T a))
-> (forall r. CodeGenFunction r (T a)) -> T (T a)
forall a.
C a =>
(forall r. a -> CodeGenFunction r a)
-> (forall r. CodeGenFunction r a) -> T a
Sig.iterate ((Exp a -> Exp a) -> T a -> CodeGenFunction r (T a)
forall ae am be bm r.
(Aggregate ae am, Aggregate be bm) =>
(ae -> be) -> am -> CodeGenFunction r bm
Expr.unliftM1 Exp a -> Exp a
f) (Exp a -> forall r. CodeGenFunction r (T a)
forall a. Exp a -> forall r. CodeGenFunction r (T a)
Expr.unExp Exp a
a)

-- ToDo: replace by constantSharing and scanl
iterateParam ::
   (Marshal.C a, Marshal.C b) =>
   (Exp b -> Exp a -> Exp a) -> Exp b -> Exp a -> MV a
iterateParam :: forall a b.
(C a, C b) =>
(Exp b -> Exp a -> Exp a) -> Exp b -> Exp a -> MV a
iterateParam Exp b -> Exp a -> Exp a
f Exp b
b Exp a
a =
   T (b, a) -> T a
forall a b. T (a, b) -> T b
MultiValue.snd (T (b, a) -> T a) -> T (T (b, a)) -> T (T a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
   (Exp (b, a) -> Exp (b, a)) -> Exp (b, a) -> T (T (b, a))
forall a. C a => (Exp a -> Exp a) -> Exp a -> MV a
iterate ((Exp b -> Exp a -> Exp (b, a)) -> Exp (b, a) -> Exp (b, a)
forall a b c. (Exp a -> Exp b -> c) -> Exp (a, b) -> c
Expr.uncurry ((Exp b -> Exp a -> Exp (b, a)) -> Exp (b, a) -> Exp (b, a))
-> (Exp b -> Exp a -> Exp (b, a)) -> Exp (b, a) -> Exp (b, a)
forall a b. (a -> b) -> a -> b
$ \Exp b
bi Exp a
ai -> Exp b -> Exp a -> Exp (b, a)
forall (val :: * -> *) a b.
Value val =>
val a -> val b -> val (a, b)
Expr.zip Exp b
bi (Exp a -> Exp (b, a)) -> Exp a -> Exp (b, a)
forall a b. (a -> b) -> a -> b
$ Exp b -> Exp a -> Exp a
f Exp b
bi Exp a
ai) (Exp b -> Exp a -> Exp (b, a)
forall (val :: * -> *) a b.
Value val =>
val a -> val b -> val (a, b)
Expr.zip Exp b
b Exp a
a)


ramp ::
   (Marshal.C a, MultiValue.Additive a) =>
   Exp a -> Exp a -> MV a
ramp :: forall a. (C a, Additive a) => Exp a -> Exp a -> MV a
ramp = (Exp a -> Exp a -> Exp a) -> Exp a -> Exp a -> MV a
forall a b.
(C a, C b) =>
(Exp b -> Exp a -> Exp a) -> Exp b -> Exp a -> MV a
iterateParam Exp a -> Exp a -> Exp a
forall a. Additive a => Exp a -> Exp a -> Exp a
Expr.add

parabola ::
   (Marshal.C a, MultiValue.Additive a) =>
   Exp a -> Exp a -> Exp a -> MV a
parabola :: forall a. (C a, Additive a) => Exp a -> Exp a -> Exp a -> MV a
parabola Exp a
d2 Exp a
d1 Exp a
start = Exp a -> T (T a) (T a)
forall a al. (C a, Additive a, T a ~ al) => Exp a -> T al al
integrate Exp a
start T (T a) (T a) -> SignalOf T (T a) -> SignalOf T (T a)
forall (process :: * -> * -> *) a b.
C process =>
process a b -> SignalOf process a -> SignalOf process b
$* Exp a -> Exp a -> T (T a)
forall a. (C a, Additive a) => Exp a -> Exp a -> MV a
ramp Exp a
d2 Exp a
d1

integrate ::
   (Marshal.C a, MultiValue.Additive a, MultiValue.T a ~ al) =>
   Exp a -> Causal.T al al
integrate :: forall a al. (C a, Additive a, T a ~ al) => Exp a -> T al al
integrate Exp a
start =
   (forall r. al -> T a -> CodeGenFunction r (al, T a))
-> (forall r. CodeGenFunction r (T a)) -> T al al
forall state a b.
C state =>
(forall r. a -> state -> CodeGenFunction r (b, state))
-> (forall r. CodeGenFunction r state) -> T a b
Causal.mapAccum (\al
a T a
s -> (,) al
T a
s (T a -> (al, T a))
-> CodeGenFunction r (T a) -> CodeGenFunction r (al, T a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> T a -> T a -> CodeGenFunction r (T a)
forall a r. Additive a => a -> a -> CodeGenFunction r a
forall r. T a -> T a -> CodeGenFunction r (T a)
A.add T a
s al
T a
a) (Exp a -> forall r. CodeGenFunction r (T a)
forall a. Exp a -> forall r. CodeGenFunction r (T a)
Expr.unExp Exp a
start)


osci ::
   (MultiValue.Fraction t, Marshal.C t) =>
   Exp t -> Exp t -> MV t
osci :: forall t. (Fraction t, C t) => Exp t -> Exp t -> MV t
osci Exp t
phase Exp t
freq  =  (Exp t -> Exp t) -> Exp t -> MV t
forall a. C a => (Exp a -> Exp a) -> Exp a -> MV a
iterate ((forall r. T t -> T t -> CodeGenFunction r (T t))
-> Exp t -> Exp t -> Exp t
forall ae am be bm c.
(Aggregate ae am, Aggregate be bm) =>
(forall r. am -> bm -> CodeGenFunction r (T c))
-> ae -> be -> Exp c
Expr.liftM2 T t -> T t -> CodeGenFunction r (T t)
forall r. T t -> T t -> CodeGenFunction r (T t)
forall a r. Fraction a => a -> a -> CodeGenFunction r a
A.incPhase Exp t
freq) Exp t
phase

exponential ::
   (Marshal.C a, MultiValue.PseudoRing a) =>
   Exp a -> Exp a -> MV a
exponential :: forall a. (C a, PseudoRing a) => Exp a -> Exp a -> MV a
exponential  =  (Exp a -> Exp a -> Exp a) -> Exp a -> Exp a -> MV a
forall a b.
(C a, C b) =>
(Exp b -> Exp a -> Exp a) -> Exp b -> Exp a -> MV a
iterateParam Exp a -> Exp a -> Exp a
forall a. PseudoRing a => Exp a -> Exp a -> Exp a
Expr.mul

exponentialBounded ::
   (Marshal.C a, MultiValue.PseudoRing a,
    MultiValue.Real a, MultiValue.IntegerConstant a) =>
   Exp a -> Exp a -> Exp a -> MV a
exponentialBounded :: forall a.
(C a, PseudoRing a, Real a, IntegerConstant a) =>
Exp a -> Exp a -> Exp a -> MV a
exponentialBounded Exp a
bound Exp a
decay =
   (Exp (a, a) -> Exp a -> Exp a) -> Exp (a, a) -> Exp a -> MV a
forall a b.
(C a, C b) =>
(Exp b -> Exp a -> Exp a) -> Exp b -> Exp a -> MV a
iterateParam
      (\Exp (a, a)
bk Exp a
y -> case Exp (a, a) -> (Exp a, Exp a)
forall (val :: * -> *) a b.
Value val =>
val (a, b) -> (val a, val b)
Expr.unzip Exp (a, a)
bk of (Exp a
b,Exp a
k) -> Exp a -> Exp a -> Exp a
forall a. Real a => Exp a -> Exp a -> Exp a
Expr.max Exp a
b (Exp a -> Exp a) -> Exp a -> Exp a
forall a b. (a -> b) -> a -> b
$ Exp a
kExp a -> Exp a -> Exp a
forall a. C a => a -> a -> a
*Exp a
y)
      (Exp a -> Exp a -> Exp (a, a)
forall (val :: * -> *) a b.
Value val =>
val a -> val b -> val (a, b)
Expr.zip Exp a
bound Exp a
decay)


noise, noiseAlt :: Exp Word32 -> MV Word32
noise :: Exp Word32 -> MV Word32
noise Exp Word32
seed =
   (Exp Word32 -> Exp Word32) -> Exp Word32 -> MV Word32
forall a. C a => (Exp a -> Exp a) -> Exp a -> MV a
iterate ((forall r. Repr Word32 -> CodeGenFunction r (Repr Word32))
-> Exp Word32 -> Exp Word32
forall a b.
(forall r. Repr a -> CodeGenFunction r (Repr b)) -> Exp a -> Exp b
Expr.liftReprM Repr Word32 -> CodeGenFunction r (Repr Word32)
Value Word32 -> CodeGenFunction r (Value Word32)
forall r. Repr Word32 -> CodeGenFunction r (Repr Word32)
forall r. Value Word32 -> CodeGenFunction r (Value Word32)
Rnd.nextCG)
      (Exp Word32 -> Exp Word32 -> Exp Word32
forall a. Integral a => Exp a -> Exp a -> Exp a
Expr.irem Exp Word32
seed (Word32 -> Exp Word32
forall a. C a => a -> Exp a
Expr.cons Word32
forall a. Integral a => a
Rnd.modulusExp Word32 -> Exp Word32 -> Exp Word32
forall a. C a => a -> a -> a
-Exp Word32
1) Exp Word32 -> Exp Word32 -> Exp Word32
forall a. C a => a -> a -> a
+ Exp Word32
1)

noiseAlt :: Exp Word32 -> MV Word32
noiseAlt Exp Word32
seed =
   (Exp Word32 -> Exp Word32) -> Exp Word32 -> MV Word32
forall a. C a => (Exp a -> Exp a) -> Exp a -> MV a
iterate ((forall r. Repr Word32 -> CodeGenFunction r (Repr Word32))
-> Exp Word32 -> Exp Word32
forall a b.
(forall r. Repr a -> CodeGenFunction r (Repr b)) -> Exp a -> Exp b
Expr.liftReprM Repr Word32 -> CodeGenFunction r (Repr Word32)
Value Word32 -> CodeGenFunction r (Value Word32)
forall r. Repr Word32 -> CodeGenFunction r (Repr Word32)
forall r. Value Word32 -> CodeGenFunction r (Value Word32)
Rnd.nextCG32)
      (Exp Word32 -> Exp Word32 -> Exp Word32
forall a. Integral a => Exp a -> Exp a -> Exp a
Expr.irem Exp Word32
seed (Word32 -> Exp Word32
forall a. C a => a -> Exp a
Expr.cons Word32
forall a. Integral a => a
Rnd.modulusExp Word32 -> Exp Word32 -> Exp Word32
forall a. C a => a -> a -> a
-Exp Word32
1) Exp Word32 -> Exp Word32 -> Exp Word32
forall a. C a => a -> a -> a
+ Exp Word32
1)