Chứng minh định lý trong Coq


10

Lý lịch

Tôi đang học hỗ trợ, Coq, một mình. Cho đến nay, tôi đã hoàn thành việc đọc Coq của Yves Bertot trong một vội vàng . Bây giờ, mục tiêu của tôi là chứng minh một số kết quả cơ bản liên quan đến các số tự nhiên, đỉnh cao là thuật toán phân chia. Tuy nhiên, tôi đã gặp phải một số thất bại trên con đường hướng tới mục tiêu đó. Cụ thể, hai kết quả sau đây đã chứng minh (ý định chơi chữ) khó chứng minh ở Coq hơn tôi tưởng tượng ban đầu. Trên thực tế, tôi đã, sau nhiều nỗ lực không có kết quả, đã dùng đến việc chứng minh chúng bằng tay (như hình dưới đây). Điều này rõ ràng không giúp tôi trở nên thành thạo hơn trong việc xử lý Coq; đó là lý do tại sao tôi chuyển sang diễn đàn này Tôi hy vọng rằng ai đó trên trang web này có thể và sẵn sàngđể giúp tôi dịch các bằng chứng của mình dưới đây thành một bằng chứng mà Coq chấp nhận. Tất cả sự giúp đỡ được trân trọng!

Định lý A

Với mọi x,yN

x<S(y)x<yI(N,x,y)
Chứng minh:

Giả sử . Do đó có một z N với I ( N , x + S ( z ) , S ( y ) ) Do đó bởi (Peano 1b và 3) I ( N , x + z , y )x<S(y)zN

(*)I(N,x+S(z),S(y))
I(N,x+z,y)

Xác định một vị

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

