Teorema Prove in Coq


10

sfondo

Sto imparando l'assistenza, Coq, da solo. Finora ho completato la lettura del Coq in a Hurry di Yves Bertot . Ora, il mio obiettivo è quello di dimostrare alcuni risultati di base riguardanti i numeri naturali, culminando con il cosiddetto algoritmo di divisione. Tuttavia, ho riscontrato alcune battute d'arresto nel mio cammino verso quell'obiettivo. In particolare, i due seguenti risultati si sono dimostrati (gioco di parole intenzionale) più difficili da dimostrare in Coq di quanto immaginassi inizialmente. In effetti, dopo molti tentativi infruttuosi, ho fatto ricorso a dimostrarli a mano (come mostrato di seguito). Ciò chiaramente non mi sta aiutando a diventare più competente nella gestione di Coq; ecco perché mi rivolgo a questo forum. La mia speranza è che qualcuno su questo sito sia capace e dispostoper aiutarmi a tradurre le mie prove di seguito in una prova che Coq accetta. Tutto l'aiuto è sinceramente apprezzato!

Teorema A

Per tutte le \ begin {equazione} x <S (y) \ subset x <y \ lor \ text {I} (N, x, y) \ end {equation} Prova:x < S ( y ) x < y I ( N , x , y )x,yN

x<S(y)x<yI(N,x,y)

Supponiamo che x<S(y) . Quindi c'è una zN con

(*)I(N,x+S(z),S(y))
Quindi di (Peano 1b e 3)
I(N,x+z,y)

Definisci un predicato

