module UVMHS.Lib.Fuzzy where

import UVMHS.Core
import UVMHS.Lib.Rand

class Fuzzy a where
  fuzzy  FuzzyM a

data FuzzyEnv = FuzzyEnv
  { FuzzyEnv -> ℕ64
fuzzyEnvRadius  ℕ64
  , FuzzyEnv -> ℕ64
fuzzyEnvDepth   ℕ64
  }

newtype FuzzyM a = FuzzyM { forall a. FuzzyM a -> RWS FuzzyEnv () RG a
unRandM  RWS FuzzyEnv () RG a }
  deriving
  ( (forall a. a -> FuzzyM a) -> Return FuzzyM
forall a. a -> FuzzyM a
forall (m :: * -> *). (forall a. a -> m a) -> Return m
$creturn :: forall a. a -> FuzzyM a
return :: forall a. a -> FuzzyM a
Return,(forall a b. FuzzyM a -> (a -> FuzzyM b) -> FuzzyM b)
-> Bind FuzzyM
forall a b. FuzzyM a -> (a -> FuzzyM b) -> FuzzyM b
forall (m :: * -> *).
(forall a b. m a -> (a -> m b) -> m b) -> Bind m
$c≫= :: forall a b. FuzzyM a -> (a -> FuzzyM b) -> FuzzyM b
≫= :: forall a b. FuzzyM a -> (a -> FuzzyM b) -> FuzzyM b
Bind,(forall a b. (a -> b) -> FuzzyM a -> FuzzyM b) -> Functor FuzzyM
forall a b. (a -> b) -> FuzzyM a -> FuzzyM b
forall (t :: * -> *).
(forall a b. (a -> b) -> t a -> t b) -> Functor t
$cmap :: forall a b. (a -> b) -> FuzzyM a -> FuzzyM b
map :: forall a b. (a -> b) -> FuzzyM a -> FuzzyM b
Functor,Bind FuzzyM
Return FuzzyM
Functor FuzzyM
(Functor FuzzyM, Return FuzzyM, Bind FuzzyM) => Monad FuzzyM
forall (m :: * -> *). (Functor m, Return m, Bind m) => Monad m
Monad
  , MonadReader FuzzyEnv
  , MonadState RG
  )

makeLenses ''FuzzyEnv

mkFuzzyM  (FuzzyEnv  RG  RG  a)  FuzzyM a
mkFuzzyM :: forall a. (FuzzyEnv -> RG -> RG ∧ a) -> FuzzyM a
mkFuzzyM FuzzyEnv -> RG -> RG ∧ a
f = RWS FuzzyEnv () RG a -> FuzzyM a
forall a. RWS FuzzyEnv () RG a -> FuzzyM a
FuzzyM (RWS FuzzyEnv () RG a -> FuzzyM a)
-> RWS FuzzyEnv () RG a -> FuzzyM a
forall a b. (a -> b) -> a -> b
$ (FuzzyEnv -> RG -> (RG ∧ ()) ∧ a) -> RWS FuzzyEnv () RG a
forall r o s a. (r -> s -> (s ∧ o) ∧ a) -> RWS r o s a
mkRWS ((FuzzyEnv -> RG -> (RG ∧ ()) ∧ a) -> RWS FuzzyEnv () RG a)
-> (FuzzyEnv -> RG -> (RG ∧ ()) ∧ a) -> RWS FuzzyEnv () RG a
forall a b. (a -> b) -> a -> b
$ \ FuzzyEnv
γ RG
  (RG -> RG ∧ ()) -> (RG ∧ a) -> (RG ∧ ()) ∧ a
forall a₁ a₂ b. (a₁ -> a₂) -> (a₁ ∧ b) -> a₂ ∧ b
mapFst ((RG -> () -> RG ∧ ()) -> () -> RG -> RG ∧ ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip RG -> () -> RG ∧ ()
forall a b. a -> b -> a ∧ b
(:*) ()) ((RG ∧ a) -> (RG ∧ ()) ∧ a) -> (RG ∧ a) -> (RG ∧ ()) ∧ a
forall a b. (a -> b) -> a -> b
$ FuzzyEnv -> RG -> RG ∧ a
f FuzzyEnv
γ RG


