[英]Coq: How to prove max a b <= a+b?
我無法使用coq的策略證明簡單的邏輯max ab <= a+b
。 我應該如何解決呢? 以下是我到目前為止一直在使用的代碼。 s_le_n
已被證明,但為簡單起見此處未提及。
Theorem s_le_n: forall (a b: nat), a <= b -> S a <= S b.
Proof. Admitted.
Theorem max_sum: forall (a b: nat), max a b <= a + b.
Proof.
intros.
induction a.
- simpl. reflexivity.
- rewrite plus_Sn_m. induction b.
+ simpl. rewrite <- plus_n_O. reflexivity.
+ rewrite <- plus_Sn_m. simpl. apply s_le_n. rewrite IHa.
考慮到@ re3el的評論,我們從其“筆和紙證明”開始:
if a>b max a b = a, a < a+b; else max a b = b, b < a+b
現在讓我們將其翻譯成Coq! 實際上,我們要做的第一件事是確定<
的可判定性,這是使用le_lt_dec ab
引理完成的。 其余的是常規的:
Require Import Arith.
Theorem max_sum (a b: nat) : max a b <= a + b.
Proof.
case (le_lt_dec a b).
+ now rewrite <- Nat.max_r_iff; intros ->; apply le_plus_r.
+ intros ha; apply Nat.lt_le_incl, Nat.max_l_iff in ha.
now rewrite ha; apply le_plus_l.
Qed.
但是,我們可以大大改善這一證明。 有各種各樣的候選人,使用stdlib的一個不錯的候選人是:
Theorem max_sum_1 (a b: nat) : max a b <= a + b.
Proof.
now rewrite Nat.max_lub_iff; split; [apply le_plus_l | apply le_plus_r].
Qed.
使用我選擇的庫[math-comp],可以鏈接重寫以獲得更緊湊的證明:
From mathcomp Require Import all_ssreflect.
Theorem max_sum_2 (a b: nat) : maxn a b <= a + b.
Proof. by rewrite geq_max leq_addl leq_addr. Qed.
實際上,從簡短的證明來看,也許甚至根本不需要原始引理。
編輯:@Jason Gross提到了另一種更經驗豐富的證明方式:
Proof. apply Max.max_case_strong; omega. Qed.
但是,該證明涉及使用重量級自動化策略omega
。 我強烈建議所有初學者暫時避免使用這種策略,並學習如何更“手動”地進行證明。 實際上,使用任何啟用SMT的策略,只需調用SMT即可簡單地解決原始目標。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.