Nó là đủ để hiển thị . Chúng tôi chứng minh điều này bằng cách cảm ứng trên z . Để xem Q ( 0 ) , không phải ethat nếu I ( N , x + 0 , y ) giữ thì I ( N , x , y ) là đúng bởi Peano 1a. Do đó, x < y tôi ( n , x , y ) . Bây giờ, chúng tôi chứng minh Q ( S ( v )Q(z)zQ(0)I(N,x+0,y)I(N,x,y)x<yI(n,x,y) : Giả sử I ( N , x + S ( v ) , y ) . Từ định nghĩa này, chúng ta có x < y và do đó x < y tôi ( N , x , y ) cũng trong trường hợp này. Cuối cùng, tiên đề thứ năm Peano của cho Q ( z ) ( * ) chúng tôi nhận x < y tôi ( N , x , yQ(S(v))I(N,x+S(v),y)x<yx<yI(N,x,y)Q(z)() . x<yI(N,x,y)

()

Định lý B

Đối với tất cả x < y tôi ( N , x , y ) y < x Chứng minh:x,yN

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

Nếu thì ¬ I ( N , x , y ) theo định nghĩa, và nếu x > y thì ¬ I ( N , x , y ) cũng theo định nghĩa. Nếu x > yy > x thì bằng độ xuyên sáng và tính phản xạ, chúng ta có I ( N , x , y ) , đó là một mâu thuẫn. Do đó, không có nhiều hơn một trong những tuyên bố là đúng.x<y¬I(N,x,y)x>y¬I(N,x,y)x>y y>xI(N,x,y)

Chúng tôi giữ cố định và quy nạp trên x . Khi tôi ( N , 0 , y ) chúng ta có 0 < y tôi ( N , 0 , y ) cho tất cả các y , trong đó chứng minh các trường hợp cơ sở. Tiếp theo, giả sử định lý giữ cho x ; bây giờ chúng tôi muốn chứng minh định lý cho S ( x ) . Từ trichotomy cho x , có ba trường hợp: x < y , I ( N , xyxI(N,0,y)0<yI(N,0,y)yxS(x)x x > y . Nếu x > y , thì rõ ràng S ( x ) > y . Nếu I ( N , x , y ) , thì S ( x ) > y (dưới dạng S ( x ) > x với mọi x N ). Cuối cùng, giả sử x < y Sau đó, theo định lý A ta có S ( x )x<y,I(N,x,y)x>yx>yS(x)>yI(N,x,y)S(x)>yS(x)>xxNx<y hoặc I ( N , S ( x ) , y ) và trong cả hai trường hợp chúng ta đã hoàn thành. S(x)<yI(N,S(x),y)

()

Các định lý mà tôi muốn chứng minh, có thể được trình bày như sau trong Coq.

Bổ đề less_lem (xy: N): less x (succ y) -> hoặc (less xy) (IN xy).

Định lý Ntrichotomy: (forall xy: N, hoặc (less xy) (hoặc (IN xy) (less yx))).

Kết quả hữu ích

Ở đây, tôi đã thu thập một số kết quả mà tôi đã xác định và chứng minh cho đến thời điểm này. Đây là những cái mà tôi đề cập ở trên. * Đây là mã mà tôi đã quản lý để viết cho đến nay, lưu ý rằng hầu hết bao gồm các định nghĩa. *

(* 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
Để hiểu bạn đã đi được bao xa, sẽ rất hữu ích nếu bạn đăng mã Coq của mình cho đến nay, để chúng tôi có thể tải nó và kiểm tra xem những gì chúng tôi đề xuất có hoạt động cho định nghĩa của bạn không.
Gilles 'SO- ngừng trở nên xấu xa'

1
Một vài ý kiến ​​và làm rõ các câu hỏi: - Liệu mục đích của bạn chỉ là sử dụng phương trình cú pháp ("=" trong Coq) thay vì I (N, x, y) là đủ? Có một lý do để sử dụng 'hoặc' theo cách bạn đã xác định nó? Coq (tốt, các thư viện cơ bản cho Coq) có cách thể hiện sự phân biệt logic hợp lý tạo điều kiện cho các khía cạnh tốt đẹp nhất định của bằng chứng. Tương tự như vậy, có một cách để xác định "ít hơn" có thể phù hợp hơn với bạn. Cuối cùng, bạn có thể muốn xem các chương đầu của Cơ sở phần mềm . Trong khi kết thúc cuốn sách ...
Luke Mathieson

... là về việc xác minh các chương trình, v.v., khởi đầu là một giới thiệu khá hay về Coq và có các định lý giống như các định lý mà bạn có được như các bài tập và ví dụ. Nó miễn phí và thực tế tất cả được viết dưới dạng tập lệnh Coq, vì vậy bạn có thể thực hiện các bài tập và biên dịch chúng khi bạn đọc qua. Đối với những gì bạn đang làm ở đây, có các bit và phần thú vị trong các chương Cơ bản, Cảm ứng, Prop và Logic - và có lẽ một số phụ thuộc từ các bit nằm giữa.
Luke Mathieson

1
Một lưu ý khác, Thm P5 (nguyên lý quy nạp) được tích hợp vào Coq ở dạng mạnh hơn (cảm ứng cấu trúc), vì vậy bạn không cần phải coi đó là một tiên đề.
Luke Mathieson

Tôi đã đăng mã Coq mà tôi đã viết cho đến nay.
dùng11942

Câu trả lời:


7

Coq tàn nhẫn hơn một chút so với bằng chứng trên giấy: khi bạn viết "và chúng tôi đã hoàn thành" hoặc "rõ ràng" trong một bằng chứng giấy, thường có nhiều việc phải làm để thuyết phục Coq.

Bây giờ tôi đã làm sạch mã của bạn một chút, trong khi cố gắng giữ nó theo cùng một tinh thần. Bạn có thể tìm thấy nó ở đây .

Một số nhận xét:

  1. Tôi đã sử dụng các kiểu dữ liệu và định nghĩa được xây dựng trong đó tôi nghĩ nó sẽ không ảnh hưởng đến ý định của bạn. Lưu ý rằng nếu tôi đã sử dụng đẳng thức tích hợp thay vì identityvà quan hệ "ít hơn" được xây dựng, bằng chứng sẽ dễ dàng hơn nhiều, vì nhiều bổ đề của bạn nằm trong cơ sở dữ liệu của các định lý đã biết, được kiểm tra tại mỗi cuộc gọi của

    auto with arith.
    
  2. Tôi đã sử dụng một số chiến thuật mà bạn có thể không biết, nhưng một siêu người dùng Coq "thực sự" sẽ có sẵn các chiến thuật mạnh mẽ hơn nhiều và viết ra các chiến thuật của riêng mình để đơn giản hóa công việc. Tôi luôn đề xuất CPDT là nơi để tìm hiểu về cách sử dụng chiến thuật một cách mạnh mẽ.

  3. inductionless

    x, m+(x+1)=n
    x, (x+m)+1=n
  4. Mặc dù bạn có thể nhận được câu trả lời cho các loại câu hỏi này tại đây, tôi khuyên bạn nên gửi tác phẩm của mình đến Câu lạc bộ Coq được tạo ra với mục đích rõ ràng là trả lời các loại câu hỏi này.


1
Câu trả lời tuyệt vời Cody! Thật tuyệt vời khi biết rằng có những người hào phóng như bạn ngoài kia, những người sẵn sàng giúp đỡ người khác khi cần. Tôi chân thành đánh giá cao nó! Tôi chắc chắn sẽ xem qua CPDT và Coq-Club; cả hai điều mà tôi có lẽ sẽ cần nhất trong tương lai gần khi tôi tiếp tục làm việc để chứng minh thuật toán phân chia trong Coq.
dùng11942

Cảm ơn! Lưu ý rằng điều này thường được gọi là "Phân chia Euclidian" và đã có mặt trong một số thư viện (mặc dù trên các số nguyên)
cody

Điều đó không làm tôi ngạc nhiên, các thư viện Coq mà tôi đã xem xét đã được lưu trữ rất tốt với các định nghĩa, bổ đề và định lý. Tôi sẽ tìm cách đăng cách tiếp cận của tôi với thuật toán phân chia Euclidian như một câu hỏi vào ngày mai muộn nhất.
dùng11942

4

Câu trả lời của Cody là tuyệt vời và đáp ứng câu hỏi của bạn về việc dịch bằng chứng của bạn sang Coq. Để bổ sung cho điều đó, tôi muốn thêm các kết quả tương tự, nhưng đã được chứng minh bằng cách sử dụng một tuyến khác, chủ yếu là minh họa một số bit của Coq và để chứng minh những gì bạn có thể chứng minh bằng cú pháp với rất ít công việc bổ sung. Đây không phải là một tuyên bố tuy nhiên đây là con đường ngắn nhất - chỉ là một con đường khác. Các bằng chứng chỉ bao gồm một bổ đề bổ trợ và chỉ dựa vào các định nghĩa cơ bản, tôi không đưa ra phép cộng, phép nhân hoặc bất kỳ thuộc tính nào của chúng, hoặc tính mở rộng chức năng và các tiên đề Peano duy nhất là một dạng đơn giản của <= b -> a + c <= b + c trong bổ đề của người trợ giúp (chỉ với c = 1) và cảm ứng cấu trúc, đi kèm với các loại quy nạp miễn phí.

Giống như Cody, nơi tôi nghĩ nó không có gì khác biệt, tôi đã sử dụng các loại được xác định trước, v.v., vì vậy trước khi chứng minh, tôi sẽ mô tả chúng:

  • Tôi đã sử dụng loại nat được xây dựng cho các số tự nhiên, có (định nghĩa chính xác) với định nghĩa giống như của bạn:

Cảm ứng nat: Đặt: = O: nat | S: nat -> nat

  • Tôi đã sử dụng tích hợp le và lt với giá trị nhỏ hơn hoặc bằng và nhỏ hơn tương ứng, có các tốc ký ký hiệu "<=" và "<" để dễ đọc. Chúng được định nghĩa:

Cảm ứng le: nat -> nat -> Prop: =
| le_n: forall n, le nn
| le_S: forall nm, (le nm) -> (le n (S m)).

Định nghĩa lt (nm: nat): = le (S n) m.

  • Eq tích hợp (tốc ký "=") là đẳng thức cú pháp và hoạt động giống như "tôi" của bạn, với một hàm tạo chỉ nói bất cứ thứ gì đều bằng chính nó. Các tính chất đối xứng và bắc cầu là bằng chứng dễ dàng từ đó, nhưng chúng ta sẽ không cần chúng trong trường hợp này. Định nghĩa cho eq dưới đây có ký hiệu được tích hợp trong đó.

Eq quy nạp (A: Loại) (x: A): A -> Prop: = eq numfl: x = x

  • Cuối cùng, tôi đã sử dụng mệnh đề hoặc (tốc ký "\ /" - đó là dấu gạch chéo ngược), có hai hàm tạo, về cơ bản là bạn có bằng chứng cho đối số bên trái hoặc đối số bên phải. Coq cũng có một số chiến thuật tốc ký, trái và phải, có nghĩa là "áp dụng or_introl" và "áp dụng or_intror" tương ứng.

Cảm ứng hoặc (AB: Prop): Prop: =
or_introl: A -> A / B | or_intror: B -> A / B

Những gì bây giờ là bằng chứng của tôi, về nguyên tắc, nếu đánh dấu không cản trở, bạn sẽ có thể cắt và dán nó vào tệp Coq .v và nó sẽ hoạt động. Tôi đã bao gồm các nhận xét để lưu ý các bit thú vị, nhưng chúng nằm trong các dấu phân cách (* *), vì vậy bạn không cần phải xóa chúng.

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.

Một câu trả lời tuyệt vời khác! Tôi thực sự biết ơn bạn vì thời gian và công sức bạn đã bỏ ra để trả lời câu hỏi của tôi.
dùng11942
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.