runFuzzyM  FuzzyEnv  RG  FuzzyM a  RG  a
runFuzzyM :: forall a. FuzzyEnv -> RG -> FuzzyM a -> RG ∧ a
runFuzzyM FuzzyEnv
γ RG
 = ((RG ∧ ()) -> RG) -> ((RG ∧ ()) ∧ a) -> RG ∧ a
forall a₁ a₂ b. (a₁ -> a₂) -> (a₁ ∧ b) -> a₂ ∧ b
mapFst (RG ∧ ()) -> RG
forall a b. (a ∧ b) -> a
fst (((RG ∧ ()) ∧ a) -> RG ∧ a)
-> (RWS FuzzyEnv () RG a -> (RG ∧ ()) ∧ a)
-> RWS FuzzyEnv () RG a
-> RG ∧ a
forall b c a. (b -> c) -> (a -> b) -> a -> c
 FuzzyEnv -> RG -> RWS FuzzyEnv () RG a -> (RG ∧ ()) ∧ a
forall r o s a. r -> s -> RWS r o s a -> (s ∧ o) ∧ a
runRWS FuzzyEnv
γ RG
 (RWS FuzzyEnv () RG a -> RG ∧ a)
-> (FuzzyM a -> RWS FuzzyEnv () RG a) -> FuzzyM a -> RG ∧ a
forall b c a. (b -> c) -> (a -> b) -> a -> c
 FuzzyM a -> RWS FuzzyEnv () RG a
forall a. FuzzyM a -> RWS FuzzyEnv () RG a
unRandM

runFuzzyMRG  FuzzyEnv  FuzzyM a  State RG a
runFuzzyMRG :: forall a. FuzzyEnv -> FuzzyM a -> State RG a
runFuzzyMRG FuzzyEnv
γ FuzzyM a
xM = (RG -> RG ∧ a) -> State RG a
forall s a. (s -> s ∧ a) -> State s a
mkState ((RG -> RG ∧ a) -> State RG a) -> (RG -> RG ∧ a) -> State RG a
forall a b. (a -> b) -> a -> b
$ \ RG
  FuzzyEnv -> RG -> FuzzyM a -> RG ∧ a
forall a. FuzzyEnv -> RG -> FuzzyM a -> RG ∧ a
runFuzzyM FuzzyEnv
γ RG
 FuzzyM a
xM

-- | Use this to ensure termination when building recursive datatypes.  Note that this will
-- underflow to the maximum natural when `d` is zero, so you should only every use this when you're
-- sure `d` is not zero, e.g. guarded behind a `wrchoose` with coefficient `d`.
fuzzyDec  FuzzyM a  FuzzyM a
fuzzyDec :: forall a. FuzzyM a -> FuzzyM a
fuzzyDec FuzzyM a
xM = do
  ℕ64
d  (FuzzyEnv ⟢ ℕ64) -> FuzzyM ℕ64
forall r'. (FuzzyEnv ⟢ r') -> FuzzyM r'
forall r (m :: * -> *) r'. MonadReader r m => (r ⟢ r') -> m r'
askL FuzzyEnv ⟢ ℕ64
fuzzyEnvDepthL
  let ()
_ = 𝔹 -> ()
assert (𝔹 -> ()) -> 𝔹 -> ()
forall a b. (a -> b) -> a -> b
$ ℕ64
d ℕ64 -> ℕ64 -> 𝔹
forall a. Eq a => a -> a -> 𝔹
 ℕ64
0
  (FuzzyEnv ⟢ ℕ64) -> ℕ64 -> FuzzyM a -> FuzzyM a
