Built with Alectryon, running Coq+SerAPI v8.19.0+0.19.3. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑ Ctrl+↓ to navigate, Ctrl+🖱️ to focus. On Mac, use instead of Ctrl.

Lecture 2: Propositional Reasoning

In this lecture, we learn how to do proofs with propositional logical connectives:

We then show how all these connectives can be encoded using only forall and ->.

P: Prop

False -> P
P: Prop

False -> P
P: Prop
H: False

P
destruct H. Qed.
P: Prop

P -> P /\ True
P: Prop

P -> P /\ True
P: Prop
H: P

P /\ True
P: Prop
H: P

P
P: Prop
H: P
True
P: Prop
H: P

True
constructor. Qed.
P, Q: Prop

P /\ Q -> Q /\ P
P, Q: Prop

P /\ Q -> Q /\ P
P, Q: Prop
H: P /\ Q

Q /\ P
P, Q: Prop
HP: P
HQ: Q

Q /\ P
P, Q: Prop
HP: P
HQ: Q

Q
P, Q: Prop
HP: P
HQ: Q
P
P, Q: Prop
HP: P
HQ: Q

Q
apply HQ.
P, Q: Prop
HP: P
HQ: Q

P
apply HP. Qed.
P, Q, R: Prop

P \/ Q -> (P -> R) /\ (Q -> R) -> R
P, Q, R: Prop

P \/ Q -> (P -> R) /\ (Q -> R) -> R
P, Q, R: Prop
HOr: P \/ Q
HAnd: (P -> R) /\ (Q -> R)

R
P, Q, R: Prop
HOr: P \/ Q
HPR: P -> R
HQR: Q -> R

R
P, Q, R: Prop
H: P
HPR: P -> R
HQR: Q -> R

R
P, Q, R: Prop
H: Q
HPR: P -> R
HQR: Q -> R
R
P, Q, R: Prop
H: P
HPR: P -> R
HQR: Q -> R

R
P, Q, R: Prop
H: P
HPR: P -> R
HQR: Q -> R

P
apply H.
P, Q, R: Prop
H: Q
HPR: P -> R
HQR: Q -> R

R
P, Q, R: Prop
H: Q
HPR: P -> R
HQR: Q -> R

Q
apply H. Qed.
P, Q: Prop

~ (P \/ Q) -> ~ P /\ ~ Q
P, Q: Prop

~ (P \/ Q) -> ~ P /\ ~ Q
P, Q: Prop
H: ~ (P \/ Q)

~ P /\ ~ Q
P, Q: Prop
H: ~ (P \/ Q)

~ P
P, Q: Prop
H: ~ (P \/ Q)
~ Q
P, Q: Prop
H: ~ (P \/ Q)

~ P
P, Q: Prop
H: ~ (P \/ Q)

P -> False
P, Q: Prop
H: ~ (P \/ Q)
HP: P

False
P, Q: Prop
H: ~ (P \/ Q)
HP: P

P \/ Q
P, Q: Prop
H: ~ (P \/ Q)
HP: P

P
apply HP.
P, Q: Prop
H: ~ (P \/ Q)

~ Q
P, Q: Prop
H: ~ (P \/ Q)

Q -> False
P, Q: Prop
H: ~ (P \/ Q)
HQ: Q

False
P, Q: Prop
H: ~ (P \/ Q)
HQ: Q

P \/ Q
P, Q: Prop
H: ~ (P \/ Q)
HQ: Q

Q
apply HQ. Qed.
P, Q: Prop

~ (P /\ Q) -> ~ P \/ ~ Q
P, Q: Prop

~ (P /\ Q) -> ~ P \/ ~ Q
P, Q: Prop
H: ~ (P /\ Q)

~ P \/ ~ Q
P, Q: Prop
H: ~ (P /\ Q)

~ P
P, Q: Prop
H: ~ (P /\ Q)
HP: P

False
P, Q: Prop
H: ~ (P /\ Q)
HP: P

P /\ Q
P, Q: Prop
H: ~ (P /\ Q)
HP: P

P
P, Q: Prop
H: ~ (P /\ Q)
HP: P
Q
P, Q: Prop
H: ~ (P /\ Q)
HP: P

