Lean 语言参考

16.9. 线性算术工作站🔗

grind策略包括一个用于任意类型的线性算术求解器,称为 linarith,用于 cutsat 不支持的类型。 与 ring 求解器一样,它可用于具有某些类型类实例的任何类型。 它根据这些类型类的可用性进行自我配置,因此无需提供所有类型类即可使用求解器;然而,它的功能随着更多实例的可用性而增强。 该求解器对于推理实数、有序向量空间以及无法嵌入到 Int 中的其他类型非常有用。

linarith 的核心功能是基于模型的整数系数线性不等式求解器。 可以使用选项 grind -linarith 禁用它。

Goals Decided by linarith

所有这些示例都依赖于以下排序符号和 linarith 类的实例:

variable [LE α] [LT α] [Std.LawfulOrderLT α] [Std.IsLinearOrder α] variable [IntModule α] [OrderedAdd α]

整数模块 (IntModule) 是具有零、加法、求反、减法和整数标量乘法的类型,满足这些运算的预期属性。 线性阶 (Std.IsLinearOrder) 是任何元素对都有序的阶,OrderedAdd 指出向两侧添加常数可以保留排序。

example {a b : α} : 2 a + b b + a + a := α:Type u_1inst✝⁵:LE αinst✝⁴:LT αinst✝³:Std.LawfulOrderLT αinst✝²:Std.IsLinearOrder αinst✝¹:IntModule αinst✝:OrderedAdd αa:αb:α2 a + b b + a + a All goals completed! 🐙 example {a b : α} (h : a b) : 3 a + b 4 b := α:Type u_1inst✝⁵:LE αinst✝⁴:LT αinst✝³:Std.LawfulOrderLT αinst✝²:Std.IsLinearOrder αinst✝¹:IntModule αinst✝:OrderedAdd αa:αb:αh:a b3 a + b 4 b All goals completed! 🐙 example {a b c : α} : a = b + c 2 b c 2 a 3 c := α:Type u_1inst✝⁵:LE αinst✝⁴:LT αinst✝³:Std.LawfulOrderLT αinst✝²:Std.IsLinearOrder αinst✝¹:IntModule αinst✝:OrderedAdd αa:αb:αc:αa = b + c 2 b c 2 a 3 c All goals completed! 🐙 example {a b c d e : α} : 2 a + b 0 b 0 c 0 d 0 e 0 a 3 c c 6 e d - 5 e 0 a + b + 3 c + d + 2 e < 0 False := α:Type u_1inst✝⁵:LE αinst✝⁴:LT αinst✝³:Std.LawfulOrderLT αinst✝²:Std.IsLinearOrder αinst✝¹:IntModule αinst✝:OrderedAdd αa:αb:αc:αd:αe:α2 a + b 0 b 0 c 0 d 0 e 0 a 3 c c 6 e d - 5 e 0 a + b + 3 c + d + 2 e < 0 False All goals completed! 🐙
Commutative Ring Goals Decided by linarith

对于具有 CommRing 实例的交换环类型(即乘法运算符可交换的类型),linarith 具有更多功能。

variable [LE R] [LT R] [Std.IsLinearOrder R] [Std.LawfulOrderLT R] variable [CommRing R] [OrderedRing R]

CommRing R 实例允许 linarith 执行基本归一化,例如识别线性原子 a * bb * a,并考虑两侧的标量乘法。 OrderedRing R 实例允许求解器支持常量,因为它可以访问 (0 : R) < 1.

example (a b : R) (h : a * b 1) : b * 3 a + 1 4 := R:Type u_1inst✝⁵:LE Rinst✝⁴:LT Rinst✝³:Std.IsLinearOrder Rinst✝²:Std.LawfulOrderLT Rinst✝¹:CommRing Rinst✝:OrderedRing Ra:Rb:Rh:a * b 1b * 3 a + 1 4 All goals completed! 🐙 example (a b c d e f : R) : 2 a + b 1 b 0 c 0 d 0 e f 0 a 3 c c 6 e f d - f * e * 5 0 a + b + 3 c + d + 2 e f < 0 False := R:Type u_1inst✝⁵:LE Rinst✝⁴:LT Rinst✝³:Std.IsLinearOrder Rinst✝²:Std.LawfulOrderLT Rinst✝¹:CommRing Rinst✝:OrderedRing Ra:Rb:Rc:Rd:Re:Rf:R2 a + b 1 b 0 c 0 d 0 e f 0 a 3 c c 6 e f d - f * e * 5 0 a + b + 3 c + d + 2 e f < 0 False All goals completed! 🐙

16.9.1. 支持linarith🔗

要向 linarith 添加对新类型的支持,第一步是在可能的情况下实现 IntModule,否则实现 NatModule。 每个 Ring 都已经是 IntModule,并且每个 Semiring 都已经是 NatModule,因此实现这些实例之一也足够了。 接下来,应实现订单类之一(Std.IsPreorderStd.IsPartialOrderStd.IsLinearOrder)。 通常,当上下文已包含矛盾时,IsPreorder 实例就足够了,但需要 IsLinearOrder 实例才能证明线性不等式目标。 通过实现 OrderedAddOrderedRing 来启用其他功能,OrderedAdd 表示模块中的加法结构与阶数兼容,OrderedRing 改进了对常量的支持。