Q(u):=(I(N,x+u,y)x<yI(N,x,y)

È sufficiente mostrare . Lo dimostriamo per induzione su . Per vedere , non ethat se contiene quindi è vero per Peano 1a. Pertanto, . Ora, dimostriamo : Supponiamo . Da questa definizione abbiamo e quindi anche in questo caso. Infine, il quinto assioma di Peano dà e per otteniamo . z Q ( 0 ) I ( N , x + 0 , y ) I ( N , x , y ) x < y I ( n , x , y ) Q ( S ( v ) ) I ( N , x + S ( v ) , y ) x <Q(z)zQ(0)I(N,x+0,y)I(N,x,y)x<yI(n,x,y)Q(S(v))I(N,x+S(v),y)x < y I ( N , x , y ) Q ( z ) ( ) x < y I ( N , x , y )x<yx<yI(N,x,y)Q(z)()x<yI(N,x,y)

()

Teorema B

Per tutte le Prova:x < y I ( N , x , y ) y < xx,yN

x<yI(N,x,y)y<x

Se quindi per definizione, e se quindi anche per definizione. Se e quindi per transitività riflessività e, abbiamo , che è una contraddizione. Di conseguenza, non più di una delle affermazioni è vera.x<y¬I(N,x,y)x>y¬I(N,x,y)x>y y>xI(N,x,y)

Manteniamo fissi e induciamo su . Quando abbiamo per tutti , il che dimostra il caso base. Quindi, supponiamo che il teorema valga per ; ora vogliamo dimostrare il teorema di . Dalla tricotomia per , ci sono tre casi: e . Se , quindi chiaramente . Se , quindi (come per tutti ). Infine, supponiamo cheyxI(N,0,y)0<yI(N,0,y)yxS(x)xx<y,I(N,x,y)x>yx>yI ( N , x , y ) S ( x ) > y S ( x ) > x x N x < y S ( x ) < y I ( N , S ( x ) , y )S(x)>yI(N,x,y)S(x)>yS(x)>xxNx<yQuindi, per teorema A abbiamo o , e in entrambi i casi abbiamo finito. S(x)<yI(N,S(x),y)

()

I teoremi che desidero dimostrare, possono essere espressi come segue in Coq.

Lemma less_lem (xy: N): less x (succ y) -> o (less xy) (IN xy).

Teorema Ntricotomia: (forall xy: N, o (less xy) (o (IN xy) (less yx))).

Risultati utili

Qui, ho raccolto alcuni dei risultati che ho definito e dimostrato fino a questo punto. Questi sono quelli a cui mi riferisco sopra. * Questo è il codice che sono riuscito a scrivere finora, nota che la maggior parte consiste in definizioni. *

(* Sigma types *)


Inductive Sigma (A:Set)(B:A -> Set) :Set :=
  Spair: forall a:A, forall b : B a,Sigma A B.

Definition E (A:Set)(B:A -> Set)
  (C: Sigma A B -> Set)
  (c: Sigma A B)
  (d: (forall x:A, forall y:B x, 
      C (Spair A B x y))): C c :=

match c as c0 return (C c0) with
| Spair a b => d a b
end. 


(* Binary sum type *)

Inductive sum' (A B:Set):Set := 
inl': A -> sum' A B | inr': B -> sum' A B.

Print sum'_rect.

Definition D (A B : Set)(C: sum' A B -> Set)
(c: sum' A B)
(d: (forall x:A, C (inl' A B x)))
(e: (forall y:B, C (inr' A B y))): C c :=

match c as c0 return C c0 with
| inl' x => d x
| inr' y => e y
end.

(* Three useful finite sets *)

Inductive N_0: Set :=.

Definition R_0
  (C:N_0 -> Set)
  (c: N_0): C c :=
match c as c0 return (C c0) with
end.

Inductive N_1: Set := zero_1:N_1.

Definition R_1 
  (C:N_1 -> Set)
  (c: N_1)
  (d_zero: C zero_1): C c :=
match c as c0 return (C c0) with
  | zero_1 => d_zero
end.

Inductive N_2: Set := zero_2:N_2 | one_2:N_2.

Definition R_2 
  (C:N_2 -> Set)
  (c: N_2)
  (d_zero: C zero_2)
  (d_one: C one_2): C c :=
match c as c0 return (C c0) with
  | zero_2 => d_zero
  | one_2  => d_one
end.


(* Natural numbers *)

Inductive N:Set :=
zero: N | succ : N -> N.

Print N. 

Print N_rect.

Definition R 
  (C:N -> Set)
  (d: C zero)
  (e: (forall x:N, C x -> C (succ x))):
  (forall n:N, C n) :=
fix F (n: N): C n :=
  match n as n0 return (C n0) with
  | zero => d
  | succ n0 => e n0 (F n0)
  end.

(* Boolean to truth-value converter *)

Definition Tr (c:N_2) : Set :=
match c as c0 with
  | zero_2 => N_0
  | one_2 => N_1
end.

(* Identity type *)

Inductive I (A: Set)(x: A) : A -> Set :=
r :  I A x x.

Print I_rect.

Theorem J 
  (A:Set)
  (C: (forall x y:A, 
              forall z: I A x y, Set))
  (d: (forall x:A, C x x (r A x)))
  (a:A)(b:A)(c:I A a b): C a b c.
induction c.
apply d.
Defined.

(* functions are extensional wrt
  identity types *)

Theorem I_I_extensionality (A B: Set)(f: A -> B):
(forall x y:A, I A x y -> I B (f x) (f y)).
Proof.
intros x y P.
induction P.
apply r.
Defined.


(* addition *)

Definition add (m n:N) : N 
 := R (fun z=> N) m (fun x y => succ y) n.

(* multiplication *)

Definition mul (m n:N) : N 
 := R (fun z=> N) zero (fun x y => add y m) n.


(* Axioms of Peano verified *)

Theorem P1a: (forall x: N, I N (add x zero) x).
intro x.
(* force use of definitional equality
  by applying reflexivity *)
apply r.
Defined.


Theorem P1b: (forall x y: N, 
I N (add x (succ y)) (succ (add x y))).
intros.
apply r.
Defined.


Theorem P2a: (forall x: N, I N (mul x zero) zero).
intros.
apply r.
Defined.


Theorem P2b: (forall x y: N, 
I N (mul x (succ y)) (add (mul x y) x)).
intros.
apply r.
Defined.

Definition pd (n: N): N :=
R (fun _=> N) zero (fun x y=> x) n.

(* alternatively
Definition pd (x: N): N :=
match x as x0 with
  | zero => zero
  | succ n0 => n0
end.
*)

Theorem P3: (forall x y:N, 
I N (succ x) (succ y) -> I N x y).
intros x y p.
apply (I_I_extensionality N N pd (succ x) (succ y)).
apply p.
Defined.

Definition not (A:Set): Set:= (A -> N_0).

Definition isnonzero (n: N): N_2:=
R (fun _ => N_2) zero_2 (fun x y => one_2) n.


Theorem P4 : (forall x:N, 
not (I N (succ x) zero)).
intro x.
intro p.

apply (J N (fun x y z => 
    Tr (isnonzero x) -> Tr (isnonzero y))
    (fun x => (fun t => t)) (succ x) zero)
.
apply p.
simpl.
apply zero_1.
Defined.

Theorem P5 (P:N -> Set):
P zero -> (forall x:N, P x -> P (succ x))
   -> (forall x:N, P x).
intros base step n.
apply R.
apply base.
apply step.
Defined.

(* I(A,-,-) is an equivalence relation *)

Lemma Ireflexive (A:Set): (forall x:A, I A x x).
intro x.
apply r.
Defined.

Lemma Isymmetric (A:Set): (forall x y:A, I A x y -> I A y x).
intros x y P.
induction P.
apply r.
Defined.

Lemma Itransitive (A:Set): 
(forall x y z:A, I A x y -> I A y z -> I A x z).
intros x y z P Q.
induction P.
assumption.
Defined.


Lemma succ_cong : (forall m n:N, I N m n -> I N (succ m) (succ n)).
intros m n H.
induction H.
apply r.
Defined.

Lemma zeroadd: (forall n:N, I N (add zero n) n).
intro n.
induction n.
simpl.
apply r.
apply succ_cong.
auto.

Defined.

Lemma succadd: (forall m n:N, I N (add (succ m) n) (succ (add m n))).
intros.
induction n.
simpl.
apply r.
simpl.
apply succ_cong.
auto.

Defined.

Lemma commutative_add: (forall m n:N, I N (add m n) (add n m)).
intros n m; elim n.
apply zeroadd.
intros y H; elim (succadd m y).
simpl.
rewrite succadd.
apply succ_cong.
assumption.


Defined.

Lemma associative_add: (forall m n k:N, 
I N (add (add m n) k) (add m (add n k))).
intros m n k.
induction k.
simpl.
apply Ireflexive.
simpl.
apply succ_cong.
assumption.
Defined.

Definition or (A B : Set):= sum' A B.


Definition less (m n: N) :=
 Sigma N (fun z => I N (add m (succ z)) n).



Lemma less_lem (x y:N) : 
less x (succ y) -> or (less x y) (I N x y).
intro.
destruct H.
right.

(* Here is where I'm working right now *)

Defined.


Theorem Ntrichotomy: (forall x y:N, 
or (less x y) (or (I N x y) (less y x))).

3
Per capire quanto lontano hai, sarebbe utile se avessi pubblicato il tuo codice Coq finora, in modo che potessimo caricarlo e verificare che ciò che proponiamo funzioni per le tue definizioni.
Gilles 'SO- smetti di essere malvagio' il

1
Un paio di commenti e domande chiarenti: - Sarebbe sufficiente per i tuoi scopi usare solo l'uguaglianza sintattica ("=" in Coq) anziché I (N, x, y)? C'è un motivo per usare 'o' il modo in cui l'hai definito? Coq (beh, le librerie di base per Coq) hanno un modo di esprimere la disgiunzione logica che facilita alcuni aspetti carini delle prove. Allo stesso modo c'è un modo per definire "meno" che potrebbe essere più praticabile per te. A tal fine, potresti voler dare un'occhiata ai primi capitoli di Software Foundations . Mentre la fine del libro ...
Luke Mathieson,

... riguarda la verifica di programmi ecc., l'avvio è una buona introduzione a Coq e ha teoremi come quelli che hai come esercizi ed esempi. È gratuito e in realtà è tutto scritto come script Coq, quindi puoi fare gli esercizi e compilarli mentre stai leggendo. Per quello che stai facendo qui, ci sono pezzi interessanti nei capitoli Nozioni di base, Induzione, Prop e Logica - e probabilmente alcune dipendenze dai bit in mezzo.
Luke Mathieson,

1
Un'altra nota, Thm P5 (principio induttivo) è integrato in Coq in una forma più forte (induzione strutturale), quindi non è necessario prenderlo esplicitamente come un assioma.
Luke Mathieson,

Ho pubblicato il codice Coq che ho scritto finora.
user11942

Risposte:


7

Coq è un po 'più crudele delle prove cartacee: quando scrivi "e abbiamo finito" o "chiaramente" in una prova cartacea, spesso c'è molto altro da fare per convincere Coq.

Ora ho fatto un po 'di pulizia del tuo codice, mentre cercavo di mantenerlo nello stesso spirito. Puoi trovarlo qui .

Diverse osservazioni:

  1. Ho usato tipi di dati e definizioni integrati in cui pensavo che non avrebbe danneggiato il tuo intento. Nota che se avessi usato l'uguaglianza integrata anziché identitye la relazione "meno di" incorporata, le prove sarebbero state molto più facili, poiché molti dei tuoi lemmi si trovano nel database di teoremi noti, che vengono controllati ad ogni chiamata di

    auto with arith.
    
  2. Ho usato alcune tattiche di cui probabilmente non sei a conoscenza, ma un "vero" superutente di Coq avrebbe a portata di mano tattiche molto più potenti e avrebbe scritto le sue tattiche per semplificare il lavoro. Consiglio sempre CPDT come luogo per imparare a usare la tattica in modo efficace.

  3. Ho usato notazioni e tabulazioni per migliorare la leggibilità e costrutti incorporati come la corrispondenza e la inductiontattica per rendere le cose più facili da provare e ripensare. In particolare, la tua definizione di lessera difficile da lavorare, puoi vedere come l'ho leggermente modificata da all'equivalente (ma più facile da usare) questo tipo di "modifica della definizione" accade molto nelle prove formali.x , ( x + m ) + 1 = n

    x, m+(x+1)=n
    x, (x+m)+1=n
  4. Sebbene tu possa ottenere risposte a questo tipo di domande qui, ti consiglio vivamente di inviare il tuo lavoro al Coq-Club che è stato creato con lo scopo esplicito di rispondere a questo tipo di domande.


1
Ottima risposta Cody! È meraviglioso apprendere che ci sono persone generose come te là fuori, che sono disposte ad aiutare gli altri bisognosi. Lo apprezzo sinceramente! Sicuramente darò un'occhiata a CPDT e Coq-Club; entrambi di cui avrò molto probabilmente bisogno nel prossimo futuro mentre continuo a lavorare per dimostrare l'algoritmo di divisione in Coq.
user11942

Grazie! Si noti che questo è spesso chiamato "divisione euclidea" ed è già presente in alcune librerie (oltre gli interi)
cody

Non mi sorprende, le librerie di Coq che ho visto sono state notevolmente fornite di definizioni, lemmi e teoremi. Cercherò di pubblicare il mio approccio all'algoritmo della divisione euclidea come una domanda entro domani.
user11942

4

La risposta di Cody è eccellente e soddisfa la tua domanda sulla traduzione della prova in Coq. A complemento di questo, volevo aggiungere gli stessi risultati, ma ho provato usando una strada diversa, principalmente come illustrazione di alcuni frammenti di Coq e per dimostrare ciò che puoi dimostrare sintatticamente con pochissimo lavoro aggiuntivo. Questa non è un'affermazione, tuttavia, che questa è la strada più breve - solo una diversa. Le prove includono solo un lemma di supporto aggiuntivo e si basano solo su definizioni di base, non introduco addizione, moltiplicazione o alcuna delle loro proprietà o estensioni funzionali e gli unici assiomi di Peano sono una semplice forma di <= b -> a + c <= b + c nel lemma dell'helper (solo per c = 1) e nell'induzione strutturale, che viene fornita gratuitamente con tipi induttivi.

Come Cody, dove pensavo che non facesse alcuna differenza, ho usato tipi predefiniti ecc., Quindi prima della prova, descriverò quelli:

  • Ho usato il tipo nat incorporato per i numeri naturali, che ha (fino alla denominazione precisa) la stessa definizione della tua:

Induttivo nat: Set: = O: nat | S: nat -> nat

  • Ho usato il le e lt integrati per rispettivamente minore o uguale e minore di rispettivamente, che hanno shorthands notazionali "<=" e "<" per leggibilità. Sono definiti:

Le induttivo: nat -> nat -> Prop: =
| le_n: forall n, le nn
| le_S: forall nm, (le nm) -> (le n (S m)).

e

Definizione lt (nm: nat): = le (S n) m.

  • L'eq incorporato (abbreviazione "=") è l'uguaglianza sintattica e funziona allo stesso modo del tuo "io", con un costruttore che dice semplicemente che tutto è uguale a se stesso. Le proprietà simmetriche e transitive sono prove facili da lì, ma in questo caso non ne avremo bisogno. La definizione per eq di seguito ha la notazione incorporata in esso.

Eq induttivo (A: Tipo) (x: A): A -> Prop: = eq_refl: x = x

  • Infine, ho usato la proposizionale o (la scorciatoia "\ /" - che è barra rovesciata in avanti), che ha due costruttori, fondamentalmente che o hai prove per l'argomento di sinistra, o l'argomento di destra. Coq ha anche alcune tattiche abbreviate, sinistra e destra, che significano rispettivamente "applica or_introl" e "applica or_intror" rispettivamente.

Induttivo o (AB: Prop): Prop: =
or_introl: A -> A / B | or_intror: B -> A / B

Ciò che segue ora sono le mie prove, in linea di principio, se il markup non interferisce, dovresti essere in grado di tagliarlo e incollarlo in un file Coq .v e funzionerà. Ho incluso commenti per notare bit interessanti, ma sono nei delimitatori (* *), quindi non dovresti rimuoverli.

Theorem lt_or_eq: forall (n m : nat),
  n < S m -> n < m \/ n = m.
Proof.
(*
  This proof is just a case analysis on n and m, whether they're zero or
  a successor of something.
*)
destruct n as [|n']; destruct m as [|m']. 

(*n = 0, m = 0*)
intros.
  right. reflexivity.

(*n = 0, m = S m'*)
intros H.
  inversion H.
  inversion H1.
  left. unfold lt. constructor.
  (*The constructor tactic tries to match the goal to a constructor
    that's in the environment.*) 
  left. unfold lt. constructor. assumption.
  (*Assumption tries to match the goal to something that's in the
    current context*)

(*n = S n', m = 0
  This case is false, so we can invert our way out of it.*)
intros.
  inversion H. inversion H1.

(*n = S n', m = S m'*)
intros.
  inversion H.
    right. reflexivity.
    left. unfold lt. assumption.
Qed.


(*
  The following lemma with be useful in the proof of the trichotomy theorem,
  it's pretty obviously true, and easy to prove. The interesting part for
  anyone relatively new to Coq is that the induction is done on the
  hypothesis "a <= b", rather than on either a or b.
*)
Lemma a_le_b_implies_Sa_le_Sb: forall a b, a <= b -> S a <= S b.
Proof.
  intros a b Hyp.
  induction Hyp.
  constructor.
  constructor.
  apply IHHyp.
Qed.

(*
  The proof of the trichotomy theorem is a little more involved than the
  last one but again we don't use anything particularly tricky. 
  Other than the helper lemma above, we don't use anything other than the
  definitions.

  The proof proceeds by induction on n, then induction on m.  My personal
  feeling is that this can probably be shortened.  
*)
Theorem trich: forall (n m : nat),
  n < m \/ n = m \/ m < n.
Proof.
  induction n.
    induction m.
      right. left. reflexivity.
        inversion IHm.
          left. unfold lt. constructor. unfold lt in H. assumption.
          inversion H.
          left. unfold lt. subst. constructor.
          inversion H0.     
    induction m.
      assert (n < 0 \/ n = 0 \/ 0 < n).
      apply IHn.
      inversion H.
      inversion H0.
      inversion H0.
      right. right. subst. unfold lt. constructor.
      right. right. unfold lt. constructor. assumption.
      inversion IHm. unfold lt in H.
      left. unfold lt. constructor. assumption.
      inversion H; subst.
      left. unfold lt. constructor.
      inversion H0.
      right. left. reflexivity.
      right. right. apply lt_or_eq in H0.

      inversion H0.
      apply a_le_b_implies_Sa_le_Sb. assumption.
      subst. unfold lt. apply a_le_b_implies_Sa_le_Sb. assumption.
Qed.

(*
  The following is just to show what can be done with some of the tactics
  The omega tactic implements a Pressburger arithmetic solver, so anything
  with natural numbers, plus, multiplication by constants, and basic logic
  can just be solved. Not very interesting for practicing Coq, but cool to
  know.
*)

Require Import Omega.

Example trich' : forall (n m : nat),
  n < m \/ n = m \/ m < n.
Proof.
  intros.
  omega.
Qed.

Un'altra risposta meravigliosa! Ti sono veramente grato per il tempo e lo sforzo che hai dedicato a rispondere alla mia domanda.
user11942
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.