我努力學習勒柯克,但我發現很難讓從我在軟件基金會和與認證相關類型編程讀我自己的飛躍用例。在勒柯克(安全第n個功能)使用相關類型
特別是,我想我會嘗試在列表上做一個驗證版本的nth
函數。我設法寫:
Require Import Arith.
Require Import List.
Import ListNotations.
Lemma zltz: 0 < 0 -> False.
Proof.
intros. contradict H. apply Lt.lt_irrefl.
Qed.
Lemma nltz: forall n: nat, n < 0 -> False.
Proof.
intros. contradict H. apply Lt.lt_n_0.
Qed.
Lemma predecessor_proof: forall {X: Type} (n: nat) (x: X) (xs: list X),
S n < length (x::xs) -> n < length xs.
Proof.
intros. simpl in H. apply Lt.lt_S_n. assumption.
Qed.
Fixpoint safe_nth {X: Type} (n: nat) (xs: list X): n < length xs -> X :=
match n, xs with
| 0, [] => fun pf: 0 < length [] => match zltz pf with end
| S n', [] => fun pf: S n' < length [] => match nltz (S n') pf with end
| 0, x::_ => fun _ => x
| S n', x::xs' => fun pf: S n' < length (x::xs') => safe_nth n' xs' (predecessor_proof n' x xs' pf)
end.
這工作,但提出了兩個問題:
- 將如何經歷勒柯克用戶寫的嗎?這三個引理是否真的有必要?這是
{ | }
類型的用例嗎? - 如何從其他代碼調用此函數,即如何提供所需的證明?
我嘗試這樣做:
Require Import NPeano.
Eval compute in if ltb 2 (length [1; 2; 3]) then safe_nth 2 [1; 2; 3] ??? else 0.
但是,當然,這是不行的,直到我弄清楚如何爲???
部分寫。我試着把(2 < length [1; 2; 3])
放在那裏,但是它的類型是Prop
而不是2 < length [1; 2; 3]
。我可以寫出並證明這個特定類型的引理,並且這是有效的。但是,通用解決方案是什麼?
感謝您使用'lt_dec'進行解釋,那是我失蹤的作品!是的,我已經看到'zltz'和'nltz'之間的相似性,但錯過了等價性...... –