免责声明:我担心此帖很长,但我觉得在较小的设置中,一些有价值的背景信息会丢失。
我目前正试图改变我的形式化以使用Charguéraud等[1]的本地无名表示。显然,这种适应并不像我希望的那样简单,因为我对表达式的定义包含列表(至少我认为这是主要问题)。
所以,我有以下(最小)表达式的定义。
Require Import Coq.Lists.List.
Require Import Coq.Arith.PeanoNat.
Parameter atom : Set.
Parameter eq_atom_dec : forall x y : atom, {x = y} + {x <> y}.
Definition VarIndex := nat.
Inductive Expr : Type :=
| BVar : VarIndex -> VarIndex -> Expr
| FVar : atom -> Expr
| LetB : list Expr -> Expr -> Expr.
有了这个定义,我可以定义开始操作。
Fixpoint open_rec (k: VarIndex) (u: list Expr) (e: Expr) :=
match e with
| BVar i j => if Nat.eq_dec k i then List.nth j u e else e
| FVar x => e
| LetB es e' => LetB (List.map (open_rec (S k) u) es) (open_rec (S k) u e')
end.
Notation "{ k ~> u } t" := (open_rec k u t) (at level 67).
Definition open e u := open_rec 0 u e.
到目前为止一切顺利。接下来,“本地关闭”的属性被归纳为如下定义。
Inductive lc : Expr -> Prop :=
| lc_var : forall x,
lc (FVar x)
| lc_let : forall (ts: list Expr) es e,
Forall lc es ->
lc (open e ts) ->
lc (LetB es e).
本教程现在指出我们可以证明有关lc
和open
的交互的引理,即在本地封闭的表达式中,当我们替换变量时没有任何事情发生。
(* this is a auxiliary lemma that works just fine for me *)
Lemma open_rec_lc_core : forall e (j: VarIndex) v (i: VarIndex) u,
i <> j ->
{j ~> v} e = {i ~> u} ({j ~> v} e) ->
e = {i ~> u} e.
Proof.
Admitted.
Lemma open_rec_lc0 : forall k u e,
lc e ->
e = {k ~> u} e.
Proof.
intros k u e LC.
generalize dependent k.
induction LC; intro k.
- reflexivity.
- simpl.
f_equal.
+ admit.
+ eapply open_rec_lc_core with (j := 0).
* auto.
* eapply IHLC.
Admitted.
正如您所看到的,有一个案例在证明中被“承认”。这里的问题是我必须证明一些关于let-bindings的东西,但我手头的所有内容如下:
H : Forall lc (map (fun e' : Expr => open e' ts) es)
LC : lc (open e ts)
IHLC : forall k : VarIndex, open e ts = {k ~> u} open e ts
我需要的是IHLC的等效假设,但es
。
我的第一个猜测是我需要修改归纳原理,因为它通常是以列表作为参数的归纳定义[2]完成的。
但是,我无法研究实际输入检查的定义。
Fail Definition lc_ind2 :=
fun (P : Expr -> Prop) (f : forall x : atom, P (FVar x))
(f0 : forall (ts es : list Expr) (e : Expr),
Forall lc (map (fun e' : Expr => open e' ts) es) ->
lc (open e ts) -> P (open e ts) ->
Forall P (map (fun e' => open e' ts ) es) ->
P (LetB es e)) =>
fix F (e : Expr) (l : lc e) {struct l} : P e :=
match l in (lc e0) return (P e0) with
| lc_var x => f x
| lc_let ts es e0 f1 l0 =>
f0 ts es e0 f1 l0 (F (open e0 ts) l0)
((fix F' (es: list Expr) : Forall P es :=
match es with
| nil => Forall_nil P
| cons x xs => Forall_cons x (F x _) (F' xs)
end) (map (fun e' => open e' ts) es))
end.
_
应用中Forall_cons
而不是lc x
我需要$('#dt-invoice').on('click', '[id^=id_paid-]', function() {
console.log("HERE")
row = $(this).closest('tr');
trid = row.attr("id");
alert(trid);
});
类型的内容,但我不知道如何提出这个值。
所以,最后我的问题是,如果有人知道我需要修改哪些定义才能使用LNR。
[1] Tutorial on LNR
[2] Induction principles with list arguments
答案 0 :(得分:3)
好的,最后我将Forall
内联到使用lc
的本地归纳定义中。
Inductive lc : Expr -> Prop :=
| lc_var : forall x,
lc (FVar x)
| lc_let : forall (ts: list Expr) es e,
Forall_lc es ->
lc (open e ts) ->
lc (LetB es e).
with Forall_lc : list Expr -> Prop :=
| nil_lc : Forall_lc nil
| cons_lc : forall e es, lc e -> Forall_lc es -> Forall_lc (e :: es).
并产生了我需要的归纳原理。
Scheme lc2_ind := Minimality for lc Sort Prop
with lc_Forall_ind := Minimality for Forall_lc Sort Prop.
采取了相同的方法here (Chapter 4)。
我想,最后,诀窍是使用相互递归的定义,而不是尝试将lc
作为参数应用于Forall
。
答案 1 :(得分:1)
这是一个有效的解决方案。我不明白所有的细节。例如,在第一个证明中,归纳必须直接在Forall
假设上进行,而不是在es
上进行,以尊重保护条件。还要注意使用refine
,它允许迭代地构建一个术语,将下划线留给未知的参数并逐渐完成。
Lemma lc_ind2 : forall P : Expr -> Prop,
(forall x : atom, P (FVar x)) ->
(forall (ts es : list Expr) (e : Expr),
Forall lc es -> Forall P es ->
lc (open e ts) -> P (open e ts) -> P (LetB es e)) ->
forall e : Expr, lc e -> P e.
Proof.
intros. revert e H1.
refine (fix aux e H1 (* {struct H1} *) := match H1 with
| lc_var x => H x
| lc_let ts es e HFor Hlc => H0 ts es e HFor _ Hlc (aux (open e ts) Hlc)
end).
induction HFor.
constructor.
constructor.
apply aux. apply H2. assumption.
Qed.
Lemma Forall_map : forall {A} f (l:list A),
Forall (fun x => x = f x) l ->
l = map f l.
Proof.
intros.
induction H.
reflexivity.
simpl. f_equal; assumption.
Qed.
Lemma open_rec_lc0 : forall k u e,
lc e ->
e = {k ~> u} e.
Proof.
intros k u e H. revert k u.
induction H using lc_ind2; intros.
- reflexivity.
- simpl. f_equal.
+ apply Forall_map. apply Forall_forall. rewrite Forall_forall in H0.
intros. apply H0. assumption.
+ eapply open_rec_lc_core with (j := 0).
* auto.
* eapply IHlc.
Qed.