{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE ImpredicativeTypes #-}
{-# LANGUAGE QuantifiedConstraints #-}
{-# LANGUAGE TypeFamilyDependencies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE ViewPatterns #-}

module Plutarch.Test.QuickCheck.Internal (
  TestableTerm (..),
  unTestableTerm,
  FailingTestableTerm (..),
  PArbitrary (..),
  PCoArbitrary (..),
  pconstantT,
  pliftT,
) where

import Data.ByteString (ByteString)
import Data.Text qualified as T (intercalate, pack, unpack)
import Data.Word (Word8)
import GHC.Exts qualified as Exts (IsList (fromList, toList))
import Plutarch (
  Config (Config, tracingMode),
  POpaque,
  PlutusType,
  S,
  Term,
  TracingMode (DoTracing, NoTracing),
  compile,
  pcon,
  pmatch,
  pto,
  (#),
  (#$),
 )
import Plutarch.Api.V1 (
  PCredential (PPubKeyCredential, PScriptCredential),
  PCurrencySymbol (PCurrencySymbol),
  PExtended (PFinite, PNegInf, PPosInf),
  PInterval (PInterval),
  PLowerBound (PLowerBound),
  PMap (PMap),
  PTokenName (PTokenName),
  PUpperBound (PUpperBound),
  PValue (PValue),
 )
import Plutarch.Api.V1.Scripts (
  PScriptHash (PScriptHash),
 )
import Plutarch.Api.V1.Time (PPOSIXTime (PPOSIXTime))
import Plutarch.Api.V1.Tuple (
  PTuple,
  pbuiltinPairFromTuple,
  ptuple,
  ptupleFromBuiltin,
 )
import Plutarch.Api.V2 (
  AmountGuarantees (NoGuarantees),
  KeyGuarantees (Unsorted),
  PAddress (PAddress),
  PDatumHash (PDatumHash),
  PMaybeData (PDJust, PDNothing),
  PPubKeyHash (PPubKeyHash),
  PStakingCredential (PStakingHash, PStakingPtr),
  PTxId (PTxId),
  PTxOutRef (PTxOutRef),
 )
import Plutarch.Evaluate (evalScriptHuge, evalTerm)
import Plutarch.Extra.Maybe (
  pfromDJust,
  pisDJust,
  pisJust,
 )
import Plutarch.Lift (PUnsafeLiftDecl (PLifted), plift, plift')
import Plutarch.Maybe (pfromJust)
import Plutarch.Num (pabs)
import Plutarch.Positive (PPositive, ptryPositive)
import Plutarch.Prelude (
  PAsData,
  PBool,
  PBuiltinList,
  PBuiltinPair,
  PByteString,
  PEither (PLeft, PRight),
  PInteger,
  PIsData,
  PIsListLike,
  PLift,
  PList,
  PListLike (pcons, phead, pnil, pnull, ptail),
  PMaybe (PJust, PNothing),
  PPair (PPair),
  PPartialOrd ((#<)),
  PRational (PRational),
  PString,
  PUnit,
  Type,
  pconstant,
  pdata,
  pdcons,
  pdenominator,
  pdnil,
  pfield,
  pfromData,
  pif,
  pnumerator,
  pshow,
  ptraceError,
 )
import Plutarch.Show (PShow)
import Plutarch.Test.QuickCheck.Helpers (loudEval)
import Test.QuickCheck (
  Arbitrary (arbitrary, shrink),
  CoArbitrary (coarbitrary),
  Function (function),
  Gen,
  Testable (property),
  chooseInt,
  chooseInteger,
  counterexample,
  elements,
  frequency,
  functionMap,
  listOf,
  sized,
  variant,
  vectorOf,
 )

{- | TestableTerm is a wrapper for closed Plutarch terms. This
     abstraction allows Plutarch values to be generated via QuickCheck
     generators.

     = Note
     The typechecker is picky about how @TestableTerm@s are constructed.
     Meaning, TestableTerm can throw an error when it's composed.

 @since 2.0.0
-}
data TestableTerm (a :: S -> Type)
  = TestableTerm (forall (s :: S). Term s a)

{- | Wrapper around the 'TestableTerm' that expect failure.

 @since 2.1.6
-}
data FailingTestableTerm (a :: S -> Type)
  = FailingTestableTerm (TestableTerm a)

-- | @since 2.2.1
instance Testable (TestableTerm PBool) where
  property :: TestableTerm PBool -> Property
property (TestableTerm forall (s :: S). Term s PBool
t) =
    case forall (p :: PType).
PUnsafeLiftDecl p =>
Config -> ClosedTerm p -> Either LiftError (PLifted p)
plift' (Config {$sel:tracingMode:Config :: TracingMode
tracingMode = TracingMode
NoTracing}) forall (s :: S). Term s PBool
t of
      Right PLifted PBool
p -> forall prop. Testable prop => prop -> Property
property PLifted PBool
p
      Left LiftError
_ ->
        case forall (a :: PType). Config -> ClosedTerm a -> Either Text Script
compile (Config {$sel:tracingMode:Config :: TracingMode
tracingMode = TracingMode
DoTracing}) forall (s :: S). Term s PBool
t of
          Left Text
err ->
            forall prop. Testable prop => String -> prop -> Property
counterexample (String
"Script failed to compile:\n" forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show Text
err) forall a b. (a -> b) -> a -> b
$
              forall prop. Testable prop => prop -> Property
property Bool
False
          Right Script
s ->
            case Script -> (Either EvalError Script, ExBudget, [Text])
evalScriptHuge Script
s of
              (Left EvalError
err, ExBudget
_, [Text]
trace) ->
                forall prop. Testable prop => String -> prop -> Property
counterexample
                  ( String
"Script evaluated with an error:\n"
                      forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show EvalError
err
                      forall a. Semigroup a => a -> a -> a
<> String
"\nTrace:\n"
                      forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show [Text]
trace
                  )
                  forall a b. (a -> b) -> a -> b
$ forall prop. Testable prop => prop -> Property
property Bool
False
              (Either EvalError Script, ExBudget, [Text])
_ -> forall a. HasCallStack => String -> a
error String
"Unreachable"

-- | @since 2.1.6
instance Testable (TestableTerm POpaque) where
  property :: TestableTerm POpaque -> Property
property (TestableTerm forall (s :: S). Term s POpaque
t) =
    case forall (a :: PType).
Config
-> ClosedTerm a
-> Either Text (Either EvalError (ClosedTerm a), ExBudget, [Text])
evalTerm (Config {$sel:tracingMode:Config :: TracingMode
tracingMode = TracingMode
NoTracing}) forall (s :: S). Term s POpaque
t of
      Right (Right forall (s :: S). Term s POpaque
_, ExBudget
_, [Text]
_) -> forall prop. Testable prop => prop -> Property
property Bool
True
      Right (Left EvalError
_, ExBudget
_, [Text]
_) ->
        case forall (a :: PType).
Config
-> ClosedTerm a
-> Either Text (Either EvalError (ClosedTerm a), ExBudget, [Text])
evalTerm (Config {$sel:tracingMode:Config :: TracingMode
tracingMode = TracingMode
DoTracing}) forall (s :: S). Term s POpaque
t of
          Right (Left EvalError
err, ExBudget
_, [Text]
trace) ->
            forall prop. Testable prop => String -> prop -> Property
counterexample
              ( String
"Script evaluated with an error:\n"
                  forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show EvalError
err
                  forall a. Semigroup a => a -> a -> a
<> String
"\nTrace:\n"
                  forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show [Text]
trace
              )
              forall a b. (a -> b) -> a -> b
$ forall prop. Testable prop => prop -> Property
property Bool
False
          Either
  Text
  (Either EvalError (forall (s :: S). Term s POpaque), ExBudget,
   [Text])
_ -> forall a. HasCallStack => String -> a
error String
"Unreachable"
      Left Text
err ->
        forall prop. Testable prop => String -> prop -> Property
counterexample (String
"Script failed to compile:\n" forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show Text
err) forall a b. (a -> b) -> a -> b
$
          forall prop. Testable prop => prop -> Property
property Bool
False

-- | @since 2.1.6
instance Testable (FailingTestableTerm a) where
  property :: FailingTestableTerm a -> Property
property (FailingTestableTerm (TestableTerm forall (s :: S). Term s a
t)) =
    case forall (a :: PType).
Config
-> ClosedTerm a
-> Either Text (Either EvalError (ClosedTerm a), ExBudget, [Text])
evalTerm (Config {$sel:tracingMode:Config :: TracingMode
tracingMode = TracingMode
NoTracing}) forall (s :: S). Term s a
t of
      Right (Right forall (s :: S). Term s a
_, ExBudget
_, [Text]
_) ->
        forall prop. Testable prop => String -> prop -> Property
counterexample String
"Script ran successfully when it is expected to fail" forall a b. (a -> b) -> a -> b
$
          forall prop. Testable prop => prop -> Property
property Bool
False
      Right (Left EvalError
_, ExBudget
_, [Text]
_) -> forall prop. Testable prop => prop -> Property
property Bool
True
      Left Text
err ->
        forall prop. Testable prop => String -> prop -> Property
counterexample (String
"Script failed to compile:\n" forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show Text
err) forall a b. (a -> b) -> a -> b
$
          forall prop. Testable prop => prop -> Property
property Bool
False

{- | Converts a 'TestableTerm' into a 'ClosedTerm'.

 @since 2.1.2
-}
unTestableTerm ::
  forall (a :: S -> Type).
  TestableTerm a ->
  (forall (s :: S). Term s a)
unTestableTerm :: forall (a :: PType). TestableTerm a -> forall (s :: S). Term s a
unTestableTerm (TestableTerm forall (s :: S). Term s a
t) = forall (s :: S). Term s a
t

-- | @since 2.0.0
instance (forall (s :: S). Num (Term s a)) => Num (TestableTerm a) where
  + :: TestableTerm a -> TestableTerm a -> TestableTerm a
(+) = forall (a :: PType) (b :: PType) (c :: PType).
(forall (s :: S). Term s a -> Term s b -> Term s c)
-> TestableTerm a -> TestableTerm b -> TestableTerm c
liftT2 forall a. Num a => a -> a -> a
(+)
  * :: TestableTerm a -> TestableTerm a -> TestableTerm a
(*) = forall (a :: PType) (b :: PType) (c :: PType).
(forall (s :: S). Term s a -> Term s b -> Term s c)
-> TestableTerm a -> TestableTerm b -> TestableTerm c
liftT2 forall a. Num a => a -> a -> a
(*)
  abs :: TestableTerm a -> TestableTerm a
abs = forall (a :: PType) (b :: PType).
(forall (s :: S). Term s a -> Term s b)
-> TestableTerm a -> TestableTerm b
liftT forall a. Num a => a -> a
abs
  negate :: TestableTerm a -> TestableTerm a
negate = forall (a :: PType) (b :: PType).
(forall (s :: S). Term s a -> Term s b)
-> TestableTerm a -> TestableTerm b
liftT forall a. Num a => a -> a
negate
  signum :: TestableTerm a -> TestableTerm a
signum = forall (a :: PType) (b :: PType).
(forall (s :: S). Term s a -> Term s b)
-> TestableTerm a -> TestableTerm b
liftT forall a. Num a => a -> a
signum
  fromInteger :: Integer -> TestableTerm a
fromInteger Integer
i = forall (a :: PType). (forall (s :: S). Term s a) -> TestableTerm a
TestableTerm (forall a. Num a => Integer -> a
fromInteger Integer
i :: Term s a)

{- | For any Plutarch Type that have a `PShow` instance, `Show` is
     available as well. For those that don't have @PShow@ instances,
     we have to use `forAllShow` with custom display function to
     execute a property check.

 @since 2.0.0
-}
instance PShow a => Show (TestableTerm a) where
  show :: TestableTerm a -> String
show (TestableTerm forall (s :: S). Term s a
term) =
    case forall (a :: PType). Config -> ClosedTerm a -> Either Text Script
compile (Config {$sel:tracingMode:Config :: TracingMode
tracingMode = TracingMode
DoTracing}) forall a b. (a -> b) -> a -> b
$
      forall (s :: S) (a :: PType). Term s PString -> Term s a
ptraceError
        (forall (a :: PType) (s :: S). PShow a => Term s a -> Term s PString
pshow forall (s :: S). Term s a
term) of
      Left Text
err -> forall a. Show a => a -> String
show Text
err
      Right (Script -> (Either EvalError Script, ExBudget, [Text])
evalScriptHuge -> (Either EvalError Script
_, ExBudget
_, [Text]
trace)) ->
        Text -> String
T.unpack forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> [Text] -> Text
T.intercalate Text
" " forall a b. (a -> b) -> a -> b
$ [Text]
trace

{- | PArbitrary is the Plutarch equivalent of the `Arbitrary` typeclass from
     QuickCheck. It generates pseudo-random closed term, which can be used
     to test properties over Plutarch code without having to compile and
     evaluate.

     Default implmentations are given for any Plutarch type that
     implements @PLift a@ and @Arbitrary (PLifted a)@. This generates
     a Haskell value and converts it into a Plutarch term using `pconstant`.

     = Note

     The default implementation for 'pshrink' does no shrinking. If at all
     possible, please define a shrinker, as this will make your test results
     much more useful.

 @since 2.0.0
-}
class PArbitrary (a :: S -> Type) where
  parbitrary :: Gen (TestableTerm a)
  default parbitrary ::
    (PLift a, Arbitrary (PLifted a)) =>
    Gen (TestableTerm a)
  parbitrary = forall {p :: PType} {h}.
(PLift p, PLifted p ~ h) =>
h -> TestableTerm p
pconstantT forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Arbitrary a => Gen a
arbitrary

  pshrink :: TestableTerm a -> [TestableTerm a]
  pshrink = forall a b. a -> b -> a
const []

class PCoArbitrary (a :: S -> Type) where
  pcoarbitrary :: TestableTerm a -> Gen b -> Gen b

{- | Any Plutarch type that implements `PArbitrary` automatically has an
     instance of `Arbitrary` for its @TestableTerm@. This allows interfacing
     between QuickCheck and Plutarch.

     = Note

     The default implementation for 'pshrink' does no shrinking. If at all
     possible, please define a shrinker, as this will make your test results
     much more useful.

 @since 2.0.0
-}
instance PArbitrary p => Arbitrary (TestableTerm p) where
  arbitrary :: Gen (TestableTerm p)
arbitrary = forall (p :: PType). PArbitrary p => Gen (TestableTerm p)
parbitrary
  shrink :: TestableTerm p -> [TestableTerm p]
shrink = forall (p :: PType).
PArbitrary p =>
TestableTerm p -> [TestableTerm p]
pshrink forall b c a. (b -> c) -> (a -> b) -> a -> c
. (\(TestableTerm forall (s :: S). Term s p
x) -> forall (a :: PType). (forall (s :: S). Term s a) -> TestableTerm a
TestableTerm forall a b. (a -> b) -> a -> b
$ forall (p :: PType). ClosedTerm p -> ClosedTerm p
loudEval forall (s :: S). Term s p
x)

instance PCoArbitrary p => CoArbitrary (TestableTerm p) where
  coarbitrary :: forall b. TestableTerm p -> Gen b -> Gen b
coarbitrary = forall (p :: PType) b.
PCoArbitrary p =>
TestableTerm p -> Gen b -> Gen b
pcoarbitrary

-- | @since 2.0.0
instance (PArbitrary p, PIsData p) => PArbitrary (PAsData p) where
  parbitrary :: Gen (TestableTerm (PAsData p))
parbitrary = forall {p :: PType}.
PIsData p =>
TestableTerm p -> TestableTerm (PAsData p)
pdataT forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (p :: PType). PArbitrary p => Gen (TestableTerm p)
parbitrary
  pshrink :: TestableTerm (PAsData p) -> [TestableTerm (PAsData p)]
pshrink = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall {p :: PType}.
PIsData p =>
TestableTerm p -> TestableTerm (PAsData p)
pdataT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Arbitrary a => a -> [a]
shrink forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {p :: PType}.
PIsData p =>
TestableTerm (PAsData p) -> TestableTerm p
pfromDataT

instance (PCoArbitrary p, PIsData p) => PCoArbitrary (PAsData p) where
  pcoarbitrary :: forall b. TestableTerm (PAsData p) -> Gen b -> Gen b
pcoarbitrary (forall {p :: PType}.
PIsData p =>
TestableTerm (PAsData p) -> TestableTerm p
pfromDataT -> TestableTerm p
x) = forall (p :: PType) b.
PCoArbitrary p =>
TestableTerm p -> Gen b -> Gen b
pcoarbitrary TestableTerm p
x

instance Function (TestableTerm PInteger) where
  function :: forall b.
(TestableTerm PInteger -> b) -> TestableTerm PInteger :-> b
function = forall b a c.
Function b =>
(a -> b) -> (b -> a) -> (a -> c) -> a :-> c
functionMap forall {p :: PType} {h}.
(PLift p, PLifted p ~ h) =>
TestableTerm p -> h
pliftT forall {p :: PType} {h}.
(PLift p, PLifted p ~ h) =>
h -> TestableTerm p
pconstantT

-- | @since 2.0.0
instance PArbitrary PInteger where
  pshrink :: TestableTerm PInteger -> [TestableTerm PInteger]
pshrink = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall {p :: PType} {h}.
(PLift p, PLifted p ~ h) =>
h -> TestableTerm p
pconstantT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Arbitrary a => a -> [a]
shrink forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {p :: PType} {h}.
(PLift p, PLifted p ~ h) =>
TestableTerm p -> h
pliftT

instance PCoArbitrary PInteger where
  pcoarbitrary :: forall b. TestableTerm PInteger -> Gen b -> Gen b
pcoarbitrary (forall {p :: PType} {h}.
(PLift p, PLifted p ~ h) =>
TestableTerm p -> h
pliftT -> Integer
x) = forall a b. CoArbitrary a => a -> Gen b -> Gen b
coarbitrary Integer
x

-- | @since 2.0.0
instance PArbitrary PBool where
  pshrink :: TestableTerm PBool -> [TestableTerm PBool]
pshrink = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall {p :: PType} {h}.
(PLift p, PLifted p ~ h) =>
h -> TestableTerm p
pconstantT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Arbitrary a => a -> [a]
shrink forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {p :: PType} {h}.
(PLift p, PLifted p ~ h) =>
TestableTerm p -> h
pliftT

instance PCoArbitrary PBool where
  pcoarbitrary :: forall b. TestableTerm PBool -> Gen b -> Gen b
pcoarbitrary (forall {p :: PType} {h}.
(PLift p, PLifted p ~ h) =>
TestableTerm p -> h
pliftT -> Bool
x) = forall a b. CoArbitrary a => a -> Gen b -> Gen b
coarbitrary Bool
x

-- | @since 2.0.0
instance PArbitrary PUnit where
  pshrink :: TestableTerm PUnit -> [TestableTerm PUnit]
pshrink = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall {p :: PType} {h}.
(PLift p, PLifted p ~ h) =>
h -> TestableTerm p
pconstantT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Arbitrary a => a -> [a]
shrink forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {p :: PType} {h}.
(PLift p, PLifted p ~ h) =>
TestableTerm p -> h
pliftT

instance PCoArbitrary PUnit where
  pcoarbitrary :: forall b. TestableTerm PUnit -> Gen b -> Gen b
pcoarbitrary (forall {p :: PType} {h}.
(PLift p, PLifted p ~ h) =>
TestableTerm p -> h
pliftT -> ()
x) = forall a b. CoArbitrary a => a -> Gen b -> Gen b
coarbitrary ()
x

-- | @since 2.0.0
instance PArbitrary PByteString where
  parbitrary :: Gen (TestableTerm PByteString)
parbitrary = forall a. (Int -> Gen a) -> Gen a
sized forall a b. (a -> b) -> a -> b
$ \Int
r -> do
    Int
len <- (Int, Int) -> Gen Int
chooseInt (Int
0, Int
r)
    ByteString
bs <- Int -> Gen ByteString
genByteString Int
len
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall {p :: PType} {h}.
(PLift p, PLifted p ~ h) =>
h -> TestableTerm p
pconstantT ByteString
bs

  pshrink :: TestableTerm PByteString -> [TestableTerm PByteString]
pshrink = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall {p :: PType} {h}.
(PLift p, PLifted p ~ h) =>
h -> TestableTerm p
pconstantT forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> [ByteString]
shrinkByteString forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {p :: PType} {h}.
(PLift p, PLifted p ~ h) =>
TestableTerm p -> h
pliftT

-- | @since 2.0.0
instance PCoArbitrary PByteString where
  pcoarbitrary :: forall b. TestableTerm PByteString -> Gen b -> Gen b
pcoarbitrary = forall a b. CoArbitrary a => a -> Gen b -> Gen b
coarbitrary forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall l. IsList l => l -> [Item l]
Exts.toList forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {p :: PType} {h}.
(PLift p, PLifted p ~ h) =>
TestableTerm p -> h
pliftT

-- | @since 2.0.0
instance PArbitrary PPositive where
  parbitrary :: Gen (TestableTerm PPositive)
parbitrary = do
    (TestableTerm forall (s :: S). Term s PInteger
x) <- forall (p :: PType). PArbitrary p => Gen (TestableTerm p)
parbitrary
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (a :: PType). (forall (s :: S). Term s a) -> TestableTerm a
TestableTerm forall a b. (a -> b) -> a -> b
$ forall (s :: S). Term s (PInteger :--> PPositive)
ptryPositive forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
#$ forall (s :: S) (a :: PType).
Term s PBool -> Term s a -> Term s a -> Term s a
pif (Term s PInteger
0 forall (t :: PType) (s :: S).
PPartialOrd t =>
Term s t -> Term s t -> Term s PBool
#< forall (s :: S). Term s PInteger
x) forall (s :: S). Term s PInteger
x (forall a. Num a => a -> a
negate forall (s :: S). Term s PInteger
x forall a. Num a => a -> a -> a
+ Term s PInteger
1)

-- | @since 2.0.0
instance PCoArbitrary PPositive where
  pcoarbitrary :: forall b. TestableTerm PPositive -> Gen b -> Gen b
pcoarbitrary = forall (p :: PType) b.
PCoArbitrary p =>
TestableTerm p -> Gen b -> Gen b
pcoarbitrary forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (a :: PType) (b :: PType).
(forall (s :: S). Term s a -> Term s b)
-> TestableTerm a -> TestableTerm b
liftT forall (s :: S) (a :: PType). Term s a -> Term s (PInner a)
pto

-- | @since 2.0.0
instance PArbitrary PRational where
  parbitrary :: Gen (TestableTerm PRational)
parbitrary = do
    (TestableTerm forall (s :: S). Term s PInteger
x) <- forall (p :: PType). PArbitrary p => Gen (TestableTerm p)
parbitrary
    (TestableTerm forall (s :: S). Term s PPositive
y) <- forall (p :: PType). PArbitrary p => Gen (TestableTerm p)
parbitrary
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall {p :: PType}.
PlutusType p =>
(forall {s :: S}. p s) -> TestableTerm p
pconT forall a b. (a -> b) -> a -> b
$ forall (s :: S). Term s PInteger -> Term s PPositive -> PRational s
PRational forall (s :: S). Term s PInteger
x forall (s :: S). Term s PPositive
y

  pshrink :: TestableTerm PRational -> [TestableTerm PRational]
pshrink (TestableTerm forall (s :: S). Term s PRational
x) =
    [ forall (a :: PType). (forall (s :: S). Term s a) -> TestableTerm a
TestableTerm forall a b. (a -> b) -> a -> b
$ forall (a :: PType) (s :: S). PlutusType a => a s -> Term s a
pcon forall a b. (a -> b) -> a -> b
$ forall (s :: S). Term s PInteger -> Term s PPositive -> PRational s
PRational forall (s :: S). Term s PInteger
a (forall (s :: S). Term s (PRational :--> PPositive)
pdenominator forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (s :: S). Term s PRational
x)
    | (TestableTerm forall (s :: S). Term s PInteger
a) <- forall a. Arbitrary a => a -> [a]
shrink (forall (a :: PType). (forall (s :: S). Term s a) -> TestableTerm a
TestableTerm forall a b. (a -> b) -> a -> b
$ forall (s :: S). Term s (PRational :--> PInteger)
pnumerator forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (s :: S). Term s PRational
x)
    ]

instance PCoArbitrary PRational where
  pcoarbitrary :: forall b. TestableTerm PRational -> Gen b -> Gen b
pcoarbitrary (TestableTerm forall (s :: S). Term s PRational
x) = forall (p :: PType) b.
PCoArbitrary p =>
TestableTerm p -> Gen b -> Gen b
pcoarbitrary TestableTerm PInteger
n forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (p :: PType) b.
PCoArbitrary p =>
TestableTerm p -> Gen b -> Gen b
pcoarbitrary TestableTerm PPositive
d
    where
      n :: TestableTerm PInteger
n = forall (a :: PType). (forall (s :: S). Term s a) -> TestableTerm a
TestableTerm forall a b. (a -> b) -> a -> b
$ forall (s :: S). Term s (PRational :--> PInteger)
pnumerator forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (s :: S). Term s PRational
x
      d :: TestableTerm PPositive
d = forall (a :: PType). (forall (s :: S). Term s a) -> TestableTerm a
TestableTerm forall a b. (a -> b) -> a -> b
$ forall (s :: S). Term s (PRational :--> PPositive)
pdenominator forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (s :: S). Term s PRational
x

-- | @since 2.0.0
instance PArbitrary PString where
  parbitrary :: Gen (TestableTerm PString)
parbitrary = forall {p :: PType} {h}.
(PLift p, PLifted p ~ h) =>
h -> TestableTerm p
pconstantT forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Arbitrary a => Gen a
arbitrary
  pshrink :: TestableTerm PString -> [TestableTerm PString]
pshrink = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall {p :: PType} {h}.
(PLift p, PLifted p ~ h) =>
h -> TestableTerm p
pconstantT forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Arbitrary a => a -> [a]
shrink forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
T.unpack forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {p :: PType} {h}.
(PLift p, PLifted p ~ h) =>
TestableTerm p -> h
pliftT

instance PCoArbitrary PString where
  pcoarbitrary :: forall b. TestableTerm PString -> Gen b -> Gen b
pcoarbitrary = forall a b. CoArbitrary a => a -> Gen b -> Gen b
coarbitrary forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
T.unpack forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {p :: PType} {h}.
(PLift p, PLifted p ~ h) =>
TestableTerm p -> h
pliftT

-- | @since 2.0.0
instance PArbitrary a => PArbitrary (PMaybe a) where
  parbitrary :: Gen (TestableTerm (PMaybe a))
parbitrary = do
    (TestableTerm forall (s :: S). Term s a
x) <- forall (p :: PType). PArbitrary p => Gen (TestableTerm p)
parbitrary
    forall a. [(Int, Gen a)] -> Gen a
frequency
      [ (Int
3, forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (a :: PType). (forall (s :: S). Term s a) -> TestableTerm a
TestableTerm forall a b. (a -> b) -> a -> b
$ forall (a :: PType) (s :: S). PlutusType a => a s -> Term s a
pcon forall a b. (a -> b) -> a -> b
$ forall (a :: PType) (s :: S). Term s a -> PMaybe a s
PJust forall (s :: S). Term s a
x)
      ,
        ( Int
1
        , forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$
            forall {p :: PType}.
PlutusType p =>
(forall {s :: S}. p s) -> TestableTerm p
pconT forall (a :: PType) (s :: S). PMaybe a s
PNothing
        )
      ]
  pshrink :: TestableTerm (PMaybe a) -> [TestableTerm (PMaybe a)]
pshrink (TestableTerm forall (s :: S). Term s (PMaybe a)
x)
    | forall (p :: PType).
(HasCallStack, PLift p) =>
ClosedTerm p -> PLifted p
plift forall a b. (a -> b) -> a -> b
$ forall (a :: PType) (s :: S). Term s (PMaybe a :--> PBool)
pisJust forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (s :: S). Term s (PMaybe a)
x =
        forall (a :: PType). (forall (s :: S). Term s a) -> TestableTerm a
TestableTerm (forall (a :: PType) (s :: S). PlutusType a => a s -> Term s a
pcon forall (a :: PType) (s :: S). PMaybe a s
PNothing)
          forall a. a -> [a] -> [a]
: [ forall (a :: PType). (forall (s :: S). Term s a) -> TestableTerm a
TestableTerm forall a b. (a -> b) -> a -> b
$ forall (a :: PType) (s :: S). PlutusType a => a s -> Term s a
pcon forall a b. (a -> b) -> a -> b
$ forall (a :: PType) (s :: S). Term s a -> PMaybe a s
PJust forall (s :: S). Term s a
a
            | (TestableTerm forall (s :: S). Term s a
a) <- forall a. Arbitrary a => a -> [a]
shrink (forall (a :: PType). (forall (s :: S). Term s a) -> TestableTerm a
TestableTerm forall a b. (a -> b) -> a -> b
$ forall (s :: S) (a :: PType). Term s (PMaybe a :--> a)
pfromJust forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (s :: S). Term s (PMaybe a)
x)
            ]
    | Bool
otherwise = []

instance PCoArbitrary a => PCoArbitrary (PMaybe a) where
  pcoarbitrary :: forall b. TestableTerm (PMaybe a) -> Gen b -> Gen b
pcoarbitrary (TestableTerm forall (s :: S). Term s (PMaybe a)
x)
    | forall (p :: PType).
(HasCallStack, PLift p) =>
ClosedTerm p -> PLifted p
plift forall a b. (a -> b) -> a -> b
$ forall (a :: PType) (s :: S). Term s (PMaybe a :--> PBool)
pisJust forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (s :: S). Term s (PMaybe a)
x =
        forall n a. Integral n => n -> Gen a -> Gen a
variant (Integer
1 :: Integer)
          forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (p :: PType) b.
PCoArbitrary p =>
TestableTerm p -> Gen b -> Gen b
pcoarbitrary
            (forall (a :: PType). (forall (s :: S). Term s a) -> TestableTerm a
TestableTerm forall a b. (a -> b) -> a -> b
$ forall (s :: S) (a :: PType). Term s (PMaybe a :--> a)
pfromJust forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (s :: S). Term s (PMaybe a)
x)
    | Bool
otherwise = forall n a. Integral n => n -> Gen a -> Gen a
variant (Integer
0 :: Integer)

-- | @since 2.0.0
instance (PIsData a, PArbitrary a) => PArbitrary (PMaybeData a) where
  parbitrary :: Gen (TestableTerm (PMaybeData a))
parbitrary = do
    (TestableTerm forall (s :: S). Term s a
x) <- forall (p :: PType). PArbitrary p => Gen (TestableTerm p)
parbitrary
    forall a. [a] -> Gen a
elements
      [ forall (a :: PType). (forall (s :: S). Term s a) -> TestableTerm a
TestableTerm forall a b. (a -> b) -> a -> b
$ forall (a :: PType) (s :: S). PlutusType a => a s -> Term s a
pcon forall a b. (a -> b) -> a -> b
$ forall (a :: PType) (s :: S).
Term s (PDataRecord '[ "_0" ':= a]) -> PMaybeData a s
PDJust forall a b. (a -> b) -> a -> b
$ forall (label :: Symbol) (a :: PType) (l :: [PLabeledType])
       (s :: S).
Term
  s
  (PAsData a
   :--> (PDataRecord l :--> PDataRecord ((label ':= a) : l)))
pdcons @"_0" forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (a :: PType) (s :: S).
PIsData a =>
Term s a -> Term s (PAsData a)
pdata forall (s :: S). Term s a
x forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (s :: S). Term s (PDataRecord '[])
pdnil
      , forall (a :: PType). (forall (s :: S). Term s a) -> TestableTerm a
TestableTerm forall a b. (a -> b) -> a -> b
$ forall (a :: PType) (s :: S). PlutusType a => a s -> Term s a
pcon forall a b. (a -> b) -> a -> b
$ forall (a :: PType) (s :: S).
Term s (PDataRecord '[]) -> PMaybeData a s
PDNothing forall (s :: S). Term s (PDataRecord '[])
pdnil
      ]
  pshrink :: TestableTerm (PMaybeData a) -> [TestableTerm (PMaybeData a)]
pshrink (TestableTerm forall (s :: S). Term s (PMaybeData a)
x)
    | forall (p :: PType).
(HasCallStack, PLift p) =>
ClosedTerm p -> PLifted p
plift forall a b. (a -> b) -> a -> b
$ forall (a :: PType) (s :: S). Term s (PMaybeData a :--> PBool)
pisDJust forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (s :: S). Term s (PMaybeData a)
x =
        forall {p :: PType}.
PlutusType p =>
(forall {s :: S}. p s) -> TestableTerm p
pconT (forall (a :: PType) (s :: S).
Term s (PDataRecord '[]) -> PMaybeData a s
PDNothing forall (s :: S). Term s (PDataRecord '[])
pdnil)
          forall a. a -> [a] -> [a]
: [ forall (a :: PType). (forall (s :: S). Term s a) -> TestableTerm a
TestableTerm forall a b. (a -> b) -> a -> b
$ forall (a :: PType) (s :: S). PlutusType a => a s -> Term s a
pcon forall a b. (a -> b) -> a -> b
$ forall (a :: PType) (s :: S).
Term s (PDataRecord '[ "_0" ':= a]) -> PMaybeData a s
PDJust forall a b. (a -> b) -> a -> b
$ forall (label :: Symbol) (a :: PType) (l :: [PLabeledType])
       (s :: S).
Term
  s
  (PAsData a
   :--> (PDataRecord l :--> PDataRecord ((label ':= a) : l)))
pdcons @"_0" forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (a :: PType) (s :: S).
PIsData a =>
Term s a -> Term s (PAsData a)
pdata forall (s :: S). Term s a
a forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (s :: S). Term s (PDataRecord '[])
pdnil
            | (TestableTerm forall (s :: S). Term s a
a) <- forall a. Arbitrary a => a -> [a]
shrink (forall (a :: PType). (forall (s :: S). Term s a) -> TestableTerm a
TestableTerm forall a b. (a -> b) -> a -> b
$ forall (a :: PType) (s :: S).
PIsData a =>
Term s (PMaybeData a :--> a)
pfromDJust forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (s :: S). Term s (PMaybeData a)
x)
            ]
    | Bool
otherwise = []

instance (PIsData a, PCoArbitrary a) => PCoArbitrary (PMaybeData a) where
  pcoarbitrary :: forall b. TestableTerm (PMaybeData a) -> Gen b -> Gen b
pcoarbitrary (TestableTerm forall (s :: S). Term s (PMaybeData a)
x)
    | forall (p :: PType).
(HasCallStack, PLift p) =>
ClosedTerm p -> PLifted p
plift forall a b. (a -> b) -> a -> b
$ forall (a :: PType) (s :: S). Term s (PMaybeData a :--> PBool)
pisDJust forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (s :: S). Term s (PMaybeData a)
x =
        forall n a. Integral n => n -> Gen a -> Gen a
variant (Integer
1 :: Integer)
          forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (p :: PType) b.
PCoArbitrary p =>
TestableTerm p -> Gen b -> Gen b
pcoarbitrary
            (forall (a :: PType). (forall (s :: S). Term s a) -> TestableTerm a
TestableTerm forall a b. (a -> b) -> a -> b
$ forall (a :: PType) (s :: S).
PIsData a =>
Term s (PMaybeData a :--> a)
pfromDJust forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (s :: S). Term s (PMaybeData a)
x)
    | Bool
otherwise = forall n a. Integral n => n -> Gen a -> Gen a
variant (Integer
0 :: Integer)

-- | @since 2.0.0
instance (PArbitrary a, PArbitrary b) => PArbitrary (PEither a b) where
  parbitrary :: Gen (TestableTerm (PEither a b))
parbitrary = do
    (TestableTerm forall (s :: S). Term s b
x) <- forall (p :: PType). PArbitrary p => Gen (TestableTerm p)
parbitrary
    (TestableTerm forall (s :: S). Term s a
y) <- forall (p :: PType). PArbitrary p => Gen (TestableTerm p)
parbitrary
    forall a. [a] -> Gen a
elements [forall (a :: PType). (forall (s :: S). Term s a) -> TestableTerm a
TestableTerm forall a b. (a -> b) -> a -> b
$ forall (a :: PType) (s :: S). PlutusType a => a s -> Term s a
pcon forall a b. (a -> b) -> a -> b
$ forall (a :: PType) (b :: PType) (s :: S).
Term s b -> PEither a b s
PRight forall (s :: S). Term s b
x, forall (a :: PType). (forall (s :: S). Term s a) -> TestableTerm a
TestableTerm forall a b. (a -> b) -> a -> b
$ forall (a :: PType) (s :: S). PlutusType a => a s -> Term s a
pcon forall a b. (a -> b) -> a -> b
$ forall (a :: PType) (b :: PType) (s :: S).
Term s a -> PEither a b s
PLeft forall (s :: S). Term s a
y]

  pshrink :: TestableTerm (PEither a b) -> [TestableTerm (PEither a b)]
pshrink TestableTerm (PEither a b)
x
    | forall {p :: PType} {h}.
(PLift p, PLifted p ~ h) =>
TestableTerm p -> h
pliftT forall a b. (a -> b) -> a -> b
$ forall {a :: PType} {b :: PType}.
TestableTerm (PEither a b) -> TestableTerm PBool
isRight TestableTerm (PEither a b)
x =
        [ forall {p :: PType}.
PlutusType p =>
(forall {s :: S}. p s) -> TestableTerm p
pconT forall a b. (a -> b) -> a -> b
$ forall (a :: PType) (b :: PType) (s :: S).
Term s b -> PEither a b s
PRight forall (s :: S). Term s b
a
        | (TestableTerm forall (s :: S). Term s b
a) <- forall a. Arbitrary a => a -> [a]
shrink (forall {a :: PType} {b :: PType}.
TestableTerm (PEither a b) -> TestableTerm b
pright TestableTerm (PEither a b)
x)
        ]
    | Bool
otherwise =
        [ forall {p :: PType}.
PlutusType p =>
(forall {s :: S}. p s) -> TestableTerm p
pconT forall a b. (a -> b) -> a -> b
$ forall (a :: PType) (b :: PType) (s :: S).
Term s a -> PEither a b s
PLeft forall (s :: S). Term s a
a
        | (TestableTerm forall (s :: S). Term s a
a) <- forall a. Arbitrary a => a -> [a]
shrink (forall {b1 :: PType} {b2 :: PType}.
TestableTerm (PEither b1 b2) -> TestableTerm b1
pleft TestableTerm (PEither a b)
x)
        ]

instance (PCoArbitrary a, PCoArbitrary b) => PCoArbitrary (PEither a b) where
  pcoarbitrary :: forall b. TestableTerm (PEither a b) -> Gen b -> Gen b
pcoarbitrary TestableTerm (PEither a b)
x
    | forall {p :: PType} {h}.
(PLift p, PLifted p ~ h) =>
TestableTerm p -> h
pliftT forall a b. (a -> b) -> a -> b
$ forall {a :: PType} {b :: PType}.
TestableTerm (PEither a b) -> TestableTerm PBool
isRight TestableTerm (PEither a b)
x = forall n a. Integral n => n -> Gen a -> Gen a
variant (Integer
0 :: Integer) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (p :: PType) b.
PCoArbitrary p =>
TestableTerm p -> Gen b -> Gen b
pcoarbitrary (forall {a :: PType} {b :: PType}.
TestableTerm (PEither a b) -> TestableTerm b
pright TestableTerm (PEither a b)
x)
    | Bool
otherwise = forall n a. Integral n => n -> Gen a -> Gen a
variant (Integer
1 :: Integer) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (p :: PType) b.
PCoArbitrary p =>
TestableTerm p -> Gen b -> Gen b
pcoarbitrary (forall {b1 :: PType} {b2 :: PType}.
TestableTerm (PEither b1 b2) -> TestableTerm b1
pleft TestableTerm (PEither a b)
x)

{- | Unfortunately, it is impossible to create @PBuiltinPair@ at the
     Plutarch level without getting into manipulating raw Plutus
     data. Instead, it can only be created from haskell level value
     and constanted.

     This limitation limites this generator to only accepting Plutarch
     types that have @PLift@ and @Arbitrary (PLifted a)@.

 @since 2.0.0
-}
instance
  ( PLift a
  , PLift b
  , Arbitrary (PLifted a, PLifted b)
  ) =>
  PArbitrary (PBuiltinPair a b)
  where
  parbitrary :: Gen (TestableTerm (PBuiltinPair a b))
parbitrary = forall {p :: PType} {h}.
(PLift p, PLifted p ~ h) =>
h -> TestableTerm p
pconstantT forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Arbitrary a => Gen a
arbitrary

  pshrink :: TestableTerm (PBuiltinPair a b)
-> [TestableTerm (PBuiltinPair a b)]
pshrink = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall {p :: PType} {h}.
(PLift p, PLifted p ~ h) =>
h -> TestableTerm p
pconstantT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Arbitrary a => a -> [a]
shrink forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {p :: PType} {h}.
(PLift p, PLifted p ~ h) =>
TestableTerm p -> h
pliftT

instance
  ( PLift a
  , PLift b
  , CoArbitrary (PLifted a, PLifted b)
  ) =>
  PCoArbitrary (PBuiltinPair a b)
  where
  pcoarbitrary :: forall b. TestableTerm (PBuiltinPair a b) -> Gen b -> Gen b
pcoarbitrary = forall a b. CoArbitrary a => a -> Gen b -> Gen b
coarbitrary forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {p :: PType} {h}.
(PLift p, PLifted p ~ h) =>
TestableTerm p -> h
pliftT

-- | @since 2.0.0
instance
  {-# OVERLAPPING #-}
  ( PArbitrary a
  , PArbitrary b
  , PIsData a
  , PIsData b
  ) =>
  PArbitrary (PBuiltinPair (PAsData a) (PAsData b))
  where
  parbitrary :: Gen (TestableTerm (PBuiltinPair (PAsData a) (PAsData b)))
parbitrary = do
    (TestableTerm forall (s :: S). Term s (PTuple a b)
x) <- forall (p :: PType). PArbitrary p => Gen (TestableTerm p)
parbitrary
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (a :: PType). (forall (s :: S). Term s a) -> TestableTerm a
TestableTerm forall a b. (a -> b) -> a -> b
$ forall (a :: PType) (s :: S).
PIsData a =>
Term s (PAsData a) -> Term s a
pfromData forall a b. (a -> b) -> a -> b
$ forall (s :: S) (a :: PType) (b :: PType).
Term s (PAsData (PTuple a b))
-> Term s (PAsData (PBuiltinPair (PAsData a) (PAsData b)))
pbuiltinPairFromTuple (forall (a :: PType) (s :: S).
PIsData a =>
Term s a -> Term s (PAsData a)
pdata forall (s :: S). Term s (PTuple a b)
x)

  pshrink :: TestableTerm (PBuiltinPair (PAsData a) (PAsData b))
-> [TestableTerm (PBuiltinPair (PAsData a) (PAsData b))]
pshrink = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall {a :: PType} {b :: PType}.
TestableTerm (PTuple a b)
-> TestableTerm (PBuiltinPair (PAsData a) (PAsData b))
fromTuple forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Arbitrary a => a -> [a]
shrink forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {a :: PType} {b :: PType}.
TestableTerm (PBuiltinPair (PAsData a) (PAsData b))
-> TestableTerm (PTuple a b)
toTuple
    where
      toTuple :: TestableTerm (PBuiltinPair (PAsData a) (PAsData b))
-> TestableTerm (PTuple a b)
toTuple = forall (a :: PType) (b :: PType).
(forall (s :: S). Term s a -> Term s b)
-> TestableTerm a -> TestableTerm b
liftT (forall (a :: PType) (s :: S).
PIsData a =>
Term s (PAsData a) -> Term s a
pfromData forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (s :: S) (a :: PType) (b :: PType).
Term s (PAsData (PBuiltinPair (PAsData a) (PAsData b)))
-> Term s (PAsData (PTuple a b))
ptupleFromBuiltin forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (a :: PType) (s :: S).
PIsData a =>
Term s a -> Term s (PAsData a)
pdata)
      fromTuple :: TestableTerm (PTuple a b)
-> TestableTerm (PBuiltinPair (PAsData a) (PAsData b))
fromTuple = forall (a :: PType) (b :: PType).
(forall (s :: S). Term s a -> Term s b)
-> TestableTerm a -> TestableTerm b
liftT (forall (a :: PType) (s :: S).
PIsData a =>
Term s (PAsData a) -> Term s a
pfromData forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (s :: S) (a :: PType) (b :: PType).
Term s (PAsData (PTuple a b))
-> Term s (PAsData (PBuiltinPair (PAsData a) (PAsData b)))
pbuiltinPairFromTuple forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (a :: PType) (s :: S).
PIsData a =>
Term s a -> Term s (PAsData a)
pdata)

instance
  {-# OVERLAPPING #-}
  ( PCoArbitrary a
  , PCoArbitrary b
  , PIsData a
  , PIsData b
  ) =>
  PCoArbitrary (PBuiltinPair (PAsData a) (PAsData b))
  where
  pcoarbitrary :: forall b.
TestableTerm (PBuiltinPair (PAsData a) (PAsData b))
-> Gen b -> Gen b
pcoarbitrary (forall (a :: PType) (b :: PType).
(forall (s :: S). Term s a -> Term s b)
-> TestableTerm a -> TestableTerm b
liftT forall (s :: S) (a :: PType) (b :: PType).
Term s (PAsData (PBuiltinPair (PAsData a) (PAsData b)))
-> Term s (PAsData (PTuple a b))
ptupleFromBuiltin forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {p :: PType}.
PIsData p =>
TestableTerm p -> TestableTerm (PAsData p)
pdataT -> TestableTerm (PAsData (PTuple a b))
t) = forall (p :: PType) b.
PCoArbitrary p =>
TestableTerm p -> Gen b -> Gen b
pcoarbitrary TestableTerm (PAsData (PTuple a b))
t

-- | @since 2.0.0
instance
  ( PArbitrary a
  , PArbitrary b
  ) =>
  PArbitrary (PPair a b)
  where
  parbitrary :: Gen (TestableTerm (PPair a b))
parbitrary = do
    (TestableTerm forall (s :: S). Term s a
x) <- forall (p :: PType). PArbitrary p => Gen (TestableTerm p)
parbitrary
    (TestableTerm forall (s :: S). Term s b
y) <- forall (p :: PType). PArbitrary p => Gen (TestableTerm p)
parbitrary
    forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {p :: PType}.
PlutusType p =>
(forall {s :: S}. p s) -> TestableTerm p
pconT forall a b. (a -> b) -> a -> b
$ forall (a :: PType) (b :: PType) (s :: S).
Term s a -> Term s b -> PPair a b s
PPair forall (s :: S). Term s a
x forall (s :: S). Term s b
y

  pshrink :: TestableTerm (PPair a b) -> [TestableTerm (PPair a b)]
pshrink TestableTerm (PPair a b)
x =
    [ forall {p :: PType}.
PlutusType p =>
(forall {s :: S}. p s) -> TestableTerm p
pconT forall a b. (a -> b) -> a -> b
$ forall (a :: PType) (b :: PType) (s :: S).
Term s a -> Term s b -> PPair a b s
PPair forall (s :: S). Term s a
a forall (s :: S). Term s b
b
    | (TestableTerm forall (s :: S). Term s a
a) <- forall a. Arbitrary a => a -> [a]
shrink forall a b. (a -> b) -> a -> b
$ forall {a :: PType} {b :: PType}.
TestableTerm (PPair a b) -> TestableTerm a
ppFstT TestableTerm (PPair a b)
x
    , (TestableTerm forall (s :: S). Term s b
b) <- forall a. Arbitrary a => a -> [a]
shrink forall a b. (a -> b) -> a -> b
$ forall {a :: PType} {b :: PType}.
TestableTerm (PPair a b) -> TestableTerm b
ppSndT TestableTerm (PPair a b)
x
    ]

instance (PCoArbitrary a, PCoArbitrary b) => PCoArbitrary (PPair a b) where
  pcoarbitrary :: forall b. TestableTerm (PPair a b) -> Gen b -> Gen b
pcoarbitrary TestableTerm (PPair a b)
x = forall (p :: PType) b.
PCoArbitrary p =>
TestableTerm p -> Gen b -> Gen b
pcoarbitrary (forall {a :: PType} {b :: PType}.
TestableTerm (PPair a b) -> TestableTerm a
ppFstT TestableTerm (PPair a b)
x) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (p :: PType) b.
PCoArbitrary p =>
TestableTerm p -> Gen b -> Gen b
pcoarbitrary (forall {a :: PType} {b :: PType}.
TestableTerm (PPair a b) -> TestableTerm b
ppSndT TestableTerm (PPair a b)
x)

-- | @since 2.0.0
instance
  forall (a :: S -> Type) (b :: S -> Type).
  ( PArbitrary a
  , PArbitrary b
  , PIsData a
  , PIsData b
  ) =>
  PArbitrary (PTuple a b)
  where
  parbitrary :: Gen (TestableTerm (PTuple a b))
parbitrary = do
    (TestableTerm forall (s :: S). Term s a
x) <- forall (p :: PType). PArbitrary p => Gen (TestableTerm p)
parbitrary
    (TestableTerm forall (s :: S). Term s b
y) <- forall (p :: PType). PArbitrary p => Gen (TestableTerm p)
parbitrary
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (a :: PType). (forall (s :: S). Term s a) -> TestableTerm a
TestableTerm forall a b. (a -> b) -> a -> b
$ forall (s :: S) (a :: PType) (b :: PType).
Term s (PAsData a :--> (PAsData b :--> PTuple a b))
ptuple forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (a :: PType) (s :: S).
PIsData a =>
Term s a -> Term s (PAsData a)
pdata forall (s :: S). Term s a
x forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (a :: PType) (s :: S).
PIsData a =>
Term s a -> Term s (PAsData a)
pdata forall (s :: S). Term s b
y

  pshrink :: TestableTerm (PTuple a b) -> [TestableTerm (PTuple a b)]
pshrink TestableTerm (PTuple a b)
x =
    [ forall (a :: PType). (forall (s :: S). Term s a) -> TestableTerm a
TestableTerm forall a b. (a -> b) -> a -> b
$ forall (s :: S) (a :: PType) (b :: PType).
Term s (PAsData a :--> (PAsData b :--> PTuple a b))
ptuple forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (s :: S). Term s (PAsData a)
a forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (s :: S). Term s (PAsData b)
b
    | (TestableTerm forall (s :: S). Term s (PAsData a)
a) <- forall a. Arbitrary a => a -> [a]
shrink forall a b. (a -> b) -> a -> b
$ forall {a :: PType} {b :: PType}.
TestableTerm (PTuple a b) -> TestableTerm (PAsData a)
ptFstT TestableTerm (PTuple a b)
x
    , (TestableTerm forall (s :: S). Term s (PAsData b)
b) <- forall a. Arbitrary a => a -> [a]
shrink forall a b. (a -> b) -> a -> b
$ forall {a :: PType} {b :: PType}.
TestableTerm (PTuple a b) -> TestableTerm (PAsData b)
ptSndT TestableTerm (PTuple a b)
x
    ]

instance
  forall (a :: S -> Type) (b :: S -> Type).
  ( PCoArbitrary a
  , PCoArbitrary b
  , PIsData a
  , PIsData b
  ) =>
  PCoArbitrary (PTuple a b)
  where
  pcoarbitrary :: forall b. TestableTerm (PTuple a b) -> Gen b -> Gen b
pcoarbitrary TestableTerm (PTuple a b)
x = forall (p :: PType) b.
PCoArbitrary p =>
TestableTerm p -> Gen b -> Gen b
pcoarbitrary (forall {a :: PType} {b :: PType}.
TestableTerm (PTuple a b) -> TestableTerm (PAsData a)
ptFstT TestableTerm (PTuple a b)
x) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (p :: PType) b.
PCoArbitrary p =>
TestableTerm p -> Gen b -> Gen b
pcoarbitrary (forall {a :: PType} {b :: PType}.
TestableTerm (PTuple a b) -> TestableTerm (PAsData b)
ptSndT TestableTerm (PTuple a b)
x)

-- | @since 2.0.0
instance
  forall (a :: S -> Type).
  (PArbitrary a, PIsListLike PBuiltinList a) =>
  PArbitrary (PBuiltinList a)
  where
  parbitrary :: Gen (TestableTerm (PBuiltinList a))
parbitrary = forall {a :: PType} {b :: PType -> PType}.
PIsListLike b a =>
[TestableTerm a] -> TestableTerm (b a)
constrPList forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Arbitrary a => Gen a
arbitrary
  pshrink :: TestableTerm (PBuiltinList a) -> [TestableTerm (PBuiltinList a)]
pshrink = forall {a :: PType} {b :: PType -> PType}.
(PArbitrary a, PIsListLike b a) =>
TestableTerm (b a) -> [TestableTerm (b a)]
shrinkPListLike

instance
  forall (a :: S -> Type).
  (PCoArbitrary a, PIsListLike PBuiltinList a) =>
  PCoArbitrary (PBuiltinList a)
  where
  pcoarbitrary :: forall b. TestableTerm (PBuiltinList a) -> Gen b -> Gen b
pcoarbitrary = forall {a :: PType} {b :: PType -> PType} {c}.
(PCoArbitrary a, PCoArbitrary (b a), PIsListLike b a) =>
TestableTerm (b a) -> Gen c -> Gen c
coArbitraryPListLike

-- | @since 2.0.0
instance
  forall (a :: S -> Type).
  (PArbitrary a, PIsListLike PList a) =>
  PArbitrary (PList a)
  where
  parbitrary :: Gen (TestableTerm (PList a))
parbitrary = forall {a :: PType} {b :: PType -> PType}.
(PArbitrary a, PIsListLike b a) =>
Gen (TestableTerm (b a))
genPListLike
  pshrink :: TestableTerm (PList a) -> [TestableTerm (PList a)]
pshrink = forall {a :: PType} {b :: PType -> PType}.
(PArbitrary a, PIsListLike b a) =>
TestableTerm (b a) -> [TestableTerm (b a)]
shrinkPListLike

instance (PCoArbitrary a, PIsListLike PList a) => PCoArbitrary (PList a) where
  pcoarbitrary :: forall b. TestableTerm (PList a) -> Gen b -> Gen b
pcoarbitrary = forall {a :: PType} {b :: PType -> PType} {c}.
(PCoArbitrary a, PCoArbitrary (b a), PIsListLike b a) =>
TestableTerm (b a) -> Gen c -> Gen c
coArbitraryPListLike

-- | @since 2.0.0
instance
  forall (a :: S -> Type) (b :: S -> Type).
  ( PArbitrary a
  , PArbitrary b
  , PIsData a
  , PIsData b
  ) =>
  PArbitrary (PMap 'Unsorted a b)
  where
  parbitrary :: Gen (TestableTerm (PMap 'Unsorted a b))
parbitrary = do
    (TestableTerm forall (s :: S).
Term s (PBuiltinList (PBuiltinPair (PAsData a) (PAsData b)))
x) <- forall (p :: PType). PArbitrary p => Gen (TestableTerm p)
parbitrary
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall {p :: PType}.
PlutusType p =>
(forall {s :: S}. p s) -> TestableTerm p
pconT forall a b. (a -> b) -> a -> b
$ forall (keysort :: KeyGuarantees) (k :: PType) (v :: PType)
       (s :: S).
Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)))
-> PMap keysort k v s
PMap forall (s :: S).
Term s (PBuiltinList (PBuiltinPair (PAsData a) (PAsData b)))
x

  pshrink :: TestableTerm (PMap 'Unsorted a b)
-> [TestableTerm (PMap 'Unsorted a b)]
pshrink = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall {k :: PType} {v :: PType} {keysort :: KeyGuarantees}.
TestableTerm (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)))
-> TestableTerm (PMap keysort k v)
reMap forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Arbitrary a => a -> [a]
shrink forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {keysort :: KeyGuarantees} {k :: PType} {v :: PType}.
TestableTerm (PMap keysort k v)
-> TestableTerm
     (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)))
unMap
    where
      reMap :: TestableTerm (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)))
-> TestableTerm (PMap keysort k v)
reMap (TestableTerm forall (s :: S).
Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)))
x) = forall {p :: PType}.
PlutusType p =>
(forall {s :: S}. p s) -> TestableTerm p
pconT forall a b. (a -> b) -> a -> b
$ forall (keysort :: KeyGuarantees) (k :: PType) (v :: PType)
       (s :: S).
Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)))
-> PMap keysort k v s
PMap forall (s :: S).
Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)))
x
      unMap :: TestableTerm (PMap keysort k v)
-> TestableTerm
     (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)))
unMap = forall a b c. (a -> b -> c) -> b -> a -> c
flip forall {p :: PType} {b :: PType}.
PlutusType p =>
TestableTerm p
-> (forall {s :: S}. p s -> Term s b) -> TestableTerm b
pmatchT forall a b. (a -> b) -> a -> b
$ \(PMap Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)))
a) -> Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)))
a

