使用let-in调用定理

时间:2018-01-16 10:34:00

标签: coq

我有一个函数f返回一对。然后我证明了一些有关它的结果。 在我的引理中,我第一次尝试获取每个组件都使用let (x, y) := f z in。但是,尝试使用这些引理似乎很麻烦。 apply不能直接使用,我必须使用pose proof或其变体添加假设中的引理并破坏f z才能使用它。有没有办法在引理中顺利使用let-in?或者是否因为使用它而感到沮丧?

要完成我的问题,以下是我撰写有关f的引理的其他尝试。我尝试直接使用fst (f z)snd (f z),但我发现它很麻烦。最后,我用forall x y, (x,y) = f z ->开始了我的引理。

这是一个具体的例子。

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.

1 个答案:

答案 0 :(得分:1)

您已找到我认为正确的解决方案。 let (l1, l2) := ... in ...将阻止减少并打破一切。您使用split_in2还是split_in3取决于您的起点。

但请注意,启用Primitive Projections并将prod重新定义为原始记录会使split_insplit_in2实际上是相同的定理,因为{ {1}}和split l在判断上是平等的。您可以使用

执行此操作
(fst (split l), snd (split l))