2011-11-01 97 views
19

[我不知道這是適當的堆棧溢出,但也有許多其他Coq的問題,這裏,所以也許有人可以提供幫助。]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 = true 

然後rewrite <- H.應用:

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

,很明顯的證明是如何成功的。

我可以看到如何以機械方式操作符號,我到達了證明。沒關係。但是我被「意義」所困擾。特別是,我如何在證明中間有false = true

看來我正在用矛盾進行某種爭論,但我不確定是什麼。我覺得我一直在盲從,遵守規則,不知何故到達了我無意中打字的地步。

我在做什麼以上?

我希望問題很清楚。

+1

你可以嘗試使用['discriminate'](http://www.fing.edu.uy/inco/grupos/mf/man/Coq/node.1.2.8.html)。 (我看到這是一箇舊帖子) – guest

回答

16

一般來說,當你在一個定理證明器中做案例分析時,很多案例歸結爲「不可能發生」。例如,如果您證實了整數的一些事實,則可能需要對整數i是正數,零還是負數進行個案分析。但是在你的背景下可能還有其他假設,或者你的目標的某個部分,與其中一個案例相矛盾。例如,你可以從前面的斷言中知道,i永遠不會是負面的。

然而Coq並不那麼聰明。所以你仍然必須通過實際上表明這兩個矛盾的假設可以被合併爲一個荒謬的證明並因此證明你的定理的機制。

想想它像計算機程序:

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 y減少到任何y爲假,因此不可能是真的)。所以你用唯一可以支配的東西(即H)轟擊了球門,你的新目標是false = andb false c

所以你應用了一個荒謬的假設,試圖達到一個荒謬的目標。你看,你最終會得到一些你可以通過反身性表現出來的東西。 QED。

UPDATE形式上,這是發生了什麼事。

回想一下,Coq中的每個歸納定義都帶有歸納原理。以下是誘導原則平等類型和False命題(相對於bool類型的術語false):

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證明,我可以給你任何提議P的證明。

eq的歸納原理比較複雜。我們認爲它侷限於bool。並具體到false。它說:

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

所以如果你開始與一些命題P(b)依賴於一個布爾b,和你有P(false)證明,那麼對於任何其他布爾y等於false,你的證據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的歸納原理,我們有:如果你給我一個false = true的證明,我可以證明任何命題。

所以回到andb_true_elim1。我們有一個假設Hfalse = true。我們想要證明某種目標。正如我上面所顯示的那樣,存在一個證明術語,可以將證據false = true變成任何你想要的證明。所以特別是Hfalse = true的證明,所以你現在可以證明你想要的任何目標。

這種策略基本上是構建證明術語的機器。

+0

謝謝,這很有道理,但我仍然不明白的是,如何將兩個「錯誤」或「荒謬」的事情聯繫起來,使事情「正確」。我可以看到它的工作 - 證明出來了 - 但爲什麼它應該起作用?爲什麼一件荒唐的事情以某種方式取消了另一件荒唐的事情,它會一直這樣工作嗎?似乎有什麼「更深」,我仍然失蹤?我是否假設了一些矛盾,然後表明這確實是矛盾的? –

+1

@andrewcooke你在這裏有什麼不是兩件錯誤的事情,而是兩件矛盾的事情。你的假設*作爲一個整體*是自相矛盾的。更確切地說,你的假設整體意味着一個虛假的陳述,因此你可以從這些假設中證明任何東西(包括你的目標)。假設可能暗含虛假陳述的唯一方式是假設沒有辦法使假設成立。 – Gilles

+0

所以我可以輸入「Admit」。而不是重寫和證明會一樣好? –

6

true = false是一個等同於兩個不同布爾值的語句。由於這些值是不同的,這個陳述顯然是不可證明的(在空白的情況下)。

考慮到你的證據:你到達目標是false = true的階段,很明顯你不能證明它......但問題是你的背景(假設)也是矛盾的。例如,當你進行案例分析時,這種情況經常發生,其中一種情況與你的其他假設相矛盾。

+0

謝謝。與其他答覆一樣,這是有道理的,但我仍然不明白爲什麼兩個相互矛盾的事情「相互抵消」。我可以看到它發生了,但感覺必須有一些潛在的原因「爲什麼」......?矛盾總是成對出現嗎?如果是這樣,那麼原理是什麼呢? –

+0

更正:在空白情境下顯然不可證明。 –

+0

@RobinGreen:的確,這就是我的想法。澄清答案;謝謝。 – akoprowski

1

我意識到這是舊的,但我想澄清一些落後Lambdageek的回答直覺的(如果有人發現了這一點)

我注意到,關鍵似乎是,我們定義一個函數F:bool->Prop不同每個點的值(即true => Truefalse => 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

這意思是,我們所使用的基本屬性是定義F的能力,這是由遞歸原理布爾給出bool_rect

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

通過設置P (b:bool) := b=>Prop,那麼這是相同的作爲

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

在這裏我們輸入TrueFalse,讓我們的功能F