-- | @since 2.0.0
instance
  forall (a :: S -> Type) (b :: S -> Type) (c :: KeyGuarantees).
  (PCoArbitrary a, PCoArbitrary b, PIsData a, PIsData b) =>
  PCoArbitrary (PMap c a b)
  where
  pcoarbitrary :: forall b. TestableTerm (PMap c a b) -> Gen b -> Gen b
pcoarbitrary = forall (p :: PType) b.
PCoArbitrary p =>
TestableTerm p -> Gen b -> Gen b
pcoarbitrary forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {keysort :: KeyGuarantees} {k :: PType} {v :: PType}.
TestableTerm (PMap keysort k v)
-> TestableTerm
     (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)))
unMap
    where
      unMap :: TestableTerm (PMap keysort k v)
-> TestableTerm
     (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)))
unMap = forall a b c. (a -> b -> c) -> b -> a -> c
flip forall {p :: PType} {b :: PType}.
PlutusType p =>
TestableTerm p
-> (forall {s :: S}. p s -> Term s b) -> TestableTerm b
pmatchT forall a b. (a -> b) -> a -> b
$ \(PMap Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)))
a) -> Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)))
a

-- | @since 2.2.2
instance PArbitrary PPOSIXTime where
  parbitrary :: Gen (TestableTerm PPOSIXTime)
