ToInt α I 表示可以将 α 忠实地嵌入整数区间 I。
实例构造子
Lean.Grind.ToInt.mk.{u}
线性整数算术求解器实现了一个针对线性整数算术的基于模型的判定过程。
该求解器能够处理四类线性多项式约束(其中 p 是一个线性多项式):
p = 0
d ∣ p
p ≤ 0
p ≠ 0
它对于线性整数算术是完备的,并且通过用 Int.ofNat 将自然数转换成整数,也支持自然数。
对于其他能够嵌入到 Int 中的类型,可以通过提供 Lean.Grind.ToInt 的实例来增加支持。
非线性项(例如 x * x)也是允许的,但会被表示为变量。
此外,该求解器还能把信息传播回比喻意义上的 grind 白板,从而触发其他子系统进一步推进证明。
默认情况下它是启用的;可以用标志 -lia 将其禁用。
下面这些命题都可以用线性整数算术求解器证明。 在第一个例子中,左边必定是 2 的倍数,因此不可能等于 5:
example {x y : Int} : 2 * x + 4 * y ≠ 5 := x:Inty:Int⊢ 2 * x + 4 * y ≠ 5
All goals completed! 🐙
求解器支持混合使用等式与不等式:
example {x y : Int} :
2 * x + 3 * y = 0 →
1 ≤ x →
y < 1 := x:Inty:Int⊢ 2 * x + 3 * y = 0 → 1 ≤ x → y < 1
All goals completed! 🐙
它也支持线性的整除约束:
example (a b : Int) :
2 ∣ a + 1 →
2 ∣ b + a →
¬ 2 ∣ b + 2 * a := a:Intb:Int⊢ 2 ∣ a + 1 → 2 ∣ b + a → ¬2 ∣ b + 2 * a
All goals completed! 🐙
如果没有 lia,grind 就无法证明该命题:
example (a b : Int) :
2 ∣ a + 1 →
2 ∣ b + a →
¬ 2 ∣ b + 2 * a := a:Intb:Int⊢ 2 ∣ a + 1 → 2 ∣ b + a → ¬2 ∣ b + 2 * a
All goals completed! 🐙
该求解器对线性整数算术是完备的。
不过,即使约束很少,搜索空间也可能迅速变得极大,而这个求解器并不是为大规模分类讨论而设计的。
grind 的 qlia 选项通过允许求解器接受有理数解来缩小搜索空间。
使用该选项后,求解器通常会更快,但它就不再完备。
下面这个例子有有理数解,但没有整数解:
example {x y : Int} :
27 ≤ 13 * x + 11 * y →
13 * x + 11 * y ≤ 30 →
-10 ≤ 9 * x - 7 * y →
9 * x - 7 * y > 4 := x:Inty:Int⊢ 27 ≤ 13 * x + 11 * y → 13 * x + 11 * y ≤ 30 → -10 ≤ 9 * x - 7 * y → 9 * x - 7 * y > 4
All goals completed! 🐙
由于它使用的是有理数解,因此在指定 +qlia 时,grind 无法驳倒目标的否定:
example {x y : Int} :
27 ≤ 13 * x + 11 * y →
13 * x + 11 * y ≤ 30 →
-10 ≤ 9 * x - 7 * y →
9 * x - 7 * y > 4 := x:Inty:Int⊢ 27 ≤ 13 * x + 11 * y → 13 * x + 11 * y ≤ 30 → -10 ≤ 9 * x - 7 * y → 9 * x - 7 * y > 4
All goals completed! 🐙
求解器构造出的有理模型,出现在目标诊断里的 Assignment satisfying linear constraints 一节中。
该求解器目前并不真正求解非线性约束,而是把 x * x 这样的非线性项当作变量处理。
该求解器支持线性的除法与取模运算。
该求解器会对交换(半)环表达式做规范化。
该求解器还实现了 基于模型的理论组合,这是一种把等式传播回共享白板的机制。
这些新增的等式又可能进一步触发新的同余。
基于模型的理论组合会扩大搜索空间;可以使用选项 grind -mbtc 将其禁用。
在上面的例子里,线性不等式与不等关系蕴含 y = 0:
example (f : Int → Int) (x y : Int) :
f x = 0 →
0 ≤ y → y ≤ 1 → y ≠ 1 →
f (x + y) = 0 := f:Int → Intx:Inty:Int⊢ f x = 0 → 0 ≤ y → y ≤ 1 → y ≠ 1 → f (x + y) = 0
All goals completed! 🐙
因此 x = x + y,于是由 同余 得到 f x = f (x + y)。
如果没有基于模型的理论组合,证明就会卡住:
example (f : Int → Int) (x y : Int) :
f x = 0 →
0 ≤ y → y ≤ 1 → y ≠ 1 →
f (x + y) = 0 := f:Int → Intx:Inty:Int⊢ f x = 0 → 0 ≤ y → y ≤ 1 → y ≠ 1 → f (x + y) = 0
All goals completed! 🐙
LIA 求解器也可以处理包含自然数的线性约束。
它会使用 Int.ofNat 将其转换为整数约束。
通过 Lean.Grind.ToInt 类型类,有一种可扩展机制可以告诉求解器某个类型能够嵌入到整数中。
借助这一机制,我们可以求解如下目标:
example (a b c : Fin 11) : a ≤ 2 → b ≤ 3 → c = a + b → c ≤ 5 := a:Fin 11b:Fin 11c:Fin 11⊢ a ≤ 2 → b ≤ 3 → c = a + b → c ≤ 5
All goals completed! 🐙
example (a : Fin 2) : a ≠ 0 → a ≠ 1 → False := a:Fin 2⊢ a ≠ 0 → a ≠ 1 → False
All goals completed! 🐙
example (a b c : UInt64) : a ≤ 2 → b ≤ 3 → c - a - b = 0 → c ≤ 5 := a:UInt64b:UInt64c:UInt64⊢ a ≤ 2 → b ≤ 3 → c - a - b = 0 → c ≤ 5
All goals completed! 🐙
整数区间,可以是有限、半无限或无限区间。
构造子
Lean.Grind.IntInterval.co (lo hi : Int) : Lean.Grind.IntInterval
有限区间 [lo, hi)。
Lean.Grind.IntInterval.ci (lo : Int) : Lean.Grind.IntInterval
半无限区间 [lo, ∞)。
Lean.Grind.IntInterval.io (hi : Int) : Lean.Grind.IntInterval
半无限区间 (-∞, hi)。
Lean.Grind.IntInterval.ii : Lean.Grind.IntInterval
无限区间 (-∞, ∞)。
线性整数算术求解器的实现受到了 Jovanović and de Moura (2023)Dejan Jovanović and Leonardo de Moura, 2023. “Cutting to the Chase: Solving Linear Integer Arithmetic”. In Automated Deduction: CADE '23. (LNCS 6803) 第 4 节的启发。 与论文相比,它还包含若干增强与修改,例如:
扩展了约束支持(等式与不等关系),
对 Cooper-Left 规则进行了优化编码,使用一个“大”析取而不是新鲜变量,以及
对分类讨论中的决策变量进行跟踪(不等关系、Cooper-Left、Cooper-Right)。
该求解过程会逐步构造一个模型(也就是对项中变量的赋值),并通过生成约束来解决冲突。
例如,给定部分模型 {x := 1} 和约束 3 ∣ 3 * y + x + 1:
求解器无法把该模型扩展到 y,因为 3 ∣ 3 * y + 2 不可满足。
因此,它会通过生成蕴含约束 3 ∣ x + 1 来消解冲突。
这个新约束迫使求解器为 x 寻找新的赋值。
在为变量 y 赋值时,求解器会考虑:
最佳的上界与下界(不等式)。
一个整除约束。
所有以 y 为最大变量的不等关系约束。
Cooper-Left 与 Cooper-Right 规则负责处理不等式与整除性的组合。
对于不可满足的不等关系 p ≠ 0,求解器会生成如下分类讨论:p + 1 ≤ 0 ∨ -p + 1 ≤ 0。