Read an error message¶
Lean's error messages are precise but not always friendly. This page lists
the errors met most often when writing game theory in Lean, each with the
message as Lean prints it, what it means, and the usual fix. The position
before each message, such as 12:10, is the line and column where Lean
reports the problem.
unsolved goals¶
This is the most common error of all:
The tactics ran without failing but did not finish the proof, and what is
left is shown after the ⊢. The position points at the by, not at the line
where something is missing. The usual fix is another tactic, or a hint to an
existing one: this message came from norm_num without [payoff].
unsolved goals and a missing import¶
Sometimes the goal left over looks too simple to have been missed:
When a goal as simple as 3 < 5 is left unsolved, the tactic is missing part
of itself. This came from a file importing only Mathlib.Data.Real.Basic,
where norm_num exists but its extensions for inequalities do not. Adding
import Mathlib.Tactic.NormNum fixes it. A missing import rarely produces an
error that mentions imports.
Unknown identifier¶
A misspelt name produces:
A name Lean does not know: usually a typo, a missing import, or a namespace
that has not been opened. Here it was a typo for payoff. The same line also
produces a second, confusing error, ⊢ sorry () = 5, because Lean carries on
with a placeholder, sorry, in place of the unknown name. Fix the first error
and the second disappears.
Ambiguous term¶
A name defined in two places produces:
error: GameTheory/HowTo/EveryStrategy.lean:12:45: Ambiguous term
payoff
Possible interpretations:
_root_.payoff : Action → Action → ℝ
RockPaperScissors.payoff : Hand → Hand → ℝ
Two definitions with the same name are both visible, here the Prisoner's
Dilemma payoff and the one opened from RockPaperScissors. Write the full
name, RockPaperScissors.payoff, or work inside the namespace rather than
opening it. See Encode a new game.
Missing cases¶
A payoff matrix with cells left out produces:
A definition by cases leaves some inputs uncovered, here two cells of a payoff matrix. The message lists exactly which, so add a line for each.
Type mismatch¶
A proof of the wrong statement produces:
error: GameTheory/Probe.lean:23:2: Type mismatch
smaller
has type
a < b
but is expected to have type
a ≤ b
A proof was given for a different statement from the goal. Lean does not
convert between < and ≤, or between other close relatives, on its own.
Bridge the gap with a lemma, here exact le_of_lt smaller. See Find a
lemma.
linarith failed¶
When linarith cannot find its argument, it shows what it tried:
error: GameTheory/Probe.lean:20:2: linarith failed to find a contradiction
x : ℝ
positive : 0 < x
a✝ : 0 ≤ x
⊢ False
failed
linarith works by assuming the goal is false and deriving a contradiction,
which is why the negated goal appears as a✝. Failure means that no linear
combination of the hypotheses works. Either the statement is false, as it is
here, or a definition needs unfolding first, or the argument needs products,
in which case try nlinarith. See Prove an
inequality.
There are no additional binders¶
A tactic applied to a goal of the wrong shape produces messages such as:
error: GameTheory/Probe.lean:26:8: Tactic `introN` failed: There are no additional binders or `let` bindings in the goal to introduce
⊢ payoff cooperate defect < payoff defect defect
intro was used on a goal that does not begin with ∀, → or ¬. Look at
the goal and choose a tactic that fits its shape.
Invalid field¶
Dot notation on a theorem that cannot be found produces:
error: GameTheory/HowTo/MixedPayoff.lean:22:9: Invalid field `isSymmetricNash`: The environment does not contain `Function.isSymmetricNash`, so it is not possible to project the field `isSymmetricNash` from an expression
stable.isSymmetricNash asks for the theorem IsESS.isSymmetricNash, since
stable is a proof of an IsESS statement. When that theorem is not
available, Lean unfolds IsESS to the ∀ underneath and tries again under
the name Function, which is what the message reports. The usual cause is a
missing import, here of GameTheory.Capstone, or a misspelt theorem name.
decide failed¶
decide fails on any statement about real numbers, with a long message
ending in Classical.choice. This is not a bug in the proof; see Computation
and the real numbers.