parbitrary = do
    TestableTerm forall (s :: S). Term s PInteger
x <- forall (p :: PType). PArbitrary p => Gen (TestableTerm p)
parbitrary
    forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {p :: PType}.
PlutusType p =>
(forall {s :: S}. p s) -> TestableTerm p
pconT forall a b. (a -> b) -> a -> b
$ forall (s :: S). Term s PInteger -> PPOSIXTime s
PPOSIXTime forall a b. (a -> b) -> a -> b
$ forall (a :: PType) (s :: S). PNum a => Term s (a :--> a)
pabs forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (s :: S). Term s PInteger
x
  pshrink :: TestableTerm PPOSIXTime -> [TestableTerm PPOSIXTime]
pshrink = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(TestableTerm forall (s :: S). Term s PInteger
x) -> forall {p :: PType}.
PlutusType p =>
(forall {s :: S}. p s) -> TestableTerm p
pconT forall a b. (a -> b) -> a -> b
$ forall (s :: S). Term s PInteger -> PPOSIXTime s
PPOSIXTime forall (s :: S). Term s PInteger
x) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Arbitrary a => a -> [a]
shrink forall b c a. (b -> c) -> (a -> b) -> a -> c
. TestableTerm PPOSIXTime -> TestableTerm PInteger
unTime
    where
      unTime :: TestableTerm PPOSIXTime -> TestableTerm PInteger
