algebra.order.interval
⟷
Mathlib.Algebra.Order.Interval
The following section lists changes to this file in mathlib3 and mathlib4 that occured after the initial port. Most recent changes are shown first. Hovering over a commit will show all commits associated with the same mathlib3 commit.
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(last sync)
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -7,7 +7,7 @@ import Algebra.Order.BigOperators.Group.Finset
import Algebra.Group.Prod
import Data.Option.NAry
import Data.Set.Pointwise.Basic
-import Order.Interval
+import Order.Interval.Basic
import Tactic.Positivity
#align_import algebra.order.interval from "leanprover-community/mathlib"@"6b31d1eebd64eab86d5bd9936bfaada6ca8b5842"
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -3,7 +3,7 @@ Copyright (c) 2022 Yaël Dillies. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Yaël Dillies
-/
-import Algebra.BigOperators.Order
+import Algebra.Order.BigOperators.Group.Finset
import Algebra.Group.Prod
import Data.Option.NAry
import Data.Set.Pointwise.Basic
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -630,7 +630,7 @@ variable [OrderedCommGroup α] {s t : NonemptyInterval α}
protected theorem mul_eq_one_iff : s * t = 1 ↔ ∃ a b, s = pure a ∧ t = pure b ∧ a * b = 1 :=
by
refine' ⟨fun h => _, _⟩
- · rw [ext_iff, Prod.ext_iff] at h
+ · rw [ext_iff, Prod.ext_iff] at h
have := (mul_le_mul_iff_of_ge s.fst_le_snd t.fst_le_snd).1 (h.2.trans h.1.symm).le
refine' ⟨s.fst, t.fst, _, _, h.1⟩ <;> ext <;> try rfl
exacts [this.1.symm, this.2.symm]
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -264,12 +264,12 @@ end Mul
/-! ### Powers -/
-#print NonemptyInterval.hasNsmul /-
+#print NonemptyInterval.hasNSMul /-
-- TODO: if `to_additive` gets improved sufficiently, derive this from `has_pow`
-instance NonemptyInterval.hasNsmul [AddMonoid α] [Preorder α] [CovariantClass α α (· + ·) (· ≤ ·)]
+instance NonemptyInterval.hasNSMul [AddMonoid α] [Preorder α] [CovariantClass α α (· + ·) (· ≤ ·)]
[CovariantClass α α (swap (· + ·)) (· ≤ ·)] : SMul ℕ (NonemptyInterval α) :=
- ⟨fun n s => ⟨(n • s.fst, n • s.snd), nsmul_le_nsmul_of_le_right s.fst_le_snd _⟩⟩
-#align nonempty_interval.has_nsmul NonemptyInterval.hasNsmul
+ ⟨fun n s => ⟨(n • s.fst, n • s.snd), nsmul_le_nsmul_right s.fst_le_snd _⟩⟩
+#align nonempty_interval.has_nsmul NonemptyInterval.hasNSMul
-/
section Pow
@@ -278,11 +278,11 @@ variable [Monoid α] [Preorder α] [CovariantClass α α (· * ·) (· ≤ ·)]
[CovariantClass α α (swap (· * ·)) (· ≤ ·)]
#print NonemptyInterval.hasPow /-
-@[to_additive NonemptyInterval.hasNsmul]
+@[to_additive NonemptyInterval.hasNSMul]
instance NonemptyInterval.hasPow : Pow (NonemptyInterval α) ℕ :=
- ⟨fun s n => ⟨s.toProd ^ n, pow_le_pow_of_le_left' s.fst_le_snd _⟩⟩
+ ⟨fun s n => ⟨s.toProd ^ n, pow_le_pow_left' s.fst_le_snd _⟩⟩
#align nonempty_interval.has_pow NonemptyInterval.hasPow
-#align nonempty_interval.has_nsmul NonemptyInterval.hasNsmul
+#align nonempty_interval.has_nsmul NonemptyInterval.hasNSMul
-/
namespace NonemptyInterval
mathlib commit https://github.com/leanprover-community/mathlib/commit/ce64cd319bb6b3e82f31c2d38e79080d377be451
@@ -3,12 +3,12 @@ Copyright (c) 2022 Yaël Dillies. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Yaël Dillies
-/
-import Mathbin.Algebra.BigOperators.Order
-import Mathbin.Algebra.Group.Prod
-import Mathbin.Data.Option.NAry
-import Mathbin.Data.Set.Pointwise.Basic
-import Mathbin.Order.Interval
-import Mathbin.Tactic.Positivity
+import Algebra.BigOperators.Order
+import Algebra.Group.Prod
+import Data.Option.NAry
+import Data.Set.Pointwise.Basic
+import Order.Interval
+import Tactic.Positivity
#align_import algebra.order.interval from "leanprover-community/mathlib"@"6b31d1eebd64eab86d5bd9936bfaada6ca8b5842"
mathlib commit https://github.com/leanprover-community/mathlib/commit/32a7e535287f9c73f2e4d2aef306a39190f0b504
@@ -657,10 +657,10 @@ instance : DivisionCommMonoid (NonemptyInterval α) :=
{ NonemptyInterval.commMonoid with
inv := Inv.inv
div := (· / ·)
- div_eq_mul_inv := fun s t => by ext <;> exact div_eq_mul_inv _ _
+ div_eq_hMul_inv := fun s t => by ext <;> exact div_eq_mul_inv _ _
inv_inv := fun s => by ext <;> exact inv_inv _
mul_inv_rev := fun s t => by ext <;> exact mul_inv_rev _ _
- inv_eq_of_mul := fun s t h =>
+ inv_eq_of_hMul := fun s t h =>
by
obtain ⟨a, b, rfl, rfl, hab⟩ := NonemptyInterval.mul_eq_one_iff.1 h
rw [inv_pure, inv_eq_of_mul_eq_one_right hab] }
@@ -714,7 +714,7 @@ instance : DivisionCommMonoid (Interval α) :=
{ Interval.commMonoid with
inv := Inv.inv
div := (· / ·)
- div_eq_mul_inv := by
+ div_eq_hMul_inv := by
rintro (_ | s) (_ | t) <;>
first
| rfl
@@ -729,7 +729,7 @@ instance : DivisionCommMonoid (Interval α) :=
first
| rfl
| exact congr_arg some (mul_inv_rev _ _)
- inv_eq_of_mul := by
+ inv_eq_of_hMul := by
rintro (_ | s) (_ | t) h <;>
first
| cases h
mathlib commit https://github.com/leanprover-community/mathlib/commit/8ea5598db6caeddde6cb734aa179cc2408dbd345
@@ -2,11 +2,6 @@
Copyright (c) 2022 Yaël Dillies. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Yaël Dillies
-
-! This file was ported from Lean 3 source module algebra.order.interval
-! leanprover-community/mathlib commit 6b31d1eebd64eab86d5bd9936bfaada6ca8b5842
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
-/
import Mathbin.Algebra.BigOperators.Order
import Mathbin.Algebra.Group.Prod
@@ -15,6 +10,8 @@ import Mathbin.Data.Set.Pointwise.Basic
import Mathbin.Order.Interval
import Mathbin.Tactic.Positivity
+#align_import algebra.order.interval from "leanprover-community/mathlib"@"6b31d1eebd64eab86d5bd9936bfaada6ca8b5842"
+
/-!
# Interval arithmetic
mathlib commit https://github.com/leanprover-community/mathlib/commit/9fb8964792b4237dac6200193a0d533f1b3f7423
@@ -106,17 +106,21 @@ theorem pure_one : pure (1 : α) = 1 :=
#align interval.pure_zero Interval.pure_zero
-/
+#print Interval.one_ne_bot /-
@[simp, to_additive]
theorem one_ne_bot : (1 : Interval α) ≠ ⊥ :=
pure_ne_bot
#align interval.one_ne_bot Interval.one_ne_bot
#align interval.zero_ne_bot Interval.zero_ne_bot
+-/
+#print Interval.bot_ne_one /-
@[simp, to_additive]
theorem bot_ne_one : (⊥ : Interval α) ≠ 1 :=
bot_ne_pure
#align interval.bot_ne_one Interval.bot_ne_one
#align interval.bot_ne_zero Interval.bot_ne_zero
+-/
end Interval
@@ -240,17 +244,21 @@ namespace Interval
variable (s t : Interval α)
+#print Interval.bot_mul /-
@[simp, to_additive]
theorem bot_mul : ⊥ * t = ⊥ :=
rfl
#align interval.bot_mul Interval.bot_mul
#align interval.bot_add Interval.bot_add
+-/
+#print Interval.mul_bot /-
@[simp, to_additive]
theorem mul_bot : s * ⊥ = ⊥ :=
Option.map₂_none_right _ _
#align interval.mul_bot Interval.mul_bot
#align interval.add_bot Interval.add_bot
+-/
end Interval
@@ -259,50 +267,62 @@ end Mul
/-! ### Powers -/
+#print NonemptyInterval.hasNsmul /-
-- TODO: if `to_additive` gets improved sufficiently, derive this from `has_pow`
instance NonemptyInterval.hasNsmul [AddMonoid α] [Preorder α] [CovariantClass α α (· + ·) (· ≤ ·)]
[CovariantClass α α (swap (· + ·)) (· ≤ ·)] : SMul ℕ (NonemptyInterval α) :=
⟨fun n s => ⟨(n • s.fst, n • s.snd), nsmul_le_nsmul_of_le_right s.fst_le_snd _⟩⟩
#align nonempty_interval.has_nsmul NonemptyInterval.hasNsmul
+-/
section Pow
variable [Monoid α] [Preorder α] [CovariantClass α α (· * ·) (· ≤ ·)]
[CovariantClass α α (swap (· * ·)) (· ≤ ·)]
+#print NonemptyInterval.hasPow /-
@[to_additive NonemptyInterval.hasNsmul]
instance NonemptyInterval.hasPow : Pow (NonemptyInterval α) ℕ :=
⟨fun s n => ⟨s.toProd ^ n, pow_le_pow_of_le_left' s.fst_le_snd _⟩⟩
#align nonempty_interval.has_pow NonemptyInterval.hasPow
#align nonempty_interval.has_nsmul NonemptyInterval.hasNsmul
+-/
namespace NonemptyInterval
variable (s : NonemptyInterval α) (a : α) (n : ℕ)
+#print NonemptyInterval.toProd_pow /-
@[simp, to_additive to_prod_nsmul]
theorem toProd_pow : (s ^ n).toProd = s.toProd ^ n :=
rfl
#align nonempty_interval.to_prod_pow NonemptyInterval.toProd_pow
#align nonempty_interval.to_prod_nsmul NonemptyInterval.toProd_nsmul
+-/
+#print NonemptyInterval.fst_pow /-
@[to_additive]
theorem fst_pow : (s ^ n).fst = s.fst ^ n :=
rfl
#align nonempty_interval.fst_pow NonemptyInterval.fst_pow
#align nonempty_interval.fst_nsmul NonemptyInterval.fst_nsmul
+-/
+#print NonemptyInterval.snd_pow /-
@[to_additive]
theorem snd_pow : (s ^ n).snd = s.snd ^ n :=
rfl
#align nonempty_interval.snd_pow NonemptyInterval.snd_pow
#align nonempty_interval.snd_nsmul NonemptyInterval.snd_nsmul
+-/
+#print NonemptyInterval.pure_pow /-
@[simp, to_additive]
theorem pure_pow : pure a ^ n = pure (a ^ n) :=
rfl
#align nonempty_interval.pure_pow NonemptyInterval.pure_pow
#align nonempty_interval.pure_nsmul NonemptyInterval.pure_nsmul
+-/
end NonemptyInterval
@@ -352,12 +372,14 @@ namespace Interval
variable [OrderedCommMonoid α] (s : Interval α) {n : ℕ}
+#print Interval.bot_pow /-
@[to_additive]
theorem bot_pow : ∀ {n : ℕ} (hn : n ≠ 0), (⊥ : Interval α) ^ n = ⊥
| 0, h => (h rfl).elim
| Nat.succ n, _ => bot_mul (⊥ ^ n)
#align interval.bot_pow Interval.bot_pow
#align interval.bot_nsmul Interval.bot_nsmul
+-/
end Interval
@@ -384,29 +406,39 @@ namespace NonemptyInterval
variable (s t : NonemptyInterval α) {a b : α}
+#print NonemptyInterval.fst_sub /-
@[simp]
theorem fst_sub : (s - t).fst = s.fst - t.snd :=
rfl
#align nonempty_interval.fst_sub NonemptyInterval.fst_sub
+-/
+#print NonemptyInterval.snd_sub /-
@[simp]
theorem snd_sub : (s - t).snd = s.snd - t.fst :=
rfl
#align nonempty_interval.snd_sub NonemptyInterval.snd_sub
+-/
+#print NonemptyInterval.coe_sub_interval /-
@[simp]
theorem coe_sub_interval : (↑(s - t) : Interval α) = s - t :=
rfl
#align nonempty_interval.coe_sub_interval NonemptyInterval.coe_sub_interval
+-/
+#print NonemptyInterval.sub_mem_sub /-
theorem sub_mem_sub (ha : a ∈ s) (hb : b ∈ t) : a - b ∈ s - t :=
⟨tsub_le_tsub ha.1 hb.2, tsub_le_tsub ha.2 hb.1⟩
#align nonempty_interval.sub_mem_sub NonemptyInterval.sub_mem_sub
+-/
+#print NonemptyInterval.pure_sub_pure /-
@[simp]
theorem pure_sub_pure (a b : α) : pure a - pure b = pure (a - b) :=
rfl
#align nonempty_interval.pure_sub_pure NonemptyInterval.pure_sub_pure
+-/
end NonemptyInterval
@@ -414,15 +446,19 @@ namespace Interval
variable (s t : Interval α)
+#print Interval.bot_sub /-
@[simp]
theorem bot_sub : ⊥ - t = ⊥ :=
rfl
#align interval.bot_sub Interval.bot_sub
+-/
+#print Interval.sub_bot /-
@[simp]
theorem sub_bot : s - ⊥ = ⊥ :=
Option.map₂_none_right _ _
#align interval.sub_bot Interval.sub_bot
+-/
end Interval
@@ -451,35 +487,45 @@ namespace NonemptyInterval
variable (s t : NonemptyInterval α) (a b : α)
+#print NonemptyInterval.fst_div /-
@[simp, to_additive]
theorem fst_div : (s / t).fst = s.fst / t.snd :=
rfl
#align nonempty_interval.fst_div NonemptyInterval.fst_div
#align nonempty_interval.fst_sub NonemptyInterval.fst_sub
+-/
+#print NonemptyInterval.snd_div /-
@[simp, to_additive]
theorem snd_div : (s / t).snd = s.snd / t.fst :=
rfl
#align nonempty_interval.snd_div NonemptyInterval.snd_div
#align nonempty_interval.snd_sub NonemptyInterval.snd_sub
+-/
+#print NonemptyInterval.coe_div_interval /-
@[simp, to_additive]
theorem coe_div_interval : (↑(s / t) : Interval α) = s / t :=
rfl
#align nonempty_interval.coe_div_interval NonemptyInterval.coe_div_interval
#align nonempty_interval.coe_sub_interval NonemptyInterval.coe_sub_interval
+-/
+#print NonemptyInterval.div_mem_div /-
@[to_additive]
theorem div_mem_div (ha : a ∈ s) (hb : b ∈ t) : a / b ∈ s / t :=
⟨div_le_div'' ha.1 hb.2, div_le_div'' ha.2 hb.1⟩
#align nonempty_interval.div_mem_div NonemptyInterval.div_mem_div
#align nonempty_interval.sub_mem_sub NonemptyInterval.sub_mem_sub
+-/
+#print NonemptyInterval.pure_div_pure /-
@[simp, to_additive]
theorem pure_div_pure : pure a / pure b = pure (a / b) :=
rfl
#align nonempty_interval.pure_div_pure NonemptyInterval.pure_div_pure
#align nonempty_interval.pure_sub_pure NonemptyInterval.pure_sub_pure
+-/
end NonemptyInterval
@@ -487,17 +533,21 @@ namespace Interval
variable (s t : Interval α)
+#print Interval.bot_div /-
@[simp, to_additive]
theorem bot_div : ⊥ / t = ⊥ :=
rfl
#align interval.bot_div Interval.bot_div
#align interval.bot_sub Interval.bot_sub
+-/
+#print Interval.div_bot /-
@[simp, to_additive]
theorem div_bot : s / ⊥ = ⊥ :=
Option.map₂_none_right _ _
#align interval.div_bot Interval.div_bot
#align interval.sub_bot Interval.sub_bot
+-/
end Interval
@@ -522,43 +572,55 @@ namespace NonemptyInterval
variable (s t : NonemptyInterval α) (a : α)
+#print NonemptyInterval.fst_inv /-
@[simp, to_additive]
theorem fst_inv : s⁻¹.fst = s.snd⁻¹ :=
rfl
#align nonempty_interval.fst_inv NonemptyInterval.fst_inv
#align nonempty_interval.fst_neg NonemptyInterval.fst_neg
+-/
+#print NonemptyInterval.snd_inv /-
@[simp, to_additive]
theorem snd_inv : s⁻¹.snd = s.fst⁻¹ :=
rfl
#align nonempty_interval.snd_inv NonemptyInterval.snd_inv
#align nonempty_interval.snd_neg NonemptyInterval.snd_neg
+-/
+#print NonemptyInterval.coe_inv_interval /-
@[simp, to_additive]
theorem coe_inv_interval : (↑s⁻¹ : Interval α) = s⁻¹ :=
rfl
#align nonempty_interval.coe_inv_interval NonemptyInterval.coe_inv_interval
#align nonempty_interval.coe_neg_interval NonemptyInterval.coe_neg_interval
+-/
+#print NonemptyInterval.inv_mem_inv /-
@[to_additive]
theorem inv_mem_inv (ha : a ∈ s) : a⁻¹ ∈ s⁻¹ :=
⟨inv_le_inv' ha.2, inv_le_inv' ha.1⟩
#align nonempty_interval.inv_mem_inv NonemptyInterval.inv_mem_inv
#align nonempty_interval.neg_mem_neg NonemptyInterval.neg_mem_neg
+-/
+#print NonemptyInterval.inv_pure /-
@[simp, to_additive]
theorem inv_pure : (pure a)⁻¹ = pure a⁻¹ :=
rfl
#align nonempty_interval.inv_pure NonemptyInterval.inv_pure
#align nonempty_interval.neg_pure NonemptyInterval.neg_pure
+-/
end NonemptyInterval
+#print Interval.inv_bot /-
@[simp, to_additive]
theorem Interval.inv_bot : (⊥ : Interval α)⁻¹ = ⊥ :=
rfl
#align interval.inv_bot Interval.inv_bot
#align interval.neg_bot Interval.neg_bot
+-/
end Inv
@@ -566,6 +628,7 @@ namespace NonemptyInterval
variable [OrderedCommGroup α] {s t : NonemptyInterval α}
+#print NonemptyInterval.mul_eq_one_iff /-
@[to_additive]
protected theorem mul_eq_one_iff : s * t = 1 ↔ ∃ a b, s = pure a ∧ t = pure b ∧ a * b = 1 :=
by
@@ -578,6 +641,7 @@ protected theorem mul_eq_one_iff : s * t = 1 ↔ ∃ a b, s = pure a ∧ t = pur
rw [pure_mul_pure, h, pure_one]
#align nonempty_interval.mul_eq_one_iff NonemptyInterval.mul_eq_one_iff
#align nonempty_interval.add_eq_zero_iff NonemptyInterval.add_eq_zero_iff
+-/
instance {α : Type u} [OrderedAddCommGroup α] : SubtractionCommMonoid (NonemptyInterval α) :=
{ NonemptyInterval.addCommMonoid with
@@ -610,6 +674,7 @@ namespace Interval
variable [OrderedCommGroup α] {s t : Interval α}
+#print Interval.mul_eq_one_iff /-
@[to_additive]
protected theorem mul_eq_one_iff : s * t = 1 ↔ ∃ a b, s = pure a ∧ t = pure b ∧ a * b = 1 :=
by
@@ -620,6 +685,7 @@ protected theorem mul_eq_one_iff : s * t = 1 ↔ ∃ a b, s = pure a ∧ t = pur
· simp [WithBot.some_eq_coe, ← NonemptyInterval.coe_mul_interval, NonemptyInterval.mul_eq_one_iff]
#align interval.mul_eq_one_iff Interval.mul_eq_one_iff
#align interval.add_eq_zero_iff Interval.add_eq_zero_iff
+-/
instance {α : Type u} [OrderedAddCommGroup α] : SubtractionCommMonoid (Interval α) :=
{ Interval.addCommMonoid with
@@ -690,34 +756,46 @@ def length : α :=
#align nonempty_interval.length NonemptyInterval.length
-/
+#print NonemptyInterval.length_nonneg /-
@[simp]
theorem length_nonneg : 0 ≤ s.length :=
sub_nonneg_of_le s.fst_le_snd
#align nonempty_interval.length_nonneg NonemptyInterval.length_nonneg
+-/
+#print NonemptyInterval.length_pure /-
@[simp]
theorem length_pure : (pure a).length = 0 :=
sub_self _
#align nonempty_interval.length_pure NonemptyInterval.length_pure
+-/
+#print NonemptyInterval.length_zero /-
@[simp]
theorem length_zero : (0 : NonemptyInterval α).length = 0 :=
length_pure _
#align nonempty_interval.length_zero NonemptyInterval.length_zero
+-/
+#print NonemptyInterval.length_neg /-
@[simp]
theorem length_neg : (-s).length = s.length :=
neg_sub_neg _ _
#align nonempty_interval.length_neg NonemptyInterval.length_neg
+-/
+#print NonemptyInterval.length_add /-
@[simp]
theorem length_add : (s + t).length = s.length + t.length :=
add_sub_add_comm _ _ _ _
#align nonempty_interval.length_add NonemptyInterval.length_add
+-/
+#print NonemptyInterval.length_sub /-
@[simp]
theorem length_sub : (s - t).length = s.length + t.length := by simp [sub_eq_add_neg]
#align nonempty_interval.length_sub NonemptyInterval.length_sub
+-/
#print NonemptyInterval.length_sum /-
@[simp]
@@ -742,37 +820,49 @@ def length : Interval α → α
#align interval.length Interval.length
-/
+#print Interval.length_nonneg /-
@[simp]
theorem length_nonneg : ∀ s : Interval α, 0 ≤ s.length
| ⊥ => le_rfl
| (s : NonemptyInterval α) => s.length_nonneg
#align interval.length_nonneg Interval.length_nonneg
+-/
+#print Interval.length_pure /-
@[simp]
theorem length_pure : (pure a).length = 0 :=
NonemptyInterval.length_pure _
#align interval.length_pure Interval.length_pure
+-/
+#print Interval.length_zero /-
@[simp]
theorem length_zero : (0 : Interval α).length = 0 :=
length_pure _
#align interval.length_zero Interval.length_zero
+-/
+#print Interval.length_neg /-
@[simp]
theorem length_neg : ∀ s : Interval α, (-s).length = s.length
| ⊥ => rfl
| (s : NonemptyInterval α) => s.length_neg
#align interval.length_neg Interval.length_neg
+-/
+#print Interval.length_add_le /-
theorem length_add_le : ∀ s t : Interval α, (s + t).length ≤ s.length + t.length
| ⊥, _ => by simp
| _, ⊥ => by simp
| (s : NonemptyInterval α), (t : NonemptyInterval α) => (s.length_add t).le
#align interval.length_add_le Interval.length_add_le
+-/
+#print Interval.length_sub_le /-
theorem length_sub_le : (s - t).length ≤ s.length + t.length := by
simpa [sub_eq_add_neg] using length_add_le s (-t)
#align interval.length_sub_le Interval.length_sub_le
+-/
#print Interval.length_sum_le /-
theorem length_sum_le (f : ι → Interval α) (s : Finset ι) :
mathlib commit https://github.com/leanprover-community/mathlib/commit/a3e83f0fa4391c8740f7d773a7a9b74e311ae2a3
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Yaël Dillies
! This file was ported from Lean 3 source module algebra.order.interval
-! leanprover-community/mathlib commit f0c8bf9245297a541f468be517f1bde6195105e9
+! leanprover-community/mathlib commit 6b31d1eebd64eab86d5bd9936bfaada6ca8b5842
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
@@ -18,6 +18,9 @@ import Mathbin.Tactic.Positivity
/-!
# Interval arithmetic
+> THIS FILE IS SYNCHRONIZED WITH MATHLIB4.
+> Any changes to this file require a corresponding PR to mathlib4.
+
This file defines arithmetic operations on intervals and prove their correctness. Note that this is
full precision operations. The essentials of float operations can be found
in `data.fp.basic`. We have not yet integrated these with the rest of the library.
mathlib commit https://github.com/leanprover-community/mathlib/commit/58a272265b5e05f258161260dd2c5d247213cbd3
@@ -51,45 +51,57 @@ instance : One (Interval α) :=
namespace NonemptyInterval
+#print NonemptyInterval.toProd_one /-
@[simp, to_additive to_prod_zero]
theorem toProd_one : (1 : NonemptyInterval α).toProd = 1 :=
rfl
#align nonempty_interval.to_prod_one NonemptyInterval.toProd_one
#align nonempty_interval.to_prod_zero NonemptyInterval.toProd_zero
+-/
+#print NonemptyInterval.fst_one /-
@[to_additive]
theorem fst_one : (1 : NonemptyInterval α).fst = 1 :=
rfl
#align nonempty_interval.fst_one NonemptyInterval.fst_one
#align nonempty_interval.fst_zero NonemptyInterval.fst_zero
+-/
+#print NonemptyInterval.snd_one /-
@[to_additive]
theorem snd_one : (1 : NonemptyInterval α).snd = 1 :=
rfl
#align nonempty_interval.snd_one NonemptyInterval.snd_one
#align nonempty_interval.snd_zero NonemptyInterval.snd_zero
+-/
+#print NonemptyInterval.coe_one_interval /-
@[simp, norm_cast, to_additive]
theorem coe_one_interval : ((1 : NonemptyInterval α) : Interval α) = 1 :=
rfl
#align nonempty_interval.coe_one_interval NonemptyInterval.coe_one_interval
#align nonempty_interval.coe_zero_interval NonemptyInterval.coe_zero_interval
+-/
+#print NonemptyInterval.pure_one /-
@[simp, to_additive]
theorem pure_one : pure (1 : α) = 1 :=
rfl
#align nonempty_interval.pure_one NonemptyInterval.pure_one
#align nonempty_interval.pure_zero NonemptyInterval.pure_zero
+-/
end NonemptyInterval
namespace Interval
+#print Interval.pure_one /-
@[simp, to_additive]
theorem pure_one : pure (1 : α) = 1 :=
rfl
#align interval.pure_one Interval.pure_one
#align interval.pure_zero Interval.pure_zero
+-/
@[simp, to_additive]
theorem one_ne_bot : (1 : Interval α) ≠ ⊥ :=
@@ -113,33 +125,41 @@ variable [PartialOrder α] [One α]
namespace NonemptyInterval
+#print NonemptyInterval.coe_one /-
@[simp, to_additive]
theorem coe_one : ((1 : NonemptyInterval α) : Set α) = 1 :=
coe_pure _
#align nonempty_interval.coe_one NonemptyInterval.coe_one
#align nonempty_interval.coe_zero NonemptyInterval.coe_zero
+-/
+#print NonemptyInterval.one_mem_one /-
@[to_additive]
theorem one_mem_one : (1 : α) ∈ (1 : NonemptyInterval α) :=
⟨le_rfl, le_rfl⟩
#align nonempty_interval.one_mem_one NonemptyInterval.one_mem_one
#align nonempty_interval.zero_mem_zero NonemptyInterval.zero_mem_zero
+-/
end NonemptyInterval
namespace Interval
+#print Interval.coe_one /-
@[simp, to_additive]
theorem coe_one : ((1 : Interval α) : Set α) = 1 :=
Icc_self _
#align interval.coe_one Interval.coe_one
#align interval.coe_zero Interval.coe_zero
+-/
+#print Interval.one_mem_one /-
@[to_additive]
theorem one_mem_one : (1 : α) ∈ (1 : Interval α) :=
⟨le_rfl, le_rfl⟩
#align interval.one_mem_one Interval.one_mem_one
#align interval.zero_mem_zero Interval.zero_mem_zero
+-/
end Interval
@@ -171,35 +191,45 @@ namespace NonemptyInterval
variable (s t : NonemptyInterval α) (a b : α)
+#print NonemptyInterval.toProd_mul /-
@[simp, to_additive to_prod_add]
theorem toProd_mul : (s * t).toProd = s.toProd * t.toProd :=
rfl
#align nonempty_interval.to_prod_mul NonemptyInterval.toProd_mul
#align nonempty_interval.to_prod_add NonemptyInterval.toProd_add
+-/
+#print NonemptyInterval.fst_mul /-
@[to_additive]
theorem fst_mul : (s * t).fst = s.fst * t.fst :=
rfl
#align nonempty_interval.fst_mul NonemptyInterval.fst_mul
#align nonempty_interval.fst_add NonemptyInterval.fst_add
+-/
+#print NonemptyInterval.snd_mul /-
@[to_additive]
theorem snd_mul : (s * t).snd = s.snd * t.snd :=
rfl
#align nonempty_interval.snd_mul NonemptyInterval.snd_mul
#align nonempty_interval.snd_add NonemptyInterval.snd_add
+-/
+#print NonemptyInterval.coe_mul_interval /-
@[simp, to_additive]
theorem coe_mul_interval : (↑(s * t) : Interval α) = s * t :=
rfl
#align nonempty_interval.coe_mul_interval NonemptyInterval.coe_mul_interval
#align nonempty_interval.coe_add_interval NonemptyInterval.coe_add_interval
+-/
+#print NonemptyInterval.pure_mul_pure /-
@[simp, to_additive]
theorem pure_mul_pure : pure a * pure b = pure (a * b) :=
rfl
#align nonempty_interval.pure_mul_pure NonemptyInterval.pure_mul_pure
#align nonempty_interval.pure_add_pure NonemptyInterval.pure_add_pure
+-/
end NonemptyInterval
@@ -304,12 +334,14 @@ instance [OrderedCommMonoid α] : CommMonoid (Interval α) :=
namespace NonemptyInterval
+#print NonemptyInterval.coe_pow_interval /-
@[simp, to_additive]
theorem coe_pow_interval [OrderedCommMonoid α] (s : NonemptyInterval α) (n : ℕ) :
(↑(s ^ n) : Interval α) = s ^ n :=
map_pow (⟨coe, coe_one_interval, coe_mul_interval⟩ : NonemptyInterval α →* Interval α) _ _
#align nonempty_interval.coe_pow_interval NonemptyInterval.coe_pow_interval
#align nonempty_interval.coe_nsmul_interval NonemptyInterval.coe_nsmul_interval
+-/
end NonemptyInterval
@@ -647,11 +679,13 @@ namespace NonemptyInterval
variable (s t : NonemptyInterval α) (a : α)
+#print NonemptyInterval.length /-
/-- The length of an interval is its first component minus its second component. This measures the
accuracy of the approximation by an interval. -/
def length : α :=
s.snd - s.fst
#align nonempty_interval.length NonemptyInterval.length
+-/
@[simp]
theorem length_nonneg : 0 ≤ s.length :=
@@ -682,11 +716,13 @@ theorem length_add : (s + t).length = s.length + t.length :=
theorem length_sub : (s - t).length = s.length + t.length := by simp [sub_eq_add_neg]
#align nonempty_interval.length_sub NonemptyInterval.length_sub
+#print NonemptyInterval.length_sum /-
@[simp]
theorem length_sum (f : ι → NonemptyInterval α) (s : Finset ι) :
(∑ i in s, f i).length = ∑ i in s, (f i).length :=
map_sum (⟨length, length_zero, length_add⟩ : NonemptyInterval α →+ α) _ _
#align nonempty_interval.length_sum NonemptyInterval.length_sum
+-/
end NonemptyInterval
@@ -694,12 +730,14 @@ namespace Interval
variable (s t : Interval α) (a : α)
+#print Interval.length /-
/-- The length of an interval is its first component minus its second component. This measures the
accuracy of the approximation by an interval. -/
def length : Interval α → α
| ⊥ => 0
| (s : NonemptyInterval α) => s.length
#align interval.length Interval.length
+-/
@[simp]
theorem length_nonneg : ∀ s : Interval α, 0 ≤ s.length
@@ -733,10 +771,12 @@ theorem length_sub_le : (s - t).length ≤ s.length + t.length := by
simpa [sub_eq_add_neg] using length_add_le s (-t)
#align interval.length_sub_le Interval.length_sub_le
+#print Interval.length_sum_le /-
theorem length_sum_le (f : ι → Interval α) (s : Finset ι) :
(∑ i in s, f i).length ≤ ∑ i in s, (f i).length :=
Finset.le_sum_of_subadditive _ length_zero length_add_le _ _
#align interval.length_sum_le Interval.length_sum_le
+-/
end Interval
mathlib commit https://github.com/leanprover-community/mathlib/commit/cca40788df1b8755d5baf17ab2f27dacc2e17acb
@@ -535,10 +535,10 @@ variable [OrderedCommGroup α] {s t : NonemptyInterval α}
protected theorem mul_eq_one_iff : s * t = 1 ↔ ∃ a b, s = pure a ∧ t = pure b ∧ a * b = 1 :=
by
refine' ⟨fun h => _, _⟩
- · rw [ext_iff, Prod.ext_iff] at h
+ · rw [ext_iff, Prod.ext_iff] at h
have := (mul_le_mul_iff_of_ge s.fst_le_snd t.fst_le_snd).1 (h.2.trans h.1.symm).le
refine' ⟨s.fst, t.fst, _, _, h.1⟩ <;> ext <;> try rfl
- exacts[this.1.symm, this.2.symm]
+ exacts [this.1.symm, this.2.symm]
· rintro ⟨b, c, rfl, rfl, h⟩
rw [pure_mul_pure, h, pure_one]
#align nonempty_interval.mul_eq_one_iff NonemptyInterval.mul_eq_one_iff
@@ -591,13 +591,25 @@ instance {α : Type u} [OrderedAddCommGroup α] : SubtractionCommMonoid (Interva
neg := Neg.neg
sub := Sub.sub
sub_eq_add_neg := by
- rintro (_ | s) (_ | t) <;> first |rfl|exact congr_arg some (sub_eq_add_neg _ _)
- neg_neg := by rintro (_ | s) <;> first |rfl|exact congr_arg some (neg_neg _)
- neg_add_rev := by rintro (_ | s) (_ | t) <;> first |rfl|exact congr_arg some (neg_add_rev _ _)
+ rintro (_ | s) (_ | t) <;>
+ first
+ | rfl
+ | exact congr_arg some (sub_eq_add_neg _ _)
+ neg_neg := by
+ rintro (_ | s) <;>
+ first
+ | rfl
+ | exact congr_arg some (neg_neg _)
+ neg_add_rev := by
+ rintro (_ | s) (_ | t) <;>
+ first
+ | rfl
+ | exact congr_arg some (neg_add_rev _ _)
neg_eq_of_add := by
rintro (_ | s) (_ | t) h <;>
first
- |cases h|exact congr_arg some (neg_eq_of_add_eq_zero_right <| Option.some_injective _ h) }
+ | cases h
+ | exact congr_arg some (neg_eq_of_add_eq_zero_right <| Option.some_injective _ h) }
@[to_additive Interval.subtractionCommMonoid]
instance : DivisionCommMonoid (Interval α) :=
@@ -605,13 +617,25 @@ instance : DivisionCommMonoid (Interval α) :=
inv := Inv.inv
div := (· / ·)
div_eq_mul_inv := by
- rintro (_ | s) (_ | t) <;> first |rfl|exact congr_arg some (div_eq_mul_inv _ _)
- inv_inv := by rintro (_ | s) <;> first |rfl|exact congr_arg some (inv_inv _)
- mul_inv_rev := by rintro (_ | s) (_ | t) <;> first |rfl|exact congr_arg some (mul_inv_rev _ _)
+ rintro (_ | s) (_ | t) <;>
+ first
+ | rfl
+ | exact congr_arg some (div_eq_mul_inv _ _)
+ inv_inv := by
+ rintro (_ | s) <;>
+ first
+ | rfl
+ | exact congr_arg some (inv_inv _)
+ mul_inv_rev := by
+ rintro (_ | s) (_ | t) <;>
+ first
+ | rfl
+ | exact congr_arg some (mul_inv_rev _ _)
inv_eq_of_mul := by
rintro (_ | s) (_ | t) h <;>
first
- |cases h|exact congr_arg some (inv_eq_of_mul_eq_one_right <| Option.some_injective _ h) }
+ | cases h
+ | exact congr_arg some (inv_eq_of_mul_eq_one_right <| Option.some_injective _ h) }
end Interval
mathlib commit https://github.com/leanprover-community/mathlib/commit/917c3c072e487b3cccdbfeff17e75b40e45f66cb
@@ -26,7 +26,7 @@ in `data.fp.basic`. We have not yet integrated these with the rest of the librar
open Function Set
-open BigOperators Pointwise
+open scoped BigOperators Pointwise
universe u
mathlib commit https://github.com/leanprover-community/mathlib/commit/738054fa93d43512da144ec45ce799d18fd44248
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Yaël Dillies
! This file was ported from Lean 3 source module algebra.order.interval
-! leanprover-community/mathlib commit 9114ddffa023340c9ec86965e00cdd6fe26fcdf6
+! leanprover-community/mathlib commit f0c8bf9245297a541f468be517f1bde6195105e9
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
@@ -20,7 +20,7 @@ import Mathbin.Tactic.Positivity
This file defines arithmetic operations on intervals and prove their correctness. Note that this is
full precision operations. The essentials of float operations can be found
-in `data.fp.basic`. We hsve not yet integrated these with the rest of the library.
+in `data.fp.basic`. We have not yet integrated these with the rest of the library.
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/bd9851ca476957ea4549eb19b40e7b5ade9428cc
@@ -279,9 +279,11 @@ instance Interval.mulOneClass [OrderedCommMonoid α] : MulOneClass (Interval α)
mul := (· * ·)
one := 1
one_mul s :=
- (Option.map₂_coe_left _ _ _).trans <| by simp_rw [one_mul, ← id_def, Option.map_id, id]
+ (Option.map₂_coe_left _ _ _).trans <| by
+ simp_rw [one_mul, ← Function.id_def, Option.map_id, id]
mul_one s :=
- (Option.map₂_coe_right _ _ _).trans <| by simp_rw [mul_one, ← id_def, Option.map_id, id]
+ (Option.map₂_coe_right _ _ _).trans <| by
+ simp_rw [mul_one, ← Function.id_def, Option.map_id, id]
@[to_additive]
instance Interval.commMonoid [OrderedCommMonoid α] : CommMonoid (Interval α) :=
@@ -711,8 +711,8 @@ theorem length_sum_le (f : ι → Interval α) (s : Finset ι) :
(∑ i in s, f i).length ≤ ∑ i in s, (f i).length := by
-- Porting note: Old proof was `:= Finset.le_sum_of_subadditive _ length_zero length_add_le _ _`
apply Finset.le_sum_of_subadditive
- exact length_zero
- exact length_add_le
+ · exact length_zero
+ · exact length_add_le
#align interval.length_sum_le Interval.length_sum_le
end Interval
Move Set.Ixx
, Finset.Ixx
, Multiset.Ixx
together under two different folders:
Order.Interval
for their definition and basic propertiesAlgebra.Order.Interval
for their algebraic propertiesMove the definitions of Multiset.Ixx
to what is now Order.Interval.Multiset
. I believe we could just delete this file in a later PR as nothing uses it (and I already had doubts when defining Multiset.Ixx
three years ago).
Move the algebraic results out of what is now Order.Interval.Finset.Basic
to a new file Algebra.Order.Interval.Finset.Basic
.
@@ -7,7 +7,7 @@ import Mathlib.Algebra.Group.Prod
import Mathlib.Algebra.Order.BigOperators.Group.Finset
import Mathlib.Data.Option.NAry
import Mathlib.Data.Set.Pointwise.Basic
-import Mathlib.Order.Interval
+import Mathlib.Order.Interval.Basic
#align_import algebra.order.interval from "leanprover-community/mathlib"@"f0c8bf9245297a541f468be517f1bde6195105e9"
Take the content of
Algebra.BigOperators.List.Basic
Algebra.BigOperators.List.Lemmas
Algebra.BigOperators.Multiset.Basic
Algebra.BigOperators.Multiset.Lemmas
Algebra.BigOperators.Multiset.Order
Algebra.BigOperators.Order
and sort it into six files:
Algebra.Order.BigOperators.Group.List
. I credit Yakov for https://github.com/leanprover-community/mathlib/pull/8543.Algebra.Order.BigOperators.Group.Multiset
. Copyright inherited from Algebra.BigOperators.Multiset.Order
.Algebra.Order.BigOperators.Group.Finset
. Copyright inherited from Algebra.BigOperators.Order
.Algebra.Order.BigOperators.Ring.List
. I credit Stuart for https://github.com/leanprover-community/mathlib/pull/10184.Algebra.Order.BigOperators.Ring.Multiset
. I credit Ruben for https://github.com/leanprover-community/mathlib/pull/8787.Algebra.Order.BigOperators.Ring.Finset
. I credit Floris for https://github.com/leanprover-community/mathlib/pull/1294.Here are the design decisions at play:
Data.Nat.Order.Basic
in a few List
files.Algebra.Order.BigOperators
instead of Algebra.BigOperators.Order
because algebraic order theory is more of a theory than big operators algebra. Another reason is that algebraic order theory is the only way to mix pure order and pure algebra, while there are more ways to mix pure finiteness and pure algebra than just big operators.Algebra.Order.BigOperators.Group
should be additivisable (except a few Nat
- or Int
-specific lemmas). In contrast, things under Algebra.Order.BigOperators.Ring
are more prone to having heavy imports.List
vs Multiset
vs Finset
. This is not strictly necessary, and can be relaxed in cases where there aren't that many lemmas to be had. As an example, I could split out the AbsoluteValue
lemmas from Algebra.Order.BigOperators.Ring.Finset
to a file Algebra.Order.BigOperators.Ring.AbsoluteValue
and it could stay this way until too many lemmas are in this file (or a split is needed for import reasons), in which case we would need files Algebra.Order.BigOperators.Ring.AbsoluteValue.Finset
, Algebra.Order.BigOperators.Ring.AbsoluteValue.Multiset
, etc...Finsupp
big operator and finprod
/finsum
order lemmas also belong in Algebra.Order.BigOperators
. I haven't done so in this PR because the diff is big enough like that.@@ -3,8 +3,8 @@ Copyright (c) 2022 Yaël Dillies. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Yaël Dillies
-/
-import Mathlib.Algebra.BigOperators.Order
import Mathlib.Algebra.Group.Prod
+import Mathlib.Algebra.Order.BigOperators.Group.Finset
import Mathlib.Data.Option.NAry
import Mathlib.Data.Set.Pointwise.Basic
import Mathlib.Order.Interval
We change the following field in the definition of an additive commutative monoid:
nsmul_succ : ∀ (n : ℕ) (x : G),
- AddMonoid.nsmul (n + 1) x = x + AddMonoid.nsmul n x
+ AddMonoid.nsmul (n + 1) x = AddMonoid.nsmul n x + x
where the latter is more natural
We adjust the definitions of ^
in monoids, groups, etc.
Originally there was a warning comment about why this natural order was preferred
use
x * npowRec n x
and notnpowRec n x * x
in the definition to make sure that definitional unfolding ofnpowRec
is blocked, to avoid deep recursion issues.
but it seems to no longer apply.
Remarks on the PR :
pow_succ
and pow_succ'
have switched their meanings.Ideal.IsPrime.mul_mem_pow
which is defined in [Mathlib/RingTheory/DedekindDomain/Ideal.lean]. Changing the order of operation forced me to add the symmetric lemma Ideal.IsPrime.mem_pow_mul
.@@ -310,7 +310,7 @@ variable [OrderedCommMonoid α] (s : Interval α) {n : ℕ}
@[to_additive]
theorem bot_pow : ∀ {n : ℕ}, n ≠ 0 → (⊥ : Interval α) ^ n = ⊥
| 0, h => (h rfl).elim
- | Nat.succ n, _ => bot_mul (⊥ ^ n)
+ | Nat.succ n, _ => mul_bot (⊥ ^ n)
#align interval.bot_pow Interval.bot_pow
#align interval.bot_nsmul Interval.bot_nsmul
This PR contains 2 changes:
@[ext (flat := false)]
, which addressed the porting notes.ext_iff
's namespace is changed due to 1.Partially addresses #11182
@@ -517,7 +517,7 @@ variable [OrderedCommGroup α] {s t : NonemptyInterval α}
@[to_additive]
protected theorem mul_eq_one_iff : s * t = 1 ↔ ∃ a b, s = pure a ∧ t = pure b ∧ a * b = 1 := by
refine' ⟨fun h => _, _⟩
- · rw [ext_iff, Prod.ext_iff] at h
+ · rw [NonemptyInterval.ext_iff, Prod.ext_iff] at h
have := (mul_le_mul_iff_of_ge s.fst_le_snd t.fst_le_snd).1 (h.2.trans h.1.symm).le
refine' ⟨s.fst, t.fst, _, _, h.1⟩ <;> apply NonemptyInterval.ext <;> dsimp [pure]
· nth_rw 2 [this.1]
nsmul
and zsmul
to default automatically (#6262)
This PR removes the default values for nsmul
and zsmul
, forcing the user to populate them manually.
The previous behavior can be obtained by writing nsmul := nsmulRec
and zsmul := zsmulRec
, which is now in the docstring for these fields.
The motivation here is to make it more obvious when module diamonds are being introduced, or at least where they might be hiding; you can now simply search for nsmulRec
in the source code.
Arguably we should do the same thing for intCast
, natCast
, pow
, and zpow
too, but diamonds are less common in those fields, so I'll leave them to a subsequent PR.
Co-authored-by: Matthew Ballard <matt@mrb.email>
@@ -541,7 +541,9 @@ instance subtractionCommMonoid {α : Type u} [OrderedAddCommGroup α] :
exact neg_add_rev _ _
neg_eq_of_add := fun s t h => by
obtain ⟨a, b, rfl, rfl, hab⟩ := NonemptyInterval.add_eq_zero_iff.1 h
- rw [neg_pure, neg_eq_of_add_eq_zero_right hab] }
+ rw [neg_pure, neg_eq_of_add_eq_zero_right hab]
+ -- TODO: use a better defeq
+ zsmul := zsmulRec }
@[to_additive existing NonemptyInterval.subtractionCommMonoid]
instance divisionCommMonoid : DivisionCommMonoid (NonemptyInterval α) :=
@@ -590,7 +592,9 @@ instance subtractionCommMonoid {α : Type u} [OrderedAddCommGroup α] :
rintro (_ | s) (_ | t) h <;>
first
| cases h
- | exact congr_arg some (neg_eq_of_add_eq_zero_right <| Option.some_injective _ h) }
+ | exact congr_arg some (neg_eq_of_add_eq_zero_right <| Option.some_injective _ h)
+ -- TODO: use a better defeq
+ zsmul := zsmulRec }
@[to_additive existing Interval.subtractionCommMonoid]
instance divisionCommMonoid : DivisionCommMonoid (Interval α) :=
The previous code often discarded the safety features of Qq by casting quoted terms to Expr
and back. This is far from an exhaustive replacement.
This makes use of a bug fix in Lean 4.6.0rc1 that allows us to write things like
match u, α, e with
| 0, ~q(ℤ), ~q([@Int](https://github.com/Int).floor $α' $i $j $a) =>
Previously these match
es did not generalize u
correctly.
To make Qq happy, we introduce a few more assertInstancesCommute
that were not previously here.
Without them, there is a higher risk that positivity
produces an ill-typed proof in weird situations.
Like every assertInstancesCommute
, this comes at a small performance cost that could be eliminated by using the unsafe assumeInstancesCommute
instead.
Another very small performance hit here is from the (possibly unnecessary) defeq check of the types before checking defeq of the values. On the other hand, this might actually increase performance when the match fails due to a type mismatch.
There is probably some boilerplate that can be extracted from the repetition here; but I am declaring that out of scope for this PR: the goal is to establish a canonical spelling for this sort of matching, so that future extensions copy-pasted from these extensions inherit the spelling automatically.
@@ -721,27 +721,17 @@ open Lean Meta Qq
/-- Extension for the `positivity` tactic: The length of an interval is always nonnegative. -/
@[positivity NonemptyInterval.length _]
def evalNonemptyIntervalLength : PositivityExt where
- eval {u α} _ _ e := do
- let .app (f : Q(NonemptyInterval $α → $α)) (a : Q(NonemptyInterval $α)) ←
- withReducible (whnf e) | throwError "not NonemptyInterval.length"
- let _eq : $e =Q $f $a := ⟨⟩
- let _I ← synthInstanceQ (q(OrderedAddCommGroup $α) : Q(Type u))
- assumeInstancesCommute
- let ⟨_f_eq⟩ ←
- withDefault <| withNewMCtxDepth <| assertDefEqQ (u := u.succ) f q(NonemptyInterval.length)
+ eval {u _α} _ _ e := do
+ let ~q(@NonemptyInterval.length _ $inst $a) := e | throwError "not NonemptyInterval.length"
+ assertInstancesCommute
return .nonnegative q(NonemptyInterval.length_nonneg $a)
/-- Extension for the `positivity` tactic: The length of an interval is always nonnegative. -/
@[positivity Interval.length _]
def evalIntervalLength : PositivityExt where
- eval {u α} _ _ e := do
- let .app (f : Q(Interval $α → $α)) (a : Q(Interval $α)) ←
- withReducible (whnf e) | throwError "not NonemptyInterval.length"
- let _eq : $e =Q $f $a := ⟨⟩
- let _I ← synthInstanceQ (q(OrderedAddCommGroup $α) : Q(Type u))
+ eval {u _α} _ _ e := do
+ let ~q(@Interval.length _ $inst $a) := e | throwError "not Interval.length"
assumeInstancesCommute
- let ⟨_f_eq⟩ ←
- withDefault <| withNewMCtxDepth <| assertDefEqQ (u := u.succ) f q(Interval.length)
return .nonnegative q(Interval.length_nonneg $a)
end Mathlib.Meta.Positivity
Some of these are already transitively imported, others aren't used at all (but not handled by noshake in #9772).
Mostly I wanted to avoid needing all of algebra imported (but unused!) in FilteredColimitCommutesFiniteLimit
; there are now some assert_not_exists
to preserve this.
Co-authored-by: Scott Morrison <scott.morrison@gmail.com>
@@ -8,7 +8,6 @@ import Mathlib.Algebra.Group.Prod
import Mathlib.Data.Option.NAry
import Mathlib.Data.Set.Pointwise.Basic
import Mathlib.Order.Interval
-import Mathlib.Tactic.Positivity
#align_import algebra.order.interval from "leanprover-community/mathlib"@"f0c8bf9245297a541f468be517f1bde6195105e9"
@@ -42,10 +42,6 @@ variable [Preorder α] [One α]
instance : One (NonemptyInterval α) :=
⟨NonemptyInterval.pure 1⟩
-@[to_additive]
-instance : One (Interval α) :=
- ⟨Interval.pure 1⟩
-
namespace NonemptyInterval
@[to_additive (attr := simp) toProd_zero]
@@ -89,15 +85,11 @@ theorem pure_one : pure (1 : α) = 1 :=
#align interval.pure_one Interval.pure_one
#align interval.pure_zero Interval.pure_zero
-@[to_additive (attr := simp)]
-theorem one_ne_bot : (1 : Interval α) ≠ ⊥ :=
- pure_ne_bot
+@[to_additive] lemma one_ne_bot : (1 : Interval α) ≠ ⊥ := pure_ne_bot
#align interval.one_ne_bot Interval.one_ne_bot
#align interval.zero_ne_bot Interval.zero_ne_bot
-@[to_additive (attr := simp)]
-theorem bot_ne_one : (⊥ : Interval α) ≠ 1 :=
- bot_ne_pure
+@[to_additive] lemma bot_ne_one : (⊥ : Interval α) ≠ 1 := bot_ne_pure
#align interval.bot_ne_one Interval.bot_ne_one
#align interval.bot_ne_zero Interval.bot_ne_zero
@@ -288,11 +280,9 @@ instance Interval.mulOneClass [OrderedCommMonoid α] : MulOneClass (Interval α)
mul := (· * ·)
one := 1
one_mul s :=
- (Option.map₂_coe_left _ _ _).trans <| by
- simp_rw [NonemptyInterval.pure_one, one_mul, ← id_def, Option.map_id, id]
+ (Option.map₂_coe_left _ _ _).trans <| by simp_rw [one_mul, ← id_def, Option.map_id, id]
mul_one s :=
- (Option.map₂_coe_right _ _ _).trans <| by
- simp_rw [NonemptyInterval.pure_one, mul_one, ← id_def, Option.map_id, id]
+ (Option.map₂_coe_right _ _ _).trans <| by simp_rw [mul_one, ← id_def, Option.map_id, id]
@[to_additive]
instance Interval.commMonoid [OrderedCommMonoid α] : CommMonoid (Interval α) :=
@@ -319,7 +319,7 @@ namespace Interval
variable [OrderedCommMonoid α] (s : Interval α) {n : ℕ}
@[to_additive]
-theorem bot_pow : ∀ {n : ℕ} (_ : n ≠ 0), (⊥ : Interval α) ^ n = ⊥
+theorem bot_pow : ∀ {n : ℕ}, n ≠ 0 → (⊥ : Interval α) ^ n = ⊥
| 0, h => (h rfl).elim
| Nat.succ n, _ => bot_mul (⊥ ^ n)
#align interval.bot_pow Interval.bot_pow
The names for lemmas about monotonicity of (a ^ ·)
and (· ^ n)
were a mess. This PR tidies up everything related by following the naming convention for (a * ·)
and (· * b)
. Namely, (a ^ ·)
is pow_right
and (· ^ n)
is pow_left
in lemma names. All lemma renames follow the corresponding multiplication lemma names closely.
Algebra.GroupPower.Order
pow_mono
→ pow_right_mono
pow_le_pow
→ pow_le_pow_right
pow_le_pow_of_le_left
→ pow_le_pow_left
pow_lt_pow_of_lt_left
→ pow_lt_pow_left
strictMonoOn_pow
→ pow_left_strictMonoOn
pow_strictMono_right
→ pow_right_strictMono
pow_lt_pow
→ pow_lt_pow_right
pow_lt_pow_iff
→ pow_lt_pow_iff_right
pow_le_pow_iff
→ pow_le_pow_iff_right
self_lt_pow
→ lt_self_pow
strictAnti_pow
→ pow_right_strictAnti
pow_lt_pow_iff_of_lt_one
→ pow_lt_pow_iff_right_of_lt_one
pow_lt_pow_of_lt_one
→ pow_lt_pow_right_of_lt_one
lt_of_pow_lt_pow
→ lt_of_pow_lt_pow_left
le_of_pow_le_pow
→ le_of_pow_le_pow_left
pow_lt_pow₀
→ pow_lt_pow_right₀
Algebra.GroupPower.CovariantClass
pow_le_pow_of_le_left'
→ pow_le_pow_left'
nsmul_le_nsmul_of_le_right
→ nsmul_le_nsmul_right
pow_lt_pow'
→ pow_lt_pow_right'
nsmul_lt_nsmul
→ nsmul_lt_nsmul_left
pow_strictMono_left
→ pow_right_strictMono'
nsmul_strictMono_right
→ nsmul_left_strictMono
StrictMono.pow_right'
→ StrictMono.pow_const
StrictMono.nsmul_left
→ StrictMono.const_nsmul
pow_strictMono_right'
→ pow_left_strictMono
nsmul_strictMono_left
→ nsmul_right_strictMono
Monotone.pow_right
→ Monotone.pow_const
Monotone.nsmul_left
→ Monotone.const_nsmul
lt_of_pow_lt_pow'
→ lt_of_pow_lt_pow_left'
lt_of_nsmul_lt_nsmul
→ lt_of_nsmul_lt_nsmul_right
pow_le_pow'
→ pow_le_pow_right'
nsmul_le_nsmul
→ nsmul_le_nsmul_left
pow_le_pow_of_le_one'
→ pow_le_pow_right_of_le_one'
nsmul_le_nsmul_of_nonpos
→ nsmul_le_nsmul_left_of_nonpos
le_of_pow_le_pow'
→ le_of_pow_le_pow_left'
le_of_nsmul_le_nsmul'
→ le_of_nsmul_le_nsmul_right'
pow_le_pow_iff'
→ pow_le_pow_iff_right'
nsmul_le_nsmul_iff
→ nsmul_le_nsmul_iff_left
pow_lt_pow_iff'
→ pow_lt_pow_iff_right'
nsmul_lt_nsmul_iff
→ nsmul_lt_nsmul_iff_left
Data.Nat.Pow
Nat.pow_lt_pow_of_lt_left
→ Nat.pow_lt_pow_left
Nat.pow_le_iff_le_left
→ Nat.pow_le_pow_iff_left
Nat.pow_lt_iff_lt_left
→ Nat.pow_lt_pow_iff_left
pow_le_pow_iff_left
pow_lt_pow_iff_left
pow_right_injective
pow_right_inj
Nat.pow_le_pow_left
to have the correct name since Nat.pow_le_pow_of_le_left
is in Std.Nat.pow_le_pow_right
to have the correct name since Nat.pow_le_pow_of_le_right
is in Std.self_le_pow
was a duplicate of le_self_pow
.Nat.pow_lt_pow_of_lt_right
is defeq to pow_lt_pow_right
.Nat.pow_right_strictMono
is defeq to pow_right_strictMono
.Nat.pow_le_iff_le_right
is defeq to pow_le_pow_iff_right
.Nat.pow_lt_iff_lt_right
is defeq to pow_lt_pow_iff_right
.0 < n
or 1 ≤ n
to n ≠ 0
.Nat
lemmas have been protected
.@@ -230,7 +230,7 @@ end Mul
-- TODO: if `to_additive` gets improved sufficiently, derive this from `hasPow`
instance NonemptyInterval.hasNSMul [AddMonoid α] [Preorder α] [CovariantClass α α (· + ·) (· ≤ ·)]
[CovariantClass α α (swap (· + ·)) (· ≤ ·)] : SMul ℕ (NonemptyInterval α) :=
- ⟨fun n s => ⟨(n • s.fst, n • s.snd), nsmul_le_nsmul_of_le_right s.fst_le_snd _⟩⟩
+ ⟨fun n s => ⟨(n • s.fst, n • s.snd), nsmul_le_nsmul_right s.fst_le_snd _⟩⟩
#align nonempty_interval.has_nsmul NonemptyInterval.hasNSMul
section Pow
@@ -240,7 +240,7 @@ variable [Monoid α] [Preorder α] [CovariantClass α α (· * ·) (· ≤ ·)]
@[to_additive existing]
instance NonemptyInterval.hasPow : Pow (NonemptyInterval α) ℕ :=
- ⟨fun s n => ⟨s.toProd ^ n, pow_le_pow_of_le_left' s.fst_le_snd _⟩⟩
+ ⟨fun s n => ⟨s.toProd ^ n, pow_le_pow_left' s.fst_le_snd _⟩⟩
#align nonempty_interval.has_pow NonemptyInterval.hasPow
namespace NonemptyInterval
Nsmul
-> NSMul
, Zpow
-> ZPow
, etc (#9067)
Normalising to naming convention rule number 6.
@@ -228,17 +228,17 @@ end Mul
-- TODO: if `to_additive` gets improved sufficiently, derive this from `hasPow`
-instance NonemptyInterval.hasNsmul [AddMonoid α] [Preorder α] [CovariantClass α α (· + ·) (· ≤ ·)]
+instance NonemptyInterval.hasNSMul [AddMonoid α] [Preorder α] [CovariantClass α α (· + ·) (· ≤ ·)]
[CovariantClass α α (swap (· + ·)) (· ≤ ·)] : SMul ℕ (NonemptyInterval α) :=
⟨fun n s => ⟨(n • s.fst, n • s.snd), nsmul_le_nsmul_of_le_right s.fst_le_snd _⟩⟩
-#align nonempty_interval.has_nsmul NonemptyInterval.hasNsmul
+#align nonempty_interval.has_nsmul NonemptyInterval.hasNSMul
section Pow
variable [Monoid α] [Preorder α] [CovariantClass α α (· * ·) (· ≤ ·)]
[CovariantClass α α (swap (· * ·)) (· ≤ ·)]
-@[to_additive existing NonemptyInterval.hasNsmul]
+@[to_additive existing]
instance NonemptyInterval.hasPow : Pow (NonemptyInterval α) ℕ :=
⟨fun s n => ⟨s.toProd ^ n, pow_le_pow_of_le_left' s.fst_le_snd _⟩⟩
#align nonempty_interval.has_pow NonemptyInterval.hasPow
This is the supremum of
along with some minor fixes from failures on nightly-testing as Mathlib master
is merged into it.
Note that some PRs for changes that are already compatible with the current toolchain and will be necessary have already been split out: #8380.
I am hopeful that in future we will be able to progressively merge adaptation PRs into a bump/v4.X.0
branch, so we never end up with a "big merge" like this. However one of these adaptation PRs (#8056) predates my new scheme for combined CI, and it wasn't possible to keep that PR viable in the meantime.
In particular this includes adjustments for the Lean PRs
We can get rid of all the
local macro_rules | `($x ^ $y) => `(HPow.hPow $x $y) -- Porting note: See issue [lean4#2220](https://github.com/leanprover/lean4/pull/2220)
macros across Mathlib (and in any projects that want to write natural number powers of reals).
Changes the default behaviour of simp
to (config := {decide := false})
. This makes simp
(and consequentially norm_num
) less powerful, but also more consistent, and less likely to blow up in long failures. This requires a variety of changes: changing some previously by simp
or norm_num
to decide
or rfl
, or adding (config := {decide := true})
.
This changed the behaviour of simp
so that simp [f]
will only unfold "fully applied" occurrences of f
. The old behaviour can be recovered with simp (config := { unfoldPartialApp := true })
. We may in future add a syntax for this, e.g. simp [!f]
; please provide feedback! In the meantime, we have made the following changes:
(config := { unfoldPartialApp := true })
in some places, to recover the old behaviour@[eqns]
to manually adjust the equation lemmas for a particular definition, recovering the old behaviour just for that definition. See #8371, where we do this for Function.comp
and Function.flip
.This change in Lean may require further changes down the line (e.g. adding the !f
syntax, and/or upstreaming the special treatment for Function.comp
and Function.flip
, and/or removing this special treatment). Please keep an open and skeptical mind about these changes!
Co-authored-by: leanprover-community-mathlib4-bot <leanprover-community-mathlib4-bot@users.noreply.github.com> Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Eric Wieser <wieser.eric@gmail.com> Co-authored-by: Mauricio Collares <mauricio@collares.org>
@@ -304,7 +304,7 @@ namespace NonemptyInterval
@[to_additive]
theorem coe_pow_interval [OrderedCommMonoid α] (s : NonemptyInterval α) (n : ℕ) :
- (s ^ n : Interval α) = (s : Interval α) ^ n :=
+ ↑(s ^ n) = (s : Interval α) ^ n :=
map_pow (⟨⟨(↑), coe_one_interval⟩, coe_mul_interval⟩ : NonemptyInterval α →* Interval α) _ _
#align nonempty_interval.coe_pow_interval NonemptyInterval.coe_pow_interval
#align nonempty_interval.coe_nsmul_interval NonemptyInterval.coe_nsmul_interval
A linter that throws on seeing a colon at the start of a line, according to the style guideline that says these operators should go before linebreaks.
@@ -305,8 +305,7 @@ namespace NonemptyInterval
@[to_additive]
theorem coe_pow_interval [OrderedCommMonoid α] (s : NonemptyInterval α) (n : ℕ) :
(s ^ n : Interval α) = (s : Interval α) ^ n :=
- map_pow ({ toFun := (↑), map_one' := coe_one_interval, map_mul' := coe_mul_interval }
- : NonemptyInterval α →* Interval α) _ _
+ map_pow (⟨⟨(↑), coe_one_interval⟩, coe_mul_interval⟩ : NonemptyInterval α →* Interval α) _ _
#align nonempty_interval.coe_pow_interval NonemptyInterval.coe_pow_interval
#align nonempty_interval.coe_nsmul_interval NonemptyInterval.coe_nsmul_interval
@@ -667,8 +666,7 @@ theorem length_sub : (s - t).length = s.length + t.length := by simp [sub_eq_add
@[simp]
theorem length_sum (f : ι → NonemptyInterval α) (s : Finset ι) :
(∑ i in s, f i).length = ∑ i in s, (f i).length :=
- map_sum ({ toFun := length, map_zero' := length_zero, map_add' := length_add}
- : NonemptyInterval α →+ α) _ _
+ map_sum (⟨⟨length, length_zero⟩, length_add⟩ : NonemptyInterval α →+ α) _ _
#align nonempty_interval.length_sum NonemptyInterval.length_sum
end NonemptyInterval
This makes it easier to refactor the order or inheritance structure of morphisms without having to change all of the anonymous constructors.
This is far from exhaustive.
@@ -305,7 +305,8 @@ namespace NonemptyInterval
@[to_additive]
theorem coe_pow_interval [OrderedCommMonoid α] (s : NonemptyInterval α) (n : ℕ) :
(s ^ n : Interval α) = (s : Interval α) ^ n :=
- map_pow (⟨⟨(↑), coe_one_interval⟩, coe_mul_interval⟩ : NonemptyInterval α →* Interval α) _ _
+ map_pow ({ toFun := (↑), map_one' := coe_one_interval, map_mul' := coe_mul_interval }
+ : NonemptyInterval α →* Interval α) _ _
#align nonempty_interval.coe_pow_interval NonemptyInterval.coe_pow_interval
#align nonempty_interval.coe_nsmul_interval NonemptyInterval.coe_nsmul_interval
@@ -666,7 +667,8 @@ theorem length_sub : (s - t).length = s.length + t.length := by simp [sub_eq_add
@[simp]
theorem length_sum (f : ι → NonemptyInterval α) (s : Finset ι) :
(∑ i in s, f i).length = ∑ i in s, (f i).length :=
- map_sum (⟨⟨length, length_zero⟩, length_add⟩ : NonemptyInterval α →+ α) _ _
+ map_sum ({ toFun := length, map_zero' := length_zero, map_add' := length_add}
+ : NonemptyInterval α →+ α) _ _
#align nonempty_interval.length_sum NonemptyInterval.length_sum
end NonemptyInterval
Type _
and Sort _
(#6499)
We remove all possible occurences of Type _
and Sort _
in favor of Type*
and Sort*
.
This has nice performance benefits.
@@ -27,7 +27,7 @@ open scoped BigOperators Pointwise
universe u
-variable {ι α : Type _}
+variable {ι α : Type*}
/-! ### One/zero -/
@@ -2,11 +2,6 @@
Copyright (c) 2022 Yaël Dillies. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Yaël Dillies
-
-! This file was ported from Lean 3 source module algebra.order.interval
-! leanprover-community/mathlib commit f0c8bf9245297a541f468be517f1bde6195105e9
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
-/
import Mathlib.Algebra.BigOperators.Order
import Mathlib.Algebra.Group.Prod
@@ -15,6 +10,8 @@ import Mathlib.Data.Set.Pointwise.Basic
import Mathlib.Order.Interval
import Mathlib.Tactic.Positivity
+#align_import algebra.order.interval from "leanprover-community/mathlib"@"f0c8bf9245297a541f468be517f1bde6195105e9"
+
/-!
# Interval arithmetic
The unported dependencies are