所以这是我一直从Software Foundations工作的练习之一,其中我必须证明乘法是可交换的。这是我的解决方案:证明乘法是可交换的
Theorem brack_help : forall n m p: nat,
n + (m + p) = n + m + p.
Proof.
intros n m p.
induction n as [| n'].
Case "n = 0".
simpl.
reflexivity.
Case "n = S n'".
simpl.
rewrite -> IHn'.
reflexivity.
Qed.
Lemma plus_help: forall n m: nat,
S (n + m) = n + S m.
Proof.
intros n m.
induction n as [| n].
Case "n = 0".
simpl.
reflexivity.
Case "n = S n".
simpl.
rewrite -> IHn.
reflexivity.
Qed.
Theorem mult_0_r : forall n:nat,
n * 0 = 0.
Proof.
intros n.
induction n as [|n'].
Case "n = 0".
simpl.
reflexivity.
Case "n = S n'".
simpl.
rewrite -> IHn'.
reflexivity.
Qed.
Theorem plus_comm : forall n m : nat,
n + m = m + n.
Proof.
intros n m.
induction n as [| n].
Case "n = 0".
simpl.
rewrite <- plus_n_O.
reflexivity.
Case "n = S n".
simpl.
rewrite -> IHn.
rewrite -> plus_help.
reflexivity.
Qed.
Theorem plus_swap : forall n m p : nat,
n + (m + p) = m + (n + p).
Proof.
intros n m p.
rewrite -> brack_help.
assert (H: n + m = m + n).
Case "Proof of assertion".
rewrite -> plus_comm.
reflexivity.
rewrite -> H.
rewrite <- brack_help.
reflexivity.
Qed.
Lemma mult_help : forall m n : nat,
m + (m * n) = m * (S n).
Proof.
intros m n.
induction m as [| m'].
Case "m = 0".
simpl.
reflexivity.
Case "m = S m'".
simpl.
rewrite <- IHm'.
rewrite -> plus_swap.
reflexivity.
Qed.
Lemma mult_identity : forall m : nat,
m * 1 = m.
Proof.
intros m.
induction m as [| m'].
Case "m = 0".
simpl.
reflexivity.
Case "m = S m'".
simpl.
rewrite -> IHm'.
reflexivity.
Qed.
Lemma plus_0_r : forall m : nat,
m + 0 = m.
Proof.
intros m.
induction m as [| m'].
Case "m = 0".
simpl.
reflexivity.
Case "m = S m'".
simpl.
rewrite -> IHm'.
reflexivity.
Qed.
Theorem mult_comm_helper : forall m n : nat,
m * S n = m + m * n.
Proof.
intros m n.
simpl.
induction n as [| n'].
Case "n = 0".
assert (H: m * 0 = 0).
rewrite -> mult_0_r.
reflexivity.
rewrite -> H.
rewrite -> mult_identity.
assert (H2: m + 0 = m).
rewrite -> plus_0_r.
reflexivity.
rewrite -> H2.
reflexivity.
Case "n = S n'".
rewrite -> IHn'.
assert (H3: m + m * n' = m * S n').
rewrite -> mult_help.
reflexivity.
rewrite -> H3.
assert (H4: m + m * S n' = m * S (S n')).
rewrite -> mult_help.
reflexivity.
rewrite -> H4.
reflexivity.
Qed.
Theorem mult_comm : forall m n : nat,
m * n = n * m.
Proof.
intros m n.
induction n as [| n'].
Case "n = 0".
simpl.
rewrite -> mult_0_r.
reflexivity.
Case "n = S n'".
simpl.
rewrite <- IHn'.
rewrite -> mult_comm_helper.
reflexivity.
Qed.
现在在我看来,这个证明是相当庞大的。没有使用任何库,有没有更简洁的方法? (请注意,对于使用Case策略,您需要一些预定义的代码。自包含的工作代码位于以下要点:https://gist.github.com/psibi/1c80d61ca574ae62c23e)。
IMO这看起来不错 - 我只有一个快速浏览,但如果你从第一原则出发,这或多或少是你必须做的(看看[Whitehead和Russel](https://en.wikipedia.org/wiki/Principia_Mathematica)必须做的事情,直到他们能证明1 + 1 = 2;)) - 说了这些(并仔细看了一下) - 也许你不需要'mult_comm_helper',如果你在'm'上进行归纳(你的'*'是如何定义的?我还没有咖啡,所以它可能是废话) – Carsten
@Carsten提供了一个很好的观点 - 有几种稍微不同的方式来定义乘法,并且确切地说,简单的和难的似乎对您选择的非常敏感。当然,让一件事情变得容易的事情几乎肯定会让事情变得更加困难。 – dfeuer
@Carsten即使我在'm'上进行了归纳,我仍然需要'mult_comm_helper'(只是在这种情况下,重写方向会不同)。 '*'是根据加法定义的。 :) – Sibi