div2
関数から誘導原理を簡単に導き出すことができますmod2
。
Functional Scheme div2_ind := Induction for div2 Sort Prop.
Functional Scheme mod2_ind := Induction for mod2 Sort Prop.
div2_ind
mod2_ind
多かれ少なかれタイプがあります:
forall P1,
P1 0 0 ->
P1 1 0 ->
(forall n1, P1 n1 (div2 n1) -> P1 (S (S n1)) (S (div2 n1))) ->
forall n1, P1 n1 (div2 n1)
forall P1,
P1 0 0 ->
P1 1 1 ->
(forall n1, P1 n1 (mod2 n1) -> P1 (S (S n1)) (mod2 n1)) ->
forall n1, P1 n1 (mod2 n1)
これらの定理を適用するには、便利なようにfunctional induction (div2 n)
、またはfunctional induction (mod2 n)
通常はどこにでも書くことができますinduction n
。
しかし、より強力な誘導原理がこれらの機能に関連付けられています。
Lemma nat_ind_alt : forall P1 : nat -> Prop,
P1 0 ->
P1 1 ->
(forall n1, P1 n1 -> P1 (S (S n1))) ->
forall n1, P1 n1.
Proof.
intros P1 H1 H2 H3. induction n1 as [[| [| n1]] H4] using lt_wf_ind.
info_auto.
info_auto.
info_auto.
Qed.
実際、任意の関数の定義域は、有用な帰納法への手がかりです。たとえば、関数のドメインに関連付けられている誘導原理は、plus : nat -> nat -> nat
構造mult : nat -> nat -> nat
誘導にすぎません。Functional Scheme
代わりに、これらのより一般的な原則を生成しないのはなぜだろうか。
いずれにせよ、定理の証明は次のようになります。
Lemma div2_eq : forall n, 2 * div2 n + mod2 n = n.
Proof.
induction n as [| | n1 H1] using nat_ind_alt.
simpl in *. omega.
simpl in *. omega.
simpl in *. omega.
Qed.
Lemma div2_le : forall n, div2 n <= n.
Proof.
induction n as [| | n1 H1] using nat_ind_alt.
simpl. omega.
simpl. omega.
simpl. omega.
Qed.
機能的帰納法に慣れる必要がありますが、さらに重要なことは、十分に根拠のある帰納法に精通する必要があります。