2011-11-01 9 views
19

[私は、これは、スタックオーバーフローのために適切であることを確認していないが、他の多くのコックの質問はので、おそらく誰かが助けることができるここにある。]Coqでは `true = false`はどういう意味ですか?

私は(念が導入された場合について)http://www.cis.upenn.edu/~bcpierce/sf/Basics.html#lab28から次を通じて働いています。私はこれで完全な初心者であり、自宅で働いています - 私は学生ではありません。

Theorem andb_true_elim1 : forall b c : bool, 
    andb b c = true -> b = true. 
Proof. 
    intros b c H. 
    destruct b. 
    Case "b = true". 
    reflexivity. 
    Case "b = false". 
    rewrite <- H. reflexivity. 
Qed. 

と私は書き換えが何をするかで探しています:

Case := "b = false" : String.string 
    c : bool 
    H : andb false c = true 
    ============================ 
    false = andb false c 

、それは証明が成功するかは明らかです:その後、

Case := "b = false" : String.string 
    c : bool 
    H : andb false c = true 
    ============================ 
    false = true 

rewrite <- H.が適用されます。

機械的な方法でシンボルを操作する方法で、私が証明に到着している様子を確認できます。それはいいです。しかし、私は "意味"に邪魔されています。特に、証明の途中でfalse = trueを取得するにはどうすればよいですか?

私は矛盾で何らかの議論をしているようですが、何がわかりません。私は盲目的にルールに従っているように感じ、ナンセンスを入力しているところに何とか到着しました。

私は上記のを行うですか?

私は質問がはっきりしていることを願っています。

+1

