Finding counterexamples automatically using plausible #
A proposition can be tested by writing it out as:
example (xs : List Nat) (w : ∃ x ∈ xs, x < 3) : ∀ y ∈ xs, y < 5 := by plausible
-- ===================
-- Found problems!
-- xs := [0, 5]
-- x := 0
-- y := 5
-- -------------------
example (x : Nat) (h : 2 ∣ x) : x < 100 := by plausible
-- ===================
-- Found problems!
-- x := 258
-- -------------------
example (α : Type) (xs ys : List α) : xs ++ ys = ys ++ xs := by plausible
-- ===================
-- Found problems!
-- α := Int
-- xs := [-4]
-- ys := [1]
-- -------------------
example : ∀ x ∈ [1,2,3], x < 4 := by plausible
-- Success
In the first example, plausible is called on the following goal:
xs : List Nat,
h : ∃ (x : Nat) (H : x ∈ xs), x < 3
⊢ ∀ (y : Nat), y ∈ xs → y < 5
The local constants are reverted and an instance is found for
Testable (∀ (xs : List Nat), (∃ x ∈ xs, x < 3) → (∀ y ∈ xs, y < 5)).
The Testable instance is supported by instances of Sampleable (List Nat),
Decidable (x < 3) and Decidable (y < 5). plausible builds a
Testable instance step by step with:
- Testable (∀ (xs : List Nat), (∃ x ∈ xs, x < 3) → (∀ y ∈ xs, y < 5))
-: Sampleable (List xs)
- Testable ((∃ x ∈ xs, x < 3) → (∀ y ∈ xs, y < 5))
- Testable (∀ x ∈ xs, x < 3 → (∀ y ∈ xs, y < 5))
- Testable (x < 3 → (∀ y ∈ xs, y < 5))
-: Decidable (x < 3)
- Testable (∀ y ∈ xs, y < 5)
-: Decidable (y < 5)
Sampleable (List Nat) lets us create random data of type List Nat in a way that
helps find small counter-examples. Next, the test of the proposition
hinges on x < 3 and y < 5 to both be decidable. The
implication between the two could be tested as a whole but it would be
less informative. Indeed, if we generate lists that only contain numbers
greater than 3, the implication will always trivially hold but we should
conclude that we haven't found meaningful examples. Instead, when x < 3
does not hold, we reject the example (i.e. we do not count it toward
the 100 required positive examples) and we start over. Therefore, when
plausible prints Success, it means that a hundred suitable lists
were found and successfully tested.
If no counter-examples are found, plausible behaves like admit.
plausible can also be invoked using #eval:
#eval Plausible.Testable.check (∀ (α : Type) (xs ys : List α), xs ++ ys = ys ++ xs)
-- ===================
-- Found problems!
-- α := Int
-- xs := [-4]
-- ys := [1]
-- -------------------
For more information on writing your own Sampleable and Testable
instances, see Testing.Plausible.Testable.
plausible considers a proof goal and tries to generate examples
that would contradict the statement.
Let's consider the following proof goal.
xs : List Nat,
h : ∃ (x : Nat) (H : x ∈ xs), x < 3
⊢ ∀ (y : Nat), y ∈ xs → y < 5
The local constants will be reverted and an instance will be found for
Testable (∀ (xs : List Nat), (∃ x ∈ xs, x < 3) → (∀ y ∈ xs, y < 5)).
The Testable instance is supported by an instance of Sampleable (List Nat),
Decidable (x < 3) and Decidable (y < 5).
Examples will be created in ascending order of size (more or less)
The first counter-examples found will be printed and will result in an error:
===================
Found problems!
xs := [1, 28]
x := 1
y := 28
-------------------
If plausible successfully tests 100 examples, it acts like
admit. If it gives up or finds a counter-example, it reports an error.
For more information on writing your own Sampleable and Testable
instances, see Testing.Plausible.Testable.
Optional arguments given with plausible (config : { ... })
numInst(default 100): number of examples to test properties withmaxSize(default 100): final size argument
Options:
set_option trace.plausible.decoration true: print the proposition with quantifier annotationsset_option trace.plausible.discarded true: print the examples discarded because they do not satisfy assumptionsset_option trace.plausible.shrink.steps true: trace the shrinking of counter-exampleset_option trace.plausible.shrink.candidates true: print the lists of candidates considered when shrinking each variableset_option trace.plausible.instance true: print the instances oftestablebeing used to test the propositionset_option trace.plausible.success true: print the tested samples that satisfy a property
Equations
- One or more equations did not get rendered due to their size.