2011-11-01 25 views
19

[no estoy seguro de que esto es apropiado para el desbordamiento de pila, pero hay muchas otras preguntas Coq aquí, así que tal vez alguien puede ayudar.]¿Qué significa `true = false` en Coq?

estoy trabajando a través de las siguientes opciones en http://www.cis.upenn.edu/~bcpierce/sf/Basics.html#lab28 (justo debajo de donde se introduce la caja). Tenga en cuenta que soy un principiante en esto, y estoy trabajando en casa, no soy un estudiante.

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. 

y yo estoy mirando lo que hace la reescritura:

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

continuación, se aplica rewrite <- H.:

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

y está claro cómo la prueba tendrá éxito.

Puedo ver cómo en términos de manipulación de símbolos de forma mecánica, estoy llegando a una prueba. Esta bien. Pero estoy perturbado por el "significado". En particular, ¿cómo puedo tener false = true en medio de una prueba?

Parece que estoy haciendo una especie de discusión con las contradicciones, pero no estoy seguro de qué. Siento que he estado siguiendo ciegamente las reglas y de alguna manera he llegado a un punto en el que estoy escribiendo tonterías.

¿Qué hago haciendo arriba?

Espero que la pregunta sea clara.

+1

Puede intentar usar: ['discriminate'] (http://www.fing.edu.uy/inco/grupos/mf/man/Coq/node.1.2.8.html). (Veo que es una publicación anterior) – guest

Respuesta

16

Generalmente, cuando haces un análisis de caso en un probador de teoremas, muchos de los casos se reducen a "no puede suceder". Por ejemplo, si está probando algún hecho sobre los números enteros, puede necesitar hacer un análisis de caso de si el número entero i es positivo, cero o negativo. Pero puede haber otras hipótesis en su contexto, o quizás alguna parte de su objetivo, que sea contradictoria con uno de los casos. Puede saber por una afirmación anterior, por ejemplo, que i nunca puede ser negativo.

Sin embargo, Coq no es tan inteligente. De modo que todavía tiene que pasar por la mecánica de mostrar realmente que las dos hipótesis contradictorias se pueden unir en una prueba de absurdo y, por lo tanto, una prueba de su teorema.

Piense en ello como en un programa de ordenador:

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

El objetivo false = true es la "no puede suceder nunca". Pero no puedes simplemente afirmar tu salida en Coq. De hecho, tienes que poner un término de prueba.

Así que arriba, tienes que demostrar el objetivo absurdo false = true. Y lo único que tienes que trabajar es la hipótesis H: andb false c = true. Un momento de reflexión le mostrará que en realidad esta es una hipótesis absurda (porque andb false y se reduce a falso para cualquier y y, por lo tanto, no puede ser cierto). Entonces usted golpea el objetivo con lo único a su disposición (a saber, H) y su nuevo objetivo es false = andb false c.

Así que aplica una hipótesis absurda tratando de lograr un objetivo absurdo. Y he aquí que terminas con algo que realmente puedes mostrar por reflexividad. Qed.

ACTUALIZACIÓN Formalmente, esto es lo que está pasando.

Recuerde que cada definición inductiva en Coq viene con un principio de inducción. Estos son los tipos de los principios de inducción para la igualdad y la proposición False (en comparación con el término false de tipo bool):

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 

Ese principio de inducción para False dice que si me das una prueba de False, me puede darle una prueba de cualquier proposición P.

El principio de inducción para eq es más complicado. Consideremos que se limita a bool. Y específicamente a false. Dice:

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

Así que si comenzar con alguna proposición P(b) que depende de un valor lógico b, y usted tiene una prueba de P(false), entonces para cualquier otra booleano y que es igual a false, usted tiene una prueba de P(y).

Esto no suena terriblemente excitante, pero podemos aplicarlo a cualquier proposición P que queramos. Y queremos una particularmente desagradable.

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 

Simplificando un poco, lo que dice es True -> forall y : bool, false = y -> (if y then False else True).

Así que esto quiere una prueba de True y luego un booleano y que podemos elegir. Así que hagámoslo.

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 

Y aquí estamos: false = true -> False.

Combinando con lo que sabemos sobre el principio de inducción para False, tenemos: si me das una prueba de false = true, puedo probar cualquier proposición.

De nuevo a andb_true_elim1. Tenemos una hipótesis H que es false = true. Y queremos demostrar algún tipo de objetivo. Como he mostrado anteriormente, existe un término de prueba que convierte las pruebas de false = true en pruebas de lo que desee. Así que, en particular, H es una prueba de false = true, por lo que ahora puede probar cualquier objetivo que desee.

Las tácticas son básicamente maquinaria que construye el término de la prueba.

+0

gracias, eso tiene mucho sentido, pero lo que todavía no entiendo es cómo combinar dos cosas que son a la vez "incorrectas" o "absurdas" hace las cosas "bien". Puedo ver que funciona, sale la prueba, pero ¿por qué debería funcionar? ¿Por qué es que una cosa absurda de alguna manera cancela otra cosa absurda, y siempre funcionará de esa manera? Parece que hay algo "más profundo" que aún me falta. ¿Es que estoy asumiendo algo contradictorio y luego estoy demostrando que de hecho es contradictorio? –

+1

@andrewcooke Lo que tienes aquí no son dos cosas equivocadas, sino dos cosas contradictorias. Sus hipótesis * tomadas en conjunto * son contradictorias. más precisamente, sus hipótesis en conjunto implican una declaración falsa, y por lo tanto, puede probar cualquier cosa (incluido su objetivo) a partir de estas hipótesis. La única manera en que las hipótesis pueden implicar una declaración falsa es si no hay forma de que las hipótesis sean verdaderas. – Gilles

+0

así que podría escribir "Admitir". en lugar de la reescritura y la prueba sería igual de bueno? –

6

true = false es una afirmación que equipara dos valores booleanos diferentes. Como esos valores son diferentes, esta afirmación claramente no es demostrable (en el contexto vacío).

Considerando su prueba: llega a la etapa donde el objetivo es false = true, por lo que es evidente que no podrá probarlo ... pero lo cierto es que su contexto (suposiciones) también son contradictorias. Esto sucede a menudo, por ejemplo, cuando haces un análisis de casos y uno de los casos es contradictorio con tus otras suposiciones.

+0

gracias. como con la otra respuesta, esto tiene sentido, pero aún no entiendo por qué dos cosas contradictorias de alguna manera "se anulan mutuamente". Puedo ver que sucede, pero parece que debe haber alguna razón subyacente "¿por qué" ...? ¿Las contradicciones siempre aparecen en pares? si es así, ¿cuál es el principio que hace esto así? –

+0

Corrección: claramente no se puede demostrar _en el contexto vacío_. –

+0

@RobinGreen: de hecho, eso es lo que tenía en mente. Aclaró la respuesta; Gracias. – akoprowski

1

Comprendo que esto es viejo, pero quiero aclarar algo de la intuición detrás de la respuesta de Lambdageek (en caso de que alguien encuentre esto)

me di cuenta que el punto clave parece ser que definamos una función F:bool->Prop con diferentes valores en cada punto (es decir, true => True y false => False). Sin embargo, puede demostrarse fácilmente desde el principio de la inducción de la igualdad eq_ind la idea intuitiva de que

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

Pero esto, entonces significaría que asumir true=false tenemos True=False, pero ya sabemos True, derivamos False.

Lo que esto significa es que la propiedad fundamental que estamos utilizando es la capacidad de definir F, que viene dada por el principio de recursividad para bool, bool_rect:

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

estableciendo P (b:bool) := b=>Prop, entonces este es el mismo como

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

en el que la entrada True y False conseguir nuestra función F.

Cuestiones relacionadas