Coqでの背理法の一例
Software Foundations Rel.vより
Definition partial_function {X: Type} (R: relation X) := forall x y1 y2 : X, R x y1 -> R x y2 -> y1 = y2. Theorem le_not_a_partial_function : ~ (partial_function le). Proof. unfold not. unfold partial_function. intros. assert (0 = 1) as Nonsense. apply H with (x:=0) (y1:=0) (y2:=1). apply le_n. apply le_S. apply le_n. inversion Nonsense. Qed.
いきなり、0 = 1ってなんぞ????と思ったけど、
仮定H
H : forall x y1 y2 : nat, x <= y1 -> x <= y2 -> y1 = y2
の x = 0, y1 = 0, y2 = 1の場合のHの結論部分(y1 = y2)か。
背理法に限らず、forallを持つ定理/仮定の、特定の値の場合を新たな仮定として置きたい時に使えるな。なるほど。
=== 追記 ===
これってでも、背理法じゃねーよな。
前提のFalseからの爆発原理を使った普通の証明だ。
Coqは直観主義論理を使用した証明器なので、背理法や二重否定はビルトインされてない。そうな。Definitionで追加したり、Classic Moduleをインポートすれば使えるらしいが。
=== 追記終り ===
しかし、SoftwareFoundationsも改訂されて、Rel.vが、Prop.vやSflib.vの章の前に置かれるようになったのに、Require Exportしてるのが、前のSflibのままだな。
それに、total_relationは、Logic.vじゃなくて、この後の章のProp.vで定義されてるぞ???
この辺もさらに修正ありそうだな。