Q
(* We cannot prove this in Coq as it is not constructively valid. *) Abort.

We can prove it if we assume the law of excluded middle.

Axiom excluded_middle : forall (P : Prop), P \/ ~P.

P, Q: Prop

~ (P /\ Q) -> ~ P \/ ~ Q
P, Q: Prop

~ (P /\ Q) -> ~ P \/ ~ Q
(* Exercise! *) Admitted.

A different encoding using forall and ->

Next, we show how to define the logical connectives using only forall and ->.

Definition Fals := forall (P : Prop), P.

P: Prop

Fals -> P
P: Prop

Fals -> P
P: Prop

(forall P : Prop, P) -> P
P: Prop
H: forall P : Prop, P

P
apply H. Qed.

Fals <-> False

Fals <-> False

Fals -> False

False -> Fals

Fals -> False
H: Fals

False
apply H.

False -> Fals
H: False

Fals
destruct H. Qed. Definition not (P : Prop) : Prop := P -> Fals. Definition Tru := not Fals.

Tru

Tru

not Fals

Fals -> Fals
H: Fals

Fals
apply H. Qed.

Tru <-> True

Tru <-> True

Tru -> True

True -> Tru

Tru -> True
H: Tru

True
constructor.

True -> Tru
H: True

Tru
apply Tru_intro. Qed. Definition and (P Q : Prop) : Prop := forall (R : Prop), (P -> Q -> R) -> R.
P, Q: Prop

and P Q -> P
P, Q: Prop

and P Q -> P
P, Q: Prop
H: and P Q

P
P, Q: Prop
H: forall R : Prop, (P -> Q -> R) -> R

P
P, Q: Prop
H: forall R : Prop, (P -> Q -> R) -> R

P -> Q -> P
P, Q: Prop
H: forall R : Prop, (P -> Q -> R) -> R
H1: P
H2: Q

P
apply H1. Qed.
P, Q: Prop

and P Q -> Q
P, Q: Prop

and P Q -> Q
P, Q: Prop
H: and P Q

Q
P, Q: Prop
H: forall R : Prop, (P -> Q -> R) -> R

Q
P, Q: Prop
H: forall R : Prop, (P -> Q -> R) -> R

P -> Q -> Q
P, Q: Prop
H: forall R : Prop, (P -> Q -> R) -> R
H1: P
H2: Q

Q
apply H2. Qed.
P, Q: Prop

P -> Q -> and P Q
P, Q: Prop

P -> Q -> and P Q
P, Q: Prop
HP: P
HQ: Q

and P Q
P, Q: Prop
HP: P
HQ: Q

forall R : Prop, (P -> Q -> R) -> R
P, Q: Prop
HP: P
HQ: Q
R: Prop
H: P -> Q -> R

R
P, Q: Prop
HP: P
HQ: Q
R: Prop
H: P -> Q -> R

P
P, Q: Prop
HP: P
HQ: Q
R: Prop
H: P -> Q -> R
Q
P, Q: Prop
HP: P
HQ: Q
R: Prop
H: P -> Q -> R

P
exact HP.
P, Q: Prop
HP: P
HQ: Q
R: Prop
H: P -> Q -> R

Q
exact HQ. Qed.
P, Q: Prop

and P Q -> and Q P
P, Q: Prop

and P Q -> and Q P
P, Q: Prop
H: and P Q

and Q P
P, Q: Prop
H: and P Q

Q
P, Q: Prop
H: and P Q
P
P, Q: Prop
H: and P Q

Q
P, Q: Prop
H: and P Q

and P Q
apply H.
P, Q: Prop
H: and P Q

P
P, Q: Prop
H: and P Q

and P Q
apply H. Qed.
P, Q: Prop

and P Q <-> P /\ Q
P, Q: Prop

and P Q <-> P /\ Q
P, Q: Prop

and P Q -> P /\ Q
P, Q: Prop
P /\ Q -> and P Q
P, Q: Prop

and P Q -> P /\ Q
P, Q: Prop
H: and P Q

P /\ Q
P, Q: Prop
H: and P Q

P
P, Q: Prop
H: and P Q
Q
P, Q: Prop
H: and P Q

P
apply (and_elim_left P Q H).
P, Q: Prop
H: and P Q

Q
apply (and_elim_right P Q H).
P, Q: Prop

P /\ Q -> and P Q
P, Q: Prop
H: P /\ Q

and P Q
P, Q: Prop
HP: P
HQ: Q

and P Q
P, Q: Prop
HP: P
HQ: Q

P
P, Q: Prop
HP: P
HQ: Q
Q
P, Q: Prop
HP: P
HQ: Q

P
apply HP.
P, Q: Prop
HP: P
HQ: Q

Q
apply HQ. Qed.

We can define our own tactics similar to the built-in tactics

Ltac destruct_and H :=
  pose proof (and_elim_left _ _ H) as H1;
  pose proof (and_elim_right _ _ H) as H2;
  clear H.

Ltac split_and := apply and_intro.

P, Q: Prop

and P Q -> and Q P
P, Q: Prop

and P Q -> and Q P
P, Q: Prop
H: and P Q

and Q P
P, Q: Prop
H1: P
H2: Q

and Q P
P, Q: Prop
H1: P
H2: Q

Q
P, Q: Prop
H1: P
H2: Q
P
P, Q: Prop
H1: P
H2: Q

Q
apply H2.
P, Q: Prop
H1: P
H2: Q

P
apply H1. Qed. Definition or (P Q : Prop) : Prop := forall (R : Prop), (P -> R) -> (Q -> R) -> R.
P, Q: Prop

P -> or P Q
P, Q: Prop

P -> or P Q
P, Q: Prop
HP: P

or P Q
P, Q: Prop
HP: P

forall R : Prop, (P -> R) -> (Q -> R) -> R
P, Q: Prop
HP: P
R: Prop
H1: P -> R
H2: Q -> R

R
P, Q: Prop
HP: P
R: Prop
H1: P -> R
H2: Q -> R

P
apply HP. Qed.
P, Q: Prop

Q -> or P Q
P, Q: Prop

Q -> or P Q
P, Q: Prop
HQ: Q

or P Q
P, Q: Prop
HQ: Q

forall R : Prop, (P -> R) -> (Q -> R) -> R
P, Q: Prop
HQ: Q
R: Prop
H1: P -> R
H2: Q -> R

R
P, Q: Prop
HQ: Q
R: Prop
H1: P -> R
H2: Q -> R

Q
apply HQ. Qed.
P, Q, R: Prop

or P Q -> (P -> R) -> (Q -> R) -> R
P, Q, R: Prop

or P Q -> (P -> R) -> (Q -> R) -> R
P, Q, R: Prop
HPQ: or P Q
H1: P -> R
H2: Q -> R

R
P, Q, R: Prop
HPQ: forall R : Prop, (P -> R) -> (Q -> R) -> R
H1: P -> R
H2: Q -> R

R
P, Q, R: Prop
HPQ: forall R : Prop, (P -> R) -> (Q -> R) -> R
H1: P -> R
H2: Q -> R

P -> R
P, Q, R: Prop
HPQ: forall R : Prop, (P -> R) -> (Q -> R) -> R
H1: P -> R
H2: Q -> R
Q -> R
P, Q, R: Prop
HPQ: forall R : Prop, (P -> R) -> (Q -> R) -> R
H1: P -> R
H2: Q -> R

P -> R
apply H1.
P, Q, R: Prop
HPQ: forall R : Prop, (P -> R) -> (Q -> R) -> R
H1: P -> R
H2: Q -> R

Q -> R
apply H2. Qed.
P, Q: Prop

or P Q <-> P \/ Q
P, Q: Prop

or P Q <-> P \/ Q
(* Exercise *) Admitted.

As a bonus, we can also encode equality à la Leibniz.

Definition eq (T : Type) (x : T) (y : T) : Prop := forall (P : T -> Prop), P x -> P y.

T: Type
x: T

eq T x x
T: Type
x: T

eq T x x
T: Type
x: T
P: T -> Prop
H: P x

P x
apply H. Qed.
T: Type
x, y: T

eq T x y -> eq T y x
T: Type
x, y: T

eq T x y -> eq T y x
T: Type
x, y: T
H: eq T x y

eq T y x
T: Type
x, y: T
H: eq T x y

eq T x x
apply eq_refl. Qed.
T: Type
x, y, z: T

eq T x y -> eq T y z -> eq T x z
T: Type
x, y, z: T

eq T x y -> eq T y z -> eq T x z
T: Type
x, y, z: T
H1: eq T x y
H2: eq T y z

eq T x z
T: Type
x, y, z: T
H1: eq T x y
H2: eq T y z

eq T x y
apply H1. Qed.
T: Type
x, y: T

eq T x y <-> x = y
T: Type
x, y: T

eq T x y <-> x = y
(* Exercise *) Admitted.

In fact, even implication (->) can be encoded using forall!

Definition imp (P Q : Prop) : Prop := forall H : P, Q.

P, Q: Prop

imp P Q <-> (P -> Q)
P, Q: Prop

imp P Q <-> (P -> Q)
P, Q: Prop

(P -> Q) <-> (P -> Q)
(* Coq already prints the forall as ->. *) (* Implication is *literally* just a forall! *)
P, Q: Prop

(P -> Q) -> P -> Q
P, Q: Prop
(P -> Q) -> P -> Q
P, Q: Prop

(P -> Q) -> P -> Q
P, Q: Prop
H: P -> Q

P -> Q
apply H.
P, Q: Prop

(P -> Q) -> P -> Q
P, Q: Prop
H: P -> Q

P -> Q
apply H. Qed.

Coq's Encoding

In Coq, the connectives are not defined in terms of forall, but in terms of Inductive types. An inductive type lists all the constructors that make up the type. For propositions, this means that it lists all the ways to prove the proposition.

There are no ways to prove False.

Inductive False' : Prop := .

There is one way to prove True.

Inductive True' : Prop :=
  | I : True'. (* I is the constructor for True' *)

To prove and P Q, we need to provide a proof of P and a proof of Q.

Inductive and' (P Q : Prop) : Prop :=
  | conj : P -> Q -> and' P Q. (* conj is the constructor for and' *)

To prove or P Q, we need to provide a proof of P or a proof of Q.

Inductive or' (A B : Prop) : Prop :=
  | or_introl : A -> or' A B (* or_introl is the constructor for proving or' from A *)
  | or_intror : B -> or' A B. (* or_intror is the constructor for proving or' from B *)

Equality is a more complex example. The only way to prove eq' T x y is if x and y are the same.

Inductive eq' (T : Type) (x : T) : T -> Prop :=
  | eq_refl' : eq' T x x. (* eq_refl' is the constructor for eq' *)

These inductive types are manipulated with two tactics:

  • destruct: do case analysis on the inductive type
  • apply [constructor_name]: apply the constructor to prove the type (we can also use constructor i for the i-th constructor, or simply constructor to apply the first matching constructor)
P, Q: Prop

and' P Q -> and' Q P
P, Q: Prop

and' P Q -> and' Q P
P, Q: Prop
H: and' P Q

and' Q P
P, Q: Prop
HP: P
HQ: Q

and' Q P
P, Q: Prop
HP: P
HQ: Q

Q
P, Q: Prop
HP: P
HQ: Q
P
P, Q: Prop
HP: P
HQ: Q

Q
apply HQ.
P, Q: Prop
HP: P
HQ: Q

P
apply HP. Qed.
P, Q: Prop

or' P Q -> or' Q P
P, Q: Prop

or' P Q -> or' Q P
P, Q: Prop
H: or' P Q

or' Q P
P, Q: Prop
HP: P

or' Q P
P, Q: Prop
HQ: Q
or' Q P
P, Q: Prop
HP: P

or' Q P
P, Q: Prop
HP: P

P
apply HP.
P, Q: Prop
HQ: Q

or' Q P
P, Q: Prop
HQ: Q

Q
apply HQ. Qed.
T: Type
x, y: T

eq' T x y -> eq' T y x
T: Type
x, y: T

eq' T x y -> eq' T y x
T: Type
x, y: T
H: eq' T x y

eq' T y x
T: Type
x: T

eq' T x x
apply eq_refl'. Qed.