software foundations LF Induction

更多内容见 https://github.com/january147/software_foundations_notes

software foundations LF Induction

导入经过编译的模块

From LF Require Export Basics.

LF表示项目目录,Basics是导入的模块名称(对应Basics.vo文件)

First create a file named _CoqProject containing the following line (if you obtained the whole volume “Logical Foundations” as a single archive, a _CoqProject should already exist and you can skip this step):

-Q . LF

This maps the current directory (".", which contains Basics.v, Induction.v, etc.) to the prefix (or “logical directory”) “LF”.

通过创建_CoqProject文件,指定-Q . LF可以将本地目录.映射到逻辑目录LF

Proof by induction

对于无法逐个列举所有情况的命题(即使用destruct无法完成证明),可以通过数学归纳法来证明,即对于命题 P ( n ) P(n) P(n), 证明 P ( 0 ) P(0) P(0)为真,并且 P ( n ) → P ( n + 1 ) P(n) \to P(n+1) P(n)P(n+1)为真,根据数学归纳法则有 P ( n ) P(n) P(n)为真。

Theorem plus_n_Sm : forall n m : nat,
  S (n + m) = n + (S m).
Proof.
  intros n m.
  (* seems impossible to induction m? *)
  induction n as [| n' Hn].
  -simpl. reflexivity.
  -simpl. rewrite <- Hn. reflexivity.
Qed.

tactic

induction

inductiondestruct有点类似,都是将变量进行分类讨论。不同的是,induction即采用数学归纳法进行证明,即将变量分为初始值和后续任意一个值两种情况进行讨论。

Theorem plus_n_O : forall n:nat, n = n + 0.
Proof.
  intros n. induction n as [| n' IHn'].
  (* n = 0 *)    
  - reflexivity.
  (* n = S n', n' = n' + 0 *)
  - simpl. rewrite <- IHn'. reflexivity.  Qed.

assert

使用assert可以在一个定理的证明过程中定义一个子定理(通常称为引理lemma),通过证明这个子定理来证明最终的定理。通常很简单或者泛用性较差(不在其他定理证明中使用)的子定理才使用assert在证明过程中定义,复杂或者通用的子定理通过使用Theorem或者Lemma直接定义。

Theorem mult_0_plus' : ∀ n m : nat,
  (0 + n) × m = n × m.
Proof.
  intros n m.
  assert (H: 0 + n = n). { reflexivity. }
  rewrite → H.
  reflexivity. Qed.

rewrite可以配合assert实现指定具体的改写目标。例如在下面这个定理的证明过程中,存在一个等式中有多个可以rewrite的地方,仅使用rewrite无法指定特定的部分进行rewrite,导致定理难以证明,通过assert声明针对该证明过程中特定变量名称的子定理可以使得rewrite仅改写我们所需的部分

Theorem mult_n_Sm: forall n m : nat, n * S m = n + n * m.
Proof.
  intros n m. induction n as [|n' Hn].
  -simpl. reflexivity.
  -simpl. rewrite -> Hn. rewrite -> plus_assoc.
  rewrite -> plus_assoc.
  (* 这一步需要时证明目标为S (m + n' + n' * m) = S (n' + m + n' * m),可以看到
  	使用加法交换律改写m + n'即可得证,然而等式中存在多个加号,使用一般得加法交换律会导
  	致rewrite无法确定应该改写哪一个(例如改写等式左边第二个加号则会导致无法证明),因
  	此我们使用assert针对上述目标中的变量名称以及需要交换的部分(m + n')定义一个特定
  	的加法交换律,实现对所需特定位置的rewrite*)
  assert(H: m + n' = n' + m).
  (* 使用通用的交换律证明这里特定的交换律 *)
  --rewrite -> plus_comm. reflexivity.
  (* 使用特定的交换律实现目标中指定部分的rewrite从而证明目标 *)
  --rewrite -> H. reflexivity.
Qed.

replace

上边提到在rewrite无法确定正确的改写位置时可以使用assert来定义一个针对目标中需要改写位置的子定理来实现控制rewrite的改写位置。除了该方法外,还可以使用replace来实现。使用replace可以将目标中的某部分t替换为q,替换之后会生成一个t = q的子目标,需要证明t=q,相当于使用assert定义了一个t=q的子定理,然后使用该子定理rewrite原目标。

replace (t) with (p)

下面是一个小例子,该例子使用加法交换律plus_comm,然而在目标中存在多个可交换的地方,因此使用replace对指定位置进行替换。

Theorem plus_swap' : forall n m p : nat,
  n + (m + p) = m + (n + p).
Proof.
  intros n m p. induction n as [|n' Hn].
  -simpl. reflexivity.
  (* 这里后续会补充当前目标,方便理解replace的使用 *)
  (* 为了证明目标,使用S (n' + p) + m替换了目标中的m + S (n' + p)
  	 另外生成了一个子目标m + S (n' + p) = S (n' + p) + m需要证明
  *)
  -simpl. replace (m + S (n' + p)) with (S (n' + p) + m).
  --simpl. rewrite -> Hn. rewrite <- plus_comm. reflexivity.
  --rewrite <- plus_comm. reflexivity.
Qed.

重点练习

定义unary表示转换为binary表示的函数

Fixpoint nat_to_bin (n:nat) : bin :=
  match n with
  (* 0到0的转换 *)
  | O => Z
  (* >= 1的数使用incr函数(第一章basics中定义)结合递归定义来实现 *)
  | S n' => incr (nat_to_bin n')
  end.

证明转换函数的正确性,即证明

Theorem nat_bin_nat : forall n, bin_to_nat (nat_to_bin n) = n.

在使用数学归纳法证明该定理的过程中,存在一个bin_to_nat (incr (nat_to_bin n')) = S n'的中间目标,而归纳假设为bin_to_nat (nat_to_bin n') = n'。为了使用归纳假设,我们需要将incr函数转换到最外层去,因此,我们定义如下引理

Lemma bin_incr: forall n : bin, bin_to_nat (incr n) = S (bin_to_nat n).
Proof.
  intros n. induction n as [|n1 Hn1 |n2 Hn2].
  -simpl. reflexivity.
  -simpl. reflexivity.
  -simpl. rewrite -> Hn2. simpl. rewrite <- plus_comm. reflexivity.
Qed.

使用该引理即可证明转换函数的正确性定理。

Theorem nat_bin_nat : forall n, bin_to_nat (nat_to_bin n) = n.
Proof.
  intros n. induction n as [|n' Hn].
  -simpl. reflexivity.
  -simpl. rewrite -> bin_incr. rewrite -> Hn. reflexivity.
Qed.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值