1
1
/- # plausible
2
2
3
- `plausible` は、証明しようとしているゴールが間違っていないかチェックし 、反例を見つけるとエラーで警告するタクティクです。 -/
3
+ `plausible` は、証明しようとしているゴールが間違っていないかランダムに例を生成してチェックし 、反例を見つけるとエラーで警告するタクティクです。 -/
4
4
import Plausible
5
5
6
+ section --#
7
+
6
8
variable (a b : Nat)
7
9
8
10
/-- error: Found a counter-example! -/
@@ -12,10 +14,9 @@ variable (a b : Nat)
12
14
13
15
sorry
14
16
17
+ end --#
15
18
/-
16
- ## 反例が見つからない時
17
-
18
- 100 個のテストケースでテストしてOKならエラーにならないのですが、途中でギブアップした場合はエラーになります。-/
19
+ 100 個のテストケースでテストして反例が見つからなかった場合、ギブアップして [ `sorry` ] (./Sorry.md) と同様にはたらきます。-/
19
20
20
21
/--
21
22
warning: Gave up after failing to generate values that fulfill the preconditions 100 times.
@@ -25,3 +26,91 @@ warning: declaration uses 'sorry'
25
26
#guard_msgs (warning) in
26
27
example (a : Nat) : a ≠ a → a ≤ 1 := by
27
28
plausible
29
+
30
+ /- ## 引数
31
+ 引数として、オプションを渡すことができます。
32
+
33
+ ### numInst
34
+
35
+ `numInst` を設定すると、ギブアップするまでに行うテストの回数を指定することができます。
36
+ -/
37
+
38
+ /--
39
+ warning: Gave up after failing to generate values that fulfill the preconditions 10 times.
40
+ ---
41
+ warning: declaration uses 'sorry'
42
+ -/
43
+ #guard_msgs (warning) in
44
+ example (a : Nat) : a ≠ a → a ≤ 1 := by
45
+ plausible (config := { numInst := 10 })
46
+
47
+ /- ## カスタマイズ
48
+
49
+ 組み込みではない、自作の型に対して `plausible` は準備なしには使うことができません。
50
+ -/
51
+
52
+ open Plausible
53
+
54
+ /-- 自前で `Nat` を模倣して定義した型 -/
55
+ inductive MyNat where
56
+ | zero : MyNat
57
+ | succ : MyNat → MyNat
58
+ deriving Repr
59
+
60
+ #guard_msgs (drop warning) in --#
61
+ example : ∀ (a b : MyNat), a = b := by
62
+ -- `plausible` は最初使うことができない
63
+ fail_if_success plausible
64
+
65
+ sorry
66
+
67
+ /- ここで定義した `MyNat` のような自作の型に対して `plausible` を使用するためには、いくつかのステップがあります。 -/
68
+
69
+ /- ### 1. Shrinkable クラスのインスタンスにする
70
+
71
+ `plausible` が反例を見つけたときに、「より小さな反例を見つける」ことができるようにするために、`Shrinkable` 型クラスのインスタンスを実装する必要があります。
72
+ -/
73
+
74
+ /-- 引数よりも小さい `MyNat` の項のリストを返す -/
75
+ def MyNat.shrink : MyNat → List MyNat
76
+ | zero => []
77
+ | succ n => n :: n.shrink
78
+
79
+ instance : Shrinkable MyNat where
80
+ shrink := MyNat.shrink
81
+
82
+ /- ### 2. SampleableExt クラスのインスタンスにする
83
+
84
+ `plausible` はテストするための要素をランダムに生成します。その方法を指定するのが `SampleableExt` 型クラスです。
85
+ -/
86
+
87
+ /-- 組み込みの自然数を `MyNat` に変換する -/
88
+ def MyNat.ofNat : Nat → MyNat
89
+ | 0 => zero
90
+ | n + 1 => succ (ofNat n)
91
+
92
+ open SampleableExt in
93
+
94
+ instance : SampleableExt MyNat := mkSelfContained do
95
+ let x ← SampleableExt.interpSample Nat
96
+ return MyNat.ofNat x
97
+
98
+ /- `SampleableExt` 型クラスのインスタンスであることは、`#sample` コマンドで確認できます。-/
99
+
100
+ #sample MyNat
101
+
102
+ /- ### 3. 決定可能にする
103
+
104
+ `plausible` でテストが行えるようにするためには、テスト対象の主張が決定可能(`Decidable` 型クラスのインスタンス)である必要があります。
105
+ -/
106
+
107
+ -- `MyNat` 同士の比較を決定可能にする
108
+ deriving instance DecidableEq for MyNat
109
+
110
+ /- 以上の準備で `plausible` が使えるようになります。 -/
111
+
112
+ /-- error: Found a counter-example! -/
113
+ #guard_msgs in
114
+ example : ∀ (a b : MyNat), a = b := by
115
+ -- `plausible` は最初使うことができない
116
+ plausible (config := { quiet := true })
0 commit comments