forall a r'. (FuzzyEnv ⟢ r') -> r' -> FuzzyM a -> FuzzyM a
forall r (m :: * -> *) a r'.
MonadReader r m =>
(r ⟢ r') -> r' -> m a -> m a
localL FuzzyEnv ⟢ ℕ64
fuzzyEnvDepthL (ℕ64
d ℕ64 -> ℕ64 -> ℕ64
forall a. Minus a => a -> a -> a
- ℕ64
1) FuzzyM a
xM

fuzzyRec  (Fuzzy a)  FuzzyM a
fuzzyRec :: forall a. Fuzzy a => FuzzyM a
fuzzyRec = FuzzyM a -> FuzzyM a
forall a. FuzzyM a -> FuzzyM a
fuzzyDec FuzzyM a
forall a. Fuzzy a => FuzzyM a
fuzzy

instance MonadRand FuzzyM where
  rng :: forall a. State RG a -> FuzzyM a
rng State RG a
xM = RWS FuzzyEnv () RG a -> FuzzyM a
forall a. RWS FuzzyEnv () RG a -> FuzzyM a
FuzzyM (RWS FuzzyEnv () RG a -> FuzzyM a)
-> RWS FuzzyEnv () RG a -> FuzzyM a
forall a b. (a -> b) -> a -> b
$ (FuzzyEnv -> RG -> (RG ∧ ()) ∧ a) -> RWS FuzzyEnv () RG a
forall r o s a. (r -> s -> (s ∧ o) ∧ a) -> RWS r o s a
mkRWS ((FuzzyEnv -> RG -> (RG ∧ ()) ∧ a) -> RWS FuzzyEnv () RG a)
-> (FuzzyEnv -> RG -> (RG ∧ ()) ∧ a) -> RWS FuzzyEnv () RG a
forall a b. (a -> b) -> a -> b
$ \ FuzzyEnv
 RG
  (RG -> RG ∧ ()) -> (RG ∧ a) -> (RG ∧ ()) ∧ a
forall a₁ a₂ b. (a₁ -> a₂) -> (a₁ ∧ b) -> a₂ ∧ b
mapFst ((RG -> () -> RG ∧ ()) -> () -> RG -> RG ∧ ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip RG -> () -> RG ∧ ()
forall a b. a -> b -> a ∧ b
(:*) ()) ((RG ∧ a) -> (RG ∧ ()) ∧ a) -> (RG ∧ a) -> (RG ∧ ()) ∧ a
forall a b. (a -> b) -> a -> b
$ RG -> State RG a -> RG ∧ a
forall s a. s -> State s a -> s ∧ a
runState RG
 State RG a
xM

rand   a m. (MonadRand m,Fuzzy a)  ℕ64  ℕ64  m a
rand :: forall a (m :: * -> *). (MonadRand m, Fuzzy a) => ℕ64 -> ℕ64 -> m a
rand ℕ64
r ℕ64
d = State RG a -> m a
forall a. State RG a -> m a
forall (m :: * -> *) a. MonadRand m => State RG a -> m a
rng (State RG a -> m a) -> State RG a -> m a
forall a b. (a -> b) -> a -> b
$ FuzzyEnv -> FuzzyM a -> State RG a
forall a. FuzzyEnv -> FuzzyM a -> State RG a
runFuzzyMRG (ℕ64 -> ℕ64 -> FuzzyEnv
FuzzyEnv ℕ64
r ℕ64
d) FuzzyM a
forall a. Fuzzy a => FuzzyM a
fuzzy

randTny   a m. (MonadRand m,Fuzzy a)  m a
randTny :: forall a (m :: * -> *). (MonadRand m, Fuzzy a) => m a
randTny = ℕ64 -> ℕ64 -> m a
forall a (m :: * -> *). (MonadRand m, Fuzzy a) => ℕ64 -> ℕ64 -> m a
rand ℕ64
1 ℕ64
1

randSml   a m. (MonadRand m,Fuzzy a)  m a
randSml :: forall a (m :: * -> *). (MonadRand m, Fuzzy a) => m a
randSml = ℕ64 -> ℕ64 -> m a
forall a (m :: * -> *). (MonadRand m, Fuzzy a) => ℕ64 -> ℕ64 -> m a
rand ℕ64
4 ℕ64
4

randMed   a m. (MonadRand m,Fuzzy a)  m a
randMed :: forall a (m :: * -> *). (MonadRand m, Fuzzy a) => m a
randMed = ℕ64 -> ℕ64 -> m a
forall a (m :: * -> *). (MonadRand m, Fuzzy a) => ℕ64 -> ℕ64 -> m a
rand ℕ64
16 ℕ64
16

randLrg   a m. (MonadRand m,Fuzzy a)  m a
randLrg :: forall a (m :: * -> *). (MonadRand m, Fuzzy a) => m a
randLrg = ℕ64 -> ℕ64 -> m a
forall a (m :: * -> *). (MonadRand m, Fuzzy a) => ℕ64 -> ℕ64 -> m a
rand ℕ64
64 ℕ64
64

fuzzyRadius  FuzzyM ℕ64
fuzzyRadius :: FuzzyM ℕ64
fuzzyRadius = ℕ64 -> ℕ64 -> FuzzyM ℕ64
forall a (m :: * -> *). (MonadRand m, RandRange a) => a -> a -> m a
randr ℕ64
0 (ℕ64 -> FuzzyM ℕ64) -> FuzzyM ℕ64 -> FuzzyM ℕ64
forall (m :: * -> *) a b. Bind m => (a -> m b) -> m a -> m b
*$ (FuzzyEnv ⟢ ℕ64) -> FuzzyM ℕ64
forall r'. (FuzzyEnv ⟢ r') -> FuzzyM r'
forall r (m :: * -> *) r'. MonadReader r m => (r ⟢ r') -> m r'
askL FuzzyEnv ⟢ ℕ64
fuzzyEnvRadiusL

