Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: getLsb_replicate #10

Closed
wants to merge 23 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
afe0b5a
perf: precise cache for `foldConsts` (#4871)
leodemoura Jul 30, 2024
a4f997b
feat: getLsb_replicate
bollu Jul 22, 2024
81719f9
chore: fix binder explicitness in List.map_subset (#4877)
kim-em Jul 31, 2024
a4015ca
chore: rename PSigma.exists (#4878)
kim-em Jul 31, 2024
a827759
fix: mistake in statement of `List.take_takeWhile` (#4875)
kmill Jul 31, 2024
82f4874
chore: copy release notes from `releases/v4.10.0` (#4864)
kmill Jul 31, 2024
d5e7dba
fix: make "use `set_option diagnostics true" message conditional on c…
kmill Jul 31, 2024
688da9d
chore: updates to release_checklist.md (#4876)
kim-em Jul 31, 2024
8acdafd
chore: correct doc-string for Array.swap! (#4869)
kim-em Jul 31, 2024
6a4159c
refactor: split out Lean.Language.Lean.Types (#4881)
Kha Jul 31, 2024
d19bab0
feat: `include` command (#4883)
Kha Jul 31, 2024
41c094c
chore: @[simp]
bollu Jul 31, 2024
d154c13
chore: delete excessive paranthesization
bollu Jul 31, 2024
fab15e3
feat: simplify proof with Nat.mod_def
bollu Jul 31, 2024
d5a8c96
fix: make import resolution case-sensitive on all platforms (#4538)
Kha Jul 31, 2024
f869902
feat: Nat simprocs for simplifying bit expressions (#4874)
bollu Jul 31, 2024
dcea47d
chore: shorten suggestion about diagnostics (#4882)
kim-em Jul 31, 2024
db59442
refactor: `sharecommon` (#4887)
leodemoura Jul 31, 2024
c517688
feat: ushiftRight bitblasting (#4872)
bollu Jul 31, 2024
a856016
perf: precise cache for `expr_eq_fn` (#4890)
leodemoura Aug 1, 2024
32b9de8
fix: export symbols needed by Verso (#4884)
david-christiansen Aug 1, 2024
e83f78d
chore: update stage0
Aug 1, 2024
d9c6f8a
Merge remote-tracking branch 'origin/master' into getLsb_replicate
tobiasgrosser Aug 1, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
296 changes: 292 additions & 4 deletions RELEASES.md

Large diffs are not rendered by default.

20 changes: 14 additions & 6 deletions doc/dev/release_checklist.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ See below for the checklist for release candidates.

We'll use `v4.6.0` as the intended release version as a running example.

- One week before the planned release, ensure that (1) someone has written the release notes and (2) someone has written the first draft of the release blog post.
If there is any material in `./releases_drafts/`, then the release notes are not done. (See the section "Writing the release notes".)
- One week before the planned release, ensure that
(1) someone has written the release notes and
(2) someone has written the first draft of the release blog post.
If there is any material in `./releases_drafts/` on the `releases/v4.6.0` branch, then the release notes are not done.
(See the section "Writing the release notes".)
- `git checkout releases/v4.6.0`
(This branch should already exist, from the release candidates.)
- `git pull`
Expand Down Expand Up @@ -187,6 +190,8 @@ We'll use `v4.7.0-rc1` as the intended release version in this example.
Please also make sure that whoever is handling social media knows the release is out.
- Begin the next development cycle (i.e. for `v4.8.0`) on the Lean repository, by making a PR that:
- Updates `src/CMakeLists.txt` to say `set(LEAN_VERSION_MINOR 8)`
- Replaces the "release notes will be copied" text in the `v4.6.0` section of `RELEASES.md` with the
finalized release notes from the `releases/v4.6.0` branch.
- Replaces the "development in progress" in the `v4.7.0` section of `RELEASES.md` with
```
Release candidate, release notes will be copied from `branch releases/v4.7.0` once completed.
Expand Down Expand Up @@ -222,12 +227,15 @@ Please read https://leanprover-community.github.io/contribute/tags_and_branches.
* This can either be done by the person managing this process directly,
or by soliciting assistance from authors of files, or generally helpful people on Zulip!
* Each repo has a `bump/v4.7.0` which accumulates reviewed changes adapting to new versions.
* Once `nightly-testing` is working on a given nightly, say `nightly-2024-02-15`, we:
* Once `nightly-testing` is working on a given nightly, say `nightly-2024-02-15`, we will create a PR to `bump/v4.7.0`.
* For Mathlib, there is a script in `scripts/create-adaptation-pr.sh` that automates this process.
* For Batteries and Aesop it is currently manual.
* For all of these repositories, the process is the same:
* Make sure `bump/v4.7.0` is up to date with `master` (by merging `master`, no PR necessary)
* Create from `bump/v4.7.0` a `bump/nightly-2024-02-15` branch.
* In that branch, `git merge --squash nightly-testing` to bring across changes from `nightly-testing`.
* In that branch, `git merge nightly-testing` to bring across changes from `nightly-testing`.
* Sanity check changes, commit, and make a PR to `bump/v4.7.0` from the `bump/nightly-2024-02-15` branch.
* Solicit review, merge the PR into `bump/v4,7,0`.
* Solicit review, merge the PR into `bump/v4.7.0`.
* It is always okay to merge in the following directions:
`master` -> `bump/v4.7.0` -> `bump/nightly-2024-02-15` -> `nightly-testing`.
Please remember to push any merges you make to intermediate steps!
Expand All @@ -239,7 +247,7 @@ The exact steps are a work in progress.
Here is the general idea:

* The work is done right on the `releases/v4.6.0` branch sometime after it is created but before the stable release is made.
The release notes for `v4.6.0` will be copied to `master`.
The release notes for `v4.6.0` will later be copied to `master` when we begin a new development cycle.
* There can be material for release notes entries in commit messages.
* There can also be pre-written entries in `./releases_drafts`, which should be all incorporated in the release notes and then deleted from the branch.
See `./releases_drafts/README.md` for more information.
Expand Down
45 changes: 0 additions & 45 deletions releases_drafts/varCtorNameLint.md

This file was deleted.

6 changes: 3 additions & 3 deletions src/Init/Core.lean
Original file line number Diff line number Diff line change
Expand Up @@ -1204,12 +1204,12 @@ def Prod.map {α₁ : Type u₁} {α₂ : Type u₂} {β₁ : Type v₁} {β₂

/-! # Dependent products -/

theorem PSigma.exists {α : Sort u} {p : α → Prop} : (PSigma (fun x => p x)) → Exists (fun x => p x)
theorem Exists.of_psigma_prop {α : Sort u} {p : α → Prop} : (PSigma (fun x => p x)) → Exists (fun x => p x)
| ⟨x, hx⟩ => ⟨x, hx⟩

@[deprecated PSigma.exists (since := "2024-07-27")]
@[deprecated Exists.of_psigma_prop (since := "2024-07-27")]
theorem ex_of_PSigma {α : Type u} {p : α → Prop} : (PSigma (fun x => p x)) → Exists (fun x => p x) :=
PSigma.exists
Exists.of_psigma_prop

protected theorem PSigma.eta {α : Sort u} {β : α → Sort v} {a₁ a₂ : α} {b₁ : β a₁} {b₂ : β a₂}
(h₁ : a₁ = a₂) (h₂ : Eq.ndrec b₁ h₁ = b₂) : PSigma.mk a₁ b₁ = PSigma.mk a₂ b₂ := by
Expand Down
2 changes: 1 addition & 1 deletion src/Init/Data/Array/Basic.lean
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ def swap (a : Array α) (i j : @& Fin a.size) : Array α :=
a'.set (size_set a i v₂ ▸ j) v₁

/--
Swaps two entries in an array, or panics if either index is out of bounds.
Swaps two entries in an array, or returns the array unchanged if either index is out of bounds.

This will perform the update destructively provided that `a` has a reference
count of 1 when called.
Expand Down
6 changes: 2 additions & 4 deletions src/Init/Data/BitVec/Basic.lean
Original file line number Diff line number Diff line change
Expand Up @@ -583,11 +583,9 @@ instance : HAppend (BitVec w) (BitVec v) (BitVec (w + v)) := ⟨.append⟩
-- TODO: write this using multiplication
/-- `replicate i x` concatenates `i` copies of `x` into a new vector of length `w*i`. -/
def replicate : (i : Nat) → BitVec w → BitVec (w*i)
| 0, _ => 0
| 0, _ => 0#0
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this change was strictly necessary, but it makes it cleaner to read.

| n+1, x =>
have hEq : w + w*n = w*(n + 1) := by
rw [Nat.mul_add, Nat.add_comm, Nat.mul_one]
hEq ▸ (x ++ replicate n x)
(x ++ replicate n x).cast (by rw [Nat.mul_succ]; omega)
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I replaced the cast by BitVec.cast, for which we have better equation lemmas.


/-!
### Cons and Concat
Expand Down
71 changes: 65 additions & 6 deletions src/Init/Data/BitVec/Bitblast.lean
Original file line number Diff line number Diff line change
Expand Up @@ -403,12 +403,8 @@ theorem shiftLeftRec_eq {x : BitVec w₁} {y : BitVec w₂} {n : Nat} :
induction n generalizing x y
case zero =>
ext i
simp only [shiftLeftRec_zero, twoPow_zero, Nat.reduceAdd, truncate_one]
suffices (y &&& 1#w₂) = zeroExtend w₂ (ofBool (y.getLsb 0)) by simp [this]
ext i
by_cases h : (↑i : Nat) = 0
· simp [h, Bool.and_comm]
· simp [h]; omega
simp only [shiftLeftRec_zero, twoPow_zero, Nat.reduceAdd, truncate_one,
and_one_eq_zeroExtend_ofBool_getLsb]
case succ n ih =>
simp only [shiftLeftRec_succ, and_twoPow]
rw [ih]
Expand All @@ -431,4 +427,67 @@ theorem shiftLeft_eq_shiftLeftRec (x : BitVec w₁) (y : BitVec w₂) :
· simp [of_length_zero]
· simp [shiftLeftRec_eq]

/- ### Logical shift right (ushiftRight) recurrence for bitblasting -/

/--
`ushiftRightRec x y n` shifts `x` logically to the right by the first `n` bits of `y`.

The theorem `shiftRight_eq_ushiftRightRec` proves the equivalence
of `(x >>> y)` and `ushiftRightRec`.

Together with equations `ushiftRightRec_zero`, `ushiftRightRec_succ`,
this allows us to unfold `ushiftRight` into a circuit for bitblasting.
-/
def ushiftRightRec (x : BitVec w₁) (y : BitVec w₂) (n : Nat) : BitVec w₁ :=
let shiftAmt := (y &&& (twoPow w₂ n))
match n with
| 0 => x >>> shiftAmt
| n + 1 => (ushiftRightRec x y n) >>> shiftAmt

@[simp]
theorem ushiftRightRec_zero (x : BitVec w₁) (y : BitVec w₂) :
ushiftRightRec x y 0 = x >>> (y &&& twoPow w₂ 0) := by
simp [ushiftRightRec]

@[simp]
theorem ushiftRightRec_succ (x : BitVec w₁) (y : BitVec w₂) :
ushiftRightRec x y (n + 1) = (ushiftRightRec x y n) >>> (y &&& twoPow w₂ (n + 1)) := by
simp [ushiftRightRec]

/--
If `y &&& z = 0`, `x >>> (y ||| z) = x >>> y >>> z`.
This follows as `y &&& z = 0` implies `y ||| z = y + z`,
and thus `x >>> (y ||| z) = x >>> (y + z) = x >>> y >>> z`.
-/
theorem ushiftRight'_or_of_and_eq_zero {x : BitVec w₁} {y z : BitVec w₂}
(h : y &&& z = 0#w₂) :
x >>> (y ||| z) = x >>> y >>> z := by
simp [← add_eq_or_of_and_eq_zero _ _ h, toNat_add_of_and_eq_zero h, shiftRight_add]

theorem ushiftRightRec_eq (x : BitVec w₁) (y : BitVec w₂) (n : Nat) :
ushiftRightRec x y n = x >>> (y.truncate (n + 1)).zeroExtend w₂ := by
induction n generalizing x y
case zero =>
ext i
simp only [ushiftRightRec_zero, twoPow_zero, Nat.reduceAdd,
and_one_eq_zeroExtend_ofBool_getLsb, truncate_one]
case succ n ih =>
simp only [ushiftRightRec_succ, and_twoPow]
rw [ih]
by_cases h : y.getLsb (n + 1) <;> simp only [h, ↓reduceIte]
· rw [zeroExtend_truncate_succ_eq_zeroExtend_truncate_or_twoPow_of_getLsb_true h,
ushiftRight'_or_of_and_eq_zero]
simp
· simp [zeroExtend_truncate_succ_eq_zeroExtend_truncate_of_getLsb_false, h]

/--
Show that `x >>> y` can be written in terms of `ushiftRightRec`.
This can be unfolded in terms of `ushiftRightRec_zero`, `ushiftRightRec_succ` for bitblasting.
-/
theorem shiftRight_eq_ushiftRightRec (x : BitVec w₁) (y : BitVec w₂) :
x >>> y = ushiftRightRec x y (w₂ - 1) := by
rcases w₂ with rfl | w₂
· simp [of_length_zero]
· simp [ushiftRightRec_eq]

end BitVec
60 changes: 60 additions & 0 deletions src/Init/Data/BitVec/Lemmas.lean
Original file line number Diff line number Diff line change
Expand Up @@ -731,6 +731,16 @@ theorem getLsb_shiftLeft' {x : BitVec w₁} {y : BitVec w₂} {i : Nat} :
getLsb (x >>> i) j = getLsb x (i+j) := by
unfold getLsb ; simp

@[simp]
theorem ushiftRight_zero_eq (x : BitVec w) : x >>> 0 = x := by
simp [bv_toNat]

/-! ### ushiftRight reductions from BitVec to Nat -/

@[simp]
theorem ushiftRight_eq' (x : BitVec w₁) (y : BitVec w₂) :
x >>> y = x >>> y.toNat := by rfl

/-! ### sshiftRight -/

theorem sshiftRight_eq {x : BitVec n} {i : Nat} :
Expand Down Expand Up @@ -1549,4 +1559,54 @@ theorem zeroExtend_truncate_succ_eq_zeroExtend_truncate_or_twoPow_of_getLsb_true
simp [hx]
· by_cases hik' : k < i + 1 <;> simp [hik, hik'] <;> omega

/-- Bitwise and of `(x : BitVec w)` with `1#w` equals zero extending `x.lsb` to `w`. -/
theorem and_one_eq_zeroExtend_ofBool_getLsb {x : BitVec w} :
(x &&& 1#w) = zeroExtend w (ofBool (x.getLsb 0)) := by
ext i
simp only [getLsb_and, getLsb_one, getLsb_zeroExtend, Fin.is_lt, decide_True, getLsb_ofBool,
Bool.true_and]
by_cases h : (0 = (i : Nat)) <;> simp [h] <;> omega

@[simp]
theorem replicate_zero_eq {x : BitVec w} : x.replicate 0 = 0#0 := by
simp [replicate]

@[simp]
theorem replicate_succ_eq {x : BitVec w} :
x.replicate (n + 1) =
(x ++ replicate n x).cast (by rw [Nat.mul_succ]; omega) := by
simp [replicate]

/--
If a number `w * n ≤ i < w * (n + 1)`, then `i - w * n` equals `i % w`.
This is true by subtracting `w * n` from the inequality, giving
`0 ≤ i - w * n < w`, which uniquely identifies `i % w`.
-/
private theorem Nat.sub_mul_eq_mod_of_lt_of_le (hlo : w * n ≤ i) (hhi : i < w * (n + 1)) :
i - w * n = i % w := by
rw [Nat.mod_def]
congr
symm
apply Nat.div_eq_of_lt_le
(by rw [Nat.mul_comm]; omega)
(by rw [Nat.mul_comm]; omega)

@[simp]
theorem getLsb_replicate {n w : Nat} (x : BitVec w) :
(x.replicate n).getLsb i =
(decide (i < w * n) && x.getLsb (i % w)) := by
induction n generalizing x
case zero => simp
case succ n ih =>
simp only [replicate_succ_eq, getLsb_cast, getLsb_append]
by_cases hi : i < w * (n + 1)
· simp only [hi, decide_True, Bool.true_and]
by_cases hi' : i < w * n
· simp [hi', ih]
· simp only [hi', decide_False, cond_false]
rw [Nat.sub_mul_eq_mod_of_lt_of_le] <;> omega
· rw [Nat.mul_succ] at hi ⊢
simp only [show ¬i < w * n by omega, decide_False, cond_false, hi, Bool.false_and]
apply BitVec.getLsb_ge (x := x) (i := i - w * n) (ge := by omega)

end BitVec
2 changes: 1 addition & 1 deletion src/Init/Data/List/Sublist.lean
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ theorem cons_subset_cons {l₁ l₂ : List α} (a : α) (s : l₁ ⊆ l₂) : a
@[simp] theorem subset_nil {l : List α} : l ⊆ [] ↔ l = [] :=
⟨fun h => match l with | [] => rfl | _::_ => (nomatch h (.head ..)), fun | rfl => Subset.refl _⟩

theorem map_subset {l₁ l₂ : List α} {f : α → β} (h : l₁ ⊆ l₂) : map f l₁ ⊆ map f l₂ :=
theorem map_subset {l₁ l₂ : List α} (f : α → β) (h : l₁ ⊆ l₂) : map f l₁ ⊆ map f l₂ :=
fun x => by simp only [mem_map]; exact .imp fun a => .imp_left (@h _)

theorem filter_subset {l₁ l₂ : List α} (p : α → Bool) (H : l₁ ⊆ l₂) : filter p l₁ ⊆ filter p l₂ :=
Expand Down
8 changes: 4 additions & 4 deletions src/Init/Data/List/TakeDrop.lean
Original file line number Diff line number Diff line change
Expand Up @@ -411,11 +411,11 @@ theorem dropWhile_replicate (p : α → Bool) :
split <;> simp_all

theorem take_takeWhile {l : List α} (p : α → Bool) n :
(l.takeWhile p).take n = (l.takeWhile p).take n := by
induction l with
| nil => rfl
(l.takeWhile p).take n = (l.take n).takeWhile p := by
induction l generalizing n with
| nil => simp
| cons x xs ih =>
by_cases h : p x <;> simp [takeWhile_cons, h, ih]
by_cases h : p x <;> cases n <;> simp [takeWhile_cons, h, ih, take_succ_cons]

@[simp] theorem all_takeWhile {l : List α} : (l.takeWhile p).all p = true := by
induction l with
Expand Down
4 changes: 4 additions & 0 deletions src/Init/Data/Nat/Div.lean
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,10 @@ theorem mod_add_div (m k : Nat) : m % k + k * (m / k) = m := by
| base x y h => simp [h]
| ind x y h IH => simp [h]; rw [Nat.mul_succ, ← Nat.add_assoc, IH, Nat.sub_add_cancel h.2]

theorem mod_def (m k : Nat) : m % k = m - k * (m / k) := by
rw [Nat.sub_eq_of_eq_add]
apply (Nat.mod_add_div _ _).symm

@[simp] protected theorem div_one (n : Nat) : n / 1 = n := by
have := mod_add_div n 1
rwa [mod_one, Nat.zero_add, Nat.one_mul] at this
Expand Down
2 changes: 1 addition & 1 deletion src/Init/ShareCommon.lean
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,4 @@ A more restrictive but efficient max sharing primitive.
Remark: it optimizes the number of RC operations, and the strategy for caching results.
-/
@[extern "lean_sharecommon_quick"]
def ShareCommon.shareCommon' (a : α) : α := a
def ShareCommon.shareCommon' (a : @& α) : α := a
5 changes: 4 additions & 1 deletion src/Lean/Compiler/IR/EmitC.lean
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,10 @@ def emitCInitName (n : Name) : M Unit :=
def shouldExport (n : Name) : Bool :=
-- HACK: exclude symbols very unlikely to be used by the interpreter or other consumers of
-- libleanshared to avoid Windows symbol limit
!(`Lean.Compiler.LCNF).isPrefixOf n && !(`Lean.IR).isPrefixOf n && !(`Lean.Server).isPrefixOf n
!(`Lean.Compiler.LCNF).isPrefixOf n &&
!(`Lean.IR).isPrefixOf n &&
-- Lean.Server.findModuleRefs is used in Verso
(!(`Lean.Server).isPrefixOf n || n == `Lean.Server.findModuleRefs)

def emitFnDeclAux (decl : Decl) (cppBaseName : String) (isExternal : Bool) : M Unit := do
let ps := decl.params
Expand Down
17 changes: 14 additions & 3 deletions src/Lean/CoreM.lean
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,16 @@ register_builtin_option maxHeartbeats : Nat := {
descr := "maximum amount of heartbeats per command. A heartbeat is number of (small) memory allocations (in thousands), 0 means no limit"
}

def useDiagnosticMsg := s!"use `set_option {diagnostics.name} true` to get diagnostic information"
/--
If the `diagnostics` option is not already set, gives a message explaining this option.
Begins with a `\n`, so an error message can look like `m!"some error occurred{useDiagnosticMsg}"`.
-/
def useDiagnosticMsg : MessageData :=
MessageData.lazy fun ctx =>
if diagnostics.get ctx.opts then
pure ""
else
pure s!"\nAdditional diagnostic information may be available using the `set_option {diagnostics.name} true` command."

namespace Core

Expand Down Expand Up @@ -300,8 +309,10 @@ register_builtin_option debug.moduleNameAtTimeout : Bool := {
def throwMaxHeartbeat (moduleName : Name) (optionName : Name) (max : Nat) : CoreM Unit := do
let includeModuleName := debug.moduleNameAtTimeout.get (← getOptions)
let atModuleName := if includeModuleName then s!" at `{moduleName}`" else ""
let msg := s!"(deterministic) timeout{atModuleName}, maximum number of heartbeats ({max/1000}) has been reached\nuse `set_option {optionName} <num>` to set the limit\n{useDiagnosticMsg}"
throw <| Exception.error (← getRef) (MessageData.ofFormat (Std.Format.text msg))
throw <| Exception.error (← getRef) m!"\
(deterministic) timeout{atModuleName}, maximum number of heartbeats ({max/1000}) has been reached\n\
Use `set_option {optionName} <num>` to set the limit.\
{useDiagnosticMsg}"

def checkMaxHeartbeatsCore (moduleName : String) (optionName : Name) (max : Nat) : CoreM Unit := do
unless max == 0 do
Expand Down
2 changes: 1 addition & 1 deletion src/Lean/Elab/Calc.lean
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def mkCalcTrans (result resultType step stepType : Expr) : MetaM (Expr × Expr)
unless (← getCalcRelation? resultType).isSome do
throwError "invalid 'calc' step, step result is not a relation{indentExpr resultType}"
return (result, resultType)
| _ => throwError "invalid 'calc' step, failed to synthesize `Trans` instance{indentExpr selfType}\n{useDiagnosticMsg}"
| _ => throwError "invalid 'calc' step, failed to synthesize `Trans` instance{indentExpr selfType}{useDiagnosticMsg}"

/--
Adds a type annotation to a hole that occurs immediately at the beginning of the term.
Expand Down
2 changes: 1 addition & 1 deletion src/Lean/Elab/Import.lean
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def parseImports (input : String) (fileName : Option String := none) : IO (Array
def printImports (input : String) (fileName : Option String) : IO Unit := do
let (deps, _, _) ← parseImports input fileName
for dep in deps do
let fname ← findOLean dep.module
let fname ← findOLean (checkExists := false) dep.module
IO.println fname

end Lean.Elab
Loading
Loading