unTime = forall a b c. (a -> b -> c) -> b -> a -> c
flip forall {p :: PType} {b :: PType}.
PlutusType p =>
TestableTerm p
-> (forall {s :: S}. p s -> Term s b) -> TestableTerm b
pmatchT forall a b. (a -> b) -> a -> b
$ \(PPOSIXTime Term s PInteger
a) -> Term s PInteger
a

-- | @since 2.0.0
instance
  forall (a :: S -> Type).
  (PIsData a, PArbitrary a) =>
  PArbitrary (PExtended a)
  where
  parbitrary :: Gen (TestableTerm (PExtended a))
parbitrary = do
    (TestableTerm forall (s :: S). Term s a
x) <- forall (p :: PType). PArbitrary p => Gen (TestableTerm p)
parbitrary
    forall a. [a] -> Gen a
elements
      [ forall {p :: PType}.
PlutusType p =>
(forall {s :: S}. p s) -> TestableTerm p
pconT forall a b. (a -> b) -> a -> b
$ forall (a :: PType) (s :: S).
Term s (PDataRecord '[]) -> PExtended a s
PNegInf forall (s :: S). Term s (PDataRecord '[])
pdnil
      , forall {p :: PType}.
PlutusType p =>
(forall {s :: S}. p s) -> TestableTerm p
pconT forall a b. (a -> b) -> a -> b
$ forall (a :: PType) (s :: S).
Term s (PDataRecord '[ "_0" ':= a]) -> PExtended a s
PFinite forall a b. (a -> b) -> a -> b
$ forall (label :: Symbol) (a :: PType) (l :: [PLabeledType])
       (s :: S).
Term
  s
  (PAsData a
   :--> (PDataRecord l :--> PDataRecord ((label ':= a) : l)))
pdcons @"_0" forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (a :: PType) (s :: S).
PIsData a =>
Term s a -> Term s (PAsData a)
pdata forall (s :: S). Term s a
x forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (s :: S). Term s (PDataRecord '[])
pdnil
      , forall {p :: PType}.
PlutusType p =>
(forall {s :: S}. p s) -> TestableTerm p
pconT forall a b. (a -> b) -> a -> b
$ forall (a :: PType) (s :: S).
Term s (PDataRecord '[]) -> PExtended a s
PPosInf forall (s :: S). Term s (PDataRecord '[])
pdnil
      ]

-- | @since 2.0.0
instance
  forall (a :: S -> Type).
  (PIsData a, PArbitrary a) =>
  PArbitrary (PLowerBound a)
  where
  parbitrary :: Gen (TestableTerm (PLowerBound a))
parbitrary = do
    (TestableTerm forall (s :: S). Term s (PExtended a)
ex) <- forall (p :: PType). PArbitrary p => Gen (TestableTerm p)
parbitrary
    (TestableTerm forall (s :: S). Term s PBool
cl) <- forall (p :: PType). PArbitrary p => Gen (TestableTerm p)
parbitrary
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$
      forall {p :: PType}.
PlutusType p =>
(forall {s :: S}. p s) -> TestableTerm p
pconT forall a b. (a -> b) -> a -> b
$
        forall (a :: PType) (s :: S).
Term s (PDataRecord '[ "_0" ':= PExtended a, "_1" ':= PBool])
-> PLowerBound a s
PLowerBound forall a b. (a -> b) -> a -> b
$
          forall (label :: Symbol) (a :: PType) (l :: [PLabeledType])
       (s :: S).
Term
  s
  (PAsData a
   :--> (PDataRecord l :--> PDataRecord ((label ':= a) : l)))
pdcons @"_0" forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (a :: PType) (s :: S).
PIsData a =>
Term s a -> Term s (PAsData a)
pdata forall (s :: S). Term s (PExtended a)
ex forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
#$ forall (label :: Symbol) (a :: PType) (l :: [PLabeledType])
       (s :: S).
Term
  s
  (PAsData a
   :--> (PDataRecord l :--> PDataRecord ((label ':= a) : l)))
pdcons @"_1" forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (a :: PType) (s :: S).
PIsData a =>
Term s a -> Term s (PAsData a)
pdata forall (s :: S). Term s PBool
cl forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (s :: S). Term s (PDataRecord '[])
pdnil

-- | @since 2.0.0
instance
  forall (a :: S -> Type).
  (PIsData a, PArbitrary a) =>
  PArbitrary (PUpperBound a)
  where
  parbitrary :: Gen (TestableTerm (PUpperBound a))
parbitrary = do
    (TestableTerm forall (s :: S). Term s (PExtended a)
ex) <- forall (p :: PType). PArbitrary p => Gen (TestableTerm p)
parbitrary
    (TestableTerm forall (s :: S). Term s PBool
cl) <- forall (p :: PType). PArbitrary p => Gen (TestableTerm p)
parbitrary
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$
      forall {p :: PType}.
PlutusType p =>
(forall {s :: S}. p s) -> TestableTerm p
pconT forall a b. (a -> b) -> a -> b
$
        forall (a :: PType) (s :: S).
Term s (PDataRecord '[ "_0" ':= PExtended a, "_1" ':= PBool])
-> PUpperBound a s
PUpperBound forall a b. (a -> b) -> a -> b
$
          forall (label :: Symbol) (a :: PType) (l :: [PLabeledType])
       (s :: S).
Term
  s
  (PAsData a
   :--> (PDataRecord l :--> PDataRecord ((label ':= a) : l)))
pdcons @"_0" forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (a :: PType) (s :: S).
PIsData a =>
Term s a -> Term s (PAsData a)
pdata forall (s :: S). Term s (PExtended a)
ex forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
#$ forall (label :: Symbol) (a :: PType) (l :: [PLabeledType])
       (s :: S).
Term
  s
  (PAsData a
   :--> (PDataRecord l :--> PDataRecord ((label ':= a) : l)))
pdcons @"_1" forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (a :: PType) (s :: S).
PIsData a =>
Term s a -> Term s (PAsData a)
pdata forall (s :: S). Term s PBool
cl forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (s :: S). Term s (PDataRecord '[])
pdnil

-- | @since 2.0.0
instance
  forall (a :: S -> Type).
  (PIsData a, PArbitrary a) =>
  PArbitrary (PInterval a)
  where
  parbitrary :: Gen (TestableTerm (PInterval a))
parbitrary = do
    (TestableTerm forall (s :: S). Term s (PLowerBound a)
lo) <- forall (p :: PType). PArbitrary p => Gen (TestableTerm p)
parbitrary
    (TestableTerm forall (s :: S). Term s (PUpperBound a)
up) <- forall (p :: PType). PArbitrary p => Gen (TestableTerm p)
parbitrary
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$
      forall {p :: PType}.
PlutusType p =>
(forall {s :: S}. p s) -> TestableTerm p
pconT forall a b. (a -> b) -> a -> b
$
        forall (a :: PType) (s :: S).
Term
  s
  (PDataRecord '[ "from" ':= PLowerBound a, "to" ':= PUpperBound a])
-> PInterval a s
PInterval forall a b. (a -> b) -> a -> b
$
          forall (label :: Symbol) (a :: PType) (l :: [PLabeledType])
       (s :: S).
Term
  s
  (PAsData a
   :--> (PDataRecord l :--> PDataRecord ((label ':= a) : l)))
pdcons @"from" forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (a :: PType) (s :: S).
PIsData a =>
Term s a -> Term s (PAsData a)
pdata forall (s :: S). Term s (PLowerBound a)
lo forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
#$ forall (label :: Symbol) (a :: PType) (l :: [PLabeledType])
       (s :: S).
Term
  s
  (PAsData a
   :--> (PDataRecord l :--> PDataRecord ((label ':= a) : l)))
pdcons @"to" forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (a :: PType) (s :: S).
PIsData a =>
Term s a -> Term s (PAsData a)
pdata forall (s :: S). Term s (PUpperBound a)
up forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (s :: S). Term s (PDataRecord '[])
pdnil

-- | @since 2.2.2
instance PArbitrary PDatumHash where
  parbitrary :: Gen (TestableTerm PDatumHash)
parbitrary = do
    -- PDatumHash should be 32 bytes long
    ByteString
bs <- Int -> Gen ByteString
genByteString Int
32
    forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {p :: PType}.
PlutusType p =>
(forall {s :: S}. p s) -> TestableTerm p
pconT forall a b. (a -> b) -> a -> b
$ forall (s :: S). Term s PByteString -> PDatumHash s
PDatumHash forall a b. (a -> b) -> a -> b
$ forall (p :: PType) (s :: S). PLift p => PLifted p -> Term s p
pconstant ByteString
bs

-- | @since 2.0.0
instance PArbitrary PPubKeyHash where
  parbitrary :: Gen (TestableTerm PPubKeyHash)
parbitrary = do
    -- PubKeyHash should be 28 bytes long
    ByteString
bs <- Int -> Gen ByteString
genByteString Int
28
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall {p :: PType}.
PlutusType p =>
(forall {s :: S}. p s) -> TestableTerm p
pconT forall a b. (a -> b) -> a -> b
$ forall (s :: S). Term s PByteString -> PPubKeyHash s
PPubKeyHash forall a b. (a -> b) -> a -> b
$ forall (p :: PType) (s :: S). PLift p => PLifted p -> Term s p
pconstant ByteString
bs

-- | @since 2.0.0
instance PArbitrary PScriptHash where
  parbitrary :: Gen (TestableTerm PScriptHash)
parbitrary = do
    -- StakeValidatorHash should be 28 bytes long
    ByteString
bs <- Int -> Gen ByteString
genByteString Int
28
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall {p :: PType}.
PlutusType p =>
(forall {s :: S}. p s) -> TestableTerm p
pconT forall a b. (a -> b) -> a -> b
$ forall (s :: S). Term s PByteString -> PScriptHash s
PScriptHash forall a b. (a -> b) -> a -> b
$ forall (p :: PType) (s :: S). PLift p => PLifted p -> Term s p
pconstant ByteString
bs

-- | @since 2.0.0
instance PArbitrary PCredential where
  parbitrary :: Gen (TestableTerm PCredential)
parbitrary = do
    (TestableTerm forall (s :: S). Term s PPubKeyHash
pk) <- forall (p :: PType). PArbitrary p => Gen (TestableTerm p)
parbitrary
    (TestableTerm forall (s :: S). Term s PScriptHash
vh) <- forall (p :: PType). PArbitrary p => Gen (TestableTerm p)
parbitrary
    forall a. [a] -> Gen a
elements
      [ forall {p :: PType}.
PlutusType p =>
(forall {s :: S}. p s) -> TestableTerm p
pconT forall a b. (a -> b) -> a -> b
$ forall (s :: S).
Term s (PDataRecord '[ "_0" ':= PScriptHash]) -> PCredential s
PScriptCredential forall a b. (a -> b) -> a -> b
$ forall (label :: Symbol) (a :: PType) (l :: [PLabeledType])
       (s :: S).
Term
  s
  (PAsData a
   :--> (PDataRecord l :--> PDataRecord ((label ':= a) : l)))
pdcons @"_0" forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (a :: PType) (s :: S).
PIsData a =>
Term s a -> Term s (PAsData a)
pdata forall (s :: S). Term s PScriptHash
vh forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (s :: S). Term s (PDataRecord '[])
pdnil
      , forall {p :: PType}.
PlutusType p =>
(forall {s :: S}. p s) -> TestableTerm p
pconT forall a b. (a -> b) -> a -> b
$ forall (s :: S).
Term s (PDataRecord '[ "_0" ':= PPubKeyHash]) -> PCredential s
PPubKeyCredential forall a b. (a -> b) -> a -> b
$ forall (label :: Symbol) (a :: PType) (l :: [PLabeledType])
       (s :: S).
Term
  s
  (PAsData a
   :--> (PDataRecord l :--> PDataRecord ((label ':= a) : l)))
pdcons @"_0" forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (a :: PType) (s :: S).
PIsData a =>
Term s a -> Term s (PAsData a)
pdata forall (s :: S). Term s PPubKeyHash
pk forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (s :: S). Term s (PDataRecord '[])
pdnil
      ]

-- | @since 2.2.2
instance PArbitrary PTxId where
  parbitrary :: Gen (TestableTerm PTxId)
parbitrary = do
    -- PTxId should be 32 bytes long
    ByteString
bs <- Int -> Gen ByteString
genByteString Int
32
    forall (f :: * -> *) a. Applicative f => a -> f a
pure forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {p :: PType}.
PlutusType p =>
(forall {s :: S}. p s) -> TestableTerm p
pconT forall a b. (a -> b) -> a -> b
$ forall (s :: S).
Term s (PDataRecord '[ "_0" ':= PByteString]) -> PTxId s
PTxId forall a b. (a -> b) -> a -> b
$ forall (label :: Symbol) (a :: PType) (l :: [PLabeledType])
       (s :: S).
Term
  s
  (PAsData a
   :--> (PDataRecord l :--> PDataRecord ((label ':= a) : l)))
pdcons @"_0" forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (a :: PType) (s :: S).
PIsData a =>
Term s a -> Term s (PAsData a)
pdata (forall (p :: PType) (s :: S). PLift p => PLifted p -> Term s p
pconstant ByteString
bs) forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (s :: S). Term s (PDataRecord '[])
pdnil

-- | @since 2.2.2
instance PArbitrary PTxOutRef where
  parbitrary :: Gen (TestableTerm PTxOutRef)
parbitrary = do
    TestableTerm forall (s :: S). Term s PTxId
id' <- forall (p :: PType). PArbitrary p => Gen (TestableTerm p)
parbitrary
    TestableTerm forall (s :: S). Term s PInteger
idx <- forall a. Num a => a -> a
abs forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (p :: PType). PArbitrary p => Gen (TestableTerm p)
parbitrary
    forall (f :: * -> *) a. Applicative f => a -> f a
pure forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {p :: PType}.
PlutusType p =>
(forall {s :: S}. p s) -> TestableTerm p
pconT forall a b. (a -> b) -> a -> b
$ forall (s :: S).
Term s (PDataRecord '[ "id" ':= PTxId, "idx" ':= PInteger])
-> PTxOutRef s
PTxOutRef forall a b. (a -> b) -> a -> b
$ forall (label :: Symbol) (a :: PType) (l :: [PLabeledType])
       (s :: S).
Term
  s
  (PAsData a
   :--> (PDataRecord l :--> PDataRecord ((label ':= a) : l)))
pdcons forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (a :: PType) (s :: S).
PIsData a =>
Term s a -> Term s (PAsData a)
pdata forall (s :: S). Term s PTxId
id' forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
#$ forall (label :: Symbol) (a :: PType) (l :: [PLabeledType])
       (s :: S).
Term
  s
  (PAsData a
   :--> (PDataRecord l :--> PDataRecord ((label ':= a) : l)))
pdcons forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (a :: PType) (s :: S).
PIsData a =>
Term s a -> Term s (PAsData a)
pdata forall (s :: S). Term s PInteger
idx forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (s :: S). Term s (PDataRecord '[])
pdnil
  pshrink :: TestableTerm PTxOutRef -> [TestableTerm PTxOutRef]
pshrink (TestableTerm forall (s :: S). Term s PTxOutRef
ref) = do
    TestableTerm forall (s :: S). Term s (PAsData PInteger)
idx' <- forall (p :: PType).
PArbitrary p =>
TestableTerm p -> [TestableTerm p]
pshrink forall a b. (a -> b) -> a -> b
$ forall (a :: PType). (forall (s :: S). Term s a) -> TestableTerm a
TestableTerm forall a b. (a -> b) -> a -> b
$ forall (name :: Symbol) (b :: PType) (p :: PType) (s :: S)
       (a :: PType) (as :: [PLabeledType]) (n :: Nat).
(PDataFields p, as ~ PFields p, n ~ PLabelIndex name as,
 KnownNat n, a ~ PUnLabel (IndexList n as), PFromDataable a b) =>
Term s (p :--> b)
pfield @"idx" forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (s :: S). Term s PTxOutRef
ref
    forall (f :: * -> *) a. Applicative f => a -> f a
pure forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {p :: PType}.
PlutusType p =>
(forall {s :: S}. p s) -> TestableTerm p
pconT forall a b. (a -> b) -> a -> b
$
      forall (s :: S).
Term s (PDataRecord '[ "id" ':= PTxId, "idx" ':= PInteger])
-> PTxOutRef s
PTxOutRef forall a b. (a -> b) -> a -> b
$
        forall (label :: Symbol) (a :: PType) (l :: [PLabeledType])
       (s :: S).
Term
  s
  (PAsData a
   :--> (PDataRecord l :--> PDataRecord ((label ':= a) : l)))
pdcons
          # (pfield @"id" # ref)
          #$ pdcons
          # idx'
          # pdnil

-- | @since 2.2.2
instance PArbitrary PStakingCredential where
  parbitrary :: Gen (TestableTerm PStakingCredential)
parbitrary = do
    (TestableTerm forall (s :: S). Term s PCredential
cred) <- forall (p :: PType). PArbitrary p => Gen (TestableTerm p)
parbitrary
    (TestableTerm forall (s :: S). Term s PInteger
x) <- Gen (TestableTerm PInteger)
go
    (TestableTerm forall (s :: S). Term s PInteger
y) <- Gen (TestableTerm PInteger)
go
    (TestableTerm forall (s :: S). Term s PInteger
z) <- Gen (TestableTerm PInteger)
go
    forall a. [a] -> Gen a
elements
      [ forall {p :: PType}.
PlutusType p =>
(forall {s :: S}. p s) -> TestableTerm p
pconT forall a b. (a -> b) -> a -> b
$ forall (s :: S).
Term s (PDataRecord '[ "_0" ':= PCredential])
-> PStakingCredential s
PStakingHash forall a b. (a -> b) -> a -> b
$ forall (label :: Symbol) (a :: PType) (l :: [PLabeledType])
       (s :: S).
Term
  s
  (PAsData a
   :--> (PDataRecord l :--> PDataRecord ((label ':= a) : l)))
pdcons @"_0" forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (a :: PType) (s :: S).
PIsData a =>
Term s a -> Term s (PAsData a)
pdata forall (s :: S). Term s PCredential
cred forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (s :: S). Term s (PDataRecord '[])
pdnil
      , forall {p :: PType}.
PlutusType p =>
(forall {s :: S}. p s) -> TestableTerm p
pconT forall a b. (a -> b) -> a -> b
$
          forall (s :: S).
Term
  s
  (PDataRecord
     '[ "_0" ':= PInteger, "_1" ':= PInteger, "_2" ':= PInteger])
-> PStakingCredential s
PStakingPtr forall a b. (a -> b) -> a -> b
$
            forall (label :: Symbol) (a :: PType) (l :: [PLabeledType])
       (s :: S).
Term
  s
  (PAsData a
   :--> (PDataRecord l :--> PDataRecord ((label ':= a) : l)))
pdcons @"_0"
              # pdata x
              #$ pdcons @"_1"
              # pdata y
              #$ pdcons @"_2"
              # pdata z
              # pdnil
      ]
    where
      -- This is needed because StakingPtr indexes are meant to be bounded to the
      -- Word64 range.
      go :: Gen (TestableTerm PInteger)
      go :: Gen (TestableTerm PInteger)
go = forall {p :: PType} {h}.
(PLift p, PLifted p ~ h) =>
h -> TestableTerm p
pconstantT forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Integer, Integer) -> Gen Integer
chooseInteger (Integer
0, Integer
18_446_744_073_709_551_615)

-- | @since 2.0.0
instance PArbitrary PAddress where
  parbitrary :: Gen (TestableTerm PAddress)
parbitrary = do
    (TestableTerm forall (s :: S). Term s PCredential
cred) <- forall (p :: PType). PArbitrary p => Gen (TestableTerm p)
parbitrary
    (TestableTerm forall (s :: S). Term s (PMaybeData PStakingCredential)
scred) <- forall (p :: PType). PArbitrary p => Gen (TestableTerm p)
parbitrary
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$
      forall {p :: PType}.
PlutusType p =>
(forall {s :: S}. p s) -> TestableTerm p
pconT forall a b. (a -> b) -> a -> b
$
        forall (s :: S).
Term
  s
  (PDataRecord
     '[ "credential" ':= PCredential,
        "stakingCredential" ':= PMaybeData PStakingCredential])
-> PAddress s
PAddress forall a b. (a -> b) -> a -> b
$
          forall (label :: Symbol) (a :: PType) (l :: [PLabeledType])
       (s :: S).
Term
  s
  (PAsData a
   :--> (PDataRecord l :--> PDataRecord ((label ':= a) : l)))
pdcons @"credential"
            # pdata cred
            #$ pdcons @"stakingCredential"
            # pdata scred
            # pdnil

-- | @since 2.0.0
instance PArbitrary PCurrencySymbol where
  parbitrary :: Gen (TestableTerm PCurrencySymbol)
parbitrary = do
    (TestableTerm forall (s :: S). Term s PByteString
cs) <- forall (p :: PType). PArbitrary p => Gen (TestableTerm p)
parbitrary
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall {p :: PType}.
PlutusType p =>
(forall {s :: S}. p s) -> TestableTerm p
pconT forall a b. (a -> b) -> a -> b
$ forall (s :: S). Term s PByteString -> PCurrencySymbol s
PCurrencySymbol forall (s :: S). Term s PByteString
cs

{- | This generates only those 'PTokenName's that correspond to ASCII strings.
 This is somewhat limited, but otherwise would require UTF-8 encoding as part
 of the generator.

 Unlike the equivalent Haskell type generator, this instance does not shrink.
 While somewhat suboptimal, this would require either a lot of lifting or
 \'lowering\' back into Haskell for the shrink.

 @since 2.2.2
-}
instance PArbitrary PTokenName where
  parbitrary :: Gen (TestableTerm PTokenName)
parbitrary = do
    [Word8]
asList <- forall a. Gen a -> Gen [a]
listOf Gen Word8
genAsciiByte
    let bs :: ByteString
bs = forall l. IsList l => [Item l] -> l
Exts.fromList [Word8]
asList
    forall (f :: * -> *) a. Applicative f => a -> f a
pure forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {p :: PType}.
PlutusType p =>
(forall {s :: S}. p s) -> TestableTerm p
pconT forall a b. (a -> b) -> a -> b
$ forall (s :: S). Term s PByteString -> PTokenName s
PTokenName forall a b. (a -> b) -> a -> b
$ forall (p :: PType) (s :: S). PLift p => PLifted p -> Term s p
pconstant ByteString
bs
    where
      -- This generates only those bytes which are readable (so, not control
      -- sequences)
      genAsciiByte :: Gen Word8
      genAsciiByte :: Gen Word8
genAsciiByte = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Int, Int) -> Gen Int
chooseInt (Int
32, Int
126)

-- | @since 2.0.0
instance PArbitrary (PValue 'Unsorted 'NoGuarantees) where
  parbitrary :: Gen (TestableTerm (PValue 'Unsorted 'NoGuarantees))
parbitrary = do
    (TestableTerm forall (s :: S).
Term
  s
  (PMap
     'Unsorted PCurrencySymbol (PMap 'Unsorted PTokenName PInteger))
val) <- forall (p :: PType). PArbitrary p => Gen (TestableTerm p)
parbitrary
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall {p :: PType}.
PlutusType p =>
(forall {s :: S}. p s) -> TestableTerm p
pconT forall a b. (a -> b) -> a -> b
$ forall (keys :: KeyGuarantees) (amounts :: AmountGuarantees)
       (s :: S).
Term s (PMap keys PCurrencySymbol (PMap keys PTokenName PInteger))
-> PValue keys amounts s
PValue forall (s :: S).
Term
  s
  (PMap
     'Unsorted PCurrencySymbol (PMap 'Unsorted PTokenName PInteger))
val

  pshrink :: TestableTerm (PValue 'Unsorted 'NoGuarantees)
-> [TestableTerm (PValue 'Unsorted 'NoGuarantees)]
pshrink = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(TestableTerm forall (s :: S).
Term
  s
  (PMap
     'Unsorted PCurrencySymbol (PMap 'Unsorted PTokenName PInteger))
x) -> forall {p :: PType}.
PlutusType p =>
(forall {s :: S}. p s) -> TestableTerm p
pconT forall a b. (a -> b) -> a -> b
$ forall (keys :: KeyGuarantees) (amounts :: AmountGuarantees)
       (s :: S).
Term s (PMap keys PCurrencySymbol (PMap keys PTokenName PInteger))
-> PValue keys amounts s
PValue forall (s :: S).
Term
  s
  (PMap
     'Unsorted PCurrencySymbol (PMap 'Unsorted PTokenName PInteger))
x) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Arbitrary a => a -> [a]
shrink forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {keys :: KeyGuarantees} {amounts :: AmountGuarantees}.
TestableTerm (PValue keys amounts)
-> TestableTerm
     (PMap keys PCurrencySymbol (PMap keys PTokenName PInteger))
unValue
    where
      unValue :: TestableTerm (PValue keys amounts)
-> TestableTerm
     (PMap keys PCurrencySymbol (PMap keys PTokenName PInteger))
unValue = forall a b c. (a -> b -> c) -> b -> a -> c
flip forall {p :: PType} {b :: PType}.
PlutusType p =>
TestableTerm p
-> (forall {s :: S}. p s -> Term s b) -> TestableTerm b
pmatchT forall a b. (a -> b) -> a -> b
$ \(PValue Term s (PMap keys PCurrencySymbol (PMap keys PTokenName PInteger))
a) -> Term s (PMap keys PCurrencySymbol (PMap keys PTokenName PInteger))
a

------------------------------------------------------------
-- Helpers

genByteString :: Int -> Gen ByteString
genByteString :: Int -> Gen ByteString
genByteString Int
l = forall l. IsList l => [Item l] -> l
Exts.fromList forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Int -> Gen a -> Gen [a]
vectorOf Int
l forall a. Arbitrary a => Gen a
arbitrary

shrinkByteString :: ByteString -> [ByteString]
shrinkByteString :: ByteString -> [ByteString]
shrinkByteString ByteString
bs = do
  [Word8]
xs' <- forall a. Arbitrary a => a -> [a]
shrink forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall l. IsList l => l -> [Item l]
Exts.toList forall a b. (a -> b) -> a -> b
$ ByteString
bs
  forall (f :: * -> *) a. Applicative f => a -> f a
pure forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall l. IsList l => [Item l] -> l
Exts.fromList forall a b. (a -> b) -> a -> b
$ [Word8]
xs'

isRight ::
  forall
    {a :: S -> Type}
    {b :: S -> Type}.
  TestableTerm (PEither a b) ->
  TestableTerm PBool
isRight :: forall {a :: PType} {b :: PType}.
TestableTerm (PEither a b) -> TestableTerm PBool
isRight = forall a b c. (a -> b -> c) -> b -> a -> c
flip forall {p :: PType} {b :: PType}.
PlutusType p =>
TestableTerm p
-> (forall {s :: S}. p s -> Term s b) -> TestableTerm b
pmatchT forall a b. (a -> b) -> a -> b
$ \case
  PRight Term s b
_ -> forall (p :: PType) (s :: S). PLift p => PLifted p -> Term s p
pconstant Bool
True
  PEither a b s
_ -> forall (p :: PType) (s :: S). PLift p => PLifted p -> Term s p
pconstant Bool
False

pright ::
  forall
    {a :: S -> Type}
    {b :: S -> Type}.
  TestableTerm (PEither a b) ->
  TestableTerm b
pright :: forall {a :: PType} {b :: PType}.
TestableTerm (PEither a b) -> TestableTerm b
pright = forall a b c. (a -> b -> c) -> b -> a -> c
flip forall {p :: PType} {b :: PType}.
PlutusType p =>
TestableTerm p
-> (forall {s :: S}. p s -> Term s b) -> TestableTerm b
pmatchT forall a b. (a -> b) -> a -> b
$ \case
  PRight Term s b
a -> Term s b
a
  PEither a b s
_ -> forall (s :: S) (a :: PType). Term s PString -> Term s a
ptraceError Term s PString
"asked for PRight when it is PLeft"

pleft ::
  forall
    {b1 :: S -> Type}
    {b2 :: S -> Type}.
  TestableTerm (PEither b1 b2) ->
  TestableTerm b1
pleft :: forall {b1 :: PType} {b2 :: PType}.
TestableTerm (PEither b1 b2) -> TestableTerm b1
pleft = forall a b c. (a -> b -> c) -> b -> a -> c
flip forall {p :: PType} {b :: PType}.
PlutusType p =>
TestableTerm p
-> (forall {s :: S}. p s -> Term s b) -> TestableTerm b
pmatchT forall a b. (a -> b) -> a -> b
$ \case
  PLeft Term s b1
a -> Term s b1
a
  PEither b1 b2 s
_ -> forall (s :: S) (a :: PType). Term s PString -> Term s a
ptraceError Term s PString
"asked for PLeft when it is PRight"

-- | @since 2.0.0
liftT ::
  forall (a :: S -> Type) (b :: S -> Type).
  (forall (s :: S). Term s a -> Term s b) ->
  TestableTerm a ->
  TestableTerm b
liftT :: forall (a :: PType) (b :: PType).
(forall (s :: S). Term s a -> Term s b)
-> TestableTerm a -> TestableTerm b
liftT forall (s :: S). Term s a -> Term s b
f (TestableTerm forall (s :: S). Term s a
x) = forall (a :: PType). (forall (s :: S). Term s a) -> TestableTerm a
TestableTerm forall a b. (a -> b) -> a -> b
$ forall (s :: S). Term s a -> Term s b
f forall (s :: S). Term s a
x

-- | @since 2.0.0
liftT2 ::
  forall (a :: S -> Type) (b :: S -> Type) (c :: S -> Type).
  (forall (s :: S). Term s a -> Term s b -> Term s c) ->
  TestableTerm a ->
  TestableTerm b ->
  TestableTerm c
liftT2 :: forall (a :: PType) (b :: PType) (c :: PType).
(forall (s :: S). Term s a -> Term s b -> Term s c)
-> TestableTerm a -> TestableTerm b -> TestableTerm c
liftT2 forall (s :: S). Term s a -> Term s b -> Term s c
f (TestableTerm forall (s :: S). Term s a
x) (TestableTerm forall (s :: S). Term s b
y) = forall (a :: PType). (forall (s :: S). Term s a) -> TestableTerm a
TestableTerm forall a b. (a -> b) -> a -> b
$ forall (s :: S). Term s a -> Term s b -> Term s c
f forall (s :: S). Term s a
x forall (s :: S). Term s b
y

ppFstT ::
  forall {a :: S -> Type} {b :: S -> Type}.
  TestableTerm (PPair a b) ->
  TestableTerm a
ppFstT :: forall {a :: PType} {b :: PType}.
TestableTerm (PPair a b) -> TestableTerm a
ppFstT = forall a b c. (a -> b -> c) -> b -> a -> c
flip forall {p :: PType} {b :: PType}.
PlutusType p =>
TestableTerm p
-> (forall {s :: S}. p s -> Term s b) -> TestableTerm b
pmatchT forall a b. (a -> b) -> a -> b
$ \(PPair Term s a
a Term s b
_) -> Term s a
a

ppSndT ::
  forall {a :: S -> Type} {b :: S -> Type}.
  TestableTerm (PPair a b) ->
  TestableTerm b
ppSndT :: forall {a :: PType} {b :: PType}.
TestableTerm (PPair a b) -> TestableTerm b
ppSndT = forall a b c. (a -> b -> c) -> b -> a -> c
flip forall {p :: PType} {b :: PType}.
PlutusType p =>
TestableTerm p
-> (forall {s :: S}. p s -> Term s b) -> TestableTerm b
pmatchT forall a b. (a -> b) -> a -> b
$ \(PPair Term s a
_ Term s b
a) -> Term s b
a

pdataT ::
  forall {p :: S -> Type}.
  PIsData p =>
  TestableTerm p ->
  TestableTerm (PAsData p)
pdataT :: forall {p :: PType}.
PIsData p =>
TestableTerm p -> TestableTerm (PAsData p)
pdataT (TestableTerm forall (s :: S). Term s p
x) = forall (a :: PType). (forall (s :: S). Term s a) -> TestableTerm a
TestableTerm forall a b. (a -> b) -> a -> b
$ forall (a :: PType) (s :: S).
PIsData a =>
Term s a -> Term s (PAsData a)
pdata forall (s :: S). Term s p
x

pfromDataT ::
  forall {p :: S -> Type}.
  PIsData p =>
  TestableTerm (PAsData p) ->
  TestableTerm p
pfromDataT :: forall {p :: PType}.
PIsData p =>
TestableTerm (PAsData p) -> TestableTerm p
pfromDataT (TestableTerm forall (s :: S). Term s (PAsData p)
x) = forall (a :: PType). (forall (s :: S). Term s a) -> TestableTerm a
TestableTerm forall a b. (a -> b) -> a -> b
$ forall (a :: PType) (s :: S).
PIsData a =>
Term s (PAsData a) -> Term s a
pfromData forall (s :: S). Term s (PAsData p)
x

pliftT ::
  forall {p :: S -> Type} {h :: Type}.
  (PLift p, PLifted p ~ h) =>
  TestableTerm p ->
  h
pliftT :: forall {p :: PType} {h}.
(PLift p, PLifted p ~ h) =>
TestableTerm p -> h
pliftT (TestableTerm forall (s :: S). Term s p
x) = forall (p :: PType).
(HasCallStack, PLift p) =>
ClosedTerm p -> PLifted p
plift forall (s :: S). Term s p
x

pconstantT ::
  forall {p :: S -> Type} {h :: Type}.
  (PLift p, PLifted p ~ h) =>
  h ->
  TestableTerm p
pconstantT :: forall {p :: PType} {h}.
(PLift p, PLifted p ~ h) =>
h -> TestableTerm p
pconstantT h
h = forall (a :: PType). (forall (s :: S). Term s a) -> TestableTerm a
TestableTerm forall a b. (a -> b) -> a -> b
$ forall (p :: PType) (s :: S). PLift p => PLifted p -> Term s p
pconstant h
h

pconT ::
  forall {p :: S -> Type}.
  PlutusType p =>
  (forall {s :: S}. p s) ->
  TestableTerm p
pconT :: forall {p :: PType}.
PlutusType p =>
(forall {s :: S}. p s) -> TestableTerm p
pconT forall {s :: S}. p s
p = forall (a :: PType). (forall (s :: S). Term s a) -> TestableTerm a
TestableTerm forall a b. (a -> b) -> a -> b
$ forall (a :: PType) (s :: S). PlutusType a => a s -> Term s a
pcon forall {s :: S}. p s
p

pmatchT ::
  forall {p :: S -> Type} {b :: S -> Type}.
  PlutusType p =>
  TestableTerm p ->
  (forall {s :: S}. p s -> Term s b) ->
  TestableTerm b
pmatchT :: forall {p :: PType} {b :: PType}.
PlutusType p =>
TestableTerm p
-> (forall {s :: S}. p s -> Term s b) -> TestableTerm b
pmatchT (TestableTerm forall (s :: S). Term s p
p) forall {s :: S}. p s -> Term s b
f = forall (a :: PType). (forall (s :: S). Term s a) -> TestableTerm a
TestableTerm forall a b. (a -> b) -> a -> b
$ forall (a :: PType) (s :: S) (b :: PType).
PlutusType a =>
Term s a -> (a s -> Term s b) -> Term s b
pmatch forall (s :: S). Term s p
p forall {s :: S}. p s -> Term s b
f

ptFstT ::
  forall {a :: S -> Type} {b :: S -> Type}.
  TestableTerm (PTuple a b) ->
  TestableTerm (PAsData a)
ptFstT :: forall {a :: PType} {b :: PType}.
TestableTerm (PTuple a b) -> TestableTerm (PAsData a)
ptFstT = forall (a :: PType) (b :: PType).
(forall (s :: S). Term s a -> Term s b)
-> TestableTerm a -> TestableTerm b
liftT (forall (name :: Symbol) (b :: PType) (p :: PType) (s :: S)
       (a :: PType) (as :: [PLabeledType]) (n :: Nat).
(PDataFields p, as ~ PFields p, n ~ PLabelIndex name as,
 KnownNat n, a ~ PUnLabel (IndexList n as), PFromDataable a b) =>
Term s (p :--> b)
pfield @"_0" forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
#)

ptSndT ::
  forall {a :: S -> Type} {b :: S -> Type}.
  TestableTerm (PTuple a b) ->
  TestableTerm (PAsData b)
ptSndT :: forall {a :: PType} {b :: PType}.
TestableTerm (PTuple a b) -> TestableTerm (PAsData b)
ptSndT = forall (a :: PType) (b :: PType).
(forall (s :: S). Term s a -> Term s b)
-> TestableTerm a -> TestableTerm b
liftT (forall (name :: Symbol) (b :: PType) (p :: PType) (s :: S)
       (a :: PType) (as :: [PLabeledType]) (n :: Nat).
(PDataFields p, as ~ PFields p, n ~ PLabelIndex name as,
 KnownNat n, a ~ PUnLabel (IndexList n as), PFromDataable a b) =>
Term s (p :--> b)
pfield @"_1" forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
#)

constrPList ::
  forall {a :: S -> Type} {b :: (S -> Type) -> S -> Type}.
  (PIsListLike b a) =>
  [TestableTerm a] ->
  TestableTerm (b a)
constrPList :: forall {a :: PType} {b :: PType -> PType}.
PIsListLike b a =>
[TestableTerm a] -> TestableTerm (b a)
constrPList [] = forall (a :: PType). (forall (s :: S). Term s a) -> TestableTerm a
TestableTerm forall (list :: PType -> PType) (a :: PType) (s :: S).
(PListLike list, PElemConstraint list a) =>
Term s (list a)
pnil
constrPList ((TestableTerm forall (s :: S). Term s a
x) : [TestableTerm a]
xs) =
  let (TestableTerm forall (s :: S). Term s (b a)
rest) = forall {a :: PType} {b :: PType -> PType}.
PIsListLike b a =>
[TestableTerm a] -> TestableTerm (b a)
constrPList [TestableTerm a]
xs
   in forall (a :: PType). (forall (s :: S). Term s a) -> TestableTerm a
TestableTerm forall a b. (a -> b) -> a -> b
$ forall (list :: PType -> PType) (a :: PType) (s :: S).
(PListLike list, PElemConstraint list a) =>
Term s (a :--> (list a :--> list a))
pcons forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (s :: S). Term s a
x forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (s :: S). Term s (b a)
rest

convToList ::
  forall {a :: S -> Type} {b :: (S -> Type) -> S -> Type}.
  (PIsListLike b a) =>
  TestableTerm (b a) ->
  [TestableTerm a]
convToList :: forall {a :: PType} {b :: PType -> PType}.
PIsListLike b a =>
TestableTerm (b a) -> [TestableTerm a]
convToList (TestableTerm forall (s :: S). Term s (b a)
x)
  | Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ forall (p :: PType).
(HasCallStack, PLift p) =>
ClosedTerm p -> PLifted p
plift forall a b. (a -> b) -> a -> b
$ forall (list :: PType -> PType) (a :: PType) (s :: S).
(PListLike list, PElemConstraint list a) =>
Term s (list a :--> PBool)
pnull forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (s :: S). Term s (b a)
x =
      forall (a :: PType). (forall (s :: S). Term s a) -> TestableTerm a
TestableTerm (forall (list :: PType -> PType) (a :: PType) (s :: S).
(PListLike list, PElemConstraint list a) =>
Term s (list a :--> a)
phead forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (s :: S). Term s (b a)
x) forall a. a -> [a] -> [a]
: forall {a :: PType} {b :: PType -> PType}.
PIsListLike b a =>
TestableTerm (b a) -> [TestableTerm a]
convToList (forall (a :: PType). (forall (s :: S). Term s a) -> TestableTerm a
TestableTerm forall a b. (a -> b) -> a -> b
$ forall (list :: PType -> PType) (a :: PType) (s :: S).
(PListLike list, PElemConstraint list a) =>
Term s (list a :--> list a)
ptail forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (s :: S). Term s (b a)
x)
  | Bool
otherwise = []

genPListLike ::
  forall {a :: S -> Type} {b :: (S -> Type) -> S -> Type}.
  (PArbitrary a, PIsListLike b a) =>
  Gen (TestableTerm (b a))
genPListLike :: forall {a :: PType} {b :: PType -> PType}.
(PArbitrary a, PIsListLike b a) =>
Gen (TestableTerm (b a))
genPListLike = forall {a :: PType} {b :: PType -> PType}.
PIsListLike b a =>
[TestableTerm a] -> TestableTerm (b a)
constrPList forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Arbitrary a => Gen a
arbitrary

shrinkPListLike ::
  forall {a :: S -> Type} {b :: (S -> Type) -> S -> Type}.
  ( PArbitrary a
  , PIsListLike b a
  ) =>
  TestableTerm (b a) ->
  [TestableTerm (b a)]
shrinkPListLike :: forall {a :: PType} {b :: PType -> PType}.
(PArbitrary a, PIsListLike b a) =>
TestableTerm (b a) -> [TestableTerm (b a)]
shrinkPListLike TestableTerm (b a)
xs' = forall {a :: PType} {b :: PType -> PType}.
PIsListLike b a =>
[TestableTerm a] -> TestableTerm (b a)
constrPList forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Arbitrary a => a -> [a]
shrink (forall {a :: PType} {b :: PType -> PType}.
PIsListLike b a =>
TestableTerm (b a) -> [TestableTerm a]
convToList TestableTerm (b a)
xs')

coArbitraryPListLike ::
  forall {a :: S -> Type} {b :: (S -> Type) -> S -> Type} {c :: Type}.
  (PCoArbitrary a, PCoArbitrary (b a), PIsListLike b a) =>
  TestableTerm (b a) ->
  Gen c ->
  Gen c
coArbitraryPListLike :: forall {a :: PType} {b :: PType -> PType} {c}.
(PCoArbitrary a, PCoArbitrary (b a), PIsListLike b a) =>
TestableTerm (b a) -> Gen c -> Gen c
coArbitraryPListLike (TestableTerm forall (s :: S). Term s (b a)
x)
  | forall (p :: PType).
(HasCallStack, PLift p) =>
ClosedTerm p -> PLifted p
plift (forall (list :: PType -> PType) (a :: PType) (s :: S).
(PListLike list, PElemConstraint list a) =>
Term s (list a :--> PBool)
pnull forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (s :: S). Term s (b a)
x) = forall n a. Integral n => n -> Gen a -> Gen a
variant (Integer
0 :: Integer)
  | Bool
otherwise =
      forall n a. Integral n => n -> Gen a -> Gen a
variant (Integer
1 :: Integer)
        forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (p :: PType) b.
PCoArbitrary p =>
TestableTerm p -> Gen b -> Gen b
pcoarbitrary (forall (a :: PType). (forall (s :: S). Term s a) -> TestableTerm a
TestableTerm forall a b. (a -> b) -> a -> b
$ forall (list :: PType -> PType) (a :: PType) (s :: S).
(PListLike list, PElemConstraint list a) =>
Term s (list a :--> a)
phead forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (s :: S). Term s (b a)
x)
        forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (p :: PType) b.
PCoArbitrary p =>
TestableTerm p -> Gen b -> Gen b
pcoarbitrary (forall (a :: PType). (forall (s :: S). Term s a) -> TestableTerm a
TestableTerm forall a b. (a -> b) -> a -> b
$ forall (list :: PType -> PType) (a :: PType) (s :: S).
(PListLike list, PElemConstraint list a) =>
Term s (list a :--> list a)
ptail forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (s :: S). Term s (b a)
x)