Lean 语言参考

14.7. 命名绑定变量🔗

simplifierrw策略引入新的绑定形式(例如函数参数)时,它们会根据所应用的重写规则的语句中的名称来选择绑定变量的名称。 如有必要,该名称可以是唯一的。 在某些情况下,例如使用良基递归的终止证明的预处理定义,终止证明义务中出现的名称应该是原始函数定义中编写的对应名称。

binderNameHint gadget 可用于指示应根据其他术语中绑定的变量来命名绑定变量。 按照惯例,术语 () 用于指示名称不应取自原始定义。

🔗def
binderNameHint.{u, v, w} {α : Sort u} {β : Sort v} {γ : Sort w} (v : α) (binder : β) (e : γ) : γ
binderNameHint.{u, v, w} {α : Sort u} {β : Sort v} {γ : Sort w} (v : α) (binder : β) (e : γ) : γ

The expression binderNameHint v binder e defined to be e.

If it is used on the right-hand side of an equation that is used for rewriting by rw or simp, and v is a local variable, and binder is an expression that (after beta-reduction) is a binder (fun w => … or ∀ w, …), then it will rename v to the name used in that binder, and remove the binderNameHint.

A typical use of this gadget would be as follows; the gadget ensures that after rewriting, the local variable is still name, and not x:

theorem all_eq_not_any_not (l : List α) (p : α → Bool) :
    l.all p = !l.any fun x => binderNameHint x p (!p x) := sorry

example (names : List String) : names.all (fun name => "Waldo".isPrefixOf name) = true := by
  rw [all_eq_not_any_not]
  -- ⊢ (!names.any fun name => !"Waldo".isPrefixOf name) = true

If binder is not a binder, then the name of v attains a macro scope. This only matters when the resulting term is used in a non-hygienic way, e.g. in termination proofs for well-founded recursion.

This gadget is supported by

  • simp, dsimp and rw in the right-hand-side of an equation

  • simp in the assumptions of congruence rules

It is ineffective in other positions (hypotheses of rewrite rules) or when used by other tactics (e.g. apply).