The Following Are Equivalent (TFAE) #
This file provides the tactics tfae_have
and tfae_finish
for proving goals of the form
TFAE [P₁, P₂, ...]
.
Parsing and syntax #
We implement tfae_have
in terms of a syntactic have
. To support as much of the same syntax as
possible, we recreate the parsers for have
, except with the changes necessary for tfae_have
.
The following parsers are similar to those for have
in Lean.Parser.Term
, but
instead of optType
, we use tfaeType := num >> impArrow >> num
(as a tfae_have
invocation must
always include this specification). Also, we disallow including extra binders, as that makes no
sense in this context; we also include " : "
after the binder to avoid breaking tfae_have 1 → 2
syntax (which, unlike have
, omits " : "
).
tfae_have
introduces hypotheses for proving goals of the form TFAE [P₁, P₂, ...]
. Specifically,
tfae_have i <arrow> j := ...
introduces a hypothesis of type Pᵢ <arrow> Pⱼ
to the local
context, where <arrow>
can be →
, ←
, or ↔
. Note that i
and j
are natural number indices
(beginning at 1) used to specify the propositions P₁, P₂, ...
that appear in the goal.
example (h : P → R) : TFAE [P, Q, R] := by
tfae_have 1 → 3 := h
...
The resulting context now includes tfae_1_to_3 : P → R
.
Once sufficient hypotheses have been introduced by tfae_have
, tfae_finish
can be used to close
the goal. For example,
example : TFAE [P, Q, R] := by
tfae_have 1 → 2 := sorry /- proof of P → Q -/
tfae_have 2 → 1 := sorry /- proof of Q → P -/
tfae_have 2 ↔ 3 := sorry /- proof of Q ↔ R -/
tfae_finish
All relevant features of have
are supported by tfae_have
, including naming, destructuring, goal
creation, and matching. These are demonstrated below.
example : TFAE [P, Q] := by
-- `tfae_1_to_2 : P → Q`:
tfae_have 1 → 2 := sorry
-- `hpq : P → Q`:
tfae_have hpq : 1 → 2 := sorry
-- inaccessible `h✝ : P → Q`:
tfae_have _ : 1 → 2 := sorry
-- `tfae_1_to_2 : P → Q`, and `?a` is a new goal:
tfae_have 1 → 2 := f ?a
-- create a goal of type `P → Q`:
tfae_have 1 → 2
· exact (sorry : P → Q)
-- match on `p : P` and prove `Q`:
tfae_have 1 → 2
| p => f p
-- introduces `pq : P → Q`, `qp : Q → P`:
tfae_have ⟨pq, qp⟩ : 1 ↔ 2 := sorry
...
Equations
- One or more equations did not get rendered due to their size.
Instances For
tfae_finish
is used to close goals of the form TFAE [P₁, P₂, ...]
once a sufficient collection
of hypotheses of the form Pᵢ → Pⱼ
or Pᵢ ↔ Pⱼ
have been introduced to the local context.
tfae_have
can be used to conveniently introduce these hypotheses; see tfae_have
.
Example:
example : TFAE [P, Q, R] := by
tfae_have 1 → 2 := sorry /- proof of P → Q -/
tfae_have 2 → 1 := sorry /- proof of Q → P -/
tfae_have 2 ↔ 3 := sorry /- proof of Q ↔ R -/
tfae_finish
Equations
- Mathlib.Tactic.TFAE.tfaeFinish = Lean.ParserDescr.node `Mathlib.Tactic.TFAE.tfaeFinish 1024 (Lean.ParserDescr.nonReservedSymbol "tfae_finish" false)
Instances For
Setup #
Extract a list of Prop
expressions from an expression of the form TFAE [P₁, P₂, ...]
as
long as [P₁, P₂, ...]
is an explicit list.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Convert an expression representing an explicit list into a list of expressions.
Proof construction #
Generate a proof of Chain (· → ·) P l
. We assume P : Prop
and l : List Prop
, and that l
is an explicit list.
tfae_have
components #
Construct a name for a hypothesis introduced by tfae_have
.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Turn syntax for a given index into a natural number, as long as it lies between 1
and
maxIndex
.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Tactic implementation #
Accesses the propositions at indices i
and j
of tfaeList
, and constructs the expression
Pi <arr> Pj
, which will be the type of our tfae_have
hypothesis
Equations
- One or more equations did not get rendered due to their size.
Instances For
"Old-style" tfae_have
#
We preserve the "old-style" tfae_have
(which behaves like Mathlib have
) for compatibility
purposes.
tfae_have
introduces hypotheses for proving goals of the form TFAE [P₁, P₂, ...]
. Specifically,
tfae_have i <arrow> j := ...
introduces a hypothesis of type Pᵢ <arrow> Pⱼ
to the local
context, where <arrow>
can be →
, ←
, or ↔
. Note that i
and j
are natural number indices
(beginning at 1) used to specify the propositions P₁, P₂, ...
that appear in the goal.
example (h : P → R) : TFAE [P, Q, R] := by
tfae_have 1 → 3 := h
...
The resulting context now includes tfae_1_to_3 : P → R
.
Once sufficient hypotheses have been introduced by tfae_have
, tfae_finish
can be used to close
the goal. For example,
example : TFAE [P, Q, R] := by
tfae_have 1 → 2 := sorry /- proof of P → Q -/
tfae_have 2 → 1 := sorry /- proof of Q → P -/
tfae_have 2 ↔ 3 := sorry /- proof of Q ↔ R -/
tfae_finish
All relevant features of have
are supported by tfae_have
, including naming, destructuring, goal
creation, and matching. These are demonstrated below.
example : TFAE [P, Q] := by
-- `tfae_1_to_2 : P → Q`:
tfae_have 1 → 2 := sorry
-- `hpq : P → Q`:
tfae_have hpq : 1 → 2 := sorry
-- inaccessible `h✝ : P → Q`:
tfae_have _ : 1 → 2 := sorry
-- `tfae_1_to_2 : P → Q`, and `?a` is a new goal:
tfae_have 1 → 2 := f ?a
-- create a goal of type `P → Q`:
tfae_have 1 → 2
· exact (sorry : P → Q)
-- match on `p : P` and prove `Q`:
tfae_have 1 → 2
| p => f p
-- introduces `pq : P → Q`, `qp : Q → P`:
tfae_have ⟨pq, qp⟩ : 1 ↔ 2 := sorry
...
Equations
- One or more equations did not get rendered due to their size.