refactor: migrate to new ranges (#8841)

This PR migrates usages of `Std.Range` to the new polymorphic ranges.

This PR unfortunately increases the transitive imports for
frequently-used parts of `Init` because the ranges now rely on iterators
in order to provide their functionality for types other than `Nat`.
However, iteration over ranges in compiled code is as efficient as
before in the examples I checked. This is because of a special
`IteratorLoop` implementation provided in the PR for this purpose.

There were two issues that were uncovered during migration:

* In `IndPredBelow.lean`, migrating the last remaining range causes
`compilerTest1.lean` to break. I have minimized the issue and came to
the conclusion it's a compiler bug. Therefore, I have not replaced said
old range usage yet (see #9186).
* In `BRecOn.lean`, we are publicly importing the ranges. Making this
import private should theoretically work, but there seems to be a
problem with the module system, causing the build to panic later in
`Init.Data.Grind.Poly` (see #9185).
* In `FuzzyMatching.lean`, inlining fails with the new ranges, which
would have led to significant slowdown. Therefore, I have not migrated
this file either.
This commit is contained in:
Paul Reichert 2025-07-07 14:41:53 +02:00 committed by GitHub
parent 6e98dfbc64
commit 98e4b2882f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
190 changed files with 1069 additions and 556 deletions

View file

@ -6,9 +6,12 @@ Author: Kim Morrison
module
prelude
public import Init.Data.Array.Basic
public import Init.Data.Nat.Lemmas
public import Init.Data.Range
public import Init.Core
import Init.Data.Array.Basic
import Init.Data.Nat.Lemmas
import Init.Data.Range.Polymorphic.Iterators
import Init.Data.Range.Polymorphic.Nat
import Init.Data.Iterators.Consumers
public section
@ -26,9 +29,9 @@ Specifically, `Array.lex as bs lt` is true if
* there is an index `i` such that `lt as[i] bs[i]`, and for all `j < i`, `as[j] == bs[j]`.
-/
def lex [BEq α] (as bs : Array α) (lt : αα → Bool := by exact (· < ·)) : Bool := Id.run do
for h : i in [0 : min as.size bs.size] do
-- TODO: `omega` should be able to find this itself.
have : i < min as.size bs.size := Membership.get_elem_helper h rfl
for h : i in 0...(min as.size bs.size) do
-- TODO: `get_elem_tactic` should be able to find this itself.
have : i < min as.size bs.size := Std.PRange.lt_upper_of_mem h
if lt as[i] bs[i] then
return true
else if as[i] != bs[i] then

View file

@ -6,9 +6,12 @@ Author: Kim Morrison
module
prelude
public import all Init.Data.Array.Lex.Basic
import all Init.Data.Array.Lex.Basic
public import Init.Data.Array.Lex.Basic
public import Init.Data.Array.Lemmas
public import Init.Data.List.Lex
import Init.Data.Range.Polymorphic.Lemmas
import Init.Data.Range.Polymorphic.NatLemmas
public section
@ -36,16 +39,38 @@ protected theorem not_le_iff_gt [LT α] {xs ys : Array α} :
Classical.not_not
@[simp] theorem lex_empty [BEq α] {lt : αα → Bool} {xs : Array α} : xs.lex #[] lt = false := by
simp [lex]
rw [lex, Std.PRange.forIn'_eq_match]
simp [Std.PRange.SupportsUpperBound.IsSatisfied]
private theorem cons_lex_cons.forIn'_congr_aux [Monad m] {as bs : ρ} {_ : Membership α ρ}
[ForIn' m ρ α inferInstance] (w : as = bs)
{b b' : β} (hb : b = b')
{f : (a' : α) → a' ∈ as → β → m (ForInStep β)}
{g : (a' : α) → a' ∈ bs → β → m (ForInStep β)}
(h : ∀ a m b, f a (by simpa [w] using m) b = g a m b) :
forIn' as b f = forIn' bs b' g := by
cases hb
cases w
have : f = g := by
ext a ha acc
apply h
cases this
rfl
private theorem cons_lex_cons [BEq α] {lt : αα → Bool} {a b : α} {xs ys : Array α} :
(#[a] ++ xs).lex (#[b] ++ ys) lt =
(lt a b || a == b && xs.lex ys lt) := by
simp only [lex]
simp only [Std.Range.forIn'_eq_forIn'_range', size_append, List.size_toArray, List.length_singleton,
Nat.add_comm 1]
simp [Nat.add_min_add_right, List.range'_succ, getElem_append_left, List.range'_succ_left,
getElem_append_right]
simp only [lex, size_append, List.size_toArray, List.length_cons, List.length_nil, Nat.zero_add,
Nat.add_min_add_left, Nat.add_lt_add_iff_left, Std.PRange.forIn'_eq_forIn'_toList]
conv =>
lhs; congr; congr
rw [cons_lex_cons.forIn'_congr_aux Std.PRange.toList_eq_match rfl (fun _ _ _ => rfl)]
simp only [Std.PRange.SupportsUpperBound.IsSatisfied, bind_pure_comp, map_pure]
rw [cons_lex_cons.forIn'_congr_aux (if_pos (by omega)) rfl (fun _ _ _ => rfl)]
simp only [Std.PRange.toList_open_eq_toList_closed_of_isSome_succ? (lo := 0) (h := rfl),
Std.PRange.UpwardEnumerable.succ?, Nat.add_comm 1, Std.PRange.Nat.ClosedOpen.toList_succ_succ,
Option.get_some, List.forIn'_cons, List.size_toArray, List.length_cons, List.length_nil,
Nat.lt_add_one, getElem_append_left, List.getElem_toArray, List.getElem_cons_zero]
cases lt a b
· rw [bne]
cases a == b <;> simp
@ -54,10 +79,17 @@ private theorem cons_lex_cons [BEq α] {lt : αα → Bool} {a b : α} {xs
@[simp, grind =] theorem _root_.List.lex_toArray [BEq α] {lt : αα → Bool} {l₁ l₂ : List α} :
l₁.toArray.lex l₂.toArray lt = l₁.lex l₂ lt := by
induction l₁ generalizing l₂ with
| nil => cases l₂ <;> simp [lex]
| nil =>
cases l₂
· rw [lex, Std.PRange.forIn'_eq_match]
simp [Std.PRange.SupportsUpperBound.IsSatisfied]
· rw [lex, Std.PRange.forIn'_eq_match]
simp [Std.PRange.SupportsUpperBound.IsSatisfied]
| cons x l₁ ih =>
cases l₂ with
| nil => simp [lex]
| nil =>
rw [lex, Std.PRange.forIn'_eq_match]
simp [Std.PRange.SupportsUpperBound.IsSatisfied]
| cons y l₂ =>
rw [List.toArray_cons, List.toArray_cons y, cons_lex_cons, List.lex, ih]

View file

@ -9,6 +9,7 @@ prelude
public import Init.RCases
public import Init.Data.Iterators.Basic
public import Init.Data.Iterators.Consumers.Monadic.Partial
public import Init.Data.Iterators.Internal.LawfulMonadLiftFunction
public section
@ -32,6 +33,8 @@ asserts that an `IteratorLoop` instance equals the default implementation.
namespace Std.Iterators
open Std.Internal
section Typeclasses
/--
@ -39,6 +42,7 @@ Relation that needs to be well-formed in order for a loop over an iterator to te
It is assumed that the `plausible_forInStep` predicate relates the input and output of the
stepper function.
-/
@[expose]
def IteratorLoop.rel (α : Type w) (m : Type w → Type w') {β : Type w} [Iterator α m β]
{γ : Type x} (plausible_forInStep : β → γ → ForInStep γ → Prop)
(p' p : IterM (α := α) m β × γ) : Prop :=
@ -48,6 +52,7 @@ def IteratorLoop.rel (α : Type w) (m : Type w → Type w') {β : Type w} [Itera
/--
Asserts that `IteratorLoop.rel` is well-founded.
-/
@[expose]
def IteratorLoop.WellFounded (α : Type w) (m : Type w → Type w') {β : Type w} [Iterator α m β]
{γ : Type x} (plausible_forInStep : β → γ → ForInStep γ → Prop) : Prop :=
_root_.WellFounded (IteratorLoop.rel α m plausible_forInStep)
@ -61,6 +66,7 @@ This class is experimental and users of the iterator API should not explicitly d
They can, however, assume that consumers that require an instance will work for all iterators
provided by the standard library.
-/
@[ext]
class IteratorLoop (α : Type w) (m : Type w → Type w') {β : Type w} [Iterator α m β]
(n : Type x → Type x') where
forIn : ∀ (_liftBind : (γ : Type w) → (δ : Type x) → (γ → n δ) → m γ → n δ) (γ : Type x),
@ -108,29 +114,24 @@ class IteratorSizePartial (α : Type w) (m : Type w → Type w') {β : Type w} [
end Typeclasses
/-- Internal implementation detail of the iterator library. -/
def IteratorLoop.WFRel {α : Type w} {m : Type w → Type w'} {β : Type w} [Iterator α m β]
{γ : Type x} {plausible_forInStep : β → γ → ForInStep γ → Prop}
(_wf : WellFounded α m plausible_forInStep) :=
IterM (α := α) m β × γ
structure IteratorLoop.WithWF (α : Type w) (m : Type w → Type w') {β : Type w} [Iterator α m β]
{γ : Type x} (PlausibleForInStep : β → γ → ForInStep γ → Prop)
(hwf : IteratorLoop.WellFounded α m PlausibleForInStep) where
it : IterM (α := α) m β
acc : γ
/-- Internal implementation detail of the iterator library. -/
def IteratorLoop.WFRel.mk {α : Type w} {m : Type w → Type w'} {β : Type w} [Iterator α m β]
{γ : Type x} {plausible_forInStep : β → γ → ForInStep γ → Prop}
(wf : WellFounded α m plausible_forInStep) (it : IterM (α := α) m β) (c : γ) :
IteratorLoop.WFRel wf :=
(it, c)
private instance {α : Type w} {m : Type w → Type w'} {β : Type w} [Iterator α m β]
{γ : Type x} {plausible_forInStep : β → γ → ForInStep γ → Prop}
(wf : IteratorLoop.WellFounded α m plausible_forInStep) :
WellFoundedRelation (IteratorLoop.WFRel wf) where
rel := IteratorLoop.rel α m plausible_forInStep
wf := wf
instance IteratorLoop.WithWF.instWellFoundedRelation
(α : Type w) (m : Type w → Type w') {β : Type w} [Iterator α m β]
{γ : Type x} (PlausibleForInStep : β → γ → ForInStep γ → Prop)
(hwf : IteratorLoop.WellFounded α m PlausibleForInStep) :
WellFoundedRelation (WithWF α m PlausibleForInStep hwf) where
rel := InvImage (IteratorLoop.rel α m PlausibleForInStep) (fun x => (x.it, x.acc))
wf := by exact InvImage.wf _ hwf
/--
This is the loop implementation of the default instance `IteratorLoop.defaultImplementation`.
-/
@[specialize]
@[specialize, expose]
def IterM.DefaultConsumers.forIn' {m : Type w → Type w'} {α : Type w} {β : Type w}
[Iterator α m β]
{n : Type x → Type x'} [Monad n]
@ -142,27 +143,59 @@ def IterM.DefaultConsumers.forIn' {m : Type w → Type w'} {α : Type w} {β : T
(f : (b : β) → P b → (c : γ) → n (Subtype (plausible_forInStep b c))) : n γ :=
haveI : WellFounded _ := wf
(lift _ _ · it.step) fun
| .yield it' out h => do
match ← f out (hP _ <| .direct ⟨_, h⟩) init with
| ⟨.yield c, _⟩ =>
IterM.DefaultConsumers.forIn' lift _ plausible_forInStep wf it' c P
(fun _ h' => hP _ <| .indirect ⟨_, rfl, h⟩ h') f
| ⟨.done c, _⟩ => return c
| .skip it' h =>
IterM.DefaultConsumers.forIn' lift _ plausible_forInStep wf it' init P
(fun _ h' => hP _ <| .indirect ⟨_, rfl, h⟩ h') f
| .done _ => return init
termination_by IteratorLoop.WFRel.mk wf it init
| .yield it' out h => do
match ← f out (hP _ <| .direct ⟨_, h⟩) init with
| ⟨.yield c, _⟩ =>
IterM.DefaultConsumers.forIn' lift _ plausible_forInStep wf it' c P
(fun _ h' => hP _ <| .indirect ⟨_, rfl, h⟩ h') f
| ⟨.done c, _⟩ => return c
| .skip it' h =>
IterM.DefaultConsumers.forIn' lift _ plausible_forInStep wf it' init P
(fun _ h' => hP _ <| .indirect ⟨_, rfl, h⟩ h') f
| .done _ => return init
termination_by IteratorLoop.WithWF.mk it init (hwf := wf)
decreasing_by
· exact Or.inl ⟨out, _, _
· exact Or.inr ⟨_, rfl⟩
theorem IterM.DefaultConsumers.forIn'_eq_forIn' {m : Type w → Type w'} {α : Type w} {β : Type w}
[Iterator α m β]
{n : Type x → Type x'} [Monad n]
{lift : ∀ γ δ, (γ → n δ) → m γ → n δ} {γ : Type x}
{Pl : β → γ → ForInStep γ → Prop}
{wf : IteratorLoop.WellFounded α m Pl}
{it : IterM (α := α) m β} {init : γ}
{P : β → Prop} {hP : ∀ b, it.IsPlausibleIndirectOutput b → P b}
{Q : β → Prop} {hQ : ∀ b, it.IsPlausibleIndirectOutput b → Q b}
{f : (b : β) → P b → (c : γ) → n (Subtype (Pl b c))}
{g : (b : β) → Q b → (c : γ) → n (Subtype (Pl b c))}
(hfg : ∀ b c, (hPb : P b) → (hQb : Q b) → f b hPb c = g b hQb c) :
IterM.DefaultConsumers.forIn' lift γ Pl wf it init P hP f =
IterM.DefaultConsumers.forIn' lift γ Pl wf it init Q hQ g := by
rw [forIn', forIn']
congr; ext step
split
· congr
· apply hfg
· ext
split
· apply IterM.DefaultConsumers.forIn'_eq_forIn'
assumption
· rfl
· apply IterM.DefaultConsumers.forIn'_eq_forIn'
assumption
· rfl
termination_by IteratorLoop.WithWF.mk it init (hwf := wf)
decreasing_by
· exact Or.inl ⟨_, _, _
· exact Or.inr ⟨_, rfl⟩
/--
This is the default implementation of the `IteratorLoop` class.
It simply iterates through the iterator using `IterM.step`. For certain iterators, more efficient
implementations are possible and should be used instead.
-/
@[always_inline, inline]
@[always_inline, inline, expose]
def IteratorLoop.defaultImplementation {α : Type w} {m : Type w → Type w'} {n : Type x → Type x'}
[Monad n] [Iterator α m β] :
IteratorLoop α m n where
@ -173,8 +206,9 @@ Asserts that a given `IteratorLoop` instance is equal to `IteratorLoop.defaultIm
(Even though equal, the given instance might be vastly more efficient.)
-/
class LawfulIteratorLoop (α : Type w) (m : Type w → Type w') (n : Type x → Type x')
[Monad n] [Iterator α m β] [Finite α m] [i : IteratorLoop α m n] where
lawful : i = .defaultImplementation
[Monad m] [Monad n] [Iterator α m β] [i : IteratorLoop α m n] where
lawful : ∀ lift [LawfulMonadLiftBindFunction lift], i.forIn lift =
IteratorLoop.defaultImplementation.forIn lift
/--
This is the loop implementation of the default instance `IteratorLoopPartial.defaultImplementation`.
@ -214,7 +248,7 @@ instance (α : Type w) (m : Type w → Type w') (n : Type x → Type x')
letI : IteratorLoop α m n := .defaultImplementation
LawfulIteratorLoop α m n :=
letI : IteratorLoop α m n := .defaultImplementation
⟨rfl⟩
fun _ => rfl⟩
theorem IteratorLoop.wellFounded_of_finite {m : Type w → Type w'}
{α β : Type w} {γ : Type x} [Iterator α m β] [Finite α m] :

View file

@ -24,6 +24,12 @@ the requirement that the `MonadLift(T)` instance induced by `f` admits a
namespace Std.Internal
class LawfulMonadLiftBindFunction {m : Type u → Type v} {n : Type w → Type x} [Monad m]
[Monad n] (liftBind : ∀ γ δ, (γ → n δ) → m γ → n δ) where
liftBind_pure {γ δ} (f : γ → n δ) (a : γ) : liftBind γ δ f (pure a) = f a
liftBind_bind {β γ δ} (f : γ → n δ) (x : m β) (g : β → m γ) :
liftBind γ δ f (x >>= g) = liftBind β δ (fun b => liftBind γ δ f (g b)) x
class LawfulMonadLiftFunction {m : Type u → Type v} {n : Type u → Type w}
[Monad m] [Monad n] (lift : ⦃α : Type u⦄ → m α → n α) where
lift_pure {α : Type u} (a : α) : lift (pure a) = pure a
@ -79,4 +85,35 @@ instance [LawfulMonadLiftFunction lift] :
{ monadLift_pure := LawfulMonadLiftFunction.lift_pure
monadLift_bind := LawfulMonadLiftFunction.lift_bind }
section LiftBind
variable {liftBind : ∀ γ δ, (γ → m δ) → m γ → m δ}
instance [LawfulMonadLiftBindFunction (n := n) (fun _ _ f x => lift x >>= f)] [LawfulMonad n] :
LawfulMonadLiftFunction lift where
lift_pure {γ} a := by
simpa using LawfulMonadLiftBindFunction.liftBind_pure (n := n)
(liftBind := fun _ _ f x => lift x >>= f) (γ := γ) (δ := γ) pure a
lift_bind {β γ} x g := by
simpa using LawfulMonadLiftBindFunction.liftBind_bind (n := n)
(liftBind := fun _ _ f x => lift x >>= f) (β := β) (γ := γ) (δ := γ) pure x g
def LawfulMonadLiftBindFunction.id [Monad m] [LawfulMonad m] :
LawfulMonadLiftBindFunction (m := Id) (n := m) (fun _ _ f x => f x.run) where
liftBind_pure := by simp
liftBind_bind := by simp
instance {m : Type u → Type v} [Monad m] {n : Type u → Type w} [Monad n] [MonadLiftT m n]
[LawfulMonadLiftT m n] [LawfulMonad n] :
LawfulMonadLiftBindFunction (fun γ δ (f : γ → n δ) (x : m γ) => monadLift x >>= f) where
liftBind_pure := by simp
liftBind_bind := by simp
instance {n : Type u → Type w} [Monad n] [LawfulMonad n] :
LawfulMonadLiftBindFunction (fun γ δ (f : γ → n δ) (x : Id γ) => f x.run) where
liftBind_pure := by simp
liftBind_bind := by simp
end LiftBind
end Std.Internal

View file

@ -6,6 +6,7 @@ Authors: Paul Reichert
module
prelude
public import Init.Control.Lawful.MonadLift.Instances
public import Init.Data.Iterators.Lemmas.Consumers.Collect
public import all Init.Data.Iterators.Lemmas.Consumers.Monadic.Loop
public import all Init.Data.Iterators.Consumers.Loop
@ -16,7 +17,7 @@ public section
namespace Std.Iterators
theorem Iter.forIn'_eq {α β : Type w} [Iterator α Id β] [Finite α Id]
{m : Type x → Type x'} [Monad m] [IteratorLoop α Id m] [hl : LawfulIteratorLoop α Id m]
{m : Type x → Type x'} [Monad m] [LawfulMonad m] [IteratorLoop α Id m] [hl : LawfulIteratorLoop α Id m]
{γ : Type x} {it : Iter (α := α) β} {init : γ}
{f : (b : β) → it.IsPlausibleIndirectOutput b → γ → m (ForInStep γ)} :
letI : ForIn' m (Iter (α := α) β) β _ := Iter.instForIn'
@ -25,21 +26,22 @@ theorem Iter.forIn'_eq {α β : Type w} [Iterator α Id β] [Finite α Id]
IteratorLoop.wellFounded_of_finite it.toIterM init _ (fun _ => id)
(fun out h acc => (⟨·, .intro⟩) <$>
f out (Iter.isPlausibleIndirectOutput_iff_isPlausibleIndirectOutput_toIterM.mpr h) acc) := by
cases hl.lawful; rfl
simp [instForIn', ForIn'.forIn', IteratorLoop.finiteForIn', hl.lawful (fun γ δ f x => f x.run),
IteratorLoop.defaultImplementation]
theorem Iter.forIn_eq {α β : Type w} [Iterator α Id β] [Finite α Id]
{m : Type x → Type x'} [Monad m] [IteratorLoop α Id m] [hl : LawfulIteratorLoop α Id m]
{γ : Type x} {it : Iter (α := α) β} {init : γ}
{m : Type x → Type x'} [Monad m] [LawfulMonad m] [IteratorLoop α Id m]
[hl : LawfulIteratorLoop α Id m] {γ : Type x} {it : Iter (α := α) β} {init : γ}
{f : (b : β) → γ → m (ForInStep γ)} :
ForIn.forIn it init f =
IterM.DefaultConsumers.forIn' (fun _ _ f c => f c.run) γ (fun _ _ _ => True)
IteratorLoop.wellFounded_of_finite it.toIterM init _ (fun _ => id)
(fun out _ acc => (⟨·, .intro⟩) <$>
f out acc) := by
cases hl.lawful; rfl
simp [ForIn.forIn, forIn'_eq, -forIn'_eq_forIn]
theorem Iter.forIn'_eq_forIn'_toIterM {α β : Type w} [Iterator α Id β]
[Finite α Id] {m : Type w → Type w'} [Monad m] [LawfulMonad m]
[Finite α Id] {m : Type w → Type w''} [Monad m] [LawfulMonad m]
[IteratorLoop α Id m] [LawfulIteratorLoop α Id m]
{γ : Type w} {it : Iter (α := α) β} {init : γ}
{f : (out : β) → _ → γ → m (ForInStep γ)} :

View file

@ -38,60 +38,31 @@ theorem IterM.DefaultConsumers.forIn'_eq_match_step {α β : Type w} {m : Type w
cases step using PlausibleIterStep.casesOn <;> rfl
theorem IterM.forIn'_eq {α β : Type w} {m : Type w → Type w'} [Iterator α m β] [Finite α m]
{n : Type w → Type w''} [Monad n] [IteratorLoop α m n] [hl : LawfulIteratorLoop α m n]
[MonadLiftT m n] {γ : Type w} {it : IterM (α := α) m β} {init : γ}
{n : Type w → Type w''} [Monad m] [Monad n] [LawfulMonad n] [IteratorLoop α m n]
[hl : LawfulIteratorLoop α m n]
[MonadLiftT m n] [LawfulMonadLiftT m n] {γ : Type w} {it : IterM (α := α) m β} {init : γ}
{f : (b : β) → it.IsPlausibleIndirectOutput b → γ → n (ForInStep γ)} :
letI : ForIn' n (IterM (α := α) m β) β _ := IterM.instForIn'
ForIn'.forIn' it init f = IterM.DefaultConsumers.forIn' (n := n)
(fun _ _ f x => monadLift x >>= f) γ (fun _ _ _ => True)
IteratorLoop.wellFounded_of_finite it init _ (fun _ => id) ((⟨·, .intro⟩) <$> f · · ·) := by
cases hl.lawful; rfl
simp [instForIn', ForIn'.forIn', IteratorLoop.finiteForIn',
hl.lawful (fun _ _ f x => monadLift x >>= f), IteratorLoop.defaultImplementation]
theorem IterM.forIn_eq {α β : Type w} {m : Type w → Type w'} [Iterator α m β] [Finite α m]
{n : Type w → Type w''} [Monad n] [IteratorLoop α m n] [hl : LawfulIteratorLoop α m n]
[MonadLiftT m n] {γ : Type w} {it : IterM (α := α) m β} {init : γ}
{n : Type w → Type w''} [Monad m] [Monad n] [LawfulMonad n] [IteratorLoop α m n]
[hl : LawfulIteratorLoop α m n]
[MonadLiftT m n] [LawfulMonadLiftT m n] {γ : Type w} {it : IterM (α := α) m β} {init : γ}
{f : β → γ → n (ForInStep γ)} :
ForIn.forIn it init f = IterM.DefaultConsumers.forIn' (n := n)
(fun _ _ f x => monadLift x >>= f) γ (fun _ _ _ => True)
IteratorLoop.wellFounded_of_finite it init _ (fun _ => id) (fun out _ acc => (⟨·, .intro⟩) <$> f out acc) := by
cases hl.lawful; rfl
theorem IterM.DefaultConsumers.forIn'_eq_forIn' {m : Type w → Type w'} {α : Type w} {β : Type w}
[Iterator α m β]
{n : Type x → Type x'} [Monad n]
{liftBind : ∀ γ δ, (γ → n δ) → m γ → n δ} {γ : Type x}
{Pl : β → γ → ForInStep γ → Prop}
{wf : IteratorLoop.WellFounded α m Pl}
{it : IterM (α := α) m β} {init : γ}
{P : β → Prop} {hP : ∀ b, it.IsPlausibleIndirectOutput b → P b}
{Q : β → Prop} {hQ : ∀ b, it.IsPlausibleIndirectOutput b → Q b}
{f : (b : β) → P b → (c : γ) → n (Subtype (Pl b c))}
{g : (b : β) → Q b → (c : γ) → n (Subtype (Pl b c))}
(hfg : ∀ b c, (hPb : P b) → (hQb : Q b) → f b hPb c = g b hQb c) :
IterM.DefaultConsumers.forIn' liftBind γ Pl wf it init P hP f =
IterM.DefaultConsumers.forIn' liftBind γ Pl wf it init Q hQ g := by
rw [forIn', forIn']
congr; ext step
split
· congr
· apply hfg
· ext
split
· apply IterM.DefaultConsumers.forIn'_eq_forIn'
assumption
· rfl
· apply IterM.DefaultConsumers.forIn'_eq_forIn'
assumption
· rfl
termination_by IteratorLoop.WFRel.mk wf it init
decreasing_by
· exact Or.inl ⟨_, _, _
· exact Or.inr ⟨_, rfl⟩
simp only [ForIn.forIn, forIn'_eq]
theorem IterM.forIn'_eq_match_step {α β : Type w} {m : Type w → Type w'} [Iterator α m β]
[Finite α m] {n : Type w → Type w''} [Monad n] [LawfulMonad n]
[Finite α m] {n : Type w → Type w''} [Monad m] [Monad n] [LawfulMonad n]
[IteratorLoop α m n] [LawfulIteratorLoop α m n]
[MonadLiftT m n] {γ : Type w} {it : IterM (α := α) m β} {init : γ}
[MonadLiftT m n] [LawfulMonadLiftT m n] {γ : Type w} {it : IterM (α := α) m β} {init : γ}
{f : (out : β) → _ → γ → n (ForInStep γ)} :
letI : ForIn' n (IterM (α := α) m β) β _ := IterM.instForIn'
ForIn'.forIn' it init f = (do
@ -124,9 +95,9 @@ theorem IterM.forIn'_eq_match_step {α β : Type w} {m : Type w → Type w'} [It
· simp
theorem IterM.forIn_eq_match_step {α β : Type w} {m : Type w → Type w'} [Iterator α m β]
[Finite α m] {n : Type w → Type w''} [Monad n] [LawfulMonad n]
[Finite α m] {n : Type w → Type w''} [Monad m] [Monad n] [LawfulMonad n]
[IteratorLoop α m n] [LawfulIteratorLoop α m n]
[MonadLiftT m n] {γ : Type w} {it : IterM (α := α) m β} {init : γ}
[MonadLiftT m n] [LawfulMonadLiftT m n] {γ : Type w} {it : IterM (α := α) m β} {init : γ}
{f : β → γ → n (ForInStep γ)} :
ForIn.forIn it init f = (do
match ← it.step with
@ -140,7 +111,7 @@ theorem IterM.forIn_eq_match_step {α β : Type w} {m : Type w → Type w'} [Ite
exact forIn'_eq_match_step
theorem IterM.forM_eq_forIn {α β : Type w} {m : Type w → Type w'} [Iterator α m β]
[Finite α m] {n : Type w → Type w''} [Monad n] [LawfulMonad n]
[Finite α m] {n : Type w → Type w''} [Monad m] [Monad n] [LawfulMonad n]
[IteratorLoop α m n] [LawfulIteratorLoop α m n]
[MonadLiftT m n] {it : IterM (α := α) m β}
{f : β → n PUnit} :
@ -148,9 +119,9 @@ theorem IterM.forM_eq_forIn {α β : Type w} {m : Type w → Type w'} [Iterator
rfl
theorem IterM.forM_eq_match_step {α β : Type w} {m : Type w → Type w'} [Iterator α m β]
[Finite α m] {n : Type w → Type w''} [Monad n] [LawfulMonad n]
[Finite α m] {n : Type w → Type w''} [Monad m] [Monad n] [LawfulMonad n]
[IteratorLoop α m n] [LawfulIteratorLoop α m n]
[MonadLiftT m n] {it : IterM (α := α) m β}
[MonadLiftT m n] [LawfulMonadLiftT m n] {it : IterM (α := α) m β}
{f : β → n PUnit} :
ForM.forM it f = (do
match ← it.step with
@ -171,7 +142,7 @@ theorem IterM.foldM_eq_forIn {α β γ : Type w} {m : Type w → Type w'} [Itera
(rfl)
theorem IterM.forIn_yield_eq_foldM {α β γ δ : Type w} {m : Type w → Type w'} [Iterator α m β]
[Finite α m] {n : Type w → Type w''} [Monad n] [LawfulMonad n] [IteratorLoop α m n]
[Finite α m] {n : Type w → Type w''} [Monad m] [Monad n] [LawfulMonad n] [IteratorLoop α m n]
[LawfulIteratorLoop α m n] [MonadLiftT m n] {f : β → γ → n δ} {g : β → γ → δ → γ} {init : γ}
{it : IterM (α := α) m β} :
ForIn.forIn it init (fun c b => (fun d => .yield (g c b d)) <$> f c b) =
@ -179,8 +150,9 @@ theorem IterM.forIn_yield_eq_foldM {α β γ δ : Type w} {m : Type w → Type w
simp [IterM.foldM_eq_forIn]
theorem IterM.foldM_eq_match_step {α β γ : Type w} {m : Type w → Type w'} [Iterator α m β] [Finite α m]
{n : Type w → Type w''} [Monad n] [LawfulMonad n] [IteratorLoop α m n] [LawfulIteratorLoop α m n]
[MonadLiftT m n] {f : γ → β → n γ} {init : γ} {it : IterM (α := α) m β} :
{n : Type w → Type w''} [Monad m] [Monad n] [LawfulMonad n] [IteratorLoop α m n]
[LawfulIteratorLoop α m n] [MonadLiftT m n] [LawfulMonadLiftT m n]
{f : γ → β → n γ} {init : γ} {it : IterM (α := α) m β} :
it.foldM (init := init) f = (do
match ← it.step with
| .yield it' out _ => it'.foldM (init := ← f init out) f

View file

@ -58,50 +58,6 @@ def size {sl su α} [UpwardEnumerable α] [BoundedUpwardEnumerable sl α]
section Iterator
theorem RangeIterator.isPlausibleIndirectOutput_iff {su α}
[UpwardEnumerable α] [SupportsUpperBound su α]
[LawfulUpwardEnumerable α] [LawfulUpwardEnumerableUpperBound su α]
{it : Iter (α := RangeIterator su α) α} {out : α} :
it.IsPlausibleIndirectOutput out ↔
∃ n, it.internalState.next.bind (UpwardEnumerable.succMany? n ·) = some out ∧
SupportsUpperBound.IsSatisfied it.internalState.upperBound out := by
constructor
· intro h
induction h
case direct h =>
rw [RangeIterator.isPlausibleOutput_iff] at h
refine ⟨0, by simp [h, LawfulUpwardEnumerable.succMany?_zero]⟩
case indirect h _ ih =>
rw [RangeIterator.isPlausibleSuccessorOf_iff] at h
obtain ⟨n, hn⟩ := ih
obtain ⟨a, ha, h₁, h₂, h₃⟩ := h
refine ⟨n + 1, ?_⟩
simp [ha, ← h₃, hn.2, LawfulUpwardEnumerable.succMany?_succ_eq_succ?_bind_succMany?, h₂, hn]
· rintro ⟨n, hn, hu⟩
induction n generalizing it
case zero =>
apply Iter.IsPlausibleIndirectOutput.direct
rw [RangeIterator.isPlausibleOutput_iff]
exact ⟨by simpa [LawfulUpwardEnumerable.succMany?_zero] using hn, hu⟩
case succ ih =>
cases hn' : it.internalState.next
· simp [hn'] at hn
rename_i a
simp only [hn', Option.bind_some] at hn
have hle : UpwardEnumerable.LE a out := ⟨_, hn⟩
rw [LawfulUpwardEnumerable.succMany?_succ_eq_succ?_bind_succMany?] at hn
cases hn' : UpwardEnumerable.succ? a
· simp only [hn', Option.bind_none, reduceCtorEq] at hn
rename_i a'
simp only [hn', Option.bind_some] at hn
specialize ih (it := ⟨some a', it.internalState.upperBound⟩) hn hu
refine Iter.IsPlausibleIndirectOutput.indirect ?_ ih
rw [RangeIterator.isPlausibleSuccessorOf_iff]
refine ⟨a, _, ?_, hn', rfl⟩
apply LawfulUpwardEnumerableUpperBound.isSatisfied_of_le _ a out
· exact hu
· exact hle
theorem Internal.isPlausibleIndirectOutput_iter_iff {sl su α}
[UpwardEnumerable α] [BoundedUpwardEnumerable sl α]
[SupportsLowerBound sl α] [SupportsUpperBound su α]

View file

@ -17,8 +17,8 @@ theorem succ_eq {n : Nat} : UpwardEnumerable.succ n = n + 1 :=
rfl
theorem ClosedOpen.toList_succ_succ {m n : Nat} :
(PRange.mk (shape := ⟨.closed, .open⟩) (m+1) (n+1)).toList =
(PRange.mk (shape := ⟨.closed, .open⟩) m n).toList.map (· + 1) := by
((m+1)...(n+1)).toList =
(m...n).toList.map (· + 1) := by
simp only [← succ_eq]
rw [Std.PRange.ClosedOpen.toList_succ_succ_eq_map]

View file

@ -110,16 +110,6 @@ theorem RangeIterator.step_eq_step {su} [UpwardEnumerable α] [SupportsUpperBoun
it.step = ⟨RangeIterator.step it, isPlausibleStep_iff.mpr rfl⟩ := by
simp [Iter.step, step_eq_monadicStep, Monadic.step_eq_step, IterM.Step.toPure]
@[always_inline, inline]
instance RangeIterator.instIteratorLoop {su} [UpwardEnumerable α] [SupportsUpperBound su α]
{n : Type v → Type w} [Monad n] :
IteratorLoop (RangeIterator su α) Id n :=
.defaultImplementation
instance RangeIterator.instIteratorLoopPartial {su} [UpwardEnumerable α] [SupportsUpperBound su α]
{n : Type v → Type w} [Monad n] : IteratorLoopPartial (RangeIterator su α) Id n :=
.defaultImplementation
instance RangeIterator.instIteratorCollect {su} [UpwardEnumerable α] [SupportsUpperBound su α]
{n : Type u → Type w} [Monad n] : IteratorCollect (RangeIterator su α) Id n :=
.defaultImplementation
@ -370,4 +360,223 @@ instance RangeIterator.instLawfulDeterministicIterator {su} [UpwardEnumerable α
LawfulDeterministicIterator (RangeIterator su α) Id where
isPlausibleStep_eq_eq it := ⟨Monadic.step it, rfl⟩
end Std.PRange
theorem RangeIterator.Monadic.isPlausibleIndirectOutput_iff {su α}
[UpwardEnumerable α] [SupportsUpperBound su α]
[LawfulUpwardEnumerable α] [LawfulUpwardEnumerableUpperBound su α]
{it : IterM (α := RangeIterator su α) Id α} {out : α} :
it.IsPlausibleIndirectOutput out ↔
∃ n, it.internalState.next.bind (UpwardEnumerable.succMany? n ·) = some out ∧
SupportsUpperBound.IsSatisfied it.internalState.upperBound out := by
constructor
· intro h
induction h
case direct h =>
rw [RangeIterator.Monadic.isPlausibleOutput_iff] at h
refine ⟨0, by simp [h, LawfulUpwardEnumerable.succMany?_zero]⟩
case indirect h _ ih =>
rw [RangeIterator.Monadic.isPlausibleSuccessorOf_iff] at h
obtain ⟨n, hn⟩ := ih
obtain ⟨a, ha, h₁, h₂, h₃⟩ := h
refine ⟨n + 1, ?_⟩
simp [ha, ← h₃, hn.2, LawfulUpwardEnumerable.succMany?_succ_eq_succ?_bind_succMany?, h₂, hn]
· rintro ⟨n, hn, hu⟩
induction n generalizing it
case zero =>
apply IterM.IsPlausibleIndirectOutput.direct
rw [RangeIterator.Monadic.isPlausibleOutput_iff]
exact ⟨by simpa [LawfulUpwardEnumerable.succMany?_zero] using hn, hu⟩
case succ ih =>
cases hn' : it.internalState.next
· simp [hn'] at hn
rename_i a
simp only [hn', Option.bind_some] at hn
have hle : UpwardEnumerable.LE a out := ⟨_, hn⟩
rw [LawfulUpwardEnumerable.succMany?_succ_eq_succ?_bind_succMany?] at hn
cases hn' : UpwardEnumerable.succ? a
· simp only [hn', Option.bind_none, reduceCtorEq] at hn
rename_i a'
simp only [hn', Option.bind_some] at hn
specialize ih (it := ⟨some a', it.internalState.upperBound⟩) hn hu
refine IterM.IsPlausibleIndirectOutput.indirect ?_ ih
rw [RangeIterator.Monadic.isPlausibleSuccessorOf_iff]
refine ⟨a, _, ?_, hn', rfl⟩
apply LawfulUpwardEnumerableUpperBound.isSatisfied_of_le _ a out
· exact hu
· exact hle
theorem RangeIterator.isPlausibleIndirectOutput_iff {su α}
[UpwardEnumerable α] [SupportsUpperBound su α]
[LawfulUpwardEnumerable α] [LawfulUpwardEnumerableUpperBound su α]
{it : Iter (α := RangeIterator su α) α} {out : α} :
it.IsPlausibleIndirectOutput out ↔
∃ n, it.internalState.next.bind (UpwardEnumerable.succMany? n ·) = some out ∧
SupportsUpperBound.IsSatisfied it.internalState.upperBound out := by
simp only [Iter.isPlausibleIndirectOutput_iff_isPlausibleIndirectOutput_toIterM,
Monadic.isPlausibleIndirectOutput_iff, Iter.toIterM]
section IteratorLoop
/-!
## Efficient `IteratorLoop` instance
As long as the compiler cannot optimize away the `Option` in the internal state, we use a special
loop implementation.
-/
@[always_inline, inline]
instance RangeIterator.instIteratorLoop {su} [UpwardEnumerable α] [SupportsUpperBound su α]
[LawfulUpwardEnumerable α] [LawfulUpwardEnumerableUpperBound su α]
{n : Type u → Type w} [Monad n] :
IteratorLoop (RangeIterator su α) Id n where
forIn _ γ Pl wf it init f :=
match it with
| ⟨⟨some next, upperBound⟩⟩ =>
if hu : SupportsUpperBound.IsSatisfied upperBound next then
loop γ Pl wf upperBound next init (fun a ha₁ ha₂ c => f a ?hf c) next ?hle hu
else
return init
| ⟨⟨none, _⟩⟩ => return init
where
@[specialize]
loop γ Pl wf (upperBound : Bound su α) least acc
(f : (out : α) → UpwardEnumerable.LE least out → SupportsUpperBound.IsSatisfied upperBound out → (c : γ) → n (Subtype (fun s : ForInStep γ => Pl out c s)))
(next : α) (hl : UpwardEnumerable.LE least next) (hu : SupportsUpperBound.IsSatisfied upperBound next) : n γ := do
match ← f next hl hu acc with
| ⟨.yield acc', h⟩ =>
match hs : UpwardEnumerable.succ? next with
| some next' =>
if hu : SupportsUpperBound.IsSatisfied upperBound next' then
loop γ Pl wf upperBound least acc' f next' ?hle' hu
else
return acc'
| none => return acc'
| ⟨.done acc', _⟩ => return acc'
termination_by IteratorLoop.WithWF.mk ⟨⟨some next, upperBound⟩⟩ acc (hwf := wf)
decreasing_by
simp [IteratorLoop.rel, RangeIterator.Monadic.isPlausibleStep_iff,
RangeIterator.Monadic.step, *]
finally
case hf =>
rw [RangeIterator.Monadic.isPlausibleIndirectOutput_iff]
obtain ⟨n, hn⟩ := ha₁
exact ⟨n, hn, ha₂⟩
case hle =>
exact UpwardEnumerable.le_refl _
case hle' =>
refine UpwardEnumerable.le_trans hl ⟨1, ?_⟩
simp [UpwardEnumerable.succMany?_one, hs]
partial instance RepeatIterator.instIteratorLoopPartial {su} [UpwardEnumerable α]
[SupportsUpperBound su α] [LawfulUpwardEnumerable α] [LawfulUpwardEnumerableUpperBound su α]
{n : Type u → Type w} [Monad n] : IteratorLoopPartial (RangeIterator su α) Id n where
forInPartial _ γ it init f :=
match it with
| ⟨⟨some next, upperBound⟩⟩ =>
if hu : SupportsUpperBound.IsSatisfied upperBound next then
loop γ upperBound next init (fun a ha₁ ha₂ c => f a ?hf c) next ?hle hu
else
return init
| ⟨⟨none, _⟩⟩ => return init
where
@[specialize]
loop γ (upperBound : Bound su α) least acc
(f : (out : α) → UpwardEnumerable.LE least out → SupportsUpperBound.IsSatisfied upperBound out → (c : γ) → n (ForInStep γ))
(next : α) (hl : UpwardEnumerable.LE least next) (hu : SupportsUpperBound.IsSatisfied upperBound next) : n γ := do
match ← f next hl hu acc with
| .yield acc' =>
match hs : UpwardEnumerable.succ? next with
| some next' =>
if hu : SupportsUpperBound.IsSatisfied upperBound next' then
loop γ upperBound least acc' f next' ?hle' hu
else
return acc'
| none => return acc'
| .done acc' => return acc'
finally
case hf =>
rw [RangeIterator.Monadic.isPlausibleIndirectOutput_iff]
obtain ⟨n, hn⟩ := ha₁
exact ⟨n, hn, ha₂⟩
case hle =>
exact UpwardEnumerable.le_refl _
case hle' =>
refine UpwardEnumerable.le_trans hl ⟨1, ?_⟩
simp [UpwardEnumerable.succMany?_one, hs]
theorem RangeIterator.instIteratorLoop.loop_eq {su} [UpwardEnumerable α] [SupportsUpperBound su α]
[LawfulUpwardEnumerable α] [LawfulUpwardEnumerableUpperBound su α]
{n : Type u → Type w} [Monad n] [LawfulMonad n] {γ : Type u}
{lift} [Internal.LawfulMonadLiftBindFunction lift]
{PlausibleForInStep} {upperBound} {next} {hl} {hu} {f} {acc} {wf} :
loop (α := α) (su := su) (n := n) γ PlausibleForInStep wf upperBound least acc f next hl hu =
(do
match ← f next hl hu acc with
| ⟨.yield c, _⟩ =>
letI it' : IterM (α := RangeIterator su α) Id α := ⟨⟨UpwardEnumerable.succ? next, upperBound⟩⟩
IterM.DefaultConsumers.forIn' (m := Id) lift γ
PlausibleForInStep wf it' c it'.IsPlausibleIndirectOutput (fun _ => id)
(fun b h c => f b
(by
refine UpwardEnumerable.le_trans hl ?_
simp only [RangeIterator.Monadic.isPlausibleIndirectOutput_iff, it',
← LawfulUpwardEnumerable.succMany?_succ_eq_succ?_bind_succMany?] at h
exact ⟨h.choose + 1, h.choose_spec.1⟩)
(by simp only [RangeIterator.Monadic.isPlausibleIndirectOutput_iff, it'] at h; exact h.choose_spec.2) c)
| ⟨.done c, _⟩ => return c) := by
rw [loop]
apply bind_congr
intro step
split
· split
· split
· simp only [*]
rw [IterM.DefaultConsumers.forIn']
simp only [Monadic.step_eq_step, Monadic.step, ↓reduceIte, *,
Internal.LawfulMonadLiftBindFunction.liftBind_pure]
rw [loop_eq (lift := lift)]
apply bind_congr
intro step
split
· apply IterM.DefaultConsumers.forIn'_eq_forIn'
intros; rfl
· simp
· simp only [*]
rw [IterM.DefaultConsumers.forIn']
simp [Monadic.step_eq_step, Monadic.step, *,
Internal.LawfulMonadLiftBindFunction.liftBind_pure]
· simp only [*]
rw [IterM.DefaultConsumers.forIn']
simp [Monadic.step_eq_step, Monadic.step, Internal.LawfulMonadLiftBindFunction.liftBind_pure]
· simp
termination_by IteratorLoop.WithWF.mk ⟨⟨some next, upperBound⟩⟩ acc (hwf := wf)
decreasing_by
simp [IteratorLoop.rel, RangeIterator.Monadic.isPlausibleStep_iff,
RangeIterator.Monadic.step, *]
instance RangeIterator.instLawfulIteratorLoop {su} [UpwardEnumerable α] [SupportsUpperBound su α]
[LawfulUpwardEnumerable α] [LawfulUpwardEnumerableUpperBound su α]
{n : Type u → Type w} [Monad n] [LawfulMonad n] :
LawfulIteratorLoop (RangeIterator su α) Id n where
lawful := by
intro lift instLawfulMonadLiftFunction
ext γ PlausibleForInStep hwf it init f
simp only [IteratorLoop.forIn, IteratorLoop.defaultImplementation]
rw [IterM.DefaultConsumers.forIn']
simp only [RangeIterator.Monadic.step_eq_step, RangeIterator.Monadic.step]
simp only [Internal.LawfulMonadLiftBindFunction.liftBind_pure]
split
· rename_i it f next upperBound f'
simp
split
· simp only
rw [instIteratorLoop.loop_eq (lift := lift)]
apply bind_congr
intro step
split
· apply IterM.DefaultConsumers.forIn'_eq_forIn'
intro b c hPb hQb
congr
· simp
· simp
· simp
end Std.PRange.IteratorLoop

View file

@ -8,13 +8,14 @@ module
prelude
public meta import Init.Coe
public import Init.Data.Stream
public import Init.Data.Array.Lemmas
public import Init.Data.Array.MapIdx
public import Init.Data.Array.InsertIdx
public import Init.Data.Array.Range
public import Init.Data.Range
import Init.Data.Slice.Array.Basic
public import Init.Data.Stream
-- TODO: Making this private leads to a panic in Init.Grind.Ring.Poly.
public import Init.Data.Slice.Array.Iterator
public section
@ -562,7 +563,7 @@ Lexicographic comparator for vectors.
- there is an index `i` such that `lt v[i] w[i]`, and for all `j < i`, `v[j] == w[j]`.
-/
def lex [BEq α] (xs ys : Vector α n) (lt : αα → Bool := by exact (· < ·)) : Bool := Id.run do
for h : i in [0 : n] do
for h : i in 0...n do
if lt xs[i] ys[i] then
return true
else if xs[i] != ys[i] then

View file

@ -10,6 +10,7 @@ public import all Init.Data.Vector.Basic
public import Init.Data.Vector.Lemmas
public import all Init.Data.Array.Lex.Basic
public import Init.Data.Array.Lex.Lemmas
import Init.Data.Range.Polymorphic.Lemmas
public section
@ -43,7 +44,7 @@ protected theorem not_le_iff_gt [LT α] {xs ys : Vector α n} :
@[simp] theorem mk_lex_mk [BEq α] {lt : αα → Bool} {xs ys : Array α} {n₁ : xs.size = n} {n₂ : ys.size = n} :
(Vector.mk xs n₁).lex (Vector.mk ys n₂) lt = xs.lex ys lt := by
simp [Vector.lex, Array.lex, n₁, n₂]
simp [Vector.lex, Array.lex, n₁, n₂, Std.PRange.forIn'_eq_forIn'_toList]
rfl
@[simp, grind =] theorem lex_toArray [BEq α] {lt : αα → Bool} {xs ys : Vector α n} :

View file

@ -523,7 +523,7 @@ def addParamsRename (ρ : IndexRenaming) (ps₁ ps₂ : Array Param) : Option In
failure
else
let mut ρ := ρ
for i in [:ps₁.size] do
for i in *...ps₁.size do
ρ ← addParamRename ρ ps₁[i]! ps₂[i]!
pure ρ

View file

@ -1176,7 +1176,7 @@ def emitFnArgs (builder : LLVM.Builder llvmctx)
(needsPackedArgs? : Bool) (llvmfn : LLVM.Value llvmctx) (params : Array Param) : M llvmctx Unit := do
if needsPackedArgs? then do
let argsp ← LLVM.getParam llvmfn 0 -- lean_object **args
for h : i in [:params.size] do
for h : i in *...params.size do
let param := params[i]
-- argsi := (args + i)
let argsi ← LLVM.buildGEP2 builder (← LLVM.voidPtrType llvmctx) argsp #[← constIntUnsigned i] s!"packed_arg_{i}_slot"
@ -1189,7 +1189,7 @@ def emitFnArgs (builder : LLVM.Builder llvmctx)
addVartoState param.x alloca llvmty
else
let n ← LLVM.countParams llvmfn
for i in [:n.toNat] do
for i in *...n.toNat do
let param := params[i]!
let llvmty ← toLLVMType param.ty
let alloca ← buildPrologueAlloca builder llvmty s!"arg_{i}"

View file

@ -20,7 +20,7 @@ def ensureHasDefault (alts : Array Alt) : Array Alt :=
private def getOccsOf (alts : Array Alt) (i : Nat) : Nat := Id.run do
let aBody := alts[i]!.body
let mut n := 1
for h : j in [i+1:alts.size] do
for h : j in (i+1)...alts.size do
if alts[j].body == aBody then
n := n+1
return n
@ -28,7 +28,7 @@ private def getOccsOf (alts : Array Alt) (i : Nat) : Nat := Id.run do
private def maxOccs (alts : Array Alt) : Alt × Nat := Id.run do
let mut maxAlt := alts[0]!
let mut max := getOccsOf alts 0
for h : i in [1:alts.size] do
for h : i in 1...alts.size do
let curr := getOccsOf alts i
if curr > max then
maxAlt := alts[i]

View file

@ -184,7 +184,7 @@ partial def lowerLet (decl : LCNF.LetDecl) (k : LCNF.Code) : M FnBody := do
let args := args.extract (start := ctorVal.numParams)
let objArgs : Array Arg ← do
let mut result : Array Arg := #[]
for i in [0:fields.size] do
for i in *...fields.size do
match args[i]! with
| .fvar fvarId =>
if let some (.var varId) := (← get).fvars[fvarId]? then

View file

@ -110,7 +110,7 @@ def isCtorParam (f : Expr) (i : Nat) : CoreM Bool := do
def checkAppArgs (f : Expr) (args : Array Arg) : CheckM Unit := do
let mut fType ← inferType f
let mut j := 0
for h : i in [:args.size] do
for h : i in *...args.size do
let arg := args[i]
if fType.isErased then
return ()

View file

@ -527,7 +527,7 @@ ones. Return whether any `Value` got updated in the process.
-/
def inferStep : InterpM Bool := do
let ctx ← read
for h : idx in [0:ctx.decls.size] do
for h : idx in *...ctx.decls.size do
let decl := ctx.decls[idx]
if !decl.safe then
continue

View file

@ -136,9 +136,9 @@ partial def evalApp (declName : Name) (args : Array Arg) : FixParamM Unit := do
let main := (← read).main
if declName == main.name then
-- Recursive call to the function being analyzed
for h : i in [:main.params.size] do
for h : i in *...main.params.size do
if _h : i < args.size then
have : i < main.params.size := h.upper
have : i < main.params.size := h.2
let param := main.params[i]
let val ← evalArg args[i]
unless val == .val i || (val == .erased && param.type.isErased) do
@ -154,7 +154,7 @@ partial def evalApp (declName : Name) (args : Array Arg) : FixParamM Unit := do
if declName == decl.name then
-- Call to another function in the same mutual block.
let mut values := #[]
for i in [:decl.params.size] do
for i in *...decl.params.size do
if h : i < args.size then
values := values.push (← evalArg args[i])
else
@ -170,7 +170,7 @@ end
def mkInitialValues (numParams : Nat) : Array AbsValue := Id.run do
let mut values := #[]
for i in [:numParams] do
for i in *...numParams do
values := values.push <| .val i
return values

View file

@ -139,7 +139,7 @@ mutual
partial def inferAppTypeCore (fType : Expr) (args : Array Arg) : InferTypeM Expr := do
let mut j := 0
let mut fType := fType
for i in [:args.size] do
for i in *...args.size do
fType := fType.headBeta
match fType with
| .forallE _ _ b _ => fType := b
@ -154,7 +154,7 @@ mutual
let mut j := 0
let mut fType ← inferType e.getAppFn
let args := e.getAppArgs
for i in [:args.size] do
for i in *...args.size do
fType := fType.headBeta
match fType with
| .forallE _ _ b _ => fType := b
@ -181,7 +181,7 @@ mutual
failed ()
else do
let mut ctorType ← inferAppType (mkAppN (mkConst ctorVal.name structLvls) structTypeArgs[*...structVal.numParams])
for _ in [:idx] do
for _ in *...idx do
match ctorType with
| .forallE _ _ body _ =>
if body.hasLooseBVars then

View file

@ -60,7 +60,7 @@ where fillCache : CoreM (Option TrivialStructureInfo) := do
if ctorType.isErased then return none
let mask ← getRelevantCtorFields ctorName
let mut result := none
for h : i in [:mask.size] do
for h : i in *...mask.size do
if mask[i] then
if result.isSome then return none
result := some { ctorName, fieldIdx := i, numParams := info.numParams }

View file

@ -131,7 +131,7 @@ def withEachOccurrence (targetName : Name) (f : Nat → PassInstaller) : PassIns
install passes := do
let highestOccurrence ← PassManager.findHighestOccurrence targetName passes
let mut passes := passes
for occurrence in [0:highestOccurrence+1] do
for occurrence in *...=highestOccurrence do
passes ← f occurrence |>.install passes
return passes

View file

@ -103,7 +103,7 @@ def getExt (phase : Phase) : DeclExt :=
def forEachDecl (f : Decl → CoreM Unit) (phase := Phase.base) : CoreM Unit := do
let ext := getExt phase
let env ← getEnv
for modIdx in [:env.allImportedModuleNames.size] do
for modIdx in *...env.allImportedModuleNames.size do
for decl in ext.getModuleEntries env modIdx do
f decl
ext.getState env |>.forM fun _ decl => f decl

View file

@ -189,7 +189,7 @@ def runGlobally (probe : Probe Decl β) (phase : Phase := Phase.base) : CoreM (A
let ext := getExt phase
let env ← getEnv
let mut decls := #[]
for modIdx in [:env.allImportedModuleNames.size] do
for modIdx in *...env.allImportedModuleNames.size do
decls := decls.append <| ext.getModuleEntries env modIdx
probe decls |>.run (phase := phase)

View file

@ -86,7 +86,7 @@ partial def attach (ps : Array ToPull) (k : Code) : Code := Id.run do
return k
where
go : StateM (Code × Array Bool) Unit := do
for i in [:ps.size] do
for i in *...ps.size do
visit i
visited (i : Nat) : StateM (Code × Array Bool) Bool :=
@ -96,7 +96,7 @@ where
unless (← visited i) do
modify fun (k, visited) => (k, visited.set! i true)
let pi := ps[i]!
for h : j in [:ps.size] do
for h : j in *...ps.size do
unless (← visited j) do
let pj := ps[j]
if pj.used.contains pi.decl.fvarId then

View file

@ -18,7 +18,7 @@ or not.
private def getMaxOccs (alts : Array Alt) : Alt × Nat := Id.run do
let mut maxAlt := alts[0]!
let mut max := getNumOccsOf alts 0
for h : i in [1:alts.size] do
for h : i in 1...alts.size do
let curr := getNumOccsOf alts i
if curr > max then
maxAlt := alts[i]
@ -34,7 +34,7 @@ where
getNumOccsOf (alts : Array Alt) (i : Nat) : Nat := Id.run do
let code := alts[i]!.getCode
let mut n := 1
for h : j in [i+1:alts.size] do
for h : j in (i+1)...alts.size do
if Code.alphaEqv alts[j].getCode code then
n := n+1
return n

View file

@ -121,7 +121,7 @@ where
let mut paramsNew := #[]
let singleton : FVarIdSet := ({} : FVarIdSet).insert params[targetParamIdx]!.fvarId
let dependsOnDiscr := k.dependsOn singleton || decls.any (·.dependsOn singleton)
for h : i in [:params.size] do
for h : i in *...params.size do
let param := params[i]
if targetParamIdx == i then
if dependsOnDiscr then

View file

@ -132,7 +132,7 @@ See comment at `.fixedNeutral`.
-/
private def hasFwdDeps (decl : Decl) (paramsInfo : Array SpecParamInfo) (j : Nat) : Bool := Id.run do
let param := decl.params[j]!
for h : k in [j+1 : decl.params.size] do
for h : k in (j+1)...decl.params.size do
if paramsInfo[k]! matches .user | .fixedHO | .fixedInst then
let param' := decl.params[k]
if param'.type.containsFVar param.fvarId then
@ -155,7 +155,7 @@ def saveSpecParamInfo (decls : Array Decl) : CompilerM Unit := do
let specArgs? := getSpecializationArgs? (← getEnv) decl.name
let contains (i : Nat) : Bool := specArgs?.getD #[] |>.contains i
let mut paramsInfo : Array SpecParamInfo := #[]
for h :i in [:decl.params.size] do
for h :i in *...decl.params.size do
let param := decl.params[i]
let info ←
if contains i then
@ -184,7 +184,7 @@ def saveSpecParamInfo (decls : Array Decl) : CompilerM Unit := do
declsInfo := declsInfo.push paramsInfo
if declsInfo.any fun paramsInfo => paramsInfo.any (· matches .user | .fixedInst | .fixedHO) then
let m := mkFixedParamsMap decls
for hi : i in [:decls.size] do
for hi : i in *...decls.size do
let decl := decls[i]
let mut paramsInfo := declsInfo[i]!
let some mask := m.find? decl.name | unreachable!
@ -194,7 +194,7 @@ def saveSpecParamInfo (decls : Array Decl) : CompilerM Unit := do
info
else
.other
for j in [:paramsInfo.size] do
for j in *...paramsInfo.size do
let mut info := paramsInfo[j]!
if info matches .fixedNeutral && !hasFwdDeps decl paramsInfo j then
paramsInfo := paramsInfo.set! j .other

View file

@ -22,13 +22,13 @@ def findStructCtorInfo? (typeName : Name) : CoreM (Option ConstructorVal) := do
def mkFieldParamsForCtorType (ctorType : Expr) (numParams : Nat) (numFields : Nat)
: CompilerM (Array Param) := do
let mut type := ctorType
for _ in [0:numParams] do
for _ in *...numParams do
match type with
| .forallE _ _ body _ =>
type := body
| _ => unreachable!
let mut fields := Array.emptyWithCapacity numFields
for _ in [0:numFields] do
for _ in *...numFields do
match type with
| .forallE name fieldType body _ =>
let param ← mkParam name (← toMonoType fieldType) false

View file

@ -510,7 +510,7 @@ where
match app with
| .fvar f =>
let mut argsNew := #[]
for h :i in [arity : args.size] do
for h : i in arity...args.size do
argsNew := argsNew.push (← visitAppArg args[i])
letValueToArg <| .fvar f argsNew
| .erased | .type .. => return .erased

View file

@ -134,13 +134,13 @@ def LetDecl.toMono (decl : LetDecl) : ToMonoM LetDecl := do
def mkFieldParamsForComputedFields (ctorType : Expr) (numParams : Nat) (numNewFields : Nat)
(oldFields : Array Param) : ToMonoM (Array Param) := do
let mut type := ctorType
for _ in [0:numParams] do
for _ in *...numParams do
match type with
| .forallE _ _ body _ =>
type := body
| _ => unreachable!
let mut newFields := Array.emptyWithCapacity (oldFields.size + numNewFields)
for _ in [0:numNewFields] do
for _ in *...numNewFields do
match type with
| .forallE name fieldType body _ =>
let param ← mkParam name (← toMonoType fieldType) false

View file

@ -37,7 +37,7 @@ structure CasesInfo where
arity : Nat
numParams : Nat
discrPos : Nat
altsRange : Std.Range
altsRange : Std.PRange ⟨.closed, .open⟩ Nat
altNumParams : Array Nat
motivePos : Nat
@ -56,7 +56,7 @@ def getCasesInfo? (declName : Name) : CoreM (Option CasesInfo) := do
let arity := numParams + 1 /- motive -/ + val.numIndices + 1 /- major -/ + val.numCtors
let discrPos := numParams + 1 /- motive -/ + val.numIndices
-- We view indices as discriminants
let altsRange := [discrPos + 1:arity]
let altsRange := (discrPos + 1)...arity
let altNumParams ← val.ctors.toArray.mapM fun ctor => do
let .ctorInfo ctorVal ← getConstInfo ctor | unreachable!
return ctorVal.numFields

View file

@ -4,7 +4,8 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Joachim Breitner
-/
prelude
import Init.Data.Range
import Init.Data.Range.Polymorphic.Nat
import Init.Data.Range.Polymorphic.Iterators
namespace Array
@ -36,7 +37,7 @@ def filterPairsM {m} [Monad m] {α} (a : Array α) (f : αα → m (Bool ×
m (Array α) := do
let mut removed := Array.replicate a.size false
let mut numRemoved := 0
for h1 : i in [:a.size] do for h2 : j in [i+1:a.size] do
for h1 : i in *...a.size do for h2 : j in (i+1)...a.size do
unless removed[i]! || removed[j]! do
let xi := a[i]
let xj := a[j]
@ -48,7 +49,7 @@ def filterPairsM {m} [Monad m] {α} (a : Array α) (f : αα → m (Bool ×
numRemoved := numRemoved + 1
removed := removed.set! j true
let mut a' := Array.mkEmpty numRemoved
for h : i in [:a.size] do
for h : i in *...a.size do
unless removed[i]! do
a' := a'.push a[i]
return a'

View file

@ -9,9 +9,11 @@ code's client side filtering algorithm. For the LLVM implementation see
https://clang.llvm.org/extra//doxygen/FuzzyMatch_8cpp_source.html
-/
prelude
import Init.Data.Range
import Init.Data.Range.Polymorphic.Iterators
import Init.Data.Range.Polymorphic.Nat
import Init.Data.OfScientific
import Init.Data.Option.Coe
import Init.Data.Range
namespace Lean
namespace FuzzyMatching
@ -36,7 +38,7 @@ private def containsInOrderLower (a b : String) : Bool := Id.run do
return true
let mut aIt := a.mkIterator
-- TODO: the following code is assuming all characters are ASCII
for i in [:b.endPos.byteIdx] do
for i in *...b.endPos.byteIdx do
if aIt.curr.toLower == (b.get ⟨i⟩).toLower then
aIt := aIt.next
if !aIt.hasNext then
@ -124,7 +126,7 @@ private def fuzzyMatchCore (pattern word : String) (patternRoles wordRoles : Arr
/- For this dynamic program to be correct, it's only necessary to populate a range of length
`word.length - pattern.length` at each index (because at the very end, we can only consider fuzzy matches
of `pattern` with a longer substring of `word`). -/
for wordIdx in [patternIdx:word.length-(pattern.length - patternIdx - 1)] do
for wordIdx in [patternIdx:(word.length-(pattern.length - patternIdx - 1))] do
let missScore? :=
if wordIdx >= 1 then
selectBest

View file

@ -45,7 +45,7 @@ protected def normalize : JsonNumber → Int × Nat × Int
let mut mAbs := m.natAbs
let nDigits := countDigits mAbs
-- eliminate trailing zeros
for _ in [0:nDigits] do
for _ in *...nDigits do
if mAbs % 10 = 0 then
mAbs := mAbs / 10
else

View file

@ -432,7 +432,7 @@ private def findNamedArgDependsOnCurrent? : M (Option NamedArg) := do
else
forallTelescopeReducing s.fType fun xs _ => do
let curr := xs[0]!
for h : i in [1:xs.size] do
for h : i in 1...xs.size do
let xDecl ← xs[i].fvarId!.getDecl
if let some arg := s.namedArgs.find? fun arg => arg.name == xDecl.userName then
/- Remark: a default value at `optParam` does not count as a dependency -/
@ -826,7 +826,7 @@ def getElabElimExprInfo (elimExpr : Expr) : MetaM ElabElimInfo := do
return s
/- Collect the major parameter positions -/
let mut majorsPos := #[]
for h : i in [:xs.size] do
for h : i in *...xs.size do
let x := xs[i]
unless motivePos == i do
let xType ← x.fvarId!.getType

View file

@ -63,7 +63,7 @@ def withNamespace {α} (ns : Name) (elabFn : CommandElabM α) : CommandElabM α
pure a
private def popScopes (numScopes : Nat) : CommandElabM Unit :=
for _ in [0:numScopes] do
for _ in *...numScopes do
popScope
private def innermostScopeName? : List Scope → Option Name

View file

@ -55,7 +55,7 @@ open Meta
let cinfo ← getConstInfoCtor ctor
let numExplicitFields ← forallTelescopeReducing cinfo.type fun xs _ => do
let mut n := 0
for h : i in [cinfo.numParams:xs.size] do
for h : i in cinfo.numParams...xs.size do
if (← getFVarLocalDecl xs[i]).binderInfo.isExplicit then
n := n + 1
return n

View file

@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Leonardo de Moura, Gabriel Ebner
-/
prelude
import Init.Data.Range.Polymorphic.Stream
import Lean.Meta.Diagnostics
import Lean.Elab.Binders
import Lean.Elab.SyntheticMVars
@ -564,7 +565,7 @@ where go := do
let opts ← getOptions
-- For each command, associate it with new promise and old snapshot, if any, and
-- elaborate recursively
for cmd in cmds, cmdPromise in cmdPromises, i in [0:cmds.size] do
for cmd in cmds, cmdPromise in cmdPromises, i in *...cmds.size do
let oldCmd? := oldCmds?.bind (·[i]?)
withReader ({ · with snap? := some {
new := cmdPromise

View file

@ -64,7 +64,7 @@ private partial def winnowExpr (e : Expr) : MetaM Expr := do
let mut fty ← inferType f
let mut j := 0
let mut e' ← visit f
for h : i in [0:args.size] do
for h : i in *...args.size do
unless fty.isForall do
fty ← withTransparency .all <| whnf <| fty.instantiateRevRange j i args
j := i

View file

@ -23,7 +23,7 @@ where
mkElseAlt : TermElabM (TSyntax ``matchAltExpr) := do
let mut patterns := #[]
-- add `_` pattern for indices
for _ in [:indVal.numIndices] do
for _ in *...indVal.numIndices do
patterns := patterns.push (← `(_))
patterns := patterns.push (← `(_))
patterns := patterns.push (← `(_))
@ -38,13 +38,13 @@ where
let type ← Core.betaReduce type -- we 'beta-reduce' to eliminate "artificial" dependencies
let mut patterns := #[]
-- add `_` pattern for indices
for _ in [:indVal.numIndices] do
for _ in *...indVal.numIndices do
patterns := patterns.push (← `(_))
let mut ctorArgs1 := #[]
let mut ctorArgs2 := #[]
let mut rhs ← `(true)
let mut rhs_empty := true
for i in [:ctorInfo.numFields] do
for i in *...ctorInfo.numFields do
let pos := indVal.numParams + ctorInfo.numFields - i - 1
let x := xs[pos]!
if type.containsFVar x.fvarId! then
@ -81,7 +81,7 @@ where
else
rhs ← `($a:ident == $b:ident && $rhs)
-- add `_` for inductive parameters, they are inaccessible
for _ in [:indVal.numParams] do
for _ in *...indVal.numParams do
ctorArgs1 := ctorArgs1.push (← `(_))
ctorArgs2 := ctorArgs2.push (← `(_))
patterns := patterns.push (← `(@$(mkIdent ctorName):ident $ctorArgs1.reverse:term*))
@ -107,7 +107,7 @@ def mkAuxFunction (ctx : Context) (i : Nat) : TermElabM Command := do
def mkMutualBlock (ctx : Context) : TermElabM Syntax := do
let mut auxDefs := #[]
for i in [:ctx.typeInfos.size] do
for i in *...ctx.typeInfos.size do
auxDefs := auxDefs.push (← mkAuxFunction ctx i)
`(mutual
set_option match.ignoreUnusedAlts true

View file

@ -45,7 +45,7 @@ where
for ctorName₂ in indVal.ctors do
let mut patterns := #[]
-- add `_` pattern for indices
for _ in [:indVal.numIndices] do
for _ in *...indVal.numIndices do
patterns := patterns.push (← `(_))
if ctorName₁ == ctorName₂ then
let alt ← forallTelescopeReducing ctorInfo.type fun xs type => do
@ -54,11 +54,11 @@ where
let mut ctorArgs1 := #[]
let mut ctorArgs2 := #[]
-- add `_` for inductive parameters, they are inaccessible
for _ in [:indVal.numParams] do
for _ in *...indVal.numParams do
ctorArgs1 := ctorArgs1.push (← `(_))
ctorArgs2 := ctorArgs2.push (← `(_))
let mut todo := #[]
for i in [:ctorInfo.numFields] do
for i in *...ctorInfo.numFields do
let x := xs[indVal.numParams + i]!
if type.containsFVar x.fvarId! then
-- If resulting type depends on this field, we don't need to compare
@ -102,7 +102,7 @@ def mkAuxFunction (ctx : Context) (auxFunName : Name) (indVal : InductiveVal): T
def mkAuxFunctions (ctx : Context) : TermElabM (TSyntax `command) := do
let mut res : Array (TSyntax `command) := #[]
for i in [:ctx.auxFunNames.size] do
for i in *...ctx.auxFunNames.size do
let auxFunName := ctx.auxFunNames[i]!
let indVal := ctx.typeInfos[i]!
res := res.push (← mkAuxFunction ctx auxFunName indVal)

View file

@ -71,16 +71,16 @@ where
let alt ← forallTelescopeReducing ctorInfo.type fun xs _ => do
let mut patterns := #[]
-- add `_` pattern for indices
for _ in [:indVal.numIndices] do
for _ in *...indVal.numIndices do
patterns := patterns.push (← `(_))
let mut ctorArgs := #[]
-- add `_` for inductive parameters, they are inaccessible
for _ in [:indVal.numParams] do
for _ in *...indVal.numParams do
ctorArgs := ctorArgs.push (← `(_))
-- bound constructor arguments and their types
let mut binders := #[]
let mut userNames := #[]
for i in [:ctorInfo.numFields] do
for i in *...ctorInfo.numFields do
let x := xs[indVal.numParams + i]!
let localDecl ← x.fvarId!.getDecl
if !localDecl.userName.hasMacroScopes then
@ -119,7 +119,7 @@ where
let alt ← do forallTelescopeReducing ctorInfo.type fun xs _ => do
let mut binders := #[]
let mut userNames := #[]
for i in [:ctorInfo.numFields] do
for i in *...ctorInfo.numFields do
let x := xs[indVal.numParams + i]!
let localDecl ← x.fvarId!.getDecl
if !localDecl.userName.hasMacroScopes then
@ -195,7 +195,7 @@ def mkFromJsonAuxFunction (ctx : Context) (i : Nat) : TermElabM Command := do
def mkToJsonMutualBlock (ctx : Context) : TermElabM Command := do
let mut auxDefs := #[]
for i in [:ctx.typeInfos.size] do
for i in *...ctx.typeInfos.size do
auxDefs := auxDefs.push (← mkToJsonAuxFunction ctx i)
`(mutual
$auxDefs:command*
@ -203,7 +203,7 @@ def mkToJsonMutualBlock (ctx : Context) : TermElabM Command := do
def mkFromJsonMutualBlock (ctx : Context) : TermElabM Command := do
let mut auxDefs := #[]
for i in [:ctx.typeInfos.size] do
for i in *...ctx.typeInfos.size do
auxDefs := auxDefs.push (← mkFromJsonAuxFunction ctx i)
`(mutual
$auxDefs:command*

View file

@ -31,14 +31,14 @@ where
let alt ← forallTelescopeReducing ctorInfo.type fun xs _ => do
let mut patterns := #[]
-- add `_` pattern for indices
for _ in [:indVal.numIndices] do
for _ in *...indVal.numIndices do
patterns := patterns.push (← `(_))
let mut ctorArgs := #[]
let mut rhs ← `($(quote ctorIdx))
-- add `_` for inductive parameters, they are inaccessible
for _ in [:indVal.numParams] do
for _ in *...indVal.numParams do
ctorArgs := ctorArgs.push (← `(_))
for i in [:ctorInfo.numFields] do
for i in *...ctorInfo.numFields do
let x := xs[indVal.numParams + i]!
let a := mkIdent (← mkFreshUserName `a)
ctorArgs := ctorArgs.push a
@ -72,7 +72,7 @@ def mkAuxFunction (ctx : Context) (i : Nat) : TermElabM Command := do
def mkHashFuncs (ctx : Context) : TermElabM Syntax := do
let mut auxDefs := #[]
for i in [:ctx.typeInfos.size] do
for i in *...ctx.typeInfos.size do
auxDefs := auxDefs.push (← mkAuxFunction ctx i)
`(mutual $auxDefs:command* end)

View file

@ -63,7 +63,7 @@ where
let ctorVal ← getConstInfoCtor ctorName
let mut indArgs := #[]
let mut binders := #[]
for i in [:indVal.numParams + indVal.numIndices] do
for i in *...indVal.numParams + indVal.numIndices do
let arg := mkIdent (← mkFreshUserName `a)
indArgs := indArgs.push arg
let binder ← `(bracketedBinderF| { $arg:ident })
@ -73,9 +73,9 @@ where
binders := binders.push binder
let type ← `(Inhabited (@$(mkIdent inductiveTypeName):ident $indArgs:ident*))
let mut ctorArgs := #[]
for _ in [:ctorVal.numParams] do
for _ in *...ctorVal.numParams do
ctorArgs := ctorArgs.push (← `(_))
for _ in [:ctorVal.numFields] do
for _ in *...ctorVal.numFields do
ctorArgs := ctorArgs.push (← ``(Inhabited.default))
let val ← `(⟨@$(mkIdent ctorName):ident $ctorArgs*⟩)
`(instance $binders:bracketedBinder* : $type := $val)
@ -86,7 +86,7 @@ where
addLocalInstancesForParams xs[*...ctorVal.numParams] fun localInst2Index => do
let mut usedInstIdxs := {}
let mut ok := true
for h : i in [ctorVal.numParams:xs.size] do
for h : i in ctorVal.numParams...xs.size do
let x := xs[i]
let instType ← mkAppM `Inhabited #[(← inferType x)]
trace[Elab.Deriving.inhabited] "checking {instType} for '{ctorName}'"

View file

@ -28,17 +28,17 @@ where
let type ← Core.betaReduce type -- we 'beta-reduce' to eliminate "artificial" dependencies
let mut indPatterns := #[]
-- add `_` pattern for indices
for _ in [:indVal.numIndices] do
for _ in *...indVal.numIndices do
indPatterns := indPatterns.push (← `(_))
let mut ctorArgs1 := #[]
let mut ctorArgs2 := #[]
-- construct RHS top-down as continuation over the remaining comparison
let mut rhsCont : Term → TermElabM Term := fun rhs => pure rhs
-- add `_` for inductive parameters, they are inaccessible
for _ in [:indVal.numParams] do
for _ in *...indVal.numParams do
ctorArgs1 := ctorArgs1.push (← `(_))
ctorArgs2 := ctorArgs2.push (← `(_))
for i in [:ctorInfo.numFields] do
for i in *...ctorInfo.numFields do
let x := xs[indVal.numParams + i]!
if type.containsFVar x.fvarId! || (←isProp (←inferType x)) then
-- If resulting type depends on this field or is a proof, we don't need to compare
@ -78,7 +78,7 @@ def mkAuxFunction (ctx : Context) (i : Nat) : TermElabM Command := do
def mkMutualBlock (ctx : Context) : TermElabM Syntax := do
let mut auxDefs := #[]
for i in [:ctx.typeInfos.size] do
for i in *...ctx.typeInfos.size do
auxDefs := auxDefs.push (← mkAuxFunction ctx i)
`(mutual
set_option match.ignoreUnusedAlts true

View file

@ -29,7 +29,7 @@ def mkBodyForStruct (header : Header) (indVal : InductiveVal) : TermElabM Term :
let mut fields ← `(Format.nil)
if xs.size != numParams + fieldNames.size then
throwError "'deriving Repr' failed, unexpected number of fields in structure"
for h : i in [:fieldNames.size] do
for h : i in *...fieldNames.size do
let fieldName := fieldNames[i]
let fieldNameLit := Syntax.mkStrLit (toString fieldName)
let x := xs[numParams + i]!
@ -54,12 +54,12 @@ where
let alt ← forallTelescopeReducing ctorInfo.type fun xs _ => do
let mut patterns := #[]
-- add `_` pattern for indices
for _ in [:indVal.numIndices] do
for _ in *...indVal.numIndices do
patterns := patterns.push (← `(_))
let mut ctorArgs := #[]
let mut rhs : Term := Syntax.mkStrLit (toString ctorInfo.name)
rhs ← `(Format.text $rhs)
for h : i in [:xs.size] do
for h : i in *...xs.size do
-- Note: some inductive parameters are explicit if they were promoted from indices,
-- so we process all constructor arguments in the same loop.
let x := xs[i]
@ -103,7 +103,7 @@ def mkAuxFunction (ctx : Context) (i : Nat) : TermElabM Command := do
def mkMutualBlock (ctx : Context) : TermElabM Syntax := do
let mut auxDefs := #[]
for i in [:ctx.typeInfos.size] do
for i in *...ctx.typeInfos.size do
auxDefs := auxDefs.push (← mkAuxFunction ctx i)
`(mutual
$auxDefs:command*

View file

@ -81,7 +81,7 @@ where
let alt ← forallTelescopeReducing ctorInfo.type fun xs _ => do
let mut patterns := #[]
-- add `_` pattern for indices, before the constructor's pattern
for _ in [:indVal.numIndices] do
for _ in *...indVal.numIndices do
patterns := patterns.push (← `(_))
let mut ctorArgs := #[]
let mut rhsArgs : Array Term := #[]
@ -93,11 +93,11 @@ where
else
``(toExpr $a)
-- add `_` pattern for inductive parameters, which are inaccessible
for i in [:ctorInfo.numParams] do
for i in *...ctorInfo.numParams do
let a := mkIdent header.argNames[i]!
ctorArgs := ctorArgs.push (← `(_))
rhsArgs := rhsArgs.push <| ← mkArg xs[i]! a
for i in [:ctorInfo.numFields] do
for i in *...ctorInfo.numFields do
let a := mkIdent (← mkFreshUserName `a)
ctorArgs := ctorArgs.push a
rhsArgs := rhsArgs.push <| ← mkArg xs[ctorInfo.numParams + i]! a
@ -178,7 +178,7 @@ Wraps the resulting definition commands in `mutual ... end`.
-/
def mkAuxFunctions (ctx : Deriving.Context) : TermElabM Syntax := do
let mut auxDefs := #[]
for i in [:ctx.typeInfos.size] do
for i in *...ctx.typeInfos.size do
auxDefs := auxDefs.push (← mkAuxFunction ctx i)
`(mutual $auxDefs:command* end)

View file

@ -49,7 +49,7 @@ invoking ``mkInstImplicitBinders `BarClass foo #[`α, `n, `β]`` gives `` `([Bar
def mkInstImplicitBinders (className : Name) (indVal : InductiveVal) (argNames : Array Name) : TermElabM (Array Syntax) :=
forallBoundedTelescope indVal.type indVal.numParams fun xs _ => do
let mut binders := #[]
for h : i in [:xs.size] do
for h : i in *...xs.size do
try
let x := xs[i]
let c ← mkAppM className #[x]
@ -86,7 +86,7 @@ def mkContext (fnPrefix : String) (typeName : Name) : TermElabM Context := do
def mkLocalInstanceLetDecls (ctx : Context) (className : Name) (argNames : Array Name) : TermElabM (Array (TSyntax ``Parser.Term.letDecl)) := do
let mut letDecls := #[]
for h : i in [:ctx.typeInfos.size] do
for h : i in *...ctx.typeInfos.size do
let indVal := ctx.typeInfos[i]
let auxFunName := ctx.auxFunNames[i]!
let currArgNames ← mkInductArgNames indVal
@ -109,7 +109,7 @@ def mkLet (letDecls : Array (TSyntax ``Parser.Term.letDecl)) (body : Term) : Ter
open TSyntax.Compat in
def mkInstanceCmds (ctx : Context) (className : Name) (typeNames : Array Name) (useAnonCtor := true) : TermElabM (Array Command) := do
let mut instances := #[]
for i in [:ctx.typeInfos.size] do
for i in *...ctx.typeInfos.size do
let indVal := ctx.typeInfos[i]!
if typeNames.contains indVal.name then
let auxFunName := ctx.auxFunNames[i]!
@ -140,7 +140,7 @@ def mkHeader (className : Name) (arity : Nat) (indVal : InductiveVal) : TermElab
let binders ← mkImplicitBinders argNames
let targetType ← mkInductiveApp indVal argNames
let mut targetNames := #[]
for _ in [:arity] do
for _ in *...arity do
targetNames := targetNames.push (← mkFreshUserName `x)
let binders := binders ++ (← mkInstImplicitBinders className indVal argNames)
let binders := binders ++ (← targetNames.mapM fun targetName => `(explicitBinderF| ($(mkIdent targetName) : $targetType)))

View file

@ -240,7 +240,7 @@ where
if indFVars.contains f then
let mut args := e.getAppArgs
-- Prefer throwing an "argument mismatch" error rather than a "missing parameter" one
for i in [:min args.size params.size] do
for i in *...min args.size params.size do
let param := params[i]!
let arg := args[i]!
unless (← isDefEq param arg) do

View file

@ -89,7 +89,7 @@ private def elabLetRecDeclValues (view : LetRecView) : TermElabM (Array Expr) :=
view.decls.mapM fun view => do
forallBoundedTelescope view.type view.binderIds.size fun xs type => do
-- Add new info nodes for new fvars. The server will detect all fvars of a binder by the binder's source location.
for h : i in [0:view.binderIds.size] do
for h : i in *...view.binderIds.size do
addLocalVarInfo view.binderIds[i] xs[i]!
withDeclName view.declName do
withInfoContext' view.valStx

View file

@ -295,12 +295,12 @@ where
matchConstInduct t.getAppFn (fun _ => failure) fun info _ => do
let tArgs := t.getAppArgs
let dArgs := d.getAppArgs
for i in [:info.numParams] do
for i in *...info.numParams do
let tArg := tArgs[i]!
let dArg := dArgs[i]!
unless (← isDefEq tArg dArg) do
return i :: (← goType tArg dArg)
for h : i in [info.numParams : tArgs.size] do
for h : i in info.numParams...tArgs.size do
let tArg := tArgs[i]
let dArg := dArgs[i]!
unless (← isDefEq tArg dArg) do
@ -318,12 +318,12 @@ where
matchConstCtor t.getAppFn (fun _ => failure) fun info _ => do
let tArgs := t.getAppArgs
let dArgs := d.getAppArgs
for i in [:info.numParams] do
for i in *...info.numParams do
let tArg := tArgs[i]!
let dArg := dArgs[i]!
unless (← isDefEq tArg dArg) do
failure
for i in [info.numParams : tArgs.size] do
for i in info.numParams...tArgs.size do
let tArg := tArgs[i]!
let dArg := dArgs[i]!
unless (← isDefEq tArg dArg) do
@ -356,13 +356,13 @@ private def elabPatterns (patternStxs : Array Syntax) (numDiscrs : Nat) (matchTy
logIncorrectNumberOfPatternsAt (← getRef) "Not enough" numDiscrs patternStxs.size patternStxs.toList
let numHoles := numDiscrs - patternStxs.size
let mut extraStxs := Array.emptyWithCapacity numHoles
for _ in [:numHoles] do
for _ in *...numHoles do
extraStxs := extraStxs.push (← `(_))
patternStxs := patternStxs ++ extraStxs
else if patternStxs.size > numDiscrs then
throwIncorrectNumberOfPatternsAt (← getRef) "Too many" numDiscrs patternStxs.size patternStxs.toList
for h : idx in [:patternStxs.size] do
for h : idx in *...patternStxs.size do
let patternStx := patternStxs[idx]
matchType ← whnf matchType
match matchType with

View file

@ -508,7 +508,7 @@ private def elabFunValues (headers : Array DefViewElabHeader) (vars : Array Expr
(if header.kind.isTheorem && !deprecated.oldSectionVars.get (← getOptions) then withHeaderSecVars vars sc #[header] else fun x => x #[]) fun vars => do
forallBoundedTelescope header.type header.numParams fun xs type => do
-- Add new info nodes for new fvars. The server will detect all fvars of a binder by the binder's source location.
for h : i in [0:header.binderIds.size] do
for h : i in *...header.binderIds.size do
-- skip auto-bound prefix in `xs`
addLocalVarInfo header.binderIds[i] xs[header.numParams - header.binderIds.size + i]!
let val ← if (← useProofAsSorry header.kind) then
@ -945,7 +945,7 @@ private def mkLetRecClosures (sectionVars : Array Expr) (mainFVarIds : Array FVa
let mut letRecsToLift := letRecsToLift
let mut freeVarMap ← mkFreeVarMap sectionVars mainFVarIds recFVarIds letRecsToLift
let mut result := #[]
for i in [:letRecsToLift.size] do
for i in *...letRecsToLift.size do
if letRecsToLift[i]!.val.hasExprMVar then
-- This can happen when this particular let-rec has nested let-rec that have been resolved in previous iterations.
-- This code relies on the fact that nested let-recs occur before the outer most let-recs at `letRecsToLift`.
@ -1352,7 +1352,7 @@ def elabMutualDef (ds : Array Syntax) : CommandElabM Unit := do
let mut views := #[]
let mut defs := #[]
let mut reusedAllHeaders := true
for h : i in [0:ds.size], headerPromise in headerPromises do
for h : i in *...ds.size, headerPromise in headerPromises do
let d := ds[i]
let modifiers ← elabModifiers ⟨d[0]⟩
if ds.size > 1 && modifiers.isNonrec then

View file

@ -386,7 +386,7 @@ private def computeFixedIndexBitMask (numParams : Nat) (indType : InductiveType)
| ctor :: ctors =>
forallTelescopeReducing ctor.type fun xs type => do
let typeArgs := type.getAppArgs
for i in [numParams:arity] do
for i in numParams...arity do
unless i < xs.size && xs[i]! == typeArgs[i]! do -- Remark: if we want to allow arguments to be rearranged, this test should be xs.contains typeArgs[i]
maskRef.modify fun mask => mask.set! i false
for x in xs[numParams...*] do
@ -394,7 +394,7 @@ private def computeFixedIndexBitMask (numParams : Nat) (indType : InductiveType)
let cond (e : Expr) := indFVars.any (fun indFVar => e.getAppFn == indFVar)
xType.forEachWhere (stopWhenVisited := true) cond fun e => do
let eArgs := e.getAppArgs
for i in [numParams:eArgs.size] do
for i in numParams...eArgs.size do
if i >= typeArgs.size then
maskRef.modify (resetMaskAt · i)
else
@ -411,7 +411,7 @@ private def computeFixedIndexBitMask (numParams : Nat) (indType : InductiveType)
```
because `i` doesn't appear in `All Iμ []`, the index shouldn't be fixed.
-/
for i in [eArgs.size:arity] do
for i in eArgs.size...arity do
maskRef.modify (resetMaskAt · i)
go ctors
go indType.ctors
@ -762,7 +762,7 @@ private def checkResultingUniverses (views : Array InductiveView) (elabs' : Arra
let u := (← instantiateLevelMVars (← getResultingUniverse indTypes)).normalize
checkResultingUniversePolymorphism views u numParams indTypes
unless u.isZero do
for h : i in [0:indTypes.length] do
for h : i in *...indTypes.length do
let indType := indTypes[i]
-- See if there is a custom error. If so, this should throw an error first:
elabs'[i]!.checkUniverses numParams u
@ -813,7 +813,7 @@ private def collectLevelParamsInInductive (indTypes : List InductiveType) : Arra
private def mkIndFVar2Const (views : Array InductiveView) (indFVars : Array Expr) (levelNames : List Name) : ExprMap Expr := Id.run do
let levelParams := levelNames.map mkLevelParam;
let mut m : ExprMap Expr := {}
for h : i in [:views.size] do
for h : i in *...views.size do
let view := views[i]
let indFVar := indFVars[i]!
m := m.insert indFVar (mkConst view.declName levelParams)
@ -865,7 +865,7 @@ private def mkInductiveDecl (vars : Array Expr) (elabs : Array InductiveElabStep
let rs := Array.zipWith (fun r indFVar => { r with indFVar : ElabHeaderResult }) rs indFVars
let mut indTypesArray : Array InductiveType := #[]
let mut elabs' := #[]
for h : i in [:views.size] do
for h : i in *...views.size do
Term.addLocalVarInfo views[i].declId indFVars[i]!
let r := rs[i]!
let elab' ← elabs[i]!.elabCtors rs r params

View file

@ -180,8 +180,9 @@ private def processVar (idStx : Syntax) : M Syntax := do
private def samePatternsVariables (startingAt : Nat) (s₁ s₂ : State) : Bool := Id.run do
if h₁ : s₁.vars.size = s₂.vars.size then
for h₂ : i in [startingAt:s₁.vars.size] do
if s₁.vars[i] != s₂.vars[i]'(by obtain ⟨_, y⟩ := h₂; simp_all +zetaDelta) then return false
for h₂ : i in startingAt...s₁.vars.size do
if s₁.vars[i] != s₂.vars[i]'(by have y := Std.PRange.lt_upper_of_mem h₂; simp_all +zetaDelta) then
return false
true
else
false

View file

@ -290,7 +290,7 @@ def checkCodomainsLevel (preDefs : Array PreDefinition) : MetaM Unit := do
lambdaTelescope preDef.value fun xs _ => return xs.size
forallBoundedTelescope preDefs[0]!.type arities[0]! fun _ type₀ => do
let u₀ ← getLevel type₀
for h : i in [1:preDefs.size] do
for h : i in 1...preDefs.size do
forallBoundedTelescope preDefs[i].type arities[i]! fun _ typeᵢ =>
unless ← isLevelDefEq u₀ (← getLevel typeᵢ) do
withOptions (fun o => pp.sanitizeNames.set o false) do
@ -307,7 +307,7 @@ def shareCommonPreDefs (preDefs : Array PreDefinition) : CoreM (Array PreDefinit
es := es.push preDef.type |>.push preDef.value
es := ShareCommon.shareCommon' es
let mut result := #[]
for h : i in [:preDefs.size] do
for h : i in *...preDefs.size do
let preDef := preDefs[i]
result := result.push { preDef with type := es[2*i]!, value := es[2*i+1]! }
return result

View file

@ -57,7 +57,7 @@ private def findMatchToSplit? (deepRecursiveSplit : Bool) (env : Environment) (e
let args := e.getAppArgs
-- If none of the discriminants is a free variable, then it is not worth splitting the match
let mut hasFVarDiscr := false
for i in [info.getFirstDiscrPos : info.getFirstDiscrPos + info.numDiscrs] do
for i in info.getFirstDiscrPos...(info.getFirstDiscrPos + info.numDiscrs) do
let discr := args[i]!
if discr.isFVar then
hasFVarDiscr := true
@ -72,7 +72,7 @@ private def findMatchToSplit? (deepRecursiveSplit : Bool) (env : Environment) (e
return Expr.FindStep.found
-- Else, the “old” behavior is split only when at least one alternative contains a `declNames`
-- application with loose bound variables.
for i in [info.getFirstAltPos : info.getFirstAltPos + info.numAlts] do
for i in info.getFirstAltPos...(info.getFirstAltPos + info.numAlts) do
let alt := args[i]!
if Option.isSome <| alt.find? fun e => declNames.any e.isAppOf && e.hasLooseBVars then
return Expr.FindStep.found
@ -409,7 +409,7 @@ def mkEqns (declName : Name) (declNames : Array Name) (tryRefl := true): MetaM (
withReducible do
mkEqnTypes declNames goal.mvarId!
let mut thmNames := #[]
for h : i in [: eqnTypes.size] do
for h : i in *...eqnTypes.size do
let type := eqnTypes[i]
trace[Elab.definition.eqns] "eqnType[{i}]: {eqnTypes[i]}"
let name := mkEqLikeNameFor (← getEnv) declName s!"{eqnThmSuffixBasePrefix}{i+1}"

View file

@ -105,8 +105,8 @@ partial def Info.setVarying (funIdx paramIdx : Nat) (info : Info) : Info := Id.r
-- Set this as varying
info := { info with graph := info.graph.modify funIdx (·.set! paramIdx none) }
-- Propagate along edges for already observed calls
for otherFunIdx in [:info.graph.size] do
for otherParamIdx in [:info.graph[otherFunIdx]!.size] do
for otherFunIdx in *...info.graph.size do
for otherParamIdx in *...info.graph[otherFunIdx]!.size do
if let some otherParamInfo := info.graph[otherFunIdx]![otherParamIdx]! then
if otherParamInfo[funIdx]! = some paramIdx then
info := Info.setVarying otherFunIdx otherParamIdx info
@ -139,12 +139,12 @@ partial def Info.setCallerParam (calleeIdx argIdx callerIdx paramIdx : Nat) (inf
-- Propagate information about the caller
let mut info : Info := info
if let some callerParamInfo := info.graph[callerIdx]![paramIdx]! then
for h : otherFunIdx in [:callerParamInfo.size] do
for h : otherFunIdx in *...callerParamInfo.size do
if let some otherParamIdx := callerParamInfo[otherFunIdx] then
info := info.setCallerParam calleeIdx argIdx otherFunIdx otherParamIdx
-- Propagate information about the callee
for otherFunIdx in [:info.graph.size] do
for otherArgIdx in [:info.graph[otherFunIdx]!.size] do
for otherFunIdx in *...info.graph.size do
for otherArgIdx in *...info.graph[otherFunIdx]!.size do
if let some otherArgsInfo := info.graph[otherFunIdx]![otherArgIdx]! then
if let some paramIdx' := otherArgsInfo[calleeIdx]! then
if paramIdx' = argIdx then
@ -175,9 +175,9 @@ open Lean Meta FixedParams
def getParamRevDeps (value : Expr) : MetaM (Array (Array Nat)) := do
lambdaTelescope value (cleanupAnnotations := true) fun xs _ => do
let mut revDeps := #[]
for h : i in [:xs.size] do
for h : i in *...xs.size do
let mut deps := #[]
for h : j in [i+1:xs.size] do
for h : j in (i+1)...xs.size do
if (← dependsOn (← inferType xs[j]) xs[i].fvarId!) then
deps := deps.push j
revDeps := revDeps.push deps
@ -190,7 +190,7 @@ def getFixedParamsInfo (preDefs : Array PreDefinition) : MetaM FixedParams.Info
ref.modify .addSelfCalls
for h : callerIdx in [:preDefs.size] do
for h : callerIdx in *...preDefs.size do
let preDef := preDefs[callerIdx]
lambdaTelescope preDef.value fun params body => do
assert! params.size = arities[callerIdx]!
@ -202,7 +202,7 @@ def getFixedParamsInfo (preDefs : Array PreDefinition) : MetaM FixedParams.Info
return .continue
let n := f.constName!
let some calleeIdx := preDefs.findIdx? (·.declName = n) | return .continue
for argIdx in [:arities[calleeIdx]!] do
for argIdx in *...arities[calleeIdx]! do
if (← ref.get).mayBeFixed calleeIdx argIdx then
if h : argIdx < args.size then
let arg := args[argIdx]
@ -215,7 +215,7 @@ def getFixedParamsInfo (preDefs : Array PreDefinition) : MetaM FixedParams.Info
else
-- Try all parameters
let mut any := false
for h : paramIdx in [:params.size] do
for h : paramIdx in *...params.size do
if (← ref.get).mayBeFixed callerIdx paramIdx then
let param := params[paramIdx]
if (← withoutProofIrrelevance <| withReducible <| isDefEq param arg) then
@ -271,7 +271,7 @@ def getFixedParamPerms (preDefs : Array PreDefinition) : MetaM FixedParamPerms :
let mut firstPerm := #[]
let mut numFixed := 0
for paramIdx in [:xs.size], x in xs, paramInfo? in paramInfos do
for paramIdx in *...xs.size, x in xs, paramInfo? in paramInfos do
if let some paramInfo := paramInfo? then
assert! paramInfo[0]! = some paramIdx
firstPerm := firstPerm.push (some numFixed)
@ -280,7 +280,7 @@ def getFixedParamPerms (preDefs : Array PreDefinition) : MetaM FixedParamPerms :
firstPerm := firstPerm.push none
let mut perms := #[firstPerm]
for h : funIdx in [1:info.graph.size] do
for h : funIdx in 1...info.graph.size do
let paramInfos := info.graph[funIdx]
let mut perm := #[]
for paramInfo? in paramInfos do
@ -397,7 +397,7 @@ Unlike `pickFixed`, this function can handle over- or under-application.
-/
def FixedParamPerm.pickVarying (perm : FixedParamPerm) (xs : Array α) : Array α := Id.run do
let mut ys := #[]
for h : i in [:xs.size] do
for h : i in *...xs.size do
if perm[i]?.join.isNone then ys := ys.push xs[i]
pure ys
@ -453,7 +453,7 @@ def FixedParamPerms.erase (fixedParamPerms : FixedParamPerms) (xs : Array Expr)
assert! toErase.size = fixedParamPerms.perms.size
-- Calculate a mask on the fixed parameters of variables to erase
let mut mask := Array.replicate fixedParamPerms.numFixed false
for funIdx in [:toErase.size], paramIdxs in toErase, mapping in fixedParamPerms.perms do
for funIdx in *...toErase.size, paramIdxs in toErase, mapping in fixedParamPerms.perms do
for paramIdx in paramIdxs do
assert! paramIdx < mapping.size
if let some fixedParamIdx := mapping[paramIdx]! then
@ -462,8 +462,8 @@ def FixedParamPerms.erase (fixedParamPerms : FixedParamPerms) (xs : Array Expr)
let mut changed := true
while changed do
changed := false
for h : funIdx in [:fixedParamPerms.perms.size] do
for h : paramIdx₁ in [:fixedParamPerms.perms[funIdx].size] do
for h : funIdx in *...fixedParamPerms.perms.size do
for h : paramIdx₁ in *...fixedParamPerms.perms[funIdx].size do
if let some fixedParamIdx₁ := fixedParamPerms.perms[funIdx][paramIdx₁] then
if mask[fixedParamIdx₁]! then
for paramIdx₂ in fixedParamPerms.revDeps[funIdx]![paramIdx₁]! do
@ -475,7 +475,7 @@ def FixedParamPerms.erase (fixedParamPerms : FixedParamPerms) (xs : Array Expr)
let mut reindex := #[]
let mut fvarsToErase :=#[]
let mut toKeep :=#[]
for i in [:mask.size], erase in mask, x in xs do
for i in *...mask.size, erase in mask, x in xs do
if erase then
reindex := reindex.push none
fvarsToErase := fvarsToErase.push x.fvarId!

View file

@ -71,7 +71,7 @@ def Positions.numIndices (positions : Positions) : Nat :=
-/
def Positions.inverse (positions : Positions) : Array Nat := Id.run do
let mut r := .replicate positions.numIndices 0
for _h : i in [:positions.size] do
for _h : i in *...positions.size do
for k in positions[i] do
r := r.set! k i
return r

View file

@ -80,7 +80,7 @@ def mkEqns (info : EqnInfo) : MetaM (Array Name) :=
let goal ← mkFreshExprSyntheticOpaqueMVar target
mkEqnTypes info.declNames goal.mvarId!
let mut thmNames := #[]
for h : i in [: eqnTypes.size] do
for h : i in *...eqnTypes.size do
let type := eqnTypes[i]
trace[Elab.definition.structural.eqns] "eqnType {i+1}: {type}"
let name := mkEqLikeNameFor (← getEnv) info.declName s!"{eqnThmSuffixBasePrefix}{i+1}"

View file

@ -127,7 +127,7 @@ def getRecArgInfos (fnName : Name) (fixedParamPerm : FixedParamPerm) (xs : Array
let mut recArgInfos := #[]
let mut report : MessageData := m!""
-- No `termination_by`, so try all, and remember the errors
for idx in [:args.size] do
for idx in *...args.size do
try
let recArgInfo ← getRecArgInfo fnName fixedParamPerm args idx
recArgInfos := recArgInfos.push recArgInfo
@ -192,7 +192,7 @@ def argsInGroup (group : IndGroupInst) (xs : Array Expr) (value : Expr)
if nestedTypeFormers.isEmpty then return .none
lambdaTelescope value fun ys _ => do
let x := (xs++ys)[recArgInfo.recArgPos]!
for nestedTypeFormer in nestedTypeFormers, indIdx in [group.all.size : group.numMotives] do
for nestedTypeFormer in nestedTypeFormers, indIdx in group.all.size...group.numMotives do
let xType ← whnfD (← inferType x)
let (indIndices, _, type) ← forallMetaTelescope nestedTypeFormer
if (← isDefEqGuarded type xType) then

View file

@ -55,7 +55,7 @@ def RecArgInfo.pickIndicesMajor (info : RecArgInfo) (xs : Array Expr) : (Array E
indexMajorArgs := indexMajorArgs.push xs[j]!
-- Then the other arguments, in the order they appear in `xs`
let mut otherVaryingArgs := #[]
for h : i in [:xs.size] do
for h : i in *...xs.size do
unless indexMajorPos.contains i do
unless info.fixedParamPerm.isFixed i do
otherVaryingArgs := otherVaryingArgs.push xs[i]

View file

@ -107,7 +107,7 @@ case, the user gets to keep both pieces (and may have to rename variables).
partial
def naryVarNames (xs : Array Name) : MetaM (Array Name) := do
let mut ns : Array Name := #[]
for h : i in [:xs.size] do
for h : i in *...xs.size do
let n := xs[i]
let n ← if n.hasMacroScopes then
freshen ns (.mkSimple s!"x{i+1}")
@ -561,7 +561,7 @@ where
go (fidx : Nat) : OptionT (ReaderT (Array Nat) (StateM (Array (Array Nat)))) Unit := do
if h : fidx < numMeasures.size then
let n := numMeasures[fidx]
for idx in [:n] do withReader (·.push idx) (go (fidx + 1))
for idx in *...n do withReader (·.push idx) (go (fidx + 1))
else
let comb ← read
unless comb.all (· == comb[0]!) do
@ -604,7 +604,7 @@ partial def solve {m} {α} [Monad m] (measures : Array α)
if calls.isEmpty then return .some acc
-- Find the first measure that has at least one < and otherwise only = or <=
for h : measureIdx in [:measures.size] do
for h : measureIdx in *...measures.size do
let measure := measures[measureIdx]
let mut has_lt := false
let mut all_le := true
@ -633,20 +633,20 @@ Single space as column separator.
-/
def formatTable : Array (Array String) → String := fun xss => Id.run do
let mut colWidths := xss[0]!.map (fun _ => 0)
for hi : i in [:xss.size] do
for hj : j in [:xss[i].size] do
for hi : i in *...xss.size do
for hj : j in *...xss[i].size do
if xss[i][j].length > colWidths[j]! then
colWidths := colWidths.set! j xss[i][j].length
let mut str := ""
for hi : i in [:xss.size] do
for hj : j in [:xss[i].size] do
for hi : i in *...xss.size do
for hj : j in *...xss[i].size do
let s := xss[i][j]
if j > 0 then -- right-align
for _ in [:colWidths[j]! - s.length] do
for _ in *...(colWidths[j]! - s.length) do
str := str ++ " "
str := str ++ s
if j = 0 then -- left-align
for _ in [:colWidths[j]! - s.length] do
for _ in *...(colWidths[j]! - s.length) do
str := str ++ " "
if j + 1 < xss[i].size then
str := str ++ " "
@ -691,9 +691,9 @@ def collectHeaders {α} (a : StateT (Nat × String) MetaM α) : MetaM (α × Str
def explainNonMutualFailure (measures : Array BasicMeasure) (rcs : Array RecCallCache) : MetaM Format := do
let (header, footer) ← collectHeaders (measures.mapM measureHeader)
let mut table : Array (Array String) := #[#[""] ++ header]
for i in [:rcs.size], rc in rcs do
for i in *...rcs.size, rc in rcs do
let mut row := #[s!"{i+1}) {← rc.rcc.posString}"]
for argIdx in [:measures.size] do
for argIdx in *...measures.size do
row := row.push (← rc.prettyEntry argIdx argIdx)
table := table.push row
let out := formatTable table
@ -719,14 +719,14 @@ def explainMutualFailure (declNames : Array Name) (measuress : Array (Array Basi
if caller = callee then
-- For self-calls, only the diagonal is interesting, so put it into one row
let mut row := #[""]
for argIdx in [:measuress[caller]!.size] do
for argIdx in *...measuress[caller]!.size do
row := row.push (← rc.prettyEntry argIdx argIdx)
table := table.push row
else
for argIdx in [:measuress[callee]!.size] do
for argIdx in *...measuress[callee]!.size do
let mut row := #[]
row := row.push headerss[callee]![argIdx]!
for paramIdx in [:measuress[caller]!.size] do
for paramIdx in *...measuress[caller]!.size do
row := row.push (← rc.prettyEntry paramIdx argIdx)
table := table.push row
r := r ++ formatTable table ++ "\n"

View file

@ -26,7 +26,7 @@ This ensures the preconditions for `ArgsPacker.uncurryND`.
def checkCodomains (names : Array Name) (fixedParamPerms : FixedParamPerms) (fixedArgs : Array Expr) (arities : Array Nat)
(termMeasures : TerminationMeasures) : TermElabM Expr := do
let mut codomains := #[]
for name in names, funIdx in [:names.size], arity in arities, termMeasure in termMeasures do
for name in names, funIdx in *...names.size, arity in arities, termMeasure in termMeasures do
let measureType ← inferType termMeasure.fn
let measureType ← fixedParamPerms.perms[funIdx]!.instantiateForall measureType fixedArgs
let codomain ← forallBoundedTelescope measureType arity fun xs codomain => do
@ -40,7 +40,7 @@ def checkCodomains (names : Array Name) (fixedParamPerms : FixedParamPerms) (fix
codomains := codomains.push codomain
let codomain0 := codomains[0]!
for h : i in [1 : codomains.size] do
for h : i in 1...codomains.size do
unless ← isDefEqGuarded codomain0 codomains[i] do
throwErrorAt termMeasures[i]!.ref m!"The termination measures of mutually recursive functions " ++
m!"must have the same return type, but the termination measure of {names[0]!} has type" ++

View file

@ -655,7 +655,7 @@ The parameter `alts` provides position information for alternatives.
-/
private def checkUnusedAlts (stx : Syntax) (alts : Array Syntax) (altIdxMap : NameMap Nat) (ignoreIfUnused : IdxSet) : TermElabM Syntax := do
let (stx, used) ← findUsedAlts stx altIdxMap
for h : i in [:alts.size] do
for h : i in *...alts.size do
unless used.contains i || ignoreIfUnused.contains i do
logErrorAt alts[i] s!"redundant alternative #{i+1}"
return stx

View file

@ -407,7 +407,7 @@ private def mkCtorHeader (ctorVal : ConstructorVal) (structureType? : Option Exp
let mut type ← instantiateTypeLevelParams cinfo.toConstantVal us
let mut params : Array Expr := #[]
let mut instMVars : Array MVarId := #[]
for _ in [0 : ctorVal.numParams] do
for _ in *...ctorVal.numParams do
let .forallE _ d b bi := type
| throwError "unexpected constructor type"
let param ←

View file

@ -909,7 +909,7 @@ Returns the binder list without these updates along with the new binder infos fo
-/
private def elabParamInfoUpdates (structParams : Array Expr) (binders : Array Syntax) : StructElabM (Array Syntax × ExprMap (Syntax × BinderInfo)) := do
let mut overrides : ExprMap (Syntax × BinderInfo) := {}
for i in [0:binders.size] do
for i in *...binders.size do
match typelessBinder? binders[i]! with
| none => return (binders.extract i, overrides)
| some (ids, bi) =>
@ -1225,7 +1225,7 @@ private def resolveFieldDefaults (structName : Name) : StructElabM Unit := do
-- We will do that in `checkResolutionOrder`, which is after the structure is registered.
let { resolutionOrder, .. } ← mergeStructureResolutionOrders structName ((← get).parents.map (·.structName)) (relaxed := true)
let mut resOrderMap : NameMap Nat := {}
for h : i in [0:resolutionOrder.size] do
for h : i in *...resolutionOrder.size do
resOrderMap := resOrderMap.insert resolutionOrder[i] i
for fieldInfo in (← get).fields do
if fieldInfo.default?.isSome then

View file

@ -150,7 +150,7 @@ where
-- Succeeded. Collect new TC problems
trace[Elab.defaultInstance] "isDefEq worked {mkMVar mvarId} : {← inferType (mkMVar mvarId)} =?= {candidate} : {← inferType candidate}"
let mut pending := []
for h : i in [:bis.size] do
for h : i in *...bis.size do
if bis[i] == BinderInfo.instImplicit then
pending := mvars[i]!.mvarId! :: pending
synthesizePending pending
@ -266,7 +266,7 @@ private def throwStuckAtUniverseCnstr : TermElabM Unit := do
unless found.contains (lhs, rhs) do
found := found.insert (lhs, rhs)
uniqueEntries := uniqueEntries.push entry
for h : i in [1:uniqueEntries.size] do
for h : i in 1...uniqueEntries.size do
logErrorAt uniqueEntries[i].ref (← mkLevelStuckErrorMessage uniqueEntries[i]!)
throwErrorAt uniqueEntries[0]!.ref (← mkLevelStuckErrorMessage uniqueEntries[0]!)

View file

@ -220,7 +220,7 @@ def CoefficientsMap.toExpr (coeff : CoefficientsMap) (op : Op) : VarStateM (Opti
let mut acc : Option Expr := none
for (var, coeff) in coeffArr do
let expr := (← get).varToExpr[var]!
for _ in [0:coeff] do
for _ in *...coeff do
acc := match acc with
| none => expr
| some acc => some <| mkApp2 op.toExpr acc expr

View file

@ -49,7 +49,7 @@ def addStructureSimpLemmas (simprocs : Simprocs) (lemmas : SimpTheoremsArray) :
lemmas ← lemmas.addTheorem (.decl lemmaName) (mkConst lemmaName)
let fields := (getStructureInfo env const).fieldNames.size
let numParams := constInfo.numParams
for proj in [0:fields] do
for proj in *...fields do
-- We use the simprocs with pre such that we push in projections eagerly in order to
-- potentially not have to simplify complex structure expressions that we only project one
-- element out of.

View file

@ -77,7 +77,7 @@ def isSupportedMatch (declName : Name) : MetaM (Option MatchKind) := do
-- Check that all parameters except the last are `h_n EnumInductive.ctor`
let numConcreteCases := xs.size - 3 -- minus motive, discr and default case
let mut handledCtors := Array.mkEmpty (xs.size - 3)
for i in [0:numConcreteCases] do
for i in *...numConcreteCases do
let argType ← inferType xs[i + 2]!
let some (.const ``Unit [], (.app m (.const c ..))) := argType.arrow? | return none
if m != motive then return none
@ -103,7 +103,7 @@ where
(numCtors : Nat) (motive : Expr) : MetaM (Option MatchKind) := do
-- Check that all parameters are `h_n EnumInductive.ctor`
let mut handledCtors := Array.mkEmpty numCtors
for i in [0:numCtors] do
for i in *...numCtors do
let argType ← inferType xs[i + 2]!
let some (.const ``Unit [], (.app m (.const c ..))) := argType.arrow? | return none
if m != motive then return none
@ -138,7 +138,7 @@ where
if !(← verifySimpleCasesOnApp inductiveInfo fn args params) then return false
-- remaining arguments are of the form `(h_n Unit.unit)`
for i in [0:inductiveInfo.numCtors] do
for i in *...inductiveInfo.numCtors do
let .app fn (.const ``Unit.unit []) := args[i + 2]! | return false
let some (_, .app _ (.const relevantCtor ..)) := (← inferType fn).arrow? | unreachable!
let some ctorIdx := ctors.findIdx? (·.name == relevantCtor) | unreachable!
@ -157,7 +157,7 @@ where
- `(h_n Unit.unit)` if the constructor is handled explicitly
- `(h_n InductiveEnum.ctor)` if the constructor is handled as part of the default case
-/
for i in [0:inductiveInfo.numCtors] do
for i in *...inductiveInfo.numCtors do
let .app fn (.const argName ..) := args[i + 2]! | return false
if argName == ``Unit.unit then
let some (_, .app _ (.const relevantCtor ..)) := (← inferType fn).arrow? | unreachable!

View file

@ -196,7 +196,7 @@ def mapping : M (Array IntAction) := do
let initialId ← M.getInitialId
let mut nextMapped := initialId
let mut newProof := #[]
for id in [initialId:emptyId+1] do
for id in initialId...=emptyId do
if ← M.isUsed id then
M.registerIdMap id nextMapped
-- This should never panic as the use def analysis has already marked this step as being used

View file

@ -469,7 +469,7 @@ def renameInaccessibles (mvarId : MVarId) (hs : TSyntaxArray ``binderIdent) : Ta
| `(binderIdent| $h:ident) => some <| extractMacroScopes h.getId
| _ => none)
| return mvarId
for i in [:n] do
for i in *...n do
let j := n - i - 1
match lctx.getAt? j with
| none => pure ()

View file

@ -100,7 +100,7 @@ def changeLhs (lhs' : Expr) : TacticM Unit := do
/-- Evaluate `sepByIndent conv "; " -/
def evalSepByIndentConv (stx : Syntax) : TacticM Unit := do
for arg in stx.getArgs, i in [:stx.getArgs.size] do
for arg in stx.getArgs, i in *...stx.getArgs.size do
if i % 2 == 0 then
evalTactic arg
else

View file

@ -34,7 +34,7 @@ private partial def mkCongrThm (origTag : Name) (f : Expr) (args : Array Expr) (
let mut proof := congrThm.proof
let mut mvarIdsNew := #[]
let mut mvarIdsNewInsts := #[]
for h : i in [:congrThm.argKinds.size] do
for h : i in *...congrThm.argKinds.size do
let arg := args[i]!
let argInfo := funInfo.paramInfo[i]!
match congrThm.argKinds[i] with
@ -124,7 +124,7 @@ private partial def mkCongrArgZeroThm (tacticName : String) (origTag : Name) (f
let mut proof := congrThm.proof
let mut mvarIdNew? := none
let mut mvarIdsNewInsts := #[]
for h : i in [:congrThm.argKinds.size] do
for h : i in *...congrThm.argKinds.size do
let arg := args[i]!
let argInfo := funInfo.paramInfo[i]!
match congrThm.argKinds[i] with
@ -207,7 +207,7 @@ where
let mut fType ← inferType f
let mut j := 0
let mut explicitIdxs := #[]
for k in [0:xs.size] do
for k in *...xs.size do
unless fType.isForall do
fType ← withTransparency .all <| whnf (fType.instantiateRevRange j k xs)
j := k
@ -332,7 +332,7 @@ private def ext (userName? : Option Name) : TacticM Unit := do
-- show initial state up to (incl.) `[`
withTacticInfoContext (mkNullNode #[token, lbrak]) (pure ())
let numEnterArgs := (enterArgsAndSeps.size + 1) / 2
for i in [:numEnterArgs] do
for i in *...numEnterArgs do
let enterArg := enterArgsAndSeps[2 * i]!
let sep := enterArgsAndSeps.getD (2 * i + 1) .missing
-- show state up to (incl.) next `,` and show errors on `enterArg`

View file

@ -135,7 +135,7 @@ def betaPreservingHypNames (σs' e : Expr) (args : Array Expr) : Expr :=
def dropStateList (σs : Expr) (n : Nat) : MetaM Expr := do
let mut σs := σs
for _ in [:n] do
for _ in *...n do
let some (_type, _σ, σs') := (← whnfR σs).app3? ``List.cons | throwError "Ambient state list not a cons {σs}"
σs := σs'
return σs

View file

@ -379,7 +379,7 @@ private partial def blameDecideReductionFailure (inst : Expr) : MetaM Expr := wi
if let some info ← getMatcherInfo? c then
if inst.getAppNumArgs == info.arity then
let args := inst.getAppArgs
for i in [0:info.numDiscrs] do
for i in *...info.numDiscrs do
let inst' := args[info.numParams + 1 + i]!
if (← Meta.isClass? (← inferType inst')) == ``Decidable then
let inst'' ← whnf inst'

View file

@ -266,7 +266,7 @@ private def isWildcard (altStx : Syntax) : Bool :=
private def checkAltNames (alts : Array Alt) (altsSyntax : Array Syntax) : TacticM Unit := do
let mut seenNames : Array Name := #[]
for h : i in [:altsSyntax.size] do
for h : i in *...altsSyntax.size do
let altStx := altsSyntax[i]
if getAltName altStx == `_ && i != altsSyntax.size - 1 then
withRef altStx <| throwError "Invalid occurrence of the wildcard alternative `| _ => ...`: It must be the last alternative"
@ -399,7 +399,7 @@ where
2- The errors are produced in the same order the appear in the code above. This is not super
important when using IDEs.
-/
for h : altStxIdx in [0:altStxs.size] do
for h : altStxIdx in *...altStxs.size do
let altStx := altStxs[altStxIdx]
let altName := getAltName altStx
if let some i := alts.findFinIdx? (·.1 == altName) then

View file

@ -26,7 +26,7 @@ register_builtin_option linter.tactic.unusedName : Bool := {
def extractLetsAddVarInfo (ids : Array Syntax) (fvars : Array FVarId) : TacticM Unit :=
withMainContext do
for h : i in [0:ids.size] do
for h : i in *...ids.size do
if h' : i < fvars.size then
Term.addLocalVarInfo ids[i] (mkFVar fvars[i])
else

View file

@ -188,7 +188,7 @@ def solveMonoStep (failK : ∀ {α}, Expr → Array Name → MetaM α := @defaul
if let some info := isMatcherAppCore? (← getEnv) e then
let candidate ← id do
let args := e.getAppArgs
for i in [info.getFirstDiscrPos : info.getFirstDiscrPos + info.numDiscrs] do
for i in info.getFirstDiscrPos...(info.getFirstDiscrPos + info.numDiscrs) do
if args[i]!.hasLooseBVars then
return false
return true

View file

@ -480,7 +480,7 @@ def fourierMotzkinData (p : Problem) : Array FourierMotzkinData := Id.run do
let mut data : Array FourierMotzkinData :=
(List.range p.numVars).foldl (fun a i => a.push { var := i}) #[]
for (_, f@⟨xs, s, _⟩) in p.constraints do
for i in [0:n] do
for i in *...n do
let x := Coeffs.get xs i
data := data.modify i fun d =>
if x = 0 then
@ -515,7 +515,7 @@ def fourierMotzkinSelect (data : Array FourierMotzkinData) : MetaM FourierMotzki
if bestSize = 0 then
trace[omega] "Selected variable {data[0]!.var}."
return data[0]!
for h : i in [1:data.size] do
for h : i in 1...data.size do
let exact := data[i].exact
let size := data[i].size
if size = 0 || !bestExact && exact || (bestExact == exact) && size < bestSize then

View file

@ -559,7 +559,7 @@ where
varNames (mask : Array Bool) : MetaM (Array String) := do
let mut names := #[]
let mut next := 0
for h : i in [:mask.size] do
for h : i in *...mask.size do
if mask[i] then
while ← inScope (varNameOf next) do next := next + 1
names := names.push (varNameOf next)

View file

@ -40,7 +40,7 @@ def withRWRulesSeq (token : Syntax) (rwRulesSeqStx : Syntax) (x : (symm : Bool)
-- show initial state up to (incl.) `[`
withTacticInfoContext (mkNullNode #[token, lbrak]) (pure ())
let numRules := (rules.size + 1) / 2
for i in [:numRules] do
for i in *...numRules do
let rule := rules[i * 2]!
let sep := rules.getD (i * 2 + 1) Syntax.missing
-- show rule state up to (incl.) next `,`

View file

@ -574,7 +574,7 @@ and different simp arguments may be used in each step.)
def warnUnusedSimpArgs (simpArgs : Array (Syntax × ElabSimpArgResult)) (usedSimps : Simp.UsedSimps) : MetaM Unit := do
if simpArgs.isEmpty then return
let mut mask : Array Bool := #[]
for h : i in [:simpArgs.size] do
for h : i in *...simpArgs.size do
let (ref, arg) := simpArgs[i]
let used ←
match arg with

View file

@ -285,7 +285,7 @@ private def mergeAll? (tacs : Array (TSyntax `tactic)) : TryTacticM (Option (TSy
if tacs.any fun tac => tac.raw.getKind != tac0.raw.getKind then
return none
let mut tac := tac0
for h : i in [1:tacs.size] do
for h : i in 1...tacs.size do
let some tac' := merge? tac tacs[i]
| return none
tac := tac'
@ -432,7 +432,7 @@ private def evalSuggestChain (tac1 tac2 : TSyntax `tactic) : TryTacticM (TSyntax
private def evalSuggestSeq (tacs : Array (TSyntax `tactic)) : TryTacticM (TSyntax `tactic) := do
if (← read).terminal then
let mut result := #[]
for i in [:tacs.size - 1] do
for i in *...(tacs.size - 1 : Nat) do
result := appendSeq result (← withNonTerminal <| evalSuggest tacs[i]!)
let suggestions ← getSuggestionOfTactic (← evalSuggest tacs.back!) |>.mapM fun tac =>
mkSeq (appendSeq result tac) (terminal := true)

View file

@ -1800,7 +1800,7 @@ We only consider extensions starting with index `>= startingAt`.
def mkExtNameMap (startingAt : Nat) : IO (Std.HashMap Name Nat) := do
let descrs ← persistentEnvExtensionsRef.get
let mut result := {}
for h : i in [startingAt : descrs.size] do
for h : i in startingAt...descrs.size do
let descr := descrs[i]
result := result.insert descr.name i
return result
@ -1816,7 +1816,7 @@ private def setImportedEntries (states : Array EnvExtensionState) (mods : Array
{ s with importedEntries := .replicate mods.size #[] }
/- For each module `mod`, and `mod.entries`, if the extension name is one of the extensions after `startingAt`, set `entries` -/
let extNameIdx ← mkExtNameMap startingAt
for h : modIdx in [:mods.size] do
for h : modIdx in *...mods.size do
let mod := mods[modIdx]
for (extName, entries) in mod.entries do
if let some entryIdx := extNameIdx[extName]? then
@ -2078,7 +2078,7 @@ def finalizeImport (s : ImportState) (imports : Array Import) (opts : Options) (
let mut const2ModIdx : Std.HashMap Name ModuleIdx := Std.HashMap.emptyWithCapacity (capacity := numPrivateConsts + numPublicConsts)
let mut privateConstantMap : Std.HashMap Name ConstantInfo := Std.HashMap.emptyWithCapacity (capacity := numPrivateConsts)
let mut publicConstantMap : Std.HashMap Name ConstantInfo := Std.HashMap.emptyWithCapacity (capacity := numPublicConsts)
for h : modIdx in [0:moduleData.size] do
for h : modIdx in *...moduleData.size do
let data := moduleData[modIdx]
for cname in data.constNames, cinfo in data.constants do
match privateConstantMap.getThenInsertIfNew? cname cinfo with

View file

@ -21,7 +21,7 @@ private def warnUnused (stx : Syntax) (i : Nat) : CoreM Unit := do
let argStx := simpArgs[i]!
let msg := m!"This simp argument is unused:{indentD argStx}"
let mut otherArgs : Array Syntax := #[]
for h : j in [:simpArgs.size] do if j != i then
for h : j in *...simpArgs.size do if j != i then
otherArgs := otherArgs.push simpArgs[j]
let stx' := Tactic.setSimpParams stx otherArgs
let suggestion : Meta.Hint.Suggestion := stx'
@ -63,7 +63,7 @@ def unusedSimpArgs : Linter where
-- Sort the outputs by position
for (_range, tacticStx, mask) in (← masksMap.get).toArray.qsort (·.1.start < ·.1.start) do
for i in [:mask.size] do
for i in *...mask.size do
unless mask[i]! do
liftCoreM <| warnUnused tacticStx i

View file

@ -115,14 +115,14 @@ where
return false
else
let infos ← getParamsInfo aFn aArgs.size
for i in [:infos.size] do
for i in *...infos.size do
-- We ignore instance implicit arguments during comparison
if !infos[i]!.isInstImplicit then
if (← lt aArgs[i]! bArgs[i]!) then
return true
else if (← lt bArgs[i]! aArgs[i]!) then
return false
for i in [infos.size:aArgs.size] do
for i in infos.size...aArgs.size do
if (← lt aArgs[i]! bArgs[i]!) then
return true
else if (← lt bArgs[i]! aArgs[i]!) then
@ -153,12 +153,12 @@ where
| .app .. =>
a.withApp fun f args => do
let infos ← getParamsInfo f args.size
for i in [:infos.size] do
for i in *...infos.size do
-- We ignore instance implicit arguments during comparison
if !infos[i]!.isInstImplicit then
if !(← lt args[i]! b) then
return false
for h : i in [infos.size:args.size] do
for h : i in infos.size...args.size do
if !(← lt args[i] b) then
return false
return true

View file

@ -115,7 +115,7 @@ private def mkTupleElems (t : Expr) (arity : Nat) : Array Expr := Id.run do
if arity = 0 then return #[]
let mut result := #[]
let mut t := t
for _ in [:arity - 1] do
for _ in *...(arity - 1 : Nat) do
result := result.push (mkProj ``PSigma 0 t)
t := mkProj ``PSigma 1 t
result.push t
@ -559,7 +559,7 @@ to produce an expression of the isomorphic type
-/
def curry (argsPacker : ArgsPacker) (e : Expr) : MetaM Expr := do
let mut es := #[]
for i in [:argsPacker.numFuncs] do
for i in *...argsPacker.numFuncs do
es := es.push (← argsPacker.curryProj e i)
PProdN.mk 0 es

View file

@ -2088,7 +2088,7 @@ def instantiateForallWithParamInfos (e : Expr) (args : Array Expr) (cleanupAnnot
let mut e := e
let mut res := Array.mkEmpty args.size
let mut j := 0
for i in [0:args.size] do
for i in *...args.size do
unless e.isForall do
e ← whnf (e.instantiateRevRange j i args)
j := i
@ -2117,7 +2117,7 @@ def instantiateLambdaWithParamInfos (e : Expr) (args : Array Expr) (cleanupAnnot
let mut e := e
let mut res := Array.mkEmpty args.size
let mut j := 0
for i in [0:args.size] do
for i in *...args.size do
unless e.isLambda do
e ← whnf (e.instantiateRevRange j i args)
j := i

View file

@ -100,7 +100,7 @@ private partial def mkKey (e : Expr) : CanonM UInt64 := do
else
getFunInfo f
let mut k ← mkKey f
for i in [:e.getAppNumArgs] do
for i in *...e.getAppNumArgs do
if h : i < info.paramInfo.size then
let info := info.paramInfo[i]
if info.isExplicit && !info.isProp then

View file

@ -116,7 +116,7 @@ where
let mut bFnType ← inferType b.getAppFn
let mut firstExplicitDiff? := none
let mut firstImplicitDiff? := none
for i in [0:as.size] do
for i in *...as.size do
unless aFnType.isForall do aFnType ← withTransparency .all <| whnf aFnType
unless bFnType.isForall do bFnType ← withTransparency .all <| whnf bFnType
-- These pattern matches are expected to succeed:

View file

@ -124,8 +124,8 @@ def mkHCongr (f : Expr) : MetaM CongrTheorem := do
-/
private def fixKindsForDependencies (info : FunInfo) (kinds : Array CongrArgKind) : Array CongrArgKind := Id.run do
let mut kinds := kinds
for i in [:info.paramInfo.size] do
for hj : j in [i+1:info.paramInfo.size] do
for i in *...info.paramInfo.size do
for hj : j in (i+1)...info.paramInfo.size do
if info.paramInfo[j].backDeps.contains i then
if kinds[j]! matches CongrArgKind.eq || kinds[j]! matches CongrArgKind.fixed then
-- We must fix `i` because there is a `j` that depends on `i` and `j` is not cast-fixed.
@ -188,7 +188,7 @@ private def getClassSubobjectMask? (f : Expr) : MetaM (Option (Array Bool)) := d
forallTelescopeReducing val.type (cleanupAnnotations := true) fun xs _ => do
let env ← getEnv
let mut mask := #[]
for h : i in [:xs.size] do
for h : i in *...xs.size do
if i < val.numParams then
mask := mask.push false
else
@ -214,7 +214,7 @@ def getCongrSimpKinds (f : Expr) (info : FunInfo) : MetaM (Array CongrArgKind) :
-/
let mut result := #[]
let mask? ← getClassSubobjectMask? f
for h : i in [:info.paramInfo.size] do
for h : i in *...info.paramInfo.size do
if info.resultDeps.contains i then
result := result.push .fixed
else if info.paramInfo[i].isProp then
@ -241,7 +241,7 @@ and otherwise it is `CongrArgKind.fixed`. This is used for the `arg` conv tactic
-/
def getCongrSimpKindsForArgZero (info : FunInfo) : MetaM (Array CongrArgKind) := do
let mut result := #[]
for h : i in [:info.paramInfo.size] do
for h : i in *...info.paramInfo.size do
if info.resultDeps.contains i then
result := result.push .fixed
else if i == 0 then

View file

@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Leonardo de Moura, Joachim Breitner
-/
prelude
import Init.Data.Range.Polymorphic.Stream
import Lean.Meta.InferType
import Lean.AuxRecursor
import Lean.AddDecl
@ -123,7 +124,7 @@ def mkBelow (indName : Name) : MetaM Unit := do
-- If this is the first inductive in a mutual group with nested inductives,
-- generate the constructions for the nested inductives now
if indVal.all[0]! = indName then
for i in [:indVal.numNested] do
for i in *...indVal.numNested do
let recName := recName.appendIndexAfter (i + 1)
let belowName := belowName.appendIndexAfter (i + 1)
mkBelowFromRec recName indVal.numParams belowName
@ -227,7 +228,7 @@ private def mkBRecOnFromRec (recName : Name) (nParams : Nat)
-- (F_1 : (t : List α) → (f : List.below t) → motive t)
-- and bring parameters of that type into scope
let mut fDecls : Array (Name × (Array Expr -> MetaM Expr)) := #[]
for motive in motives, below in belows, i in [:motives.size] do
for motive in motives, below in belows, i in *...motives.size do
let fType ← forallTelescope (← inferType motive) fun targs _ => do
withLocalDeclD `f (mkAppN below targs) fun f =>
mkForallFVars (targs.push f) (mkAppN motive targs)
@ -280,7 +281,7 @@ def mkBRecOn (indName : Name) : MetaM Unit := do
-- If this is the first inductive in a mutual group with nested inductives,
-- generate the constructions for the nested inductives now.
if indVal.all[0]! = indName then
for i in [:indVal.numNested] do
for i in *...indVal.numNested do
let recName := recName.appendIndexAfter (i + 1)
let brecOnName := brecOnName.appendIndexAfter (i + 1)
mkBRecOnFromRec recName indVal.numParams indVal.all.toArray brecOnName

View file

@ -71,7 +71,7 @@ where
let natType := mkConst ``Nat
let declType ← mkArrow enumType natType
let mut minors := #[]
for i in [:numCtors] do
for i in *...numCtors do
minors := minors.push <| mkNatLit i
withLocalDeclD `x enumType fun x => do
let motive ← mkLambdaFVars #[x] natType

View file

@ -123,7 +123,7 @@ where
goN (num : Nat) : StateRefT (List Key) CoreM (Array MessageData) := do
let mut r := #[]
for _ in [: num] do
for _ in *...num do
r := r.push (← go)
return r

View file

@ -80,7 +80,7 @@ where
checkpointDefEq do
let args := b.getAppArgs
let params := args[*...ctorVal.numParams].toArray
for h : i in [ctorVal.numParams : args.size] do
for h : i in ctorVal.numParams...args.size do
let j := i - ctorVal.numParams
let proj ← mkProjFn ctorVal us params j a
if ← isProof proj then
@ -255,7 +255,7 @@ private def isDefEqArgsFirstPass
(paramInfo : Array ParamInfo) (args₁ args₂ : Array Expr) : MetaM DefEqArgsFirstPassResult := do
let mut postponedImplicit := #[]
let mut postponedHO := #[]
for h : i in [:paramInfo.size] do
for h : i in *...paramInfo.size do
let info := paramInfo[i]
let a₁ := args₁[i]!
let a₂ := args₂[i]!
@ -291,7 +291,7 @@ private partial def isDefEqArgs (f : Expr) (args₁ args₂ : Array Expr) : Meta
let finfo ← getFunInfoNArgs f args₁.size
let .ok postponedImplicit postponedHO ← isDefEqArgsFirstPass finfo.paramInfo args₁ args₂ | pure false
-- finfo.paramInfo.size may be smaller than args₁.size
for i in [finfo.paramInfo.size:args₁.size] do
for i in finfo.paramInfo.size...args₁.size do
unless (← Meta.isExprDefEqAux args₁[i]! args₂[i]!) do
return false
for i in postponedImplicit do
@ -432,7 +432,7 @@ where
let check (lctx : LocalContext) : Bool := Id.run do
let start := lctx.getFVar! xs[0]! |>.index
let stop := lctx.getFVar! xs.back! |>.index
for i in [start+1:stop] do
for i in (start+1)...stop do
match lctx.getAt? i with
| some localDecl =>
if localDecl.isLet then
@ -503,7 +503,7 @@ where
let start := lctx.getFVar! xs[0]! |>.index
let stop := lctx.getFVar! xs.back! |>.index
let mut ys := #[]
for i in [start:stop+1] do
for i in start...=stop do
match lctx.getAt? i with
| none => pure ()
| some localDecl =>

View file

@ -93,7 +93,7 @@ def setMVarUserNamesAt (e : Expr) (isTarget : Array Expr) : MetaM (Array MVarId)
forEachExpr (← instantiateMVars e) fun e => do
if e.isApp then
let args := e.getAppArgs
for h : i in [:args.size] do
for h : i in *...args.size do
let arg := args[i]
if arg.isMVar && isTarget.contains arg then
let mvarId := arg.mvarId!

View file

@ -59,7 +59,7 @@ private def getFunInfoAux (fn : Expr) (maxArgs? : Option Nat) : MetaM FunInfo :=
forallBoundedTelescope fnType maxArgs? fun fvars type => do
let mut paramInfo := #[]
let mut higherOrderOutParams : FVarIdSet := {}
for h : i in [:fvars.size] do
for h : i in *...fvars.size do
let fvar := fvars[i]
let decl ← getFVarLocalDecl fvar
let backDeps := collectDeps fvars decl.type
@ -79,7 +79,7 @@ private def getFunInfoAux (fn : Expr) (maxArgs? : Option Nat) : MetaM FunInfo :=
if let some outParamPositions := getOutParamPositions? (← getEnv) className then
unless outParamPositions.isEmpty do
let args := decl.type.getAppArgs
for h2 : i in [:args.size] do
for h2 : i in *...args.size do
if outParamPositions.contains i then
let arg := args[i]
if let some idx := fvars.idxOf? arg then

View file

@ -190,7 +190,7 @@ where
let mut withWs := #[]
let mut (wssIdx, wss'Idx) := (0, 0)
let mut inSubst := false
for h : diffIdx in [:diff.size] do
for h : diffIdx in *...diff.size do
let (a₁, s₁) := diff[diffIdx]
withWs := withWs.push (a₁, s₁)
if let some (a₂, s₂) := diff[diffIdx + 1]? then

View file

@ -493,7 +493,7 @@ where
-- `belowIndices` is a mapping from non-`below` to the `below` version of each field.
let mut belowFieldOpts := .replicate belowCtor.numFields none
let fields := fields.toArray
for fieldIdx in [:fields.size] do
for fieldIdx in *...fields.size do
belowFieldOpts := belowFieldOpts.set! belowIndices[fieldIdx]! (some fields[fieldIdx]!)
let belowParams := params.toArray.push belowMotive
@ -591,6 +591,7 @@ def mkBelow (declName : Name) : MetaM Unit := do
addDecl decl
trace[Meta.IndPredBelow] "added {ctx.belowNames}"
ctx.belowNames.forM Lean.mkCasesOn
-- TODO: use new ranges as soon as it does not break compilerTest1.lean anymore
for i in [:ctx.typeInfos.size] do
try
let decl ← IndPredBelow.mkBrecOnDecl ctx i

Some files were not shown because too many files have changed in this diff Show more