fuzzyDepth  FuzzyM ℕ64
fuzzyDepth :: FuzzyM ℕ64
fuzzyDepth = ℕ64 -> ℕ64 -> FuzzyM ℕ64
forall a (m :: * -> *). (MonadRand m, RandRange a) => a -> a -> m a
randr ℕ64
0 (ℕ64 -> FuzzyM ℕ64) -> FuzzyM ℕ64 -> FuzzyM ℕ64
forall (m :: * -> *) a b. Bind m => (a -> m b) -> m a -> m b
*$ (FuzzyEnv ⟢ ℕ64) -> FuzzyM ℕ64
forall r'. (FuzzyEnv ⟢ r') -> FuzzyM r'
forall r (m :: * -> *) r'. MonadReader r m => (r ⟢ r') -> m r'
askL FuzzyEnv ⟢ ℕ64
fuzzyEnvDepthL

---------------------
-- FUZZY INSTANCES --
---------------------

isoFuzzy  (a  b,Fuzzy b)  FuzzyM a
isoFuzzy :: forall a b. (a ⇄ b, Fuzzy b) => FuzzyM a
isoFuzzy = b -> a
forall a b. (a ⇄ b) => b -> a
isofr (b -> a) -> FuzzyM b -> FuzzyM a
forall (t :: * -> *) a b. Functor t => (a -> b) -> t a -> t b
^$ FuzzyM b
forall a. Fuzzy a => FuzzyM a
fuzzy

instance Fuzzy ℕ64 where fuzzy :: FuzzyM ℕ64
fuzzy = ℕ64 -> ℕ64 -> FuzzyM ℕ64
forall a (m :: * -> *). (MonadRand m, RandRange a) => a -> a -> m a
randr ℕ64
forall a. Zero a => a
zero          (ℕ64 -> FuzzyM ℕ64) -> (ℕ64 -> ℕ64) -> ℕ64 -> FuzzyM ℕ64
forall b c a. (b -> c) -> (a -> b) -> a -> c
 (ℕ64 -> ℕ64 -> ℕ64
forall a. Times a => a -> a -> a
×ℕ64
2) (ℕ64 -> FuzzyM ℕ64) -> FuzzyM ℕ64 -> FuzzyM ℕ64
forall (m :: * -> *) a b. Bind m => (a -> m b) -> m a -> m b
*$ (FuzzyEnv ⟢ ℕ64) -> FuzzyM ℕ64
forall r'. (FuzzyEnv ⟢ r') -> FuzzyM r'
forall r (m :: * -> *) r'. MonadReader r m => (r ⟢ r') -> m r'
askL FuzzyEnv ⟢ ℕ64
fuzzyEnvRadiusL
instance Fuzzy ℕ32 where fuzzy :: FuzzyM ℕ32
fuzzy = ℕ32 -> ℕ32 -> FuzzyM ℕ32
forall a (m :: * -> *). (MonadRand m, RandRange a) => a -> a -> m a
randr ℕ32
forall a. Zero a => a
zero (ℕ32 -> FuzzyM ℕ32) -> (ℕ64 -> ℕ32) -> ℕ64 -> FuzzyM ℕ32
forall b c a. (b -> c) -> (a -> b) -> a -> c
 ℕ64 -> ℕ32
