(* Copyright (c) 2008-2012, Adam Chlipala
*
* This work is licensed under a
* Creative Commons Attribution-Noncommercial-No Derivative Works 3.0
* Unported License.
* The license text is available at:
* http://creativecommons.org/licenses/by-nc-nd/3.0/
*)
Require Import List.
Require Import CpdtTactics.
Set Implicit Arguments.
Section Propositional.
Variables P Q R : Prop.
Theorem obvious : True.
apply I.
Qed.
Theorem obvious' : True.
constructor.
Qed.
Theorem False_imp : False -> 2 + 2 = 5.
destruct 1.
Qed.
Theorem arith_neq : 2 + 2 = 5 -> 9 + 9 = 835.
intro.
elimtype False.
crush.
Qed.
Theorem arith_neq' : ~ (2 + 2 = 5).
unfold not.
crush.
Qed.
Theorem and_comm : P /\ Q -> Q /\ P.
destruct 1.
split.
assumption.
assumption.
Qed.
Theorem or_comm : P \/ Q -> Q \/ P.
destruct 1.
right; assumption.
left; assumption.
Qed.
Theorem contra : P -> ~P -> R.
Admitted.
Theorem and_assoc : (P /\ Q) /\ R -> P /\ (Q /\ R).
Admitted.
(* ...boy, isn't this annoying? *)
Theorem or_assoc : (P \/ Q) \/ R -> P \/ (Q \/ R).
Admitted.
Theorem or_comm' : P \/ Q -> Q \/ P.
Admitted.
Theorem arith_comm : forall ls1 ls2 : list nat,
length ls1 = length ls2 \/ length ls1 + length ls2 = 6
-> length (ls1 ++ ls2) = 6 \/ length ls1 = length ls2.
intuition.
rewrite app_length.
tauto. (* or intuition. *)
Qed.
Theorem arith_comm' : forall ls1 ls2 : list nat,
length ls1 = length ls2 \/ length ls1 + length ls2 = 6
-> length (ls1 ++ ls2) = 6 \/ length ls1 = length ls2.
Hint Rewrite app_length.
crush.
Qed.
End Propositional.
Theorem exist1 : exists x : nat, x + 1 = 2.
exists 1.
reflexivity.
Qed.
Theorem exist2 : forall n m : nat, (exists x : nat, n + x = m) -> n <= m.
destruct 1.
crush.
Qed.
Theorem forall_exists_commute : forall (A B : Type) (P : A -> B -> Prop),
(exists x : A, forall y : B, P x y) -> (forall y : B, exists x : A, P x y).
Admitted.
(* ...can we just tauto? *)
(** * Predicates with Implicit Equality *)
(* Actually, slipped something by you:
P, Q, R := ...
| x = y
*)
Locate "=".
Print eq.
Theorem eq_cong : 3 = 2 + 1.
reflexivity.
Qed.
Inductive isZero : nat -> Prop :=
| IsZero : isZero 0.
Definition isZero' := fun x => x = 0.
Theorem same_damn_thing (x : nat) : isZero x <-> isZero' x.
crush.
Qed.
Theorem isZero_zero : isZero 0.
constructor.
Qed.
(* How do we choose whether to put parameters before or after the colon? *)
Theorem isZero_plus : forall n m : nat, isZero m -> n + m = n.
destruct 1.
crush.
Qed.
Theorem isZero_contra : isZero 1 -> False.
destruct 1.
(* gotcha! *)
Restart.
remember 1.
destruct 1.
discriminate.
Restart.
inversion 1.
Qed.
Theorem isZero_contra' : isZero 1 -> 2 + 2 = 5.
destruct 1.
(* gotcha! *)
Abort.
Check isZero_ind.
Check isZero_ind (fun n => S n + S n = S (S (S (S n)))).
(** * Recursive Predicates *)
Inductive even : nat -> Prop :=
| EvenO : even O
| EvenSS : forall n, even n -> even (S (S n)).
Theorem even_0 : even 0.
constructor.
Qed.
Theorem even_4 : even 4.
constructor; constructor; constructor.
Qed.
Hint Constructors even.
Theorem even_4' : even 4.
auto. (* or crush *)
Qed.
Theorem even_1_contra : even 1 -> False.
inversion 1.
Qed.
Theorem even_3_contra : even 3 -> False.
destruct 1.
Focus 2.
Restart.
inversion 1.
inversion H1.
Qed.
(* important trick for the homework here, pay attention *)
Theorem even_plus : forall n m, even n -> even m -> even (n + m).
induction n; crush.
inversion H.
simpl.
constructor.
Restart.
induction 1.
crush.
intro.
simpl; constructor.
apply IHeven; assumption.
Restart.
induction 1; crush.
Qed.
Theorem even_contra : forall n, even (S (n + n)) -> False.
induction 1.
Restart.
intros.
remember (S (n + n)).
generalize dependent n.
induction H.
discriminate.
intros.
destruct n; destruct n0; crush.
inversion Heqn0.
SearchRewrite (_ + S _).
rewrite <- plus_n_Sm in H1.
apply IHeven with n0.
assumption.
Abort.
Lemma even_contra' : forall n', even n' -> forall n, n' = S (n + n) -> False.
induction 1; crush.
destruct n; destruct n0; crush.
rewrite <- plus_n_Sm in H0.
apply IHeven with n0.
assumption.
Restart.
Hint Rewrite <- plus_n_Sm.
induction 1; crush;
match goal with
| [ H : S ?N = ?N0 + ?N0 |- _ ] => destruct N; destruct N0
end; crush; eauto.
Qed.
Theorem even_contra : forall n, even (S (n + n)) -> False.
intros; eapply even_contra'; eauto.
Qed.
Lemma even_contra'' : forall n' n, even n' -> n' = S (n + n) -> False.
induction 1; crush;
match goal with
| [ H : S ?N = ?N0 + ?N0 |- _ ] => destruct N; destruct N0
end; crush; eauto.
(* gotcha! *)
Abort.