(here是我迄今为止工作的要点。)
Coq带有关于eta减少的规则,允许我们证明以下内容:
Variables X Y Z : Type.
Variable f : X -> Y -> Z.
Lemma eta1 : (fun x => f x) = f.
Proof.
auto.
Qed.
eta规则不仅仅是一个平等重写,所以我们也可以在绑定器下面使用它:
Lemma eta2 : (fun x y => f x y) = f.
Proof.
auto.
Qed.
当然,人们可以预期你可以将其概括为f
任意的arity。这是我天真的尝试:
Require Import Coq.Lists.List.
Import ListNotations.
Fixpoint toType(ts : list Type)(t : Type) : Type :=
match ts with
|[] => t
|u::vs => u -> (toType vs t)
end.
Compute toType [X;Y] Z.
(*
= X -> Y -> Z
: Type
*)
Fixpoint etaexpand(ts : list Type) : forall t : Type, toType ts t -> toType ts t :=
match ts as ts return forall t, toType ts t -> toType ts t with
|[] => fun t x => x
|u::vs => fun t f (x:u) => etaexpand vs t (f x)
end.
Compute etaexpand [X;Y] Z f.
(*
= fun (x : X) (x0 : Y) => f x x0
: toType [X; Y] Z
*)
Lemma etaexpand_id : forall ts t f, etaexpand ts t f = f.
Proof.
induction ts; intros.
auto.
simpl.
(*stuck here*)
我陷入了上述引理的归纳步骤。当然,我想用归纳假设重写,但我不能,因为相关的子项发生在一个活页夹下面。当然,我自己也知道归纳假设应该可以在绑定器下使用,因为它只是一个eta重写链。我想知道是否有一种聪明的方式来陈述和说服Coq这个事实。
答案 0 :(得分:2)
万一有人好奇,here's我想出了解决方案。
关键是要同时证明以下"好看" etaexpand ts t
的属性:
Definition nice{X Y}(F : Y -> Y) := (forall y, F y = y) -> forall f : X -> Y,
(fun x => F (f x)) = f.