(** * Logic: Logic in Coq *)
Set Warnings "-notation-overridden,-parsing".
Require Export Tactics.
(** In previous chapters, we have seen many examples of factual claims (_propositions_) and ways of presenting evidence of their truth (_proofs_).  In particular, we have worked extensively with _equality propositions_ of the form [e1 = e2], with implications ([P -> Q]), and with quantified propositions ([forall x, P]).  In this chapter, we will see how Coq can be used to carry out other familiar forms of logical reasoning.  Before diving into details, let's talk a bit about the status of mathematical statements in Coq.  Recall that Coq is a _typed_ language, which means that every sensible expression in its world has an associated type.  Logical claims are no exception: any statement we might try to prove in Coq has a type, namely [Prop], the type of _propositions_.  We can see this with the [Check] command: *)
Check 3 = 3.
(* ===> Prop *)
Check forall n m : nat, n + m = m + n.
(* ===> Prop *)
(** Note that _all_ syntactically well-formed propositions have type [Prop] in Coq, regardless of whether they are true or not.  Simply _being_ a proposition is one thing; being _provable_ is something else! *)
Check forall n : nat, n = 2.
(* ===> Prop *)
Check 3 = 4.
(* ===> Prop *)
(** Indeed, propositions don't just have types: they are _first-class objects_ that can be manipulated in the same ways as the other entities in Coq's world.  So far, we've seen one primary place that propositions can appear: in [Theorem] (and [Lemma] and [Example]) declarations. *)

(* Specifications: *)
Theorem plus_2_2_is_4 :
2 + 2 = 4.