🔗type class
Lean.Grind.NatModule.{u} (M : Type u) : Type u
Lean.Grind.NatModule.{u} (M : Type u) : Type u

A module over the natural numbers, i.e. a type with zero, addition, and scalar multiplication by natural numbers, satisfying appropriate compatibilities.

Equivalently, an additive commutative monoid.

Use IntModule if the type has negation.

Instance Constructor

Lean.Grind.NatModule.mk.{u}

Extends

Methods

zero : M
Inherited from
  1. AddCommMonoid M
add : M  M  M
Inherited from
  1. AddCommMonoid M
add_zero :  (a : M), a + 0 = a
Inherited from
  1. AddCommMonoid M
add_comm :  (a b : M), a + b = b + a
Inherited from
  1. AddCommMonoid M
add_assoc :  (a b c : M), a + b + c = a + (b + c)
Inherited from
  1. AddCommMonoid M
nsmul : SMul Nat M

Scalar multiplication by natural numbers.

zero_nsmul :  (a : M), 0  a = 0

Scalar multiplication by zero is zero.

add_one_nsmul :  (n : Nat) (a : M), (n + 1)  a = n  a + a

Scalar multiplication by a successor.

🔗type class
Lean.Grind.IntModule.{u} (M : Type u) : Type u
Lean.Grind.IntModule.{u} (M : Type u) : Type u

A module over the integers, i.e. a type with zero, addition, negation, subtraction, and scalar multiplication by integers, satisfying appropriate compatibilities.

Equivalently, an additive commutative group.

Instance Constructor

Lean.Grind.IntModule.mk.{u}

Extends

Methods

zero : M
Inherited from
  1. AddCommGroup M
add : M  M  M
Inherited from
  1. AddCommGroup M
add_zero :  (a : M), a + 0 = a
Inherited from
  1. AddCommGroup M
add_comm :  (a b : M), a + b = b + a
Inherited from
  1. AddCommGroup M
add_assoc :  (a b c : M), a + b + c = a + (b + c)
Inherited from
  1. AddCommGroup M
neg : M  M
Inherited from
  1. AddCommGroup M
sub : M  M  M
Inherited from
  1. AddCommGroup M
neg_add_cancel :  (a : M), -a + a = 0
Inherited from
  1. AddCommGroup M
sub_eq_add_neg :  (a b : M), a - b = a + -b
Inherited from
  1. AddCommGroup M
nsmul : SMul Nat M

Scalar multiplication by natural numbers.

zsmul : SMul Int M

Scalar multiplication by integers.

zero_zsmul :  (a : M), 0  a = 0

Scalar multiplication by zero is zero.

one_zsmul :  (a : M), 1  a = a

Scalar multiplication by one is the identity.

add_zsmul :  (n m : Int) (a : M), (n + m)  a = n  a + m  a

Scalar multiplication is distributive over addition in the integers.

zsmul_natCast_eq_nsmul :  (n : Nat) (a : M), n  a = n  a

Scalar multiplication by natural numbers is consistent with scalar multiplication by integers.

🔗type class
Lean.Grind.OrderedAdd.{u} (M : Type u) [HAdd M M M] [LE M] [Std.IsPreorder M] : Prop
Lean.Grind.OrderedAdd.{u} (M : Type u) [HAdd M M M] [LE M] [Std.IsPreorder M] : Prop

Addition is compatible with a preorder if a b a + c b + c.

Instance Constructor

Lean.Grind.OrderedAdd.mk.{u}

Methods

add_le_left_iff :  {a b : M} (c : M), a  b  a + c  b + c

a + c b + c iff a b.

🔗type class
Lean.Grind.OrderedRing.{u} (R : Type u) [Semiring R] [LE R] [LT R] [Std.IsPreorder R] : Prop
Lean.Grind.OrderedRing.{u} (R : Type u) [Semiring R] [LE R] [LT R] [Std.IsPreorder R] : Prop

A ring which is also equipped with a preorder is considered a strict ordered ring if addition, negation, and multiplication are compatible with the preorder, and 0 < 1.

Instance Constructor

Lean.Grind.OrderedRing.mk.{u}

Extends

Methods

add_le_left_iff :  {a b : R} (c : R), a  b  a + c  b + c
Inherited from
  1. OrderedAdd R
zero_lt_one : 0 < 1

In a strict ordered semiring, we have 0 < 1.

mul_lt_mul_of_pos_left :  {a b c : R}, a < b  0 < c  c * a < c * b

In a strict ordered semiring, we can multiply an inequality a < b on the left by a positive element 0 < c to obtain c * a < c * b.

mul_lt_mul_of_pos_right :  {a b c : R}, a < b  0 < c  a * c < b * c

In a strict ordered semiring, we can multiply an inequality a < b on the right by a positive element 0 < c to obtain a * c < b * c.