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:
parent
6e98dfbc64
commit
98e4b2882f
190 changed files with 1069 additions and 556 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
||||
|
|
|
|||
|
|
@ -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] :
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 γ)} :
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 α]
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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} :
|
||||
|
|
|
|||
|
|
@ -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 ρ
|
||||
|
||||
|
|
|
|||
|
|
@ -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}"
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 ()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 }
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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*
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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}'"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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*
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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)))
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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}"
|
||||
|
|
|
|||
|
|
@ -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!
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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}"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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" ++
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 ←
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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]!)
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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!
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 ()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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`
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 `,`
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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 =>
|
||||
|
|
|
|||
|
|
@ -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!
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Add table
Reference in a new issue