探索歸納的奧祕


從初中開始我們就使用數學歸納法證明數學題,我們首先需要確定歸納的基礎,在n=1或n=1,n=2時式子成立,然後在此基礎上假設n=k-1時所證內容成立,從而推導出n=k時成立,命題得證,實際上歸納是數學的基礎之一,我們利用歸納定義了自然數,定義了布爾表達式,在機器證明系統中歸納法也有着不可磨滅的作用,本文將介紹集合論中歸納法的應用,以及歸納法在coq證明系統中的應用。
首先要明確歸納法的核心歸納基礎構造算子

集合論中的歸納法

這裏的歸納法都基於集合,那麼我們先從集合的構造講起(這部分內容在集合論(二)中有涉及,但是筆者覺得和induction結合在一起更容易理解)

集合的構造——從有限到無限

從1到自然數

😈 Power Set
對於每個集合S,存在一個集合,該集合的元素正好是集合S的子集合,稱之爲S的冪集合,記爲℘(S),或者2^s
冪集合的基數
😈 自然數的構造
|O:base
|S:nat→nat
比如這樣一種歸納:

Inductive nat:Set:=
|Lilghost
|Darling (n:nat).
Check Darling(Lilghost).

利用空集合構造自然數
在這裏插入圖片描述
在這裏插入圖片描述

從序偶到多元組

😈 序偶是兩個元素組成的對象,(第一分量,第二分量)
將序偶理解爲(a,b)=(a,{a,b})表示兩個元素不等價,不在一個次元
證明(a,b)=(a’,b’)的充要條件(這裏僅證明必要性)

Theorem equl:forall a b m n:nat,
a=m->b=n->(a,b)=(m,n).
Proof.
  intros.
  rewrite H0.
  rewrite H.
  reflexivity.
Qed.

😈 n-tuple n元組
多元函數運用到高階函數(維基百科)
設 (a1; a2; : : : ; an) (n >= 2) 是 n 元組,則 n + 1 元組定義
爲 (a1; a2; : : : an; a) ≜ ((a1; a2; : : : an); a).
😈 字符串的歸納定義

在這裏插入圖片描述
當集合Σ爲任意集合時,就是我們定義的鏈表。(見coq-list部分)
😈連接運算
在這裏插入圖片描述

計算機中的歸納思想

  • 歸納定義從最小的元素開始按照歸納條款有限步驟內逐步增長到被定義的集合
  • 根據可計算性理論,計算機處理的對象一定是具有歸納結構的集合
  • 數據結構的鏈表,棧和樹等等

利用歸納法證明

😈結構歸納法:
在這裏插入圖片描述

coq:Induction

Require export

from LP require export basic這條語句表示從有前綴LP相關的目錄中導入basic.vo相關的內容

Proof by Induction

😈 證明0是一個neutral element for +
第一反應的證明:

Theorem neutral_0 : forall n:nat,
n+0=n.
Proof.
 intros.
 simpl.
 reflexivity.
Qed.

但是coq中的simpl只能簡化一些確定的值,如1+2=3這類簡化,n是未知的,就好像是n+1不能看作(n+1)一樣,前者的加是運算符,後者是一個整體的數字,所以我們必須使用枚舉法標識出n所有可能的情況,但是當n很大時,顯然使用destruct分類很不明智,我們就要考慮到歸納法
歸納基礎:n=0時成立
證明當n=k-1時成立,從而證明n=k時成立
我們先來看看coq代碼是怎樣實現的:

Theorem netrul :forall n,n+0=n.`對定理的描述`
Proof.
  intros.
  induction n as [|n' HL].`將n析構爲0和n’,但是同時給出條件HL作爲歸納假設,表示當n’時上式成立`
  -reflexivity.
  -simpl. rewrite HL. reflexivity.`要證明的式子爲:S n’=S n’+0,simpl後變爲S n’=S(n’+0),代入歸納假設得證`
Qed.

關於S n’+0=S(n’+0),這裏體現了之前介紹一進制數字加法的基本規則,比如A+B,相當於A+B的前驅再取後繼。
induction規則能自動執行intros的效果,但是筆者的coq筆記主要講述離散數學中的基本思想,對於基本語法關注較少。

Proofs within proofs

我們在證明一個定理時,通常需要用到其他的定理,這時我們就有一個關於定理的結構,哪個定理是需要證明的主要定理,哪個是他的子定理,爲了方便起見,我們用assert描述需要用到的子定理,更清晰的展現定理之間的關係。
😈

Theorem mult_0_plus' : forall n m : nat,
  (0 + n) * m = n * m.
Proof.
  intros n m.
  assert (H: 0 + n = n). { reflexivity. } 
  rewrite -> H.
  reflexivity. 
Qed.

通過逐步運行,發現assert會產生兩個子目標,一個是證明我們需要的前提,另一個是我們利用前提證明的定理。用{}表示對assert的證明過程。
😈 rewrite功能的侷限
在之前的博客中我們證明了析取運算的交換律,發現了一些問題。

Theorem andb_commutative : forall b c,  (b & c) =  (c & b).
Proof.
  intros b c. destruct b.
  - destruct c.
    + reflexivity.
    + reflexivity.
  - destruct c.
    + reflexivity.
    + reflexivity.
Qed.

Theorem andb_assoc: forall b c d : bool, (b & c & d) = ((b & c) & d). 
Proof.
  intros.
  destruct b.
  - destruct c.
    + destruct d.
      * reflexivity.
      * reflexivity.
    + destruct d; reflexivity.
  - destruct c; destruct d; reflexivity.
Qed.

Theorem andb_permute: forall b c d, (b & c & d) = (d & c & b).
Proof.
  intros.
  rewrite andb_commutative.//之前規定了是右結合,所以這個會應用到左式最右邊的與運算,所以下邊使用函數化運用交換律,此時交換律運用到參數b0
  pattern (c & d).
  rewrite andb_commutative.
  symmetry.//rewrite只能從左到右替換,選擇交換。
  apply andb_assoc.
Qed.

在這裏插入圖片描述
rewrite在面臨多個運算符時,會優先考慮到括號外的運算符。(由於coq很多定理證明需要之前的定理,爲了節約閱讀時間,只展示主定理證明過程)

Theorem plus_rearrange_firsttry : 
forall n m p q : nat,
  (n + m) + (p + q) = (m + n) + (p + q).
Proof.
  intros n m p q.
  (* We just need to swap (n + m) for (m + n)... seems
     like plus_comm should do the trick! *)
  rewrite -> plus_comm.
  (* Doesn't work...Coq rewrites the wrong plus! *)
Abort.

assert可以對我們這裏需要用到的m+n=n+m進行特指的證明。

Theorem plus_rearrange_firsttry : 
forall n m p q : nat,
  (n + m) + (p + q) = (m + n) + (p + q).
Proof.
  intros n m p q.
  assert (H:n+m=m+n).  { rewrite plus_comm. reflexivity. }
  rewrite -> H.
  reflexivity.
Qed.

應用舉例:list的構造

Pairs of Numbers

😈 Inductive接受多個參數
⭐ 兩個參數

Inductive natprod:Type :=
|pair (n1 n2:nat).
Check pair 3 5.
Definition fst (p:natprod):nat:=
match p with
|pair x y=>x
end.
Definition snd (p:natprod):nat:=
match p with
|pair x y=>y
end.
Compute fst (pair 3 5).
Notation "( x , y )":=(pair x y).
Compute fst (3,5).
Definition swap_pair (p:natprod):natprod:=
match p with
|(x,y)=>(y,x)
end.
Compute swap_pair (3,5).

pair兩種表示方式的不同證明:

Theorem surjective_pairing' : 
forall (n m : nat),
  (n,m) = (fst (n,m), snd (n,m)).
Proof.
  reflexivity. 
Qed.

Theorem surjective_pairing_stuck : 
forall (p : natprod),
  p = (fst p, snd p).
Proof.
  intros.
  destruct p as [n m].
  simpl. reflexivity. 
Qed.

😈 list of numbers
定義鏈表:

Inductive natlist :Type:=
|nil
|cons (a:nat) (l:natlist).
Definition mylist:=cons 1(cons 2(cons 3 nil)).
Notation "[ ]":=nil.
Notation "[ a ; .. ; b ]" := (cons a .. (cons b nil) .. ).

利用遞歸函數求解鏈表的一些問題

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章