`le`的归纳原理
Induction principle for `le`
对于归纳类型nat
,生成的归纳原理在其语句中使用构造函数O
和S
:
Inductive nat : Set := O : nat | S : nat -> nat
nat_ind
: forall P : nat -> Prop,
P 0 ->
(forall n : nat, P n -> P (S n)) -> forall n : nat, P n
但是对于le
,生成的语句不使用构造函数le_n
和le_S
:
Inductive le (n : nat) : nat -> Prop :=
le_n : n <= n | le_S : forall m : nat, n <= m -> n <= S m
le_ind
: forall (n : nat) (P : nat -> Prop),
P n ->
(forall m : nat, n <= m -> P m -> P (S m)) ->
forall n0 : nat, n <= n0 -> P n0
然而,可以按照与 nat
:
相同的形状来陈述和证明归纳原理
Lemma le_ind' : forall n (P : forall m, le n m -> Prop),
P n (le_n n) ->
(forall m (p : le n m), P m p -> P (S m) (le_S n m p)) ->
forall m (p : le n m), P m p.
Proof.
fix H 6; intros; destruct p.
apply H0.
apply H1, H.
apply H0.
apply H1.
Qed.
我想生成的更方便。但是 Coq 是如何为其生成的归纳原理选择形状的呢?如果有任何规则,我在参考手册中找不到它们。其他证明助手如 Agda 呢?
您可以使用命令Scheme
(参见documentation)为归纳类型手动生成归纳原理。
该命令有两种形式:
Scheme scheme := Induction for Sort Prop
生成标准归纳方案。
Scheme scheme := Minimality for Sort Prop
生成更适合归纳谓词的简化归纳方案。
如果在Type
中定义归纳类型,生成的归纳原理是第一类。如果在Prop
中定义归纳类型(即归纳谓词),则生成的归纳原理属于第二种。
要在le
的情况下得到你想要的归纳原理,你可以在Type
中定义:
Inductive le (n : nat) : nat -> Type :=
| le_n : le n n
| le_S : forall m : nat, le n m -> le n (S m).
Check le_ind.
(* forall (n : nat) (P : forall n0 : nat, le n n0 -> Prop),
P n (le_n n) ->
(forall (m : nat) (l : le n m), P m l -> P (S m) (le_S n m l)) ->
forall (n0 : nat) (l : le n n0), P n0 l
*)
或者你可以手动要求 Coq 生成预期的归纳原理:
Inductive le (n : nat) : nat -> Prop :=
| le_n : le n n
| le_S : forall m : nat, le n m -> le n (S m).
Check le_ind.
(* forall (n : nat) (P : nat -> Prop),
P n ->
(forall m : nat, le n m -> P m -> P (S m)) ->
forall n0 : nat, le n n0 -> P n0
*)
Scheme le_ind2 := Induction for le Sort Prop.
Check le_ind2.
(* forall (n : nat) (P : forall n0 : nat, le n n0 -> Prop),
P n (le_n n) ->
(forall (m : nat) (l : le n m), P m l -> P (S m) (le_S n m l)) ->
forall (n0 : nat) (l : le n n0), P n0 l
*)
对于归纳类型nat
,生成的归纳原理在其语句中使用构造函数O
和S
:
Inductive nat : Set := O : nat | S : nat -> nat
nat_ind
: forall P : nat -> Prop,
P 0 ->
(forall n : nat, P n -> P (S n)) -> forall n : nat, P n
但是对于le
,生成的语句不使用构造函数le_n
和le_S
:
Inductive le (n : nat) : nat -> Prop :=
le_n : n <= n | le_S : forall m : nat, n <= m -> n <= S m
le_ind
: forall (n : nat) (P : nat -> Prop),
P n ->
(forall m : nat, n <= m -> P m -> P (S m)) ->
forall n0 : nat, n <= n0 -> P n0
然而,可以按照与 nat
:
Lemma le_ind' : forall n (P : forall m, le n m -> Prop),
P n (le_n n) ->
(forall m (p : le n m), P m p -> P (S m) (le_S n m p)) ->
forall m (p : le n m), P m p.
Proof.
fix H 6; intros; destruct p.
apply H0.
apply H1, H.
apply H0.
apply H1.
Qed.
我想生成的更方便。但是 Coq 是如何为其生成的归纳原理选择形状的呢?如果有任何规则,我在参考手册中找不到它们。其他证明助手如 Agda 呢?
您可以使用命令Scheme
(参见documentation)为归纳类型手动生成归纳原理。
该命令有两种形式:
Scheme scheme := Induction for Sort Prop
生成标准归纳方案。Scheme scheme := Minimality for Sort Prop
生成更适合归纳谓词的简化归纳方案。
如果在Type
中定义归纳类型,生成的归纳原理是第一类。如果在Prop
中定义归纳类型(即归纳谓词),则生成的归纳原理属于第二种。
要在le
的情况下得到你想要的归纳原理,你可以在Type
中定义:
Inductive le (n : nat) : nat -> Type :=
| le_n : le n n
| le_S : forall m : nat, le n m -> le n (S m).
Check le_ind.
(* forall (n : nat) (P : forall n0 : nat, le n n0 -> Prop),
P n (le_n n) ->
(forall (m : nat) (l : le n m), P m l -> P (S m) (le_S n m l)) ->
forall (n0 : nat) (l : le n n0), P n0 l
*)
或者你可以手动要求 Coq 生成预期的归纳原理:
Inductive le (n : nat) : nat -> Prop :=
| le_n : le n n
| le_S : forall m : nat, le n m -> le n (S m).
Check le_ind.
(* forall (n : nat) (P : nat -> Prop),
P n ->
(forall m : nat, le n m -> P m -> P (S m)) ->
forall n0 : nat, le n n0 -> P n0
*)
Scheme le_ind2 := Induction for le Sort Prop.
Check le_ind2.
(* forall (n : nat) (P : forall n0 : nat, le n n0 -> Prop),
P n (le_n n) ->
(forall (m : nat) (l : le n m), P m l -> P (S m) (le_S n m l)) ->
forall (n0 : nat) (l : le n n0), P n0 l
*)