Coq归纳谓词归纳规则中的抽象模式
考虑Coq中的以下命题:Coq归纳谓词归纳规则中的抽象模式,coq,Coq,考虑Coq中的以下命题: Inductive subseq : list nat -> list nat -> Prop := | nil_s : forall (l: list nat), subseq nil l | cons_in l1 l2 x (H: subseq l1 l2) : subseq (x :: l1) (x :: l2) | cons_nin l1 l2 x (H: subseq l1 l2) : subseq l1 (x :: l2) . Lemm
Inductive subseq : list nat -> list nat -> Prop :=
| nil_s : forall (l: list nat), subseq nil l
| cons_in l1 l2 x (H: subseq l1 l2) : subseq (x :: l1) (x :: l2)
| cons_nin l1 l2 x (H: subseq l1 l2) : subseq l1 (x :: l2)
.
Lemma subseq_remove_rewritten: forall (x:nat) (l1' l1 l2 : list nat),
subseq l1' l2 ->
l1' = (x :: l1) ->
subseq l1 l2.
Proof.
intros x l1' l1 l2 H1 H2.
induction H1.
- discriminate.
- injection H2 as H3 H4.
rewrite H4 in H1.
apply cons_nin. apply H1.
- apply IHsubseq in H2.
apply cons_nin. apply H2.
Qed.
Lemma subseq_remove: forall (x:nat) (l1 l2 : list nat),
subseq (x :: l1) l2 ->
subseq l1 l2.
Proof.
intros x l1 l2 H.
apply subseq_remove_rewritten with (x:=x) (l1':=x :: l1).
apply H.
reflexivity.
Qed.
我在科克之前在伊莎贝尔工作过。最初,归纳法无法直接解决这一目标,而诀窍是提出一个类似subseq_remove_重写的引理,然后证明原始目标。这是手册Isabelle/HOL中的情况:高阶逻辑的证明助手。后来,这一策略变得更加聪明,人们可以编写用于抽象的模式。所以证据是这样写的:
lemma
assumes "subseq (x # l1) l2"
shows "subseq l1 l2"
using assms
apply(induction "x # l1" "l2" rule: subseq.induct)
apply simp
apply(intro subseq.intros(3),simp)
by (intro subseq.intros(3))
我想知道Coq是否有类似的方法来避免证明像subseq_remove_重写的引理,直接去证明subseq_remove 您可以使用
依赖诱导
策略(有文档记录)。例如:
Require Import Coq.Lists.List.
Import ListNotations.
Require Import Coq.Program.Equality. (* Needed to use the tactic *)
Inductive subseq : list nat -> list nat -> Prop :=
| nil_s : forall (l: list nat), subseq nil l
| cons_in l1 l2 x (H: subseq l1 l2) : subseq (x :: l1) (x :: l2)
| cons_nin l1 l2 x (H: subseq l1 l2) : subseq l1 (x :: l2)
.
Lemma subseq_remove: forall (x:nat) (l1 l2 : list nat),
subseq (x :: l1) l2 ->
subseq l1 l2.
Proof.
intros x l1 l2 H.
dependent induction H generalizing x.
- now apply cons_nin.
- eauto using cons_nin.
Qed.
Require Import Coq.Lists.List.
Import ListNotations.
Fixpoint subseq (l1 l2 : list nat) : Prop :=
match l1, l2 with
| [], _ => True
| x1 :: l1, [] => False
| x1 :: l1, x2 :: l2 => x1 = x2 /\ subseq l1 l2 \/ subseq (x1 :: l1) l2
end.
Lemma subseq_nin x2 l1 l2 : subseq l1 l2 -> subseq l1 (x2 :: l2).
Proof. destruct l1 as [|x1 l1]; simpl; eauto. Qed.
Lemma subseq_remove: forall (x:nat) (l1 l2 : list nat),
subseq (x :: l1) l2 ->
subseq l1 l2.
Proof.
intros x l1 l2 H.
induction l2 as [|x2 l2 IH]; try easy.
destruct H as [[<- H]|H]; eauto using subseq_nin.
Qed.
不幸的是,尽管这种策略已经存在了一段时间,但在参考手册中仍然被描述为实验性的,我不知道Coq开发人员将来是否有任何改进的计划。它有一些不足之处,例如不允许用户命名归纳证明中使用的变量和假设。我个人更喜欢将等式假设添加到证明中,就像您第一次尝试一样,或者将subseq
的定义重新表述为固定点
,这样您就可以通过简化来反转假设。例如:
Require Import Coq.Lists.List.
Import ListNotations.
Require Import Coq.Program.Equality. (* Needed to use the tactic *)
Inductive subseq : list nat -> list nat -> Prop :=
| nil_s : forall (l: list nat), subseq nil l
| cons_in l1 l2 x (H: subseq l1 l2) : subseq (x :: l1) (x :: l2)
| cons_nin l1 l2 x (H: subseq l1 l2) : subseq l1 (x :: l2)
.
Lemma subseq_remove: forall (x:nat) (l1 l2 : list nat),
subseq (x :: l1) l2 ->
subseq l1 l2.
Proof.
intros x l1 l2 H.
dependent induction H generalizing x.
- now apply cons_nin.
- eauto using cons_nin.
Qed.
Require Import Coq.Lists.List.
Import ListNotations.
Fixpoint subseq (l1 l2 : list nat) : Prop :=
match l1, l2 with
| [], _ => True
| x1 :: l1, [] => False
| x1 :: l1, x2 :: l2 => x1 = x2 /\ subseq l1 l2 \/ subseq (x1 :: l1) l2
end.
Lemma subseq_nin x2 l1 l2 : subseq l1 l2 -> subseq l1 (x2 :: l2).
Proof. destruct l1 as [|x1 l1]; simpl; eauto. Qed.
Lemma subseq_remove: forall (x:nat) (l1 l2 : list nat),
subseq (x :: l1) l2 ->
subseq l1 l2.
Proof.
intros x l1 l2 H.
induction l2 as [|x2 l2 IH]; try easy.
destruct H as [[<- H]|H]; eauto using subseq_nin.
Qed.
需要导入Coq.Lists.List。
导入列表符号。
固定点水下(l1 l2:列表nat):道具:=
将l1、l2与
|[],\uU9=>True
|x1::l1,[]=>错误
|x1::l1,x2::l2=>x1=x2/\subseq l1 l2\/subseq(x1::l1)l2
结束。
x2 l1 l2中的引理subseq_:subseq l1 l2->subseq l1(x2::l2)。
证明。将l1分解为[| x1 l1];单纯形;奥托。Qed。
引理subseq_remove:forall(x:nat)(l1-l2:list-nat),
水下(x::l1)l2->
水下l1和l2。
证明。
简介x l1 l2 H。
诱导l2为[| x2 l2 IH];别着急。
自毁[[