あなたは['discriminate'](http://www.fing.edu.uy/inco/grupos/mf/man/Coq/node.1.2.8.html)を試してみることができます。 (私はそれが古い投稿だと思う) – guest

答えて

16

一般に、定理証明者のケース分析を行うと、多くのケースが「起こり得ない」ということになります。たとえば、整数に関する事実を証明している場合は、整数iが正、ゼロ、または負の値であるかどうかのケース分析を行う必要があります。しかし、あなたの状況や、おそらくあなたの目標のいくつかの部分に、他の仮説があるかもしれません。それは、ケースの1つと矛盾しています。たとえば、iは否定できないという前の主張から知ることができます。

しかし、Coqはそれほどスマートではありません。だから、あなたはまだ2つの矛盾した仮説が一緒に馬鹿げた証拠に結びつくことができ、したがってあなたの定理の証明であることを実際に示している仕組みを理解しなければなりません。

は、コンピュータプログラムのようにそれについて考える:

switch (k) { 
    case X: 
    /* do stuff */ 
    break; 
    case Y: 
    /* do other stuff */ 
    break; 
    default: 
    assert(false, "can't ever happen"); 
} 

false = true目標は「今までに起こることができません」です。しかし、あなたはCoqであなたの方法を断言することはできません。あなたは実際に証拠用語を記入する必要があります。

上記のように、不合理な目標false = trueを証明する必要があります。あなたと一緒に作業しなければならない唯一のものは、偽物H: andb false c = trueです。瞬間の考えは、実際にはこれが不条理な仮説であることを示しています(andb false yyについてはfalseになり、おそらく真とは言えません)。だからあなたは自由に唯一のもの(つまりH)で目標を叩き、新しい目標はfalse = andb false cです。

あなたは不条理な目標を達成しようとするばかばかしい仮説を適用します。そして、あなたが実際に反射的に示すことのできるもので終わるのを見てください。 Qed。

更新日正に、ここでは何が起こっているのですか。

Coqのすべての帰納的定義には誘導原理があることを想起してください。

Check eq_ind. 
eq_ind 
    : forall (A : Type) (x : A) (P : A -> Prop), 
    P x -> forall y : A, x = y -> P y 
Check False_ind. 
False_ind 
: forall P : Prop, False -> P 

Falseのための誘導原理は、あなたが私にFalseの証拠を与えた場合と言う私は、:ここでは平等とFalse命題のための誘導の原則の種類は(タイプboolの用語falseではなく)ですどんな命題の証拠を与えることができるP

eqの誘導原理はより複雑です。それがboolに限定されているとしましょう。具体的にはfalseです。それは言う:

Check eq_ind false. 
eq_ind false 
: forall P : bool -> Prop, P false -> forall y : bool, false = y -> P y 

あなたはブールbに依存して、いくつかの命題P(b)で始まり、そしてあなたがP(false)の証拠を持っているのであれば、その後、falseに等しく、他のブールyのために、あなたが証拠を持っていますP(y)

これはひどく奇妙なことではありませんが、私たちが望むすべての命題Pに適用できます。そして、私たちは特に厄介なものを求めています。

Check eq_ind false (fun b : bool => if b then False else True). 
eq_ind false (fun b : bool => if b then False else True) 
: (fun b : bool => if b then False else True) false -> 
    forall y : bool, 
    false = y -> (fun b : bool => if b then False else True) y 

ビットを簡略化すると、True -> forall y : bool, false = y -> (if y then False else True)と表示されます。

したがって、これはTrueの証明と、私たちが選ぶブールyを求めています。そうしましょう。

Check eq_ind false (fun b : bool => if b then False else True) I true. 
eq_ind false (fun b : bool => if b then False else True) I true 
: false = true -> (fun b : bool => if b then False else True) true 

ここでは:false = true -> Falseです。

の誘導原理について私たちが知っているものと組み合わせると、あなたは私にfalse = trueの証明を与えれば、どんな命題も証明できます。

so back to andb_true_elim1。仮説Hfalse = trueです。そして私たちはある種の目標を証明したいと思っています。上に示したように、false = trueの証明をあなたが望むものの証明に変える証明項が存在します。したがって、特にHfalse = trueという証明であるため、あなたが望む目標を証明できるようになりました。

戦術は基本的に証明用語を構成する機械です。

+0

ありがとう、それは意味をなさないが、私がまだ理解していないのはどういうわけか "間違った"か "ばかげた"の2つのことを組み合わせることである。私はそれが動作することを見ることができます - 証拠が出てくる - しかし、なぜそれは動作する必要がありますか?それはなぜそんなに不条理な事が別のばかげたことを取り消し、それはいつもそのように働くのだろうか?それは私がまだ行方不明である "深い"何かがあるように思えますか?私は何か矛盾していると仮定して、それが本当に矛盾していることを示していますか? –

+1

@andrewcookeあなたがここにいるのは、2つの間違ったことではなく、2つの矛盾したことです。あなたの仮説*は全体としては*自己矛盾しています。より正確に言えば、あなたの仮説は全体として虚偽の陳述を意味するので、これらの仮説から何か(あなたの目標を含む)を証明することができます。仮説が虚偽の陳述を意味する唯一の方法は、仮説が真である方法がない場合です。 – Gilles

+0

だから私はちょうど同様に "認める"ことができます。書き換えの代わりに、証明は同じくらい良いでしょうか? –

6

true = falseは、2つの異なるブール値に等しいステートメントです。これらの値が異なるため、この文は明らかに証明できません(空の文脈では)。

ゴールがfalse = trueであるステージに到着したことを証明すると、明らかにそのことを証明できなくなります...しかし、あなたのコンテキスト(前提条件)も矛盾しています。これは、ケース分析を行うときによく起こります。ケースの1つは、他の前提と矛盾しています。

+0

他の回答と同じように、これは理にかなっていますが、私はまだ2つの矛盾した事がどうしても「互いに打ち消し合う」ことを理解していません。私はそれが起こることを見ることができますが、いくつかの根本的な理由があるに違いないと感じています "なぜ" ...?矛盾は常にペアで出現するのですか?もしそうなら、これを作る原理は何ですか? –

+0

修正:空のコンテキスト_では明らかに証明できません。 –

+0

@RobinGreen:確かに、それは私が心に留めていたことです。答えを明確にした。ありがとう。 – akoprowski

1

私は重要な点は、我々は異なると機能F:bool->Propを定義することであると考えられることに気づいた

(場合には、誰かがこれを見つけた)私はこれが古い実現が、私はLambdageekの答えの背後にある直観のいくつかを明確にしたいです各点の値(すなわち、true => Trueおよびfalse => False)。しかし、それは簡単に平等eq_indのための誘導原理から

forall A:Type, forall P:A->Prop, forall x y:A, (x=y) -> (P x = P y), 

その直感的な考えを示すことができる。しかし、これは、その後true=falseは、我々はTrue=Falseを持っているが、我々はTrueを知っているので、我々はFalseを引き出すと仮定していることを意味します。

これが意味することは、我々が使用している基本的なプロパティはブール値、bool_rectのための再帰原理で与えられるFを定義する機能、であるということです。そして、これは同じである、P (b:bool) := b=>Propを設定することにより、

forall P:bool -> Type, P true -> P false -> (forall b:bool, P b) 

我々入力TrueFalseが私たちの機能Fを取得する

Prop -> Prop -> (forall b:bool, Prop), 

として。

関連する問題