(** **** Exercise: 1 star, standard (plus_id_exercise) *)
Theorem plus_id_exercise : forall n m o : nat, n = m -> m = o -> n + m = m + o. Proof. intros n m o. (* intros 务必按照匹配的顺序进行变量和谓词 *) intros H H'. rewrite -> H. rewrite -> H'. reflexivity. Qed. (** [] *)
->``<-意思是改写的方向,如果不具体写出就是->
1 2 3 4 5 6 7 8 9 10 11
(** **** Exercise: 1 star, standard (mult_n_1) *)
Theorem mult_n_1 : forall p : nat, p * 1 = p. Proof. intros p. rewrite <- mult_n_Sm. rewrite <- mult_n_O. reflexivity. Qed. (** [] *)
Proof by Case Analysis
有时候命题的两边难以简化至其他term,无法直接使用rewrite.或者simpl.
比如:
1
Theorem add_0_r : forall n : nat, 0 + n = n.
很容易证明,但是:
1
Theorem add_0_l : forall n : nat, n + 0 = n.
需要一些额外的技巧。 假设plus是这样定义的
1 2 3 4 5
Fixpoint plus (n : nat) (m : nat) : nat := match n with | O => m | S n' => S (plus n' m) end.
add_0_r左边很容易简化到n,左右 term 相同就证明成功了。add_0_l则不知道具体走哪个match-branch。
(** **** Exercise: 2 stars, standard (andb_true_elim2) 1. 可以对假设进行简化,[simpl in H.] 2. 最终会需要破坏(destruct)两个 bool,最好在破坏第二个之前就简化一下 H 3. 在某些不合理的 subgoal(比如已经枚举 c 是 false 了)下,你很可能发现 H 也不合理,这时使用 H rewrite,就能负负得正。 *)
Theorem andb_true_elim2 : forall b c : bool, andb b c = true -> c = true. Proof. intros b c. intros H. simplin H. destruct b eqn:Eb. (* true | false *) - destruct c eqn:Ec. + reflexivity. + rewrite <- H. reflexivity. - destruct c eqn:Ec. + reflexivity. + rewrite <- H. reflexivity. Qed. (** [] *)
(** **** Exercise: 1 star, standard (identity_fn_applied_twice) *)
Theorem identity_fn_applied_twice : forall (f : bool -> bool), (forall (x : bool), f x = x) -> forall (b : bool), f (f b) = b. Proof. intros f Fx b. rewrite -> Fx. rewrite -> Fx. reflexivity. Qed.
(** **** Exercise: 1 star, standard (negation_fn_applied_twice) *)
Theorem negation_fn_applied_twice : forall (f : bool -> bool), (forall (x : bool), f x = negb x) -> forall (b : bool), f (f b) = b. Proof. intros f Fx b. rewrite -> Fx. rewrite -> Fx. destruct b as []. - reflexivity. - reflexivity. Qed.
(* Do not modify the following line: *) Definition manual_grade_for_negation_fn_applied_twice : option (nat*string) := None. (** (The last definition is used by the autograder.) [] *)
Theorem andb_eq_orb : forall (b c : bool), (andb b c = orb b c) -> b = c. Proof. intros [] c H. (* 需要注意的是 simpl in H 不能提出来,因为 bullet 内外 context 不同,化简结果也不同 *) - simplin H. rewrite -> H. reflexivity. - simplin H. rewrite -> H. reflexivity. Qed.
(** **** Exercise: 2 stars, standard (grade_comparison) *)
Definition grade_comparison (g1 g2 : grade) : comparison := match g1, g2 with | (Grade l1 m1), (Grade l2 m2) => match letter_comparison l1 l2 with | Eq => modifier_comparison m1 m2 | Gt => Gt | Lt => Lt end end.
(** The following "unit tests" of your [grade_comparison] function should pass once you have defined it correctly. *)
Example test_grade_comparison1 : (grade_comparison (Grade A Minus) (Grade B Plus)) = Gt. Proof. simpl. reflexivity. Qed.
Example test_grade_comparison2 : (grade_comparison (Grade A Minus) (Grade A Plus)) = Lt. Proof. simpl. reflexivity. Qed.
Example test_grade_comparison3 : (grade_comparison (Grade F Plus) (Grade F Plus)) = Eq. Proof. simpl. reflexivity. Qed.
Example test_grade_comparison4 : (grade_comparison (Grade B Minus) (Grade C Plus)) = Gt. Proof. simpl. reflexivity. Qed.
重写Theorem lower_letter_lowers,需要特殊处理l = F的情况
1 2 3 4 5 6 7 8 9 10 11 12 13
(** **** Exercise: 2 stars, standard (lower_letter_lowers) *) Theorem lower_letter_lowers: forall (l : letter), letter_comparison F l = Lt -> letter_comparison (lower_letter l) l = Lt. Proof. intros l H. destruct l; simplin H; tryrewrite <- H; simpl; reflexivity. Qed.
填写并验证降级函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
(** **** Exercise: 2 stars, standard (lower_grade) *) Definition lower_grade (g : grade) : grade := match g with | Grade l m => match m with | Plus => Grade l Natural | Natural => Grade l Minus | Minus => match letter_comparison l F with | Eq => Grade F Minus | _ => Grade (lower_letter l) Plus end end end.
(** **** Exercise: 3 stars, standard (lower_grade_lowers) Hint: If you defined your [grade_comparison] function as suggested, you will only need to destruct a [letter] in one case. The case for [F] will probably benefit from [lower_grade_F_Minus]. *) Theorem lower_grade_lowers : forall (g : grade), grade_comparison (Grade F Minus) g = Lt -> grade_comparison (lower_grade g) g = Lt. Proof. intros g H. destruct g as [l m] eqn:Eg. destruct l, m; simpl lower_grade; tryrewrite -> H; reflexivity. Qed.
(* 能用上 lower_grade_F_Minus 的写法 *) Theorem lower_grade_lowers' : forall (g : grade), grade_comparison (Grade F Minus) g = Lt -> grade_comparison (lower_grade g) g = Lt. Proof. intros g H. destruct g as [l m] eqn:Eg. rewrite <- lower_grade_F_Minus in H. destruct l, m; tryrewrite -> H; simpl; reflexivity. Qed.
Inductive bin : Type := | Z | B0 (n : bin) | B1 (n : bin).
(** Complete the definitions below of an increment function [incr] for binary numbers, and a function [bin_to_nat] to convert binary numbers to unary numbers. *)
Fixpoint incr (m:bin) : bin := match m with | Z => B1 Z | B0 m' => B1 m' | B1 Z => B0 (B1 Z) (* B0 m *) | B1 m' => B0 (incr m') end. Fixpoint bin_to_nat (m:bin) : nat := match m with | Z => O | B0 m' => mult 2 (bin_to_nat m') | B1 m' => 1 + (mult 2 (bin_to_nat m')) end. (** The following "unit tests" of your increment and binary-to-unary functions should pass after you have defined those functions correctly. Of course, unit tests don't fully demonstrate the correctness of your functions! We'll return to that thought at the end of the next chapter. *)