SampleableExt Class #
This class permits the creation samples of a given type
controlling the size of those values using the Gen monad.
Shrinkable Class #
This class helps minimize examples by creating smaller versions of given values.
When testing a proposition like ∀ n : Nat, Prime n → n ≤ 100,
Plausible requires that Nat have an instance of SampleableExt and for
Prime n to be decidable. Plausible will then use the instance of
SampleableExt to generate small examples of Nat and progressively increase
in size. For each example n, Prime n is tested. If it is false,
the example will be rejected (not a test success nor a failure) and
Plausible will move on to other examples. If Prime n is true,
n ≤ 100 will be tested. If it is false, n is a counter-example of
∀ n : Nat, Prime n → n ≤ 100 and the test fails. If n ≤ 100 is true,
the test passes and Plausible moves on to trying more examples.
Main definitions #
SampleableExtclassShrinkableclass
SampleableExt #
SampleableExt can be used in two ways. The first (and most common)
is to simply generate values of a type directly using the Gen monad,
if this is what you want to do then the way to go is to declare an Arbitrary
instance, and rely on the default selfContained instance.
Furthermore it makes it possible to express generators for types that
do not lend themselves to introspection, such as Nat → Nat.
If we test a quantification over functions the
counter-examples cannot be shrunken or printed meaningfully.
For that purpose, SampleableExt provides a proxy representation
proxy that can be printed and shrunken as well
as interpreted (using interp) as an object of the right type. If you
are using it in the first way, this proxy type will simply be the type
itself and the interp function id.
Shrinkable #
Given an example x : α, Shrinkable α gives us a way to shrink it
and suggest simpler examples.
Shrinking #
Shrinking happens when Plausible finds a counter-example to a
property. It is likely that the example will be more complicated than
necessary so Plausible proceeds to shrink it as much as
possible. Although equally valid, a smaller counter-example is easier
for a user to understand and use.
The Shrinkable class, , has a shrink function so that we can use
specialized knowledge while shrinking a value. It is not responsible
for the whole shrinking process however. It only has to take one step
in the shrinking process. Plausible will repeatedly call shrink
until no more steps can be taken. Because shrink guarantees that the
size of the candidates it produces is strictly smaller than the
argument, we know that Plausible is guaranteed to terminate.
Tags #
random testing
References #
Given an example x : α, Shrinkable α gives us a way to shrink it
and suggest simpler examples.
- shrink (x : α) : List α
Instances
SampleableExt can be used in two ways. The first (and most common)
is to simply generate values of a type directly using the Gen monad,
if this is what you want to do then declaring an Arbitrary instance is the
way to go.
Furthermore it makes it possible to express generators for types that
do not lend themselves to introspection, such as Nat → Nat.
If we test a quantification over functions the
counter-examples cannot be shrunken or printed meaningfully.
For that purpose, SampleableExt provides a proxy representation
proxy that can be printed and shrunken as well
as interpreted (using interp) as an object of the right type.
- proxy : Type v
- shrink : Shrinkable (proxy α)
- interp : proxy α → α
Instances
Default instance whose purpose is to simply generate values
of a type directly using the Arbitrary instance
Equations
- Plausible.SampleableExt.selfContained = { proxy := α, proxyRepr := inferInstance, shrink := inferInstance, sample := inferInstance, interp := id }
This is kept for backwards compatibility
Instances For
First samples a proxy value and interprets it. Especially useful if the proxy and target type are the same.
Equations
Instances For
Equations
- One or more equations did not get rendered due to their size.
Nat.shrink' n creates a list of smaller natural numbers by
successively dividing n by 2 . For example, Nat.shrink 5 = [2, 1, 0].
Equations
- Plausible.Nat.shrink n = if h : 0 < n then have m := n / 2; m :: Plausible.Nat.shrink m else []
Instances For
Equations
- Plausible.Nat.shrinkable = { shrink := Plausible.Nat.shrink }
Equations
- Plausible.Fin.shrinkable = { shrink := fun (m : Fin n.succ) => List.map (Fin.ofNat n.succ) (Plausible.Nat.shrink ↑m) }
Equations
- Plausible.BitVec.shrinkable = { shrink := fun (m : BitVec n) => List.map (BitVec.ofNat n) (Plausible.Nat.shrink m.toNat) }
Equations
- Plausible.UInt8.shrinkable = { shrink := fun (m : UInt8) => List.map UInt8.ofNat (Plausible.Nat.shrink m.toNat) }
Equations
- Plausible.UInt16.shrinkable = { shrink := fun (m : UInt16) => List.map UInt16.ofNat (Plausible.Nat.shrink m.toNat) }
Equations
- Plausible.UInt32.shrinkable = { shrink := fun (m : UInt32) => List.map UInt32.ofNat (Plausible.Nat.shrink m.toNat) }
Equations
- Plausible.UInt64.shrinkable = { shrink := fun (m : UInt64) => List.map UInt64.ofNat (Plausible.Nat.shrink m.toNat) }
Equations
- Plausible.USize.shrinkable = { shrink := fun (m : USize) => List.map USize.ofNat (Plausible.Nat.shrink m.toNat) }
Int.shrinkable operates like Nat.shrinkable but also includes the negative variants.
Equations
- One or more equations did not get rendered due to their size.
Equations
- One or more equations did not get rendered due to their size.
Equations
- One or more equations did not get rendered due to their size.
Shrink a list of a shrinkable type, either by discarding an element or shrinking an element.
Equations
- One or more equations did not get rendered due to their size.
Equations
- Plausible.ULift.shrinkable = { shrink := fun (u : ULift α) => List.map ULift.up (Plausible.Shrinkable.shrink u.down) }
Equations
- Plausible.String.shrinkable = { shrink := fun (s : String) => List.map String.mk (Plausible.Shrinkable.shrink s.toList) }
Equations
- Plausible.Array.shrinkable = { shrink := fun (xs : Array α) => List.map Array.mk (Plausible.Shrinkable.shrink xs.toList) }
Equations
- One or more equations did not get rendered due to their size.
Equations
- One or more equations did not get rendered due to their size.
Equations
- One or more equations did not get rendered due to their size.
Equations
- One or more equations did not get rendered due to their size.
Equations
- One or more equations did not get rendered due to their size.
Equations
- Plausible.Prop.sampleableExt = { proxy := Bool, proxyRepr := inferInstance, shrink := inferInstance, sample := inferInstance, interp := Coe.coe }
Equations
- One or more equations did not get rendered due to their size.
Equations
- One or more equations did not get rendered due to their size.
Equations
- One or more equations did not get rendered due to their size.
An annotation for values that should never get shrunk.
Equations
- Plausible.NoShrink α = α
Instances For
Equations
Instances For
Equations
Equations
- Plausible.NoShrink.repr = inst
Equations
Equations
Equations
- One or more equations did not get rendered due to their size.
#sample type, where type has an instance of SampleableExt, prints ten random
values of type type using an increasing size parameter.
#sample Nat
-- prints
-- 0
-- 0
-- 2
-- 24
-- 64
-- 76
-- 5
-- 132
-- 8
-- 449
-- or some other sequence of numbers
#sample List Int
-- prints
-- []
-- [1, 1]
-- [-7, 9, -6]
-- [36]
-- [-500, 105, 260]
-- [-290]
-- [17, 156]
-- [-2364, -7599, 661, -2411, -3576, 5517, -3823, -968]
-- [-643]
-- [11892, 16329, -15095, -15461]
-- or whatever
Equations
- Plausible.«command#sample_» = Lean.ParserDescr.node `Plausible.«command#sample_» 1022 (Lean.ParserDescr.binary `andthen (Lean.ParserDescr.symbol "#sample ") (Lean.ParserDescr.cat `term 0))