And P Q
has only one constructor, called And.intro
.inductive And (P Q : Prop) : Prop
| intro : P → Q → And P Q
So, formally, defining a proposition is no different from defining a type.
We are starting to see that propositions behave like types, with functions between those types representings implications:
inductive False : Prop
The induction principle attached to
def cons_imp_classical {P Q : Prop} : (P → Q) → ¬(P ∧ ¬Q) :=
fun (f : P → Q) ↦ fun (And.intro (p : P) (g : Q → False)) ↦ g (f p)
Or.inl
and Or.inr
).inductive Or (P Q : Prop) : Prop
| inl : P → Or P Q
| inr : Q → Or P Q
inductive Iff (P Q : Prop) : Prop
| intro : (P → Q) → (Q → P) → Iff P Q
structure
).structure Iff (P Q : Prop) : Prop where
intro :: (mp : P → Q) (mpr : Q → P)
The basic tactic we shall need are the following:
exact
apply
intro
revert
constructor
rcases
(and cases
)left
and right
rfl
All these tactics are presented in the accompanying file for this lecture.
Let us use tactic mode to prove the modus ponens rule. The point is to see the proof state and the goal evolve after each use of a tactic, until the goal is closed.
theorem mp {P Q : Prop} : (P → Q) ∧ P → Q := by -- the goal is `(P → Q) ∧ P → Q`
intro h
-- introduces a term of type `(P → Q) ∧ P` in the local context (new goal: `Q`)
rcases h with ⟨f, p⟩ -- destructs `h` into `f : P → Q` and `p : P` (goal is still `Q`)
exact f p -- constructs a term `f p : Q`, which closes the goal (unification)
For comparison, the term mode proof would be more or less of the same length, but in term mode the infoview does not show anything, except the absence of an error message.
theorem mp {P Q : Prop} : (P → Q) ∧ P → Q :=
fun (And.intro (f : P → Q) (p : P)) ↦ f p
A tautology is a proposition which is built up from older ones and which has a proof regardless of whether the old ones do. Proving such propositions help familiarise oneself with the basic tactics. Can you state and prove the following ones?