forall a. (ToNatO32 a, STACK) => a -> ℕ32
natΩ32 (ℕ64 -> FuzzyM ℕ32) -> (ℕ64 -> ℕ64) -> ℕ64 -> FuzzyM ℕ32
forall b c a. (b -> c) -> (a -> b) -> a -> c
 (ℕ64 -> ℕ64 -> ℕ64
forall a. Times a => a -> a -> a
×ℕ64
2) (ℕ64 -> FuzzyM ℕ32) -> FuzzyM ℕ64 -> FuzzyM ℕ32
forall (m :: * -> *) a b. Bind m => (a -> m b) -> m a -> m b
*$ (FuzzyEnv ⟢ ℕ64) -> FuzzyM ℕ64
forall r'. (FuzzyEnv ⟢ r') -> FuzzyM r'
forall r (m :: * -> *) r'. MonadReader r m => (r ⟢ r') -> m r'
askL FuzzyEnv ⟢ ℕ64
fuzzyEnvRadiusL
instance Fuzzy ℕ16 where fuzzy :: FuzzyM ℕ16
fuzzy = ℕ16 -> ℕ16 -> FuzzyM ℕ16
forall a (m :: * -> *). (MonadRand m, RandRange a) => a -> a -> m a
randr ℕ16
forall a. Zero a => a
zero (ℕ16 -> FuzzyM ℕ16) -> (ℕ64 -> ℕ16) -> ℕ64 -> FuzzyM ℕ16
forall b c a. (b -> c) -> (a -> b) -> a -> c
 ℕ64 -> ℕ16
forall a. (ToNatO16 a, STACK) => a -> ℕ16
natΩ16 (ℕ64 -> FuzzyM ℕ16) -> (ℕ64 -> ℕ64) -> ℕ64 -> FuzzyM ℕ16
forall b c a. (b -> c) -> (a -> b) -> a -> c
 (ℕ64 -> ℕ64 -> ℕ64
forall a. Times a => a -> a -> a
×ℕ64
2) (ℕ64 -> FuzzyM ℕ16) -> FuzzyM ℕ64 -> FuzzyM ℕ16
forall (m :: * -> *) a b. Bind m => (a -> m b) -> m a -> m b
*$ (FuzzyEnv ⟢ ℕ64) -> FuzzyM ℕ64
forall r'. (FuzzyEnv ⟢ r') -> FuzzyM r'
forall r (m :: * -> *) r'. MonadReader r m => (r ⟢ r') -> m r'
askL FuzzyEnv ⟢ ℕ64
fuzzyEnvRadiusL
instance Fuzzy ℕ8  where fuzzy :: FuzzyM ℕ8
fuzzy = ℕ8 -> ℕ8 -> FuzzyM ℕ8
forall a (m :: * -> *). (MonadRand m, RandRange a) => a -> a -> m a
randr ℕ8
forall a. Zero a => a
zero (ℕ8 -> FuzzyM ℕ8) -> (ℕ64 -> ℕ8) -> ℕ64 -> FuzzyM ℕ8
forall b c a. (b -> c) -> (a -> b) -> a -> c
 ℕ64 -> ℕ8
forall a. (ToNatO8 a, STACK) => a -> ℕ8
natΩ8  (ℕ64 -> FuzzyM ℕ8) -> (ℕ64 -> ℕ64) -> ℕ64 -> FuzzyM ℕ8
forall b c a. (b -> c) -> (a -> b) -> a -> c
 (ℕ64 -> ℕ64 -> ℕ64
forall a. Times a => a -> a -> a
×ℕ64
2) (ℕ64 -> FuzzyM ℕ8) -> FuzzyM ℕ64 -> FuzzyM ℕ8
forall (m :: * -> *) a b. Bind m => (a -> m b) -> m a -> m b
*$ (FuzzyEnv ⟢ ℕ64) -> FuzzyM ℕ64
forall r'. (FuzzyEnv ⟢ r') -> FuzzyM r'
forall r (m :: * -> *) r'. MonadReader r m => (r ⟢ r') -> m r'
askL FuzzyEnv ⟢ ℕ64
fuzzyEnvRadiusL

