在Coq中证明`forall x xs ys,subseq(x :: xs)ys-> subseq xs ys`

时间:2019-01-26 12:11:57

标签: coq proof theorem-proving

我有以下定义

Inductive subseq : list nat -> list nat -> Prop :=
| empty_subseq : subseq [] []
| add_right : forall y xs ys, subseq xs ys -> subseq xs (y::ys)
| add_both : forall x y xs ys, subseq xs ys -> subseq (x::xs) (y::ys)
.

借此,我想证明以下引理

Lemma del_l_preserves_subseq : forall x xs ys, subseq (x :: xs) ys -> subseq xs ys.

因此,我尝试通过进行subseq (x :: xs) ys来查看destruct H的证明。

Proof.
  intros. induction H.
3 subgoals (ID 209)

  x : nat
  xs : list nat
  ============================
  subseq xs [ ]

subgoal 2 (ID 216) is:
 subseq xs (y :: ys)
subgoal 3 (ID 222) is:
 subseq xs (y :: ys)

为什么第一个子目标要求我证明subseq xs []

难道destruct策略不知道证明不能采用empty_subseq的形式,因为类型包含x :: xs而不是[]

一般而言,我如何证明我要证明的引理?

2 个答案:

答案 0 :(得分:5)

  

破坏策略不应该知道证明不能采用empty_subseq形式,因为类型包含x :: xs而不是[]吗?

实际上,destruct并不那么了解。在x :: xs情况下,它仅用xs[]替换[]empty_subseq。特别是,这经常导致上下文中的信息丢失。更好的选择:

  • 使用inversion代替destruct

  • 使用remember确保subseq的两个类型索引都是destruct之前的变量。 (remember (x :: xs) as xxs in H.)这种更明确的目标管理也可以与induction一起很好地工作。

答案 1 :(得分:0)

李瑶的回答实际上很有用。这是引理的证明。

Lemma del_l_preserves_subseq : forall x xs ys, subseq (x :: xs) ys -> subseq xs ys.
Proof.
  intros x xs ys.
  induction ys as [|y ys'].
  - intros. inversion H. (* Inversion will detect that no constructor matches the type of H *)
  - intros. inversion H. (* Inversion will automatically discharge the first case *)
    + (* When [subseq (x :: xs) ys'] holds *)
      apply IHys' in H2. now apply add_right.
    + (* When [subseq xs ys'] holds *)
      now apply add_right.
Qed