![](/img/trans.png)
[英]The exact definition of an in built Tactic (case, destruct, inversion etc.) in Coq
[英]Coq: performing inversion on Prop for Set when there is only one case
假設我有一些編程語言,具有“有類型”關系和“小步”關系。
Inductive type : Set :=
| Nat : type
| Bool : type.
Inductive tm : Set :=
| num : nat -> tm
| plus : tm -> tm -> tm
| lt : tm -> tm -> tm
| ifthen : tm -> tm -> tm -> tm.
Inductive hasType : tm -> type -> Prop :=
| hasTypeNum :
forall n, hasType (num n) Nat
| hasTypePlus:
forall tm1 tm2,
hasType tm1 Nat ->
hasType tm2 Nat ->
hasType (plus tm1 tm2) Nat
| hasTypeLt:
forall tm1 tm2,
hasType tm1 Nat ->
hasType tm2 Nat ->
hasType (lt tm1 tm2) Bool
| hasTypeIfThen:
forall tm1 tm2 tm3,
hasType tm1 Bool ->
hasType tm2 Nat ->
hasType tm3 Nat ->
hasType (ifthen tm1 tm2 tm3) Nat.
Inductive SmallStep : tm -> tm -> Prop :=
...
Definition is_value (t : tm) := ...
這里的關鍵細節是,對於每個術語變體,只有一種可能匹配的HasType變體。
假設我想證明一個進度引理,但我也希望能夠從中提取一個解釋器。
Lemma progress_interp:
forall tm t,
hasType tm t ->
(is_value tm = false) ->
{tm2 | SmallStep tm tm2}.
intro; induction tm0; intros; inversion H.
這給出了錯誤Inversion would require case analysis on sort Set which is not allowed for inductive definition hasType.
我理解它為什么這樣做: inversion
在排序的值進行案例分析Prop
,這因為它在提取的代碼被擦除,我們不能這樣做。
但是,因為術語變體和類型派生規則之間存在一對一的對應關系,所以我們實際上不必在運行時執行任何分析。
理想情況下,我可以應用一堆看起來像這樣的lemmas:
plusInv: forall e t, hasType e t ->
(forall e1 e2, e = plus e1 e2 -> hasType e1 Nat /\ hasType e2 Nat ).
對於每種情況都會有這樣的引理(或者是這些情況的結合的單個引理)。
我看過Derive Inversion
但它似乎沒有做我在這里尋找的東西,雖然也許我不能正確理解它。
有沒有辦法做這種“只有一個案例的案例分析?” 或者為了獲得Prop
證明所隱含的平等,以便我只能在我提取的解釋器中寫出可能的案例? 使用Ltac或Deriving機制可以自動導出這些引理嗎?
引理plus_inv
可以通過類型tm
的案例分析而不是類型hasType
的案例分析來hasType
。
Lemma plus_inv : forall e t, hasType e t ->
(forall e1 e2, e = plus e1 e2 -> hasType e1 Nat /\ hasType e2 Nat ).
Proof.
intros e; case e; try (intros; discriminate).
intros e1 e2 t h; inversion h; intros e5 e6 heq; inversion heq; subst; auto.
Qed.
您的主要目標progress_interp
的證明也可以通過感應tm
的結構來執行。 這相當於直接將解釋器編寫為gallina遞歸函數。
您的問題有第二部分:這可以自動化嗎? 可能答案是肯定的。 我建議使用template-coq軟件包或elpi軟件包。 這兩個包都可以作為opam包使用。
我認為eexists
會做的伎倆:存在變量應該在sigma類型的證明期間的某個時刻填充(你可以在hasType
假設上自由地使用inversion
)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.