instance Fuzzy ℤ64 where fuzzy :: FuzzyM ℤ64
fuzzy = ℤ64 -> FuzzyM ℤ64
forall a (m :: * -> *).
(MonadRand m, RandRange a, Zero a, Minus a) =>
a -> m a
randrRadius (ℤ64 -> FuzzyM ℤ64) -> (ℕ64 -> ℤ64) -> ℕ64 -> FuzzyM ℤ64
forall b c a. (b -> c) -> (a -> b) -> a -> c
 ℕ64 -> ℤ64
forall a. (ToIntO64 a, STACK) => a -> ℤ64
intΩ64 (ℕ64 -> FuzzyM ℤ64) -> FuzzyM ℕ64 -> FuzzyM ℤ64
forall (m :: * -> *) a b. Bind m => (a -> m b) -> m a -> m b
*$ (FuzzyEnv ⟢ ℕ64) -> FuzzyM ℕ64
forall r'. (FuzzyEnv ⟢ r') -> FuzzyM r'
forall r (m :: * -> *) r'. MonadReader r m => (r ⟢ r') -> m r'
askL FuzzyEnv ⟢ ℕ64
fuzzyEnvRadiusL
instance Fuzzy ℤ32 where fuzzy :: FuzzyM ℤ32
fuzzy = ℤ32 -> FuzzyM ℤ32
forall a (m :: * -> *).
(MonadRand m, RandRange a, Zero a, Minus a) =>
a -> m a
randrRadius (ℤ32 -> FuzzyM ℤ32) -> (ℕ64 -> ℤ32) -> ℕ64 -> FuzzyM ℤ32
forall b c a. (b -> c) -> (a -> b) -> a -> c
 ℕ64 -> ℤ32
forall a. (ToIntO32 a, STACK) => a -> ℤ32
intΩ32 (ℕ64 -> FuzzyM ℤ32) -> FuzzyM ℕ64 -> FuzzyM ℤ32
forall (m :: * -> *) a b. Bind m => (a -> m b) -> m a -> m b
*$ (FuzzyEnv ⟢ ℕ64) -> FuzzyM ℕ64
forall r'. (FuzzyEnv ⟢ r') -> FuzzyM r'
forall r (m :: * -> *) r'. MonadReader r m => (r ⟢ r') -> m r'
askL FuzzyEnv ⟢ ℕ64
fuzzyEnvRadiusL
instance Fuzzy ℤ16 where fuzzy :: FuzzyM ℤ16
fuzzy = ℤ16 -> FuzzyM ℤ16
forall a (m :: * -> *).
(MonadRand m, RandRange a, Zero a, Minus a) =>
a -> m a
randrRadius (ℤ16 -> FuzzyM ℤ16) -> (ℕ64 -> ℤ16) -> ℕ64 -> FuzzyM ℤ16
forall b c a. (b -> c) -> (a -> b) -> a -> c
 ℕ64 -> ℤ16
forall a. (ToIntO16 a, STACK) => a -> ℤ16
intΩ16 (ℕ64 -> FuzzyM ℤ16) -> FuzzyM ℕ64 -> FuzzyM ℤ16
forall (m :: * -> *) a b. Bind m => (a -> m b) -> m a -> m b
*$ (FuzzyEnv ⟢ ℕ64) -> FuzzyM ℕ64
forall r'. (FuzzyEnv ⟢ r') -> FuzzyM r'
forall r (m :: * -> *) r'. MonadReader r m => (r ⟢ r') -> m r'
askL FuzzyEnv ⟢ ℕ64
fuzzyEnvRadiusL
instance Fuzzy ℤ8  where fuzzy :: FuzzyM ℤ8
fuzzy = ℤ8 -> FuzzyM ℤ8
forall a (m :: * -> *).
(MonadRand m, RandRange a, Zero a, Minus a) =>
a -> m a
randrRadius (ℤ8 -> FuzzyM ℤ8) -> (ℕ64 -> ℤ8) -> ℕ64 -> FuzzyM ℤ8
forall b c a. (b -> c) -> (a -> b) -> a -> c
 ℕ64 -> ℤ8
forall a. (ToIntO8 a, STACK) => a -> ℤ8
intΩ8  (ℕ64 -> FuzzyM ℤ8) -> FuzzyM ℕ64 -> FuzzyM ℤ8
forall (m :: * -> *) a b. Bind m => (a -> m b) -> m a -> m b
*$ (FuzzyEnv ⟢ ℕ64) -> FuzzyM ℕ64
forall r'. (FuzzyEnv ⟢ r') -> FuzzyM r'
forall r (m :: * -> *) r'. MonadReader r m => (r ⟢ r') -> m r'
askL FuzzyEnv ⟢ ℕ64
fuzzyEnvRadiusL

instance Fuzzy 𝔻   where fuzzy :: FuzzyM 𝔻
fuzzy = 𝔻 -> FuzzyM 𝔻
forall a (m :: * -> *).
(MonadRand m, RandRange a, Zero a, Minus a) =>
a -> m a
randrRadius (𝔻 -> FuzzyM 𝔻) -> (ℕ64 -> 𝔻) -> ℕ64 -> FuzzyM 𝔻
forall b c a. (b -> c) -> (a -> b) -> a -> c
 ℕ64 -> 𝔻
forall a. ToDouble a => a -> 𝔻
dbl    (ℕ64 -> FuzzyM 𝔻) -> FuzzyM ℕ64 -> FuzzyM 𝔻
forall (m :: * -> *) a b. Bind m => (a -> m b) -> m a -> m b
*$ (FuzzyEnv ⟢ ℕ64) -> FuzzyM ℕ64
forall r'. (FuzzyEnv ⟢ r') -> FuzzyM r'
forall r (m :: * -> *) r'. MonadReader r m => (r ⟢ r') -> m r'
askL FuzzyEnv ⟢ ℕ64
fuzzyEnvRadiusL

instance Fuzzy () where fuzzy :: FuzzyM ()
fuzzy = () -> FuzzyM ()
forall a. a -> FuzzyM a
forall (m :: * -> *) a. Return m => a -> m a
return ()

instance Fuzzy 𝔹 where
  fuzzy :: FuzzyM 𝔹
fuzzy = [() -> FuzzyM 𝔹] -> FuzzyM 𝔹
forall (m :: * -> *) a t.
(Monad m, MonadRand m, ToIter (() -> m a) t) =>
t -> m a
rchoose
    [ \ ()  𝔹 -> FuzzyM 𝔹
forall a. a -> FuzzyM a
forall (m :: * -> *) a. Return m => a -> m a
return 𝔹
True
    , \ ()  𝔹 -> FuzzyM 𝔹
forall a. a -> FuzzyM a
forall (m :: * -> *) a. Return m => a -> m a
return 𝔹
False
    ]

instance (Fuzzy a)  Fuzzy (𝑂 a) where
  fuzzy :: FuzzyM (𝑂 a)
fuzzy = [() -> FuzzyM (𝑂 a)] -> FuzzyM (𝑂 a)
forall (m :: * -> *) a t.
(Monad m, MonadRand m, ToIter (() -> m a) t) =>
t -> m a
rchoose
    [ \ ()  𝑂 a -> FuzzyM (𝑂 a)
forall a. a -> FuzzyM a
forall (m :: * -> *) a. Return m => a -> m a
return 𝑂 a
forall a. 𝑂 a
None
    , \ ()  a -> 𝑂 a
forall a. a -> 𝑂 a
Some (a -> 𝑂 a) -> FuzzyM a -> FuzzyM (𝑂 a)
forall (t :: * -> *) a b. Functor t => (a -> b) -> t a -> t b
^$ FuzzyM a
forall a. Fuzzy a => FuzzyM a
fuzzy
    ]

instance (Fuzzy a,Fuzzy b)  Fuzzy (a  b) where
  fuzzy :: FuzzyM (a ∨ b)
fuzzy = [() -> FuzzyM (a ∨ b)] -> FuzzyM (a ∨ b)
forall (m :: * -> *) a t.
(Monad m, MonadRand m, ToIter (() -> m a) t) =>
t -> m a
rchoose
    [ \ ()  a -> a ∨ b
forall a b. a -> a ∨ b
Inl (a -> a ∨ b) -> FuzzyM a -> FuzzyM (a ∨ b)
forall (t :: * -> *) a b. Functor t => (a -> b) -> t a -> t b
^$ FuzzyM a
forall a. Fuzzy a => FuzzyM a
fuzzy
    , \ ()  b -> a ∨ b
forall a b. b -> a ∨ b
Inr (b -> a ∨ b) -> FuzzyM b -> FuzzyM (a ∨ b)
forall (t :: * -> *) a b. Functor t => (a -> b) -> t a -> t b
^$ FuzzyM b
forall a. Fuzzy a => FuzzyM a
fuzzy
    ]

instance (Fuzzy a,Fuzzy b)  Fuzzy (a  b) where
  fuzzy :: FuzzyM (a ∧ b)
fuzzy = do
    a
x  FuzzyM a
forall a. Fuzzy a => FuzzyM a
fuzzy
    b
y  FuzzyM b
forall a. Fuzzy a => FuzzyM a
fuzzy
    (a ∧ b) -> FuzzyM (a ∧ b)
forall a. a -> FuzzyM a
forall (m :: * -> *) a. Return m => a -> m a
return ((a ∧ b) -> FuzzyM (a ∧ b)) -> (a ∧ b) -> FuzzyM (a ∧ b)
forall a b. (a -> b) -> a -> b
$ a
x a -> b -> a ∧ b
forall a b. a -> b -> a ∧ b
:* b
y

instance (Fuzzy a)  Fuzzy (𝐿 a) where
  fuzzy :: FuzzyM (𝐿 a)
fuzzy = do
    ℕ64
w  FuzzyM ℕ64
fuzzyDepth
    𝐼 a -> 𝐿 a
forall a t. ToIter a t => t -> 𝐿 a
list (𝐼 a -> 𝐿 a) -> FuzzyM (𝐼 a) -> FuzzyM (𝐿 a)
forall (t :: * -> *) a b. Functor t => (a -> b) -> t a -> t b
^$ 𝐼 ℕ64 -> (ℕ64 -> FuzzyM a) -> FuzzyM (𝐼 a)
forall (t :: * -> *) (m :: * -> *) a b.
(FunctorM t, Monad m) =>
t a -> (a -> m b) -> m (t b)
mapMOn (ℕ64 -> 𝐼 ℕ64
forall n. (Eq n, Additive n, One n) => n -> 𝐼 n
upto ℕ64
w) ((ℕ64 -> FuzzyM a) -> FuzzyM (𝐼 a))
-> (ℕ64 -> FuzzyM a) -> FuzzyM (𝐼 a)
forall a b. (a -> b) -> a -> b
$ FuzzyM a -> ℕ64 -> FuzzyM a
forall a b. a -> b -> a
const FuzzyM a
forall a. Fuzzy a => FuzzyM a
fuzzy

instance (Ord k,Fuzzy k,Fuzzy v)  Fuzzy (k  v) where
  fuzzy :: FuzzyM (k ⇰ v)
fuzzy = 𝐿 (k ∧ v) -> k ⇰ v
forall (d :: * -> *) t a k s.
(Dict k s d, ToIter (k ∧ a) t) =>
t -> d a
assoc (𝐿 (k ∧ v) -> k ⇰ v) -> FuzzyM (𝐿 (k ∧ v)) -> FuzzyM (k ⇰ v)
forall (t :: * -> *) a b. Functor t => (a -> b) -> t a -> t b
^$ forall a. Fuzzy a => FuzzyM a
fuzzy @(𝐿 _)

instance (Fuzzy a)  Fuzzy (()  a) where fuzzy :: FuzzyM (() -> a)
fuzzy = a -> () -> a
forall a b. a -> b -> a
const (a -> () -> a) -> FuzzyM a -> FuzzyM (() -> a)
forall (t :: * -> *) a b. Functor t => (a -> b) -> t a -> t b
^$ FuzzyM a
forall a. Fuzzy a => FuzzyM a
fuzzy