Coq 使用let-in调用一个定理

Coq 使用let-in调用一个定理,coq,Coq,我有一个函数f返回一对。然后我证明了关于它的一些结果。 在我的引理中,我第一次尝试得到每个组件是使用let(x,y):=fz In。但是,尝试使用这些引理似乎很麻烦apply不能直接工作,我必须使用pose-proof或其变体在假设中添加引理,然后析构函数f z才能使用它。有没有办法在引理中顺利地使用let-in?还是因为使用起来很痛苦而被劝阻 为了完成我的问题,下面是我写的关于f的引理的其他尝试。我试着直接使用fst(fz)和snd(fz),但我也发现它很麻烦。最后,我从所有xy,(x,y)=

我有一个函数
f
返回一对。然后我证明了关于它的一些结果。 在我的引理中,我第一次尝试得到每个组件是使用
let(x,y):=fz In
。但是,尝试使用这些引理似乎很麻烦
apply
不能直接工作,我必须使用
pose-proof
或其变体在假设中添加引理,然后析构函数
f z
才能使用它。有没有办法在引理中顺利地使用let-in?还是因为使用起来很痛苦而被劝阻

为了完成我的问题,下面是我写的关于
f
的引理的其他尝试。我试着直接使用
fst(fz)
snd(fz)
,但我也发现它很麻烦。最后,我从所有xy,(x,y)=fz->开始我的引理

这里有一个具体的例子

Require Import List. Import ListNotations.

Fixpoint split {A} (l:list A) :=
  match l with
  | [] => ([], [])
  | [a] => ([a], [])
  | a::b::l => let (l1, l2) := split l in (a::l1, b::l2)
  end.

Lemma split_in : forall {A} (l:list A) x,
  let (l1, l2) := split l in 
  In x l1 \/ In x l2 <-> In x l.

Lemma split_in2 : forall {A} (l:list A) x,
  In x (fst (split l)) \/ In x (snd (split l)) <-> In x l.

Lemma split_in3 : forall {A} (l:list A) x l1 l2,
  (l1, l2) = split l ->
  In x l1 \/ In x l2 <-> In x l.
需要导入列表。导入列表符号。
不动点拆分{A}(l:列表A):=
匹配
| [] => ([], [])
|[a]=>([a],])
|a::b::l=>let(l1,l2):=在(a::l1,b::l2)中拆分l
结束。
引理在:forall{A}(l:list A)x中分裂,
let(l1,l2):=在
在x l1\/在x l2在x l中。
引理分裂为2:forall{A}(l:list A)x,
在x(fst(split l))\/在x(snd(split l))在x l中。
引理3:forall{A}(l:list A)x l1 l2,
(l1,l2)=拆分l->
在x l1\/在x l2在x l中。

您已经找到了我认为正确的解决方案<代码>let(l1,l2):=。。。在…中,将阻止还原并破坏一切。您是使用
split_in2
还是
split_in3
取决于您的起点

然而,请注意,打开
基本投影
并将
prod
重新定义为基本记录将使其成为
split_in
split_in
实际上是相同的定理,因为
split l
(fst(split l)、snd(split l))
在判断上是相等的。你可以用它来做这个

Set Primitive Projections.
Record prod {A B} := pair { fst : A ; snd : B }.
Arguments prod : clear implicits.
Arguments pair {A B}.
Add Printing Let prod.
Notation "x * y" := (prod x y) : type_scope.
Notation "( x , y , .. , z )" := (pair .. (pair x y) .. z) : core_scope.
Hint Resolve pair : core.

我相信我们还需要
参数对{abb}。
使其更像标准的
prod
类型。不,我在
prod
的定义中在
{abb}
周围添加了花括号(这会自动为
fst
snd
添加它们),然后将它们从
prod
中删除。它对我不起作用(Coq 8.7.1):
检查(0,0):nat*nat
,因为
pair
具有这些类型参数explicit@AntonTrunov嗯,我从未意识到花括号只适用于类型成型器和投影,而不适用于构造函数。谢谢@eponier关于默认打开它们,我刚刚