Lean 4(元)编程 Cookbook

把策略当作快捷方式🔗

在配方 编写宏 中,我们已经看到如何编写自定义语法以及解析该语法的 macro。本配方中,我们将看到如何用 macro 编写一个自定义策略。我们先从一个简单例子开始:一个反复应用同一定理直到无法再应用的策略;然后把它推广为一个接受两个定理作为参数、并按特定顺序应用它们的策略。

证明自然数不等式的策略🔗

我们从一个可能会写来证明 2 ≤ 6 的常规证明例子开始。

同样或相似的策略模式常常适用于一系列问题。为避免反复输入这段序列,我们可以用 宏(macro) 为该模式创建一个策略。更重要的是,我们可以给这个策略起一个更易记、更易懂的描述性名字。

我们从一个常规证明的例子开始,即 2 ≤ 6

example : 2 6 := 2 6 2 5 2 4 2 3 2 2 All goals completed! 🐙

这种做法高度重复。我们可以用 repeatfirst 策略组合子来简化它。

example : 2 6 := 2 6 repeat (first| All goals completed! 🐙 | 2 2)

为了把它精简成单独一行、易读的形式,我们可以用 macro 定义一个自定义策略。

macro "nat_le" : tactic => `(tactic| repeat(first| apply Nat.le_refl | apply Nat.le_succ_of_le)) example: 2 6 := 2 6 All goals completed! 🐙

反复应用定理的策略🔗

虽然 nat_le 对我们的特定情形有效,但我们可以通过对定理进行抽象让它更有用。我们来构造一个带参数的 macro,它接受两个定理作为参数。它会反复尝试应用第二个定理(t₂)来关闭目标,而每当失败时,就通过应用第一个定理(t₁)取得进展。

下面是构造这样一个策略的方法:

macro "repeat_apply" t₁:term "then" t₂:term : tactic => `(tactic| repeat(first| apply $t₂| apply $t₁ )) example : 10 12 := 10 12 All goals completed! 🐙