mirror of
https://github.com/leanprover/lean4.git
synced 2026-03-23 21:34:10 +00:00
Compare commits
2 Commits
master
...
lean-sym-i
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d881b43ca7 | ||
|
|
be9d2644d6 |
2
.github/workflows/build-template.yml
vendored
2
.github/workflows/build-template.yml
vendored
@@ -33,7 +33,7 @@ jobs:
|
||||
include: ${{fromJson(inputs.config)}}
|
||||
# complete all jobs
|
||||
fail-fast: false
|
||||
runs-on: ${{ endsWith(matrix.os, '-with-cache') && fromJSON(format('["{0}", "nscloud-git-mirror-5gb"]', matrix.os)) || matrix.os }}
|
||||
runs-on: ${{ endsWith(matrix.os, '-with-cache') && fromJSON(format('["{0}", "nscloud-git-mirror-1gb"]', matrix.os)) || matrix.os }}
|
||||
defaults:
|
||||
run:
|
||||
shell: ${{ matrix.shell || 'nix develop -c bash -euxo pipefail {0}' }}
|
||||
|
||||
29
.github/workflows/check-empty-pr.yml
vendored
29
.github/workflows/check-empty-pr.yml
vendored
@@ -1,29 +0,0 @@
|
||||
name: Check for empty PR
|
||||
|
||||
on:
|
||||
merge_group:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
check-empty-pr:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
|
||||
fetch-depth: 0
|
||||
filter: tree:0
|
||||
|
||||
- name: Check for empty diff
|
||||
run: |
|
||||
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
|
||||
base=$(git merge-base "origin/${{ github.base_ref }}" HEAD)
|
||||
else
|
||||
base=$(git rev-parse HEAD^1)
|
||||
fi
|
||||
if git diff --quiet "$base" HEAD --; then
|
||||
echo "This PR introduces no changes compared to its base branch." | tee "$GITHUB_STEP_SUMMARY"
|
||||
echo "It may be a duplicate of an already-merged PR." | tee -a "$GITHUB_STEP_SUMMARY"
|
||||
exit 1
|
||||
fi
|
||||
shell: bash
|
||||
@@ -236,7 +236,7 @@ def parse_version(version_str):
|
||||
def is_version_gte(version1, version2):
|
||||
"""Check if version1 >= version2, including proper handling of release candidates."""
|
||||
# Check if version1 is a nightly toolchain
|
||||
if version1.startswith("leanprover/lean4:nightly-") or version1.startswith("leanprover/lean4-nightly:"):
|
||||
if version1.startswith("leanprover/lean4:nightly-"):
|
||||
return False
|
||||
return parse_version(version1) >= parse_version(version2)
|
||||
|
||||
|
||||
@@ -66,8 +66,3 @@ theorem BEq.neq_of_beq_of_neq [BEq α] [PartialEquivBEq α] {a b c : α} :
|
||||
instance (priority := low) [BEq α] [LawfulBEq α] : EquivBEq α where
|
||||
symm h := beq_iff_eq.2 <| Eq.symm <| beq_iff_eq.1 h
|
||||
trans hab hbc := beq_iff_eq.2 <| (beq_iff_eq.1 hab).trans <| beq_iff_eq.1 hbc
|
||||
|
||||
theorem equivBEq_of_iff_apply_eq [BEq α] (f : α → β) (hf : ∀ a b, a == b ↔ f a = f b) : EquivBEq α where
|
||||
rfl := by simp [hf]
|
||||
symm := by simp [hf, eq_comm]
|
||||
trans hab hbc := (hf _ _).2 (Eq.trans ((hf _ _).1 hab) ((hf _ _).1 hbc))
|
||||
|
||||
@@ -852,10 +852,6 @@ theorem Slice.rawEndPos_copy {s : Slice} : s.copy.rawEndPos = s.rawEndPos := by
|
||||
theorem copy_toSlice {s : String} : s.toSlice.copy = s := by
|
||||
simp [← toByteArray_inj, Slice.toByteArray_copy, ← size_toByteArray]
|
||||
|
||||
@[simp]
|
||||
theorem copy_comp_toSlice : String.Slice.copy ∘ String.toSlice = id := by
|
||||
ext; simp
|
||||
|
||||
theorem Slice.getUTF8Byte_eq_getUTF8Byte_copy {s : Slice} {p : Pos.Raw} {h : p < s.rawEndPos} :
|
||||
s.getUTF8Byte p h = s.copy.getUTF8Byte p (by simpa) := by
|
||||
simp [getUTF8Byte, String.getUTF8Byte, toByteArray_copy, ByteArray.getElem_extract]
|
||||
|
||||
@@ -6,5 +6,29 @@ Authors: Markus Himmel
|
||||
module
|
||||
|
||||
prelude
|
||||
public import Init.Data.String.Iter.Basic
|
||||
public import Init.Data.String.Iter.Intercalate
|
||||
public import Init.Data.Iterators.Combinators.FilterMap
|
||||
public import Init.Data.Iterators.Consumers.Collect
|
||||
|
||||
set_option doc.verso true
|
||||
|
||||
namespace Std
|
||||
|
||||
/--
|
||||
Convenience function for turning an iterator into a list of strings, provided the output of the
|
||||
iterator implements {name}`ToString`.
|
||||
-/
|
||||
@[inline]
|
||||
public abbrev Iter.toStringList {α β : Type} [Iterator α Id β] [ToString β]
|
||||
(it : Iter (α := α) β) : List String :=
|
||||
it.map toString |>.toList
|
||||
|
||||
/--
|
||||
Convenience function for turning an iterator into an array of strings, provided the output of the
|
||||
iterator implements {name}`ToString`.
|
||||
-/
|
||||
@[inline]
|
||||
public abbrev Iter.toStringArray {α β : Type} [Iterator α Id β] [ToString β]
|
||||
(it : Iter (α := α) β) : Array String :=
|
||||
it.map toString |>.toArray
|
||||
|
||||
end Std
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
/-
|
||||
Copyright (c) 2026 Lean FRO, LLC. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Markus Himmel
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
public import Init.Data.Iterators.Combinators.FilterMap
|
||||
public import Init.Data.Iterators.Consumers.Collect
|
||||
|
||||
set_option doc.verso true
|
||||
|
||||
namespace Std
|
||||
|
||||
/--
|
||||
Convenience function for turning an iterator into a list of strings, provided the output of the
|
||||
iterator implements {name}`ToString`.
|
||||
-/
|
||||
@[inline]
|
||||
public abbrev Iter.toStringList {α β : Type} [Iterator α Id β] [ToString β]
|
||||
(it : Iter (α := α) β) : List String :=
|
||||
it.map toString |>.toList
|
||||
|
||||
/--
|
||||
Convenience function for turning an iterator into an array of strings, provided the output of the
|
||||
iterator implements {name}`ToString`.
|
||||
-/
|
||||
@[inline]
|
||||
public abbrev Iter.toStringArray {α β : Type} [Iterator α Id β] [ToString β]
|
||||
(it : Iter (α := α) β) : Array String :=
|
||||
it.map toString |>.toArray
|
||||
|
||||
end Std
|
||||
@@ -1,36 +0,0 @@
|
||||
/-
|
||||
Copyright (c) 2026 Lean FRO, LLC. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Julia Markus Himmel
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
public import Init.Data.Iterators.Combinators.Monadic.FilterMap
|
||||
public import Init.Data.String.Basic
|
||||
import Init.Data.String.Slice
|
||||
|
||||
set_option doc.verso true
|
||||
|
||||
namespace Std
|
||||
|
||||
/--
|
||||
Appends all the elements in the iterator, in order.
|
||||
-/
|
||||
public def Iter.joinString {α β : Type} [Iterator α Id β] [IteratorLoop α Id Id] [ToString β]
|
||||
(it : Std.Iter (α := α) β) : String :=
|
||||
(it.map toString).fold (init := "") (· ++ ·)
|
||||
|
||||
/--
|
||||
Appends the elements of the iterator into a string, placing the separator {name}`s` between them.
|
||||
-/
|
||||
@[inline]
|
||||
public def Iter.intercalateString {α β : Type} [Iterator α Id β] [IteratorLoop α Id Id] [ToString β]
|
||||
(s : String.Slice) (it : Std.Iter (α := α) β) : String :=
|
||||
it.map toString
|
||||
|>.fold (init := none) (fun
|
||||
| none, sl => some sl
|
||||
| some str, sl => some (str ++ s ++ sl))
|
||||
|>.getD ""
|
||||
|
||||
end Std
|
||||
@@ -17,8 +17,6 @@ public import Init.Data.String.Lemmas.Pattern
|
||||
public import Init.Data.String.Lemmas.Slice
|
||||
public import Init.Data.String.Lemmas.Iterate
|
||||
public import Init.Data.String.Lemmas.Intercalate
|
||||
public import Init.Data.String.Lemmas.Iter
|
||||
public import Init.Data.String.Lemmas.Hashable
|
||||
import Init.Data.Order.Lemmas
|
||||
public import Init.Data.String.Basic
|
||||
import Init.Data.Char.Lemmas
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
/-
|
||||
Copyright (c) 2026 Lean FRO, LLC. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Julia Markus Himmel
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
public import Init.Data.String.Slice
|
||||
public import Init.Data.LawfulHashable
|
||||
import all Init.Data.String.Slice
|
||||
import Init.Data.String.Lemmas.Slice
|
||||
|
||||
namespace String
|
||||
|
||||
public theorem hash_eq {s : String} : hash s = String.hash s := rfl
|
||||
|
||||
namespace Slice
|
||||
|
||||
public theorem hash_eq {s : String.Slice} : hash s = String.hash s.copy := (rfl)
|
||||
|
||||
public instance : LawfulHashable String.Slice where
|
||||
hash_eq a b hab := by simp [hash_eq, beq_eq_true_iff.1 hab]
|
||||
|
||||
end String.Slice
|
||||
@@ -10,7 +10,6 @@ public import Init.Data.String.Defs
|
||||
import all Init.Data.String.Defs
|
||||
public import Init.Data.String.Slice
|
||||
import all Init.Data.String.Slice
|
||||
import Init.ByCases
|
||||
|
||||
public section
|
||||
|
||||
@@ -43,16 +42,6 @@ theorem intercalate_cons_of_ne_nil {s t : String} {l : List String} (h : l ≠ [
|
||||
match l, h with
|
||||
| u::l, _ => by simp
|
||||
|
||||
theorem intercalate_append_of_ne_nil {l m : List String} {s : String} (hl : l ≠ []) (hm : m ≠ []) :
|
||||
s.intercalate (l ++ m) = s.intercalate l ++ s ++ s.intercalate m := by
|
||||
induction l with
|
||||
| nil => simp_all
|
||||
| cons hd tl ih =>
|
||||
rw [List.cons_append, intercalate_cons_of_ne_nil (by simp_all)]
|
||||
by_cases ht : tl = []
|
||||
· simp_all
|
||||
· simp [ih ht, intercalate_cons_of_ne_nil ht, String.append_assoc]
|
||||
|
||||
@[simp]
|
||||
theorem toList_intercalate {s : String} {l : List String} :
|
||||
(s.intercalate l).toList = s.toList.intercalate (l.map String.toList) := by
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
/-
|
||||
Copyright (c) 2026 Lean FRO, LLC. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Julia Markus Himmel
|
||||
-/
|
||||
module
|
||||
|
||||
prelude
|
||||
public import Init.Data.String.Iter.Intercalate
|
||||
public import Init.Data.String.Slice
|
||||
import all Init.Data.String.Iter.Intercalate
|
||||
import all Init.Data.String.Defs
|
||||
import Init.Data.String.Lemmas.Intercalate
|
||||
import Init.Data.Iterators.Lemmas.Consumers.Loop
|
||||
import Init.Data.Iterators.Lemmas.Combinators.FilterMap
|
||||
|
||||
namespace Std.Iter
|
||||
|
||||
@[simp]
|
||||
public theorem joinString_eq {α β : Type} [Std.Iterator α Id β] [Std.Iterators.Finite α Id]
|
||||
[Std.IteratorLoop α Id Id] [Std.LawfulIteratorLoop α Id Id] [ToString β]
|
||||
{it : Std.Iter (α := α) β} : it.joinString = String.join (it.toList.map toString) := by
|
||||
rw [joinString, String.join, ← foldl_toList, toList_map]
|
||||
|
||||
@[simp]
|
||||
public theorem intercalateString_eq {α β : Type} [Std.Iterator α Id β] [Std.Iterators.Finite α Id]
|
||||
[Std.IteratorLoop α Id Id] [Std.LawfulIteratorLoop α Id Id] [ToString β] {s : String.Slice}
|
||||
{it : Std.Iter (α := α) β} :
|
||||
it.intercalateString s = s.copy.intercalate (it.toList.map toString) := by
|
||||
simp only [intercalateString, String.appendSlice_eq, ← foldl_toList, toList_map]
|
||||
generalize s.copy = s
|
||||
suffices ∀ (l m : List String),
|
||||
(l.foldl (init := if m = [] then none else some (s.intercalate m))
|
||||
(fun | none, sl => some sl | some str, sl => some (str ++ s ++ sl))).getD ""
|
||||
= s.intercalate (m ++ l) by
|
||||
simpa [-foldl_toList] using this (it.toList.map toString) []
|
||||
intro l m
|
||||
induction l generalizing m with
|
||||
| nil => cases m <;> simp
|
||||
| cons hd tl ih =>
|
||||
rw [List.append_cons, ← ih, List.foldl_cons]
|
||||
congr
|
||||
simp only [List.append_eq_nil_iff, List.cons_ne_self, and_false, ↓reduceIte]
|
||||
match m with
|
||||
| [] => simp
|
||||
| x::xs =>
|
||||
simp only [reduceCtorEq, ↓reduceIte, List.cons_append, Option.some.injEq]
|
||||
rw [← List.cons_append, String.intercalate_append_of_ne_nil (by simp) (by simp),
|
||||
String.intercalate_singleton]
|
||||
|
||||
end Std.Iter
|
||||
@@ -23,7 +23,6 @@ import Init.Data.String.OrderInstances
|
||||
import Init.Data.String.Lemmas.Order
|
||||
import Init.Data.String.Lemmas.Intercalate
|
||||
import Init.Data.List.SplitOn.Lemmas
|
||||
import Init.Data.String.Lemmas.Slice
|
||||
|
||||
public section
|
||||
|
||||
@@ -71,11 +70,6 @@ theorem Slice.toList_split_intercalate {c : Char} {l : List Slice} (hl : ∀ s
|
||||
· simp_all
|
||||
· rw [List.splitOn_intercalate] <;> simp_all
|
||||
|
||||
theorem Slice.toList_split_intercalate_beq {c : Char} {l : List Slice} (hl : ∀ s ∈ l, c ∉ s.copy.toList) :
|
||||
((Slice.intercalate (String.singleton c) l).split c).toList ==
|
||||
if l = [] then ["".toSlice] else l := by
|
||||
split <;> simp_all [toList_split_intercalate hl, beq_list_iff]
|
||||
|
||||
theorem toList_split_intercalate {c : Char} {l : List String} (hl : ∀ s ∈ l, c ∉ s.toList) :
|
||||
((String.intercalate (String.singleton c) l).split c).toList.map (·.copy) =
|
||||
if l = [] then [""] else l := by
|
||||
@@ -84,9 +78,4 @@ theorem toList_split_intercalate {c : Char} {l : List String} (hl : ∀ s ∈ l,
|
||||
· simp_all
|
||||
· rw [List.splitOn_intercalate] <;> simp_all
|
||||
|
||||
theorem toList_split_intercalate_beq {c : Char} {l : List String} (hl : ∀ s ∈ l, c ∉ s.toList) :
|
||||
((String.intercalate (String.singleton c) l).split c).toList ==
|
||||
if l = [] then ["".toSlice] else l.map String.toSlice := by
|
||||
split <;> simp_all [toList_split_intercalate hl, Slice.beq_list_iff]
|
||||
|
||||
end String
|
||||
|
||||
@@ -33,22 +33,8 @@ theorem beq_eq_true_iff {s t : Slice} : s == t ↔ s.copy = t.copy := by
|
||||
theorem beq_eq_false_iff {s t : Slice} : (s == t) = false ↔ s.copy ≠ t.copy := by
|
||||
simp [← Bool.not_eq_true]
|
||||
|
||||
theorem beq_eq_decide {s t : Slice} : (s == t) = decide (s.copy = t.copy) :=
|
||||
Bool.eq_iff_iff.2 (by simp)
|
||||
|
||||
instance : EquivBEq String.Slice :=
|
||||
equivBEq_of_iff_apply_eq copy (by simp)
|
||||
|
||||
theorem beq_list_iff {l l' : List String.Slice} : l == l' ↔ l.map copy = l'.map copy := by
|
||||
induction l generalizing l' <;> cases l' <;> simp_all
|
||||
|
||||
theorem beq_list_eq_false_iff {l l' : List String.Slice} :
|
||||
(l == l') = false ↔ l.map copy ≠ l'.map copy := by
|
||||
simp [← Bool.not_eq_true, beq_list_iff]
|
||||
|
||||
theorem beq_list_eq_decide {l l' : List String.Slice} :
|
||||
(l == l') = decide (l.map copy = l'.map copy) :=
|
||||
Bool.eq_iff_iff.2 (by simp [beq_list_iff])
|
||||
theorem beq_eq_decide {s t : Slice} : (s == t) = decide (s.copy = t.copy) := by
|
||||
cases h : s == t <;> simp_all
|
||||
|
||||
end BEq
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ public import Init.Data.Ord.Basic
|
||||
public import Init.Data.Iterators.Combinators.FilterMap
|
||||
public import Init.Data.String.ToSlice
|
||||
public import Init.Data.String.Subslice
|
||||
public import Init.Data.String.Iter.Basic
|
||||
public import Init.Data.String.Iter
|
||||
public import Init.Data.String.Iterate
|
||||
import Init.Data.Iterators.Consumers.Collect
|
||||
import Init.Data.Iterators.Consumers.Loop
|
||||
@@ -84,11 +84,10 @@ instance : ToString String.Slice where
|
||||
theorem toStringToString_eq : ToString.toString = String.Slice.copy := (rfl)
|
||||
|
||||
@[extern "lean_slice_hash"]
|
||||
protected def hash (s : @& Slice) : UInt64 :=
|
||||
String.hash s.copy
|
||||
opaque hash (s : @& Slice) : UInt64
|
||||
|
||||
instance : Hashable Slice where
|
||||
hash := Slice.hash
|
||||
hash := hash
|
||||
|
||||
instance : LT Slice where
|
||||
lt x y := x.copy < y.copy
|
||||
|
||||
@@ -107,9 +107,6 @@ syntax (name := showLocalThms) "show_local_thms" : grind
|
||||
-/
|
||||
syntax (name := showTerm) "show_term " grindSeq : grind
|
||||
|
||||
/-- Shows the pending goals. -/
|
||||
syntax (name := showGoals) "show_goals" : grind
|
||||
|
||||
declare_syntax_cat grind_ref (behavior := both)
|
||||
|
||||
syntax:max anchor : grind_ref
|
||||
@@ -318,8 +315,5 @@ Only available in `sym =>` mode.
|
||||
-/
|
||||
syntax (name := symSimp) "simp" (ppSpace colGt ident)? (" [" ident,* "]")? : grind
|
||||
|
||||
/-- `exact e` closes the main goal if its target type matches that of `e`. -/
|
||||
macro "exact " e:term : grind => `(grind| tactic => exact $e:term)
|
||||
|
||||
end Grind
|
||||
end Lean.Parser.Tactic
|
||||
|
||||
@@ -4082,7 +4082,7 @@ Actions in the resulting monad are functions that take the local value as a para
|
||||
ordinary actions in `m`.
|
||||
-/
|
||||
def ReaderT (ρ : Type u) (m : Type u → Type v) (α : Type u) : Type (max u v) :=
|
||||
(a : @&ρ) → m α
|
||||
ρ → m α
|
||||
|
||||
/--
|
||||
Interpret `ρ → m α` as an element of `ReaderT ρ m α`.
|
||||
|
||||
@@ -49,14 +49,6 @@ syntax (name := ground) "ground" : sym_simproc
|
||||
/-- Simplify telescope binders but not the final body. -/
|
||||
syntax (name := telescope) "telescope" : sym_simproc
|
||||
|
||||
/-- Simplify control-flow expressions (`if-then-else`, `match`, `cond`, `dite`).
|
||||
Visits only conditions and discriminants. Intended as a `pre` simproc. -/
|
||||
syntax (name := control) "control" : sym_simproc
|
||||
|
||||
/-- Simplify arrow telescopes (`p₁ → p₂ → ... → q`) without entering binders.
|
||||
Simplifies each `pᵢ` and `q` individually. Intended as a `pre` simproc. -/
|
||||
syntax (name := arrowTelescope) "arrow_telescope" : sym_simproc
|
||||
|
||||
/-- Rewrite using a named theorem set. Optionally specify a discharger for conditional rewrites. -/
|
||||
syntax (name := rewriteSet) "rewrite" ident (" with " sym_discharger)? : sym_simproc
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ public section
|
||||
|
||||
namespace Lean.IR
|
||||
|
||||
set_option compiler.ignoreBorrowAnnotation true in
|
||||
@[export lean_add_extern]
|
||||
def addExtern (declName : Name) (externAttrData : ExternAttrData) : CoreM Unit := do
|
||||
if !isPrivateName declName then
|
||||
|
||||
@@ -97,7 +97,6 @@ partial def collectCode (code : Code .impure) : M Unit := do
|
||||
match decl.value with
|
||||
| .oproj _ parent =>
|
||||
addDerivedValue parent decl.fvarId
|
||||
-- Keep in sync with PropagateBorrow, InferBorrow
|
||||
| .fap ``Array.getInternal args =>
|
||||
if let .fvar parent := args[1]! then
|
||||
addDerivedValue parent decl.fvarId
|
||||
|
||||
@@ -213,8 +213,6 @@ inductive OwnReason where
|
||||
| jpArgPropagation (jpFVar : FVarId)
|
||||
/-- Tail call preservation at a join point jump. -/
|
||||
| jpTailCallPreservation (jpFVar : FVarId)
|
||||
/-- Annotated as an owned parameter (currently only triggerable through `@[export]`)-/
|
||||
| ownedAnnotation
|
||||
|
||||
def OwnReason.toString (reason : OwnReason) : CompilerM String := do
|
||||
PP.run do
|
||||
@@ -231,7 +229,6 @@ def OwnReason.toString (reason : OwnReason) : CompilerM String := do
|
||||
| .tailCallPreservation funcName => return s!"tail call preservation of {funcName}"
|
||||
| .jpArgPropagation jpFVar => return s!"backward propagation from JP {← PP.ppFVar jpFVar}"
|
||||
| .jpTailCallPreservation jpFVar => return s!"JP tail call preservation {← PP.ppFVar jpFVar}"
|
||||
| .ownedAnnotation => return s!"Annotated as owned"
|
||||
|
||||
/--
|
||||
Determine whether an `OwnReason` is necessary for correctness (forced) or just an optimization
|
||||
@@ -248,7 +245,7 @@ def OwnReason.isForced (reason : OwnReason) : Bool :=
|
||||
| .constructorResult .. | .functionCallResult ..
|
||||
-- We cannot pass borrowed values to reset or have borrow annotations destroy tail calls for
|
||||
-- correctness reasons.
|
||||
| .resetReuse .. | .tailCallPreservation .. | .jpTailCallPreservation .. | .ownedAnnotation
|
||||
| .resetReuse .. | .tailCallPreservation .. | .jpTailCallPreservation ..
|
||||
| .forwardProjectionProp .. | .backwardProjectionProp .. => true
|
||||
|
||||
/--
|
||||
@@ -259,19 +256,10 @@ partial def infer (decls : Array (Decl .impure)) : CompilerM ParamMap := do
|
||||
return map.paramMap
|
||||
where
|
||||
go : InferM Unit := do
|
||||
for (_, params) in (← get).paramMap.map do
|
||||
for param in params do
|
||||
if !param.borrow && param.type.isPossibleRef then
|
||||
-- if the param already disqualifies as borrow now this is because of an annotation
|
||||
ownFVar param.fvarId .ownedAnnotation
|
||||
modify fun s => { s with modified := false }
|
||||
loop
|
||||
|
||||
loop : InferM Unit := do
|
||||
step
|
||||
if (← get).modified then
|
||||
modify fun s => { s with modified := false }
|
||||
loop
|
||||
go
|
||||
else
|
||||
return ()
|
||||
|
||||
@@ -373,16 +361,6 @@ where
|
||||
| .oproj _ x _ =>
|
||||
if ← isOwned x then ownFVar z (.forwardProjectionProp z)
|
||||
if ← isOwned z then ownFVar x (.backwardProjectionProp z)
|
||||
-- Keep in sync with ExplicitRC, PropagateBorrow
|
||||
| .fap ``Array.getInternal args =>
|
||||
if let .fvar parent := args[1]! then
|
||||
if ← isOwned parent then ownFVar z (.forwardProjectionProp z)
|
||||
| .fap ``Array.get!Internal args =>
|
||||
if let .fvar parent := args[2]! then
|
||||
if ← isOwned parent then ownFVar z (.forwardProjectionProp z)
|
||||
| .fap ``Array.uget args =>
|
||||
if let .fvar parent := args[1]! then
|
||||
if ← isOwned parent then ownFVar z (.forwardProjectionProp z)
|
||||
| .fap f args =>
|
||||
let ps ← getParamInfo (.decl f)
|
||||
ownFVar z (.functionCallResult z)
|
||||
|
||||
@@ -105,22 +105,9 @@ where
|
||||
|
||||
collectLetValue (z : FVarId) (v : LetValue .impure) : InferM Unit := do
|
||||
match v with
|
||||
| .oproj _ parent _ =>
|
||||
let parentVal ← getOwnedness parent
|
||||
join z parentVal
|
||||
-- Keep in sync with ExplicitRC, InferBorrow
|
||||
| .fap ``Array.getInternal args =>
|
||||
if let .fvar parent := args[1]! then
|
||||
let parentVal ← getOwnedness parent
|
||||
join z parentVal
|
||||
| .fap ``Array.get!Internal args =>
|
||||
if let .fvar parent := args[2]! then
|
||||
let parentVal ← getOwnedness parent
|
||||
join z parentVal
|
||||
| .fap ``Array.uget args =>
|
||||
if let .fvar parent := args[1]! then
|
||||
let parentVal ← getOwnedness parent
|
||||
join z parentVal
|
||||
| .oproj _ x _ =>
|
||||
let xVal ← getOwnedness x
|
||||
join z xVal
|
||||
| .ctor .. | .fap .. | .fvar .. | .pap .. | .sproj .. | .uproj .. | .erased .. | .lit .. =>
|
||||
join z .own
|
||||
| _ => unreachable!
|
||||
|
||||
@@ -343,13 +343,13 @@ def instantiateTypeLevelParams (c : ConstantVal) (us : List Level) : CoreM Expr
|
||||
modifyInstLevelTypeCache fun s => s.insert c.name (us, r)
|
||||
return r
|
||||
|
||||
def instantiateValueLevelParams (c : ConstantInfo) (us : List Level) (allowOpaque := false) : CoreM Expr := do
|
||||
def instantiateValueLevelParams (c : ConstantInfo) (us : List Level) : CoreM Expr := do
|
||||
if let some (us', r) := (← get).cache.instLevelValue.find? c.name then
|
||||
if us == us' then
|
||||
return r
|
||||
unless c.hasValue (allowOpaque := allowOpaque) do
|
||||
unless c.hasValue do
|
||||
throwError "Not a definition or theorem: {.ofConstName c.name}"
|
||||
let r := c.instantiateValueLevelParams! us (allowOpaque := allowOpaque)
|
||||
let r := c.instantiateValueLevelParams! us
|
||||
modifyInstLevelValueCache fun s => s.insert c.name (us, r)
|
||||
return r
|
||||
|
||||
|
||||
@@ -14,35 +14,29 @@ public section
|
||||
|
||||
namespace Lean
|
||||
/--
|
||||
Reducibility hints guide the kernel's *lazy delta reduction* strategy. When the kernel encounters a
|
||||
definitional equality constraint
|
||||
Reducibility hints are used in the convertibility checker.
|
||||
When trying to solve a constraint such a
|
||||
|
||||
(f ...) =?= (g ...)
|
||||
|
||||
where `f` and `g` are definitions, it must decide which side to unfold. The rules (implemented in
|
||||
`lazy_delta_reduction_step` in `src/kernel/type_checker.cpp`) are:
|
||||
where f and g are definitions, the checker has to decide which one will be unfolded.
|
||||
If f (g) is opaque, then g (f) is unfolded if it is also not marked as opaque,
|
||||
Else if f (g) is abbrev, then f (g) is unfolded if g (f) is also not marked as abbrev,
|
||||
Else if f and g are regular, then we unfold the one with the biggest definitional height.
|
||||
Otherwise both are unfolded.
|
||||
|
||||
* If `f` and `g` have the **same hint kind**:
|
||||
- Both `.opaque` or both `.abbrev`: unfold both.
|
||||
- Both `.regular`: unfold the one with the **greater** height first. If their heights are equal
|
||||
(in particular, if `f` and `g` are the same definition), first try to compare their arguments
|
||||
for definitional equality (short-circuiting the unfolding if they match), then unfold both.
|
||||
* If `f` and `g` have **different hint kinds**: unfold the one that is *not* `.opaque`, preferring to
|
||||
unfold `.abbrev` over `.regular`.
|
||||
The arguments of the `regular` Constructor are: the definitional height and the flag `selfOpt`.
|
||||
|
||||
The `.regular` constructor carries a `UInt32` *definitional height*, which is computed by the
|
||||
elaborator as one plus the maximum height of all `.regular` constants appearing in the definition's
|
||||
body (see `getMaxHeight`). This means `.abbrev` and `.opaque` constants do not contribute to the
|
||||
height. When creating declarations via meta-programming, the height can be specified manually.
|
||||
The definitional height is by default computed by the kernel. It only takes into account
|
||||
other regular definitions used in a definition. When creating declarations using meta-programming,
|
||||
we can specify the definitional depth manually.
|
||||
|
||||
The hints only affect performance — they control the order in which definitions are unfolded, but
|
||||
never prevent the kernel from unfolding a definition during type checking.
|
||||
Remark: the hint only affects performance. None of the hints prevent the kernel from unfolding a
|
||||
declaration during Type checking.
|
||||
|
||||
The `ReducibilityHints` are not related to the `@[reducible]`/`@[irreducible]`/`@[semireducible]`
|
||||
attributes. Those attributes are used by the elaborator to control which definitions tactics like
|
||||
`simp`, `rfl`, and `dsimp` will unfold; they do not affect the kernel. Conversely,
|
||||
`ReducibilityHints` are set when a declaration is added to the kernel and cannot be changed
|
||||
afterwards. -/
|
||||
Remark: the ReducibilityHints are not related to the attributes: reducible/irrelevance/semireducible.
|
||||
These attributes are used by the Elaborator. The ReducibilityHints are used by the kernel (and Elaborator).
|
||||
Moreover, the ReducibilityHints cannot be changed after a declaration is added to the kernel. -/
|
||||
inductive ReducibilityHints where
|
||||
| opaque : ReducibilityHints
|
||||
| abbrev : ReducibilityHints
|
||||
@@ -475,37 +469,24 @@ def numLevelParams (d : ConstantInfo) : Nat :=
|
||||
def type (d : ConstantInfo) : Expr :=
|
||||
d.toConstantVal.type
|
||||
|
||||
/--
|
||||
Returns the value of a definition. With `allowOpaque := true`, values
|
||||
of theorems and opaque declarations are also returned.
|
||||
-/
|
||||
def value? (info : ConstantInfo) (allowOpaque := false) : Option Expr :=
|
||||
match info with
|
||||
| .defnInfo {value, ..} => some value
|
||||
| .thmInfo {value, ..} => if allowOpaque then some value else none
|
||||
| .thmInfo {value, ..} => some value
|
||||
| .opaqueInfo {value, ..} => if allowOpaque then some value else none
|
||||
| _ => none
|
||||
|
||||
/--
|
||||
Returns `true` if this declaration as a value for the purpose of reduction
|
||||
and type-checking, i.e. is a definition.
|
||||
With `allowOpaque := true`, theorems and opaque declarations are also considered to have values.
|
||||
-/
|
||||
def hasValue (info : ConstantInfo) (allowOpaque := false) : Bool :=
|
||||
match info with
|
||||
| .defnInfo _ => true
|
||||
| .thmInfo _ => allowOpaque
|
||||
| .thmInfo _ => true
|
||||
| .opaqueInfo _ => allowOpaque
|
||||
| _ => false
|
||||
|
||||
/--
|
||||
Returns the value of a definition. With `allowOpaque := true`, values
|
||||
of theorems and opaque declarations are also returned.
|
||||
-/
|
||||
def value! (info : ConstantInfo) (allowOpaque := false) : Expr :=
|
||||
match info with
|
||||
| .defnInfo {value, ..} => value
|
||||
| .thmInfo {value, ..} => if allowOpaque then value else panic! "declaration with value expected"
|
||||
| .thmInfo {value, ..} => value
|
||||
| .opaqueInfo {value, ..} => if allowOpaque then value else panic! "declaration with value expected"
|
||||
| _ => panic! s!"declaration with value expected, but {info.name} has none"
|
||||
|
||||
@@ -529,10 +510,6 @@ def isDefinition : ConstantInfo → Bool
|
||||
| .defnInfo _ => true
|
||||
| _ => false
|
||||
|
||||
def isTheorem : ConstantInfo → Bool
|
||||
| .thmInfo _ => true
|
||||
| _ => false
|
||||
|
||||
def inductiveVal! : ConstantInfo → InductiveVal
|
||||
| .inductInfo val => val
|
||||
| _ => panic! "Expected a `ConstantInfo.inductInfo`."
|
||||
|
||||
@@ -101,7 +101,7 @@ def inferDefEqAttr (declName : Name) : MetaM Unit := do
|
||||
withoutExporting do
|
||||
let info ← getConstInfo declName
|
||||
let isRfl ←
|
||||
if let some value := info.value? (allowOpaque := true) then
|
||||
if let some value := info.value? then
|
||||
isRflProofCore info.type value
|
||||
else
|
||||
pure false
|
||||
|
||||
@@ -329,8 +329,7 @@ private def mkSilentAnnotationIfHole (e : Expr) : TermElabM Expr := do
|
||||
let inst ← if backward.inferInstanceAs.wrap.get (← getOptions) then
|
||||
-- Normalize to instance normal form.
|
||||
let logCompileErrors := !(← read).isNoncomputableSection && !(← read).declName?.any (Lean.isNoncomputable (← getEnv))
|
||||
let isMeta := (← read).isMetaSection
|
||||
withNewMCtxDepth <| normalizeInstance inst expectedType (logCompileErrors := logCompileErrors) (isMeta := isMeta)
|
||||
withNewMCtxDepth <| normalizeInstance inst expectedType (logCompileErrors := logCompileErrors)
|
||||
else
|
||||
pure inst
|
||||
ensureHasType expectedType? inst
|
||||
|
||||
@@ -666,8 +666,7 @@ private def mkTermContext (ctx : Context) (s : State) : CommandElabM Term.Contex
|
||||
return {
|
||||
macroStack := ctx.macroStack
|
||||
sectionVars := sectionVars
|
||||
isNoncomputableSection := scope.isNoncomputable
|
||||
isMetaSection := scope.isMeta }
|
||||
isNoncomputableSection := scope.isNoncomputable }
|
||||
|
||||
/--
|
||||
Lift the `TermElabM` monadic action `x` into a `CommandElabM` monadic action.
|
||||
|
||||
@@ -220,12 +220,10 @@ def processDefDeriving (view : DerivingClassView) (decl : Expr) (isNoncomputable
|
||||
instName ← liftMacroM <| mkUnusedBaseName instName
|
||||
if isPrivateName declName then
|
||||
instName := mkPrivateName env instName
|
||||
let isMeta := (← read).isMetaSection
|
||||
let inst ← if backward.inferInstanceAs.wrap.get (← getOptions) then
|
||||
withDeclNameForAuxNaming instName <| withNewMCtxDepth <|
|
||||
normalizeInstance result.instVal result.instType
|
||||
(logCompileErrors := false) -- covered by noncomputable check below
|
||||
(isMeta := isMeta)
|
||||
else
|
||||
pure result.instVal
|
||||
let closure ← Closure.mkValueTypeClosure result.instType inst (zetaDelta := true)
|
||||
|
||||
@@ -63,11 +63,10 @@ def addPreDefAttributes (preDefs : Array PreDefinition) : TermElabM Unit := do
|
||||
a wrong setting and creates bad `defEq` equations.
|
||||
-/
|
||||
for preDef in preDefs do
|
||||
unless preDef.kind.isTheorem do
|
||||
unless preDef.modifiers.attrs.any fun a =>
|
||||
a.name = `reducible || a.name = `semireducible ||
|
||||
a.name = `instance_reducible || a.name = `implicit_reducible do
|
||||
setIrreducibleAttribute preDef.declName
|
||||
unless preDef.modifiers.attrs.any fun a =>
|
||||
a.name = `reducible || a.name = `semireducible ||
|
||||
a.name = `instance_reducible || a.name = `implicit_reducible do
|
||||
setIrreducibleAttribute preDef.declName
|
||||
|
||||
/-
|
||||
`enableRealizationsForConst` must happen before `generateEagerEqns`
|
||||
|
||||
@@ -184,7 +184,6 @@ def getUnfoldFor? (declName : Name) : MetaM (Option Name) := do
|
||||
else
|
||||
return none
|
||||
|
||||
set_option compiler.ignoreBorrowAnnotation true in
|
||||
@[export lean_get_structural_rec_arg_pos]
|
||||
def getStructuralRecArgPosImp? (declName : Name) : CoreM (Option Nat) := do
|
||||
let some info := eqnInfoExt.find? (← getEnv) declName | return none
|
||||
|
||||
@@ -80,32 +80,6 @@ private def elimMutualRecursion (preDefs : Array PreDefinition) (fixedParamPerms
|
||||
withRecFunsAsAxioms preDefs do
|
||||
mkBRecOnF recArgInfos positions r values[idx]! FTypes[idx]!
|
||||
trace[Elab.definition.structural] "FArgs: {FArgs}"
|
||||
|
||||
-- Extract the functionals into named `_f` helper definitions (e.g. `foo._f`) so they show up
|
||||
-- with a helpful name in kernel diagnostics. The `_f` definitions are `.abbrev` so the kernel
|
||||
-- unfolds them eagerly; their body heights are registered via `setDefHeightOverride` so that
|
||||
-- `getMaxHeight` computes the correct height for parent definitions.
|
||||
-- For inductive predicates, the previous inline behavior is kept.
|
||||
let FArgs ←
|
||||
if isIndPred then
|
||||
pure FArgs
|
||||
else
|
||||
let us := preDefs[0]!.levelParams.map mkLevelParam
|
||||
FArgs.mapIdxM fun idx fArg => do
|
||||
let fName := preDefs[idx]!.declName ++ `_f
|
||||
let fValue ← eraseRecAppSyntaxExpr (← mkLambdaFVars xs fArg)
|
||||
let fType ← Meta.letToHave (← inferType fValue)
|
||||
let fHeight := getMaxHeight (← getEnv) fValue
|
||||
addDecl (.defnDecl {
|
||||
name := fName, levelParams := preDefs[idx]!.levelParams,
|
||||
type := fType, value := fValue,
|
||||
hints := .abbrev,
|
||||
safety := if preDefs[idx]!.modifiers.isUnsafe then .unsafe else .safe,
|
||||
all := [fName] })
|
||||
modifyEnv (setDefHeightOverride · fName fHeight)
|
||||
setReducibleAttribute fName
|
||||
return mkAppN (mkConst fName us) xs
|
||||
|
||||
let brecOn := brecOnConst 0
|
||||
-- the indices and the major premise are not mentioned in the minor premises
|
||||
-- so using `default` is fine here
|
||||
|
||||
@@ -76,10 +76,6 @@ def evalGrindSeq : GrindTactic := fun stx =>
|
||||
@[builtin_grind_tactic skip] def evalSkip : GrindTactic := fun _ =>
|
||||
return ()
|
||||
|
||||
@[builtin_grind_tactic showGoals] def evalShowGoals : GrindTactic := fun _ => do
|
||||
let goals ← getUnsolvedGoalMVarIds
|
||||
addRawTrace (goalsToMessageData goals)
|
||||
|
||||
@[builtin_grind_tactic paren] def evalParen : GrindTactic := fun stx =>
|
||||
evalGrindTactic stx[1]
|
||||
|
||||
|
||||
@@ -9,8 +9,6 @@ import Lean.Elab.Tactic.Grind.SimprocDSL
|
||||
import Init.Sym.Simp.SimprocDSL
|
||||
import Lean.Meta.Sym.Simp.EvalGround
|
||||
import Lean.Meta.Sym.Simp.Telescope
|
||||
import Lean.Meta.Sym.Simp.ControlFlow
|
||||
import Lean.Meta.Sym.Simp.Forall
|
||||
import Lean.Meta.Sym.Simp.Rewrite
|
||||
namespace Lean.Elab.Tactic.Grind
|
||||
open Meta Sym.Simp
|
||||
@@ -25,14 +23,6 @@ def elabSimprocGround : SymSimprocElab := fun _ =>
|
||||
def elabSimprocTelescope : SymSimprocElab := fun _ =>
|
||||
return simpTelescope
|
||||
|
||||
@[builtin_sym_simproc Lean.Parser.Sym.Simp.control]
|
||||
def elabSimprocControl : SymSimprocElab := fun _ =>
|
||||
return simpControl
|
||||
|
||||
@[builtin_sym_simproc Lean.Parser.Sym.Simp.arrowTelescope]
|
||||
def elabSimprocArrowTelescope : SymSimprocElab := fun _ =>
|
||||
return simpArrowTelescope
|
||||
|
||||
@[builtin_sym_simproc self]
|
||||
def elabSimprocSelf : SymSimprocElab := fun _ =>
|
||||
return simp
|
||||
|
||||
@@ -787,7 +787,6 @@ where
|
||||
throw ex
|
||||
|
||||
-- `evalSuggest` implementation
|
||||
set_option compiler.ignoreBorrowAnnotation true in
|
||||
@[export lean_eval_suggest_tactic]
|
||||
private partial def evalSuggestImpl : TryTactic := fun tac => do
|
||||
trace[try.debug] "{tac}"
|
||||
|
||||
@@ -309,8 +309,6 @@ structure Context where
|
||||
heedElabAsElim : Bool := true
|
||||
/-- Noncomputable sections automatically add the `noncomputable` modifier to any declaration we cannot generate code for. -/
|
||||
isNoncomputableSection : Bool := false
|
||||
/-- `true` when inside a `meta section`. -/
|
||||
isMetaSection : Bool := false
|
||||
/-- When `true` we skip TC failures. We use this option when processing patterns. -/
|
||||
ignoreTCFailures : Bool := false
|
||||
/-- `true` when elaborating patterns. It affects how we elaborate named holes. -/
|
||||
|
||||
@@ -1193,8 +1193,8 @@ namespace ConstantInfo
|
||||
def instantiateTypeLevelParams (c : ConstantInfo) (ls : List Level) : Expr :=
|
||||
c.toConstantVal.instantiateTypeLevelParams ls
|
||||
|
||||
def instantiateValueLevelParams! (c : ConstantInfo) (ls : List Level) (allowOpaque := false) : Expr :=
|
||||
(c.value! (allowOpaque := allowOpaque)).instantiateLevelParams c.levelParams ls
|
||||
def instantiateValueLevelParams! (c : ConstantInfo) (ls : List Level) : Expr :=
|
||||
c.value!.instantiateLevelParams c.levelParams ls
|
||||
|
||||
end ConstantInfo
|
||||
|
||||
@@ -2755,28 +2755,13 @@ def mkThmOrUnsafeDef [Monad m] [MonadEnv m] (thm : TheoremVal) : m Declaration :
|
||||
else
|
||||
return .thmDecl thm
|
||||
|
||||
/-- Environment extension for overriding the height that `getMaxHeight` assigns to a definition.
|
||||
This is consulted for all definitions regardless of their reducibility hints. Currently used by
|
||||
structural recursion to ensure that parent definitions get the correct height even though the
|
||||
`_f` helper definitions are marked as `.abbrev` (which `getMaxHeight` would otherwise ignore). -/
|
||||
builtin_initialize defHeightOverrideExt : EnvExtension (NameMap UInt32) ←
|
||||
registerEnvExtension (pure {}) (asyncMode := .local)
|
||||
|
||||
/-- Register a height override for a definition so that `getMaxHeight` uses it. -/
|
||||
def setDefHeightOverride (env : Environment) (declName : Name) (height : UInt32) : Environment :=
|
||||
defHeightOverrideExt.modifyState env fun m => m.insert declName height
|
||||
|
||||
def getMaxHeight (env : Environment) (e : Expr) : UInt32 :=
|
||||
let overrides := defHeightOverrideExt.getState env
|
||||
e.foldConsts 0 fun constName max =>
|
||||
match overrides.find? constName with
|
||||
| some h => if h > max then h else max
|
||||
| none =>
|
||||
match env.findAsync? constName with
|
||||
| some { kind := .defn, constInfo := info, .. } =>
|
||||
match info.get.hints with
|
||||
| ReducibilityHints.regular h => if h > max then h else max
|
||||
| _ => max
|
||||
| _ => max
|
||||
match env.findAsync? constName with
|
||||
| some { kind := .defn, constInfo := info, .. } =>
|
||||
match info.get.hints with
|
||||
| ReducibilityHints.regular h => if h > max then h else max
|
||||
| _ => max
|
||||
| _ => max
|
||||
|
||||
end Lean
|
||||
|
||||
@@ -1321,7 +1321,7 @@ private def getDefInfoTemp (info : ConstantInfo) : MetaM (Option ConstantInfo) :
|
||||
`constName` is an instance. This difference should be irrelevant for `isClassQuickConst?`. -/
|
||||
private def getConstTemp? (constName : Name) : MetaM (Option ConstantInfo) := do
|
||||
match (← getEnv).find? constName with
|
||||
| some (ConstantInfo.thmInfo _) => return none
|
||||
| some (info@(ConstantInfo.thmInfo _)) => getTheoremInfo info
|
||||
| some (info@(ConstantInfo.defnInfo _)) => getDefInfoTemp info
|
||||
| some info => pure (some info)
|
||||
| none => throwUnknownConstantAt (← getRef) constName
|
||||
|
||||
@@ -1126,7 +1126,6 @@ def checkAssignment (mvarId : MVarId) (fvars : Array Expr) (v : Expr) : MetaM (O
|
||||
return none
|
||||
return some v
|
||||
|
||||
set_option compiler.ignoreBorrowAnnotation true in
|
||||
-- Implementation for `_root_.Lean.MVarId.checkedAssign`
|
||||
@[export lean_checked_assign]
|
||||
def checkedAssignImpl (mvarId : MVarId) (val : Expr) : MetaM Bool := do
|
||||
@@ -2234,7 +2233,6 @@ private def whnfCoreAtDefEq (e : Expr) : MetaM Expr := do
|
||||
else
|
||||
whnfCore e
|
||||
|
||||
set_option compiler.ignoreBorrowAnnotation true in
|
||||
@[export lean_is_expr_def_eq]
|
||||
partial def isExprDefEqAuxImpl (t : Expr) (s : Expr) : MetaM Bool := withIncRecDepth do
|
||||
withTraceNodeBefore `Meta.isDefEq (fun _ => return m!"{t} =?= {s}") do
|
||||
|
||||
@@ -46,7 +46,11 @@ External users wanting to look up names should be using `Lean.getConstInfo`.
|
||||
def getUnfoldableConst? (constName : Name) : MetaM (Option ConstantInfo) := do
|
||||
let some ainfo := (← getEnv).findAsync? constName | throwUnknownConstantAt (← getRef) constName
|
||||
match ainfo.kind with
|
||||
| .thm => return none
|
||||
| .thm =>
|
||||
if (← shouldReduceAll) then
|
||||
return some ainfo.toConstantInfo
|
||||
else
|
||||
return none
|
||||
| .defn => if (← canUnfold ainfo.toConstantInfo) then return ainfo.toConstantInfo else return none
|
||||
| _ => return none
|
||||
|
||||
@@ -55,7 +59,7 @@ As with `getUnfoldableConst?` but return `none` instead of failing if the consta
|
||||
-/
|
||||
def getUnfoldableConstNoEx? (constName : Name) : MetaM (Option ConstantInfo) := do
|
||||
match (← getEnv).find? constName with
|
||||
| some (.thmInfo _) => return none
|
||||
| some (info@(.thmInfo _)) => getTheoremInfo info
|
||||
| some (info@(.defnInfo _)) => if (← canUnfold info) then return info else return none
|
||||
| some (.axiomInfo _) => recordUnfoldAxiom constName; return none
|
||||
| _ => return none
|
||||
|
||||
@@ -206,7 +206,6 @@ because it overrides unrelated configurations.
|
||||
else
|
||||
withConfig (fun cfg => { cfg with beta := true, iota := true, zeta := true, zetaHave := true, zetaDelta := true, proj := .yesWithDelta, etaStruct := .all }) x
|
||||
|
||||
set_option compiler.ignoreBorrowAnnotation true in
|
||||
@[export lean_infer_type]
|
||||
def inferTypeImp (e : Expr) : MetaM Expr :=
|
||||
let rec infer (e : Expr) : MetaM Expr := do
|
||||
|
||||
@@ -99,7 +99,7 @@ Normalize an instance value to "instance normal form".
|
||||
See the module docstring for the full algorithm specification.
|
||||
-/
|
||||
partial def normalizeInstance (inst expectedType : Expr) (compile : Bool := true)
|
||||
(logCompileErrors : Bool := true) (isMeta : Bool := false) : MetaM Expr := withTransparency .instances do
|
||||
(logCompileErrors : Bool := true) : MetaM Expr := withTransparency .instances do
|
||||
withTraceNode `Meta.instanceNormalForm
|
||||
(fun _ => return m!"type: {expectedType}") do
|
||||
let some className ← isClass? expectedType
|
||||
@@ -124,11 +124,9 @@ partial def normalizeInstance (inst expectedType : Expr) (compile : Bool := true
|
||||
return inst
|
||||
else
|
||||
let name ← mkAuxDeclName
|
||||
let wrapped ← mkAuxDefinition name expectedType inst (compile := false)
|
||||
let wrapped ← mkAuxDefinition name expectedType inst (compile := compile)
|
||||
(logCompileErrors := logCompileErrors)
|
||||
setReducibilityStatus name .implicitReducible
|
||||
if isMeta then modifyEnv (markMeta · name)
|
||||
if compile then
|
||||
compileDecls (logErrors := logCompileErrors) #[name]
|
||||
enableRealizationsForConst name
|
||||
return wrapped
|
||||
else
|
||||
@@ -171,7 +169,7 @@ partial def normalizeInstance (inst expectedType : Expr) (compile : Bool := true
|
||||
catch _ => pure ()
|
||||
|
||||
mvarId.assign (← normalizeInstance arg argExpectedType (compile := compile)
|
||||
(logCompileErrors := logCompileErrors) (isMeta := isMeta))
|
||||
(logCompileErrors := logCompileErrors))
|
||||
else
|
||||
-- For data fields, assign directly or wrap in aux def to fix types.
|
||||
if backward.inferInstanceAs.wrap.data.get (← getOptions) then
|
||||
@@ -182,7 +180,6 @@ partial def normalizeInstance (inst expectedType : Expr) (compile : Bool := true
|
||||
let name ← mkAuxDeclName
|
||||
mvarId.assign (← mkAuxDefinition name argExpectedType arg (compile := false))
|
||||
setInlineAttribute name
|
||||
if isMeta then modifyEnv (markMeta · name)
|
||||
if compile then
|
||||
compileDecls (logErrors := logCompileErrors) #[name]
|
||||
enableRealizationsForConst name
|
||||
|
||||
@@ -85,7 +85,6 @@ private def isMVarWithGreaterDepth (v : Level) (mvarId : LMVarId) : MetaM Bool :
|
||||
| Level.mvar mvarId' => return (← mvarId'.getLevel) > (← mvarId.getLevel)
|
||||
| _ => return false
|
||||
|
||||
set_option compiler.ignoreBorrowAnnotation true in
|
||||
mutual
|
||||
|
||||
private partial def solve (u v : Level) : MetaM LBool := do
|
||||
|
||||
@@ -138,7 +138,6 @@ Creates conditional equations and splitter for the given match auxiliary declara
|
||||
|
||||
See also `getEquationsFor`.
|
||||
-/
|
||||
set_option compiler.ignoreBorrowAnnotation true in
|
||||
@[export lean_get_match_equations_for]
|
||||
def getEquationsForImpl (matchDeclName : Name) : MetaM MatchEqns := do
|
||||
/-
|
||||
@@ -247,7 +246,6 @@ where go baseName splitterName := withConfig (fun c => { c with etaStruct := .no
|
||||
let result := { eqnNames, splitterName, splitterMatchInfo }
|
||||
registerMatchEqns matchDeclName result
|
||||
|
||||
set_option compiler.ignoreBorrowAnnotation true in
|
||||
/--
|
||||
Generate the congruence equations for the given match auxiliary declaration.
|
||||
The congruence equations have a completely unrestricted left-hand side (arbitrary discriminants),
|
||||
|
||||
@@ -785,7 +785,6 @@ def isDefEqApp (tFn : Expr) (t : Expr) (s : Expr) (_ : tFn = t.getAppFn) : DefEq
|
||||
let numArgs := t.getAppNumArgs
|
||||
isDefEqAppWithInfo t s (numArgs - 1) info
|
||||
|
||||
set_option compiler.ignoreBorrowAnnotation true in
|
||||
/--
|
||||
`isDefEqMain` implementation.
|
||||
-/
|
||||
|
||||
@@ -40,7 +40,6 @@ abbrev cacheResult (e : Expr) (r : Result) : SimpM Result := do
|
||||
modify fun s => { s with persistentCache := s.persistentCache.insert { expr := e } r }
|
||||
return r
|
||||
|
||||
set_option compiler.ignoreBorrowAnnotation true in
|
||||
@[export lean_sym_simp]
|
||||
def simpImpl (e₁ : Expr) : SimpM Result := withIncRecDepth do
|
||||
let numSteps := (← get).numSteps
|
||||
|
||||
@@ -944,7 +944,6 @@ def synthInstance (type : Expr) (maxResultSize? : Option Nat := none) : MetaM Ex
|
||||
| none => throwFailedToSynthesize type)
|
||||
(fun _ => throwFailedToSynthesize type)
|
||||
|
||||
set_option compiler.ignoreBorrowAnnotation true in
|
||||
@[export lean_synth_pending]
|
||||
private def synthPendingImp (mvarId : MVarId) : MetaM Bool := withIncRecDepth <| mvarId.withContext do
|
||||
let mvarDecl ← mvarId.getDecl
|
||||
|
||||
@@ -10,18 +10,18 @@ import Lean.Meta.Transform
|
||||
public section
|
||||
namespace Lean.Meta
|
||||
|
||||
def delta? (e : Expr) (p : Name → Bool := fun _ => true) (allowOpaque := false) : CoreM (Option Expr) :=
|
||||
def delta? (e : Expr) (p : Name → Bool := fun _ => true) : CoreM (Option Expr) :=
|
||||
matchConst e.getAppFn (fun _ => return none) fun fInfo fLvls => do
|
||||
if p fInfo.name && fInfo.hasValue (allowOpaque := allowOpaque) && fInfo.levelParams.length == fLvls.length then
|
||||
let f ← instantiateValueLevelParams fInfo fLvls (allowOpaque := allowOpaque)
|
||||
if p fInfo.name && fInfo.hasValue && fInfo.levelParams.length == fLvls.length then
|
||||
let f ← instantiateValueLevelParams fInfo fLvls
|
||||
return some (f.betaRev e.getAppRevArgs (useZeta := true))
|
||||
else
|
||||
return none
|
||||
|
||||
/-- Low-level delta expansion. It is used to implement equation lemmas and elimination principles for recursive definitions. -/
|
||||
def deltaExpand (e : Expr) (p : Name → Bool) (allowOpaque := false) : CoreM Expr :=
|
||||
def deltaExpand (e : Expr) (p : Name → Bool) : CoreM Expr :=
|
||||
Core.transform e fun e => do
|
||||
match (← delta? e p (allowOpaque := allowOpaque)) with
|
||||
match (← delta? e p) with
|
||||
| some e' => return .visit e'
|
||||
| none => return .continue
|
||||
|
||||
|
||||
@@ -347,13 +347,11 @@ partial def foldAndCollect (oldIH newIH : FVarId) (isRecCall : Expr → Option E
|
||||
|
||||
if e.getAppArgs.any (·.isFVarOf oldIH) then
|
||||
-- Sometimes Fix.lean abstracts over oldIH in a proof definition.
|
||||
-- So delta-beta-reduce that definition. We need to look through theorems here!
|
||||
if let .const declName lvls := e.getAppFn then
|
||||
if let some cinfo := (← getEnv).find? declName then
|
||||
if let some val := cinfo.value? (allowOpaque := true) then
|
||||
let e' := (val.instantiateLevelParams cinfo.levelParams lvls).betaRev e.getAppRevArgs
|
||||
return ← foldAndCollect oldIH newIH isRecCall e'
|
||||
throwError "Internal error in `foldAndCollect`: Cannot reduce application of `{e.getAppFn}` in:{indentExpr e}"
|
||||
-- So beta-reduce that definition. We need to look through theorems here!
|
||||
if let some e' ← withTransparency .all do unfoldDefinition? e then
|
||||
return ← foldAndCollect oldIH newIH isRecCall e'
|
||||
else
|
||||
throwError "Internal error in `foldAndCollect`: Cannot reduce application of `{e.getAppFn}` in:{indentExpr e}"
|
||||
|
||||
match e with
|
||||
| .app e1 e2 =>
|
||||
@@ -744,13 +742,6 @@ partial def buildInductionBody (toErase toClear : Array FVarId) (goal : Expr)
|
||||
let b' ← buildInductionBody toErase toClear goal' oldIH newIH isRecCall (b.instantiate1 x)
|
||||
mkLambdaFVars #[x] b'
|
||||
|
||||
-- Unfold constant applications that take `oldIH` as an argument (e.g. `_f` auxiliary
|
||||
-- definitions from structural recursion), so that we can see their body structure.
|
||||
-- Similar to the case in `foldAndCollect`.
|
||||
if e.getAppFn.isConst && e.getAppArgs.any (·.isFVarOf oldIH) then
|
||||
if let some e' ← withTransparency .all (unfoldDefinition? e) then
|
||||
return ← buildInductionBody toErase toClear goal oldIH newIH isRecCall e'
|
||||
|
||||
liftM <| buildInductionCase oldIH newIH isRecCall toErase toClear goal e
|
||||
|
||||
/--
|
||||
|
||||
@@ -276,7 +276,6 @@ private def propagateNonlinearPow (x : Var) : GoalM Bool := do
|
||||
c'.assert
|
||||
return true
|
||||
|
||||
set_option compiler.ignoreBorrowAnnotation true in
|
||||
@[export lean_cutsat_propagate_nonlinear]
|
||||
def propagateNonlinearTermImpl (y : Var) (x : Var) : GoalM Bool := do
|
||||
unless (← isVarEqConst? y).isSome do return false
|
||||
@@ -339,7 +338,6 @@ partial def _root_.Int.Linear.Poly.updateOccsForElimEq (p : Poly) (x : Var) : Go
|
||||
go p
|
||||
go p
|
||||
|
||||
set_option compiler.ignoreBorrowAnnotation true in
|
||||
@[export lean_grind_cutsat_assert_eq]
|
||||
def EqCnstr.assertImpl (c : EqCnstr) : GoalM Unit := do
|
||||
if (← inconsistent) then return ()
|
||||
|
||||
@@ -99,7 +99,6 @@ where
|
||||
return some { p := c.p.addConst 1, h := .ofLeDiseq c c' }
|
||||
return none
|
||||
|
||||
set_option compiler.ignoreBorrowAnnotation true in
|
||||
@[export lean_grind_cutsat_assert_le]
|
||||
def LeCnstr.assertImpl (c : LeCnstr) : GoalM Unit := do
|
||||
if (← inconsistent) then return ()
|
||||
|
||||
@@ -325,9 +325,7 @@ private def mkPowEqProof (ka : Int) (ca? : Option EqCnstr) (kb : Nat) (cb? : Opt
|
||||
let h := mkApp8 (mkConst ``Int.Linear.pow_eq) a b (toExpr ka) (toExpr kbInt) (toExpr k) h₁ h₂ eagerReflBoolTrue
|
||||
return mkApp6 (mkConst ``Int.Linear.of_var_eq) (← getContext) (← mkVarDecl x) (toExpr k) (← mkPolyDecl c'.p) eagerReflBoolTrue h
|
||||
|
||||
set_option compiler.ignoreBorrowAnnotation true in
|
||||
mutual
|
||||
|
||||
@[export lean_cutsat_eq_cnstr_to_proof]
|
||||
private partial def EqCnstr.toExprProofImpl (c' : EqCnstr) : ProofM Expr := caching c' do
|
||||
trace[grind.debug.lia.proof] "{← c'.pp}"
|
||||
|
||||
@@ -64,7 +64,6 @@ where
|
||||
registerNonlinearOcc e x
|
||||
| _ => registerNonlinearOcc e x
|
||||
|
||||
set_option compiler.ignoreBorrowAnnotation true in
|
||||
@[export lean_grind_cutsat_mk_var]
|
||||
def mkVarImpl (expr : Expr) : GoalM Var := do
|
||||
if let some var := (← get').varMap.find? { expr } then
|
||||
|
||||
@@ -239,7 +239,6 @@ private def normOfNatArgs? (args : Array Expr) : MetaM (Option (Array Expr)) :=
|
||||
return some args.toArray
|
||||
return none
|
||||
|
||||
set_option compiler.ignoreBorrowAnnotation true in
|
||||
@[export lean_grind_canon]
|
||||
partial def canonImpl (e : Expr) : GoalM Expr := do profileitM Exception "grind canon" (← getOptions) do
|
||||
trace_goal[grind.debug.canon] "{e}"
|
||||
|
||||
@@ -348,7 +348,6 @@ where
|
||||
internalize rhs generation p
|
||||
addEqCore lhs rhs proof isHEq
|
||||
|
||||
set_option compiler.ignoreBorrowAnnotation true in
|
||||
@[export lean_grind_process_new_facts]
|
||||
private def processNewFactsImpl : GoalM Unit := do
|
||||
repeat
|
||||
|
||||
@@ -535,7 +535,6 @@ private def internalizeOfNatFinBitVecLiteral (e : Expr) (generation : Nat) (pare
|
||||
updateIndicesFound (.const ``OfNat.ofNat)
|
||||
activateTheorems ``OfNat.ofNat generation
|
||||
|
||||
set_option compiler.ignoreBorrowAnnotation true in
|
||||
@[export lean_grind_internalize]
|
||||
private partial def internalizeImpl (e : Expr) (generation : Nat) (parent? : Option Expr := none) : GoalM Unit := withIncRecDepth do
|
||||
if (← alreadyInternalized e) then
|
||||
|
||||
@@ -328,7 +328,6 @@ mutual
|
||||
|
||||
end
|
||||
|
||||
set_option compiler.ignoreBorrowAnnotation true in
|
||||
/--
|
||||
Returns a proof that `a = b`.
|
||||
It assumes `a` and `b` are in the same equivalence class.
|
||||
@@ -339,7 +338,6 @@ def mkEqProofImpl (a b : Expr) : GoalM Expr := do
|
||||
throwError "internal `grind` error, `mkEqProof` invoked with terms of different types{indentExpr a}\nhas type{indentExpr (← inferType a)}\nbut{indentExpr b}\nhas type{indentExpr (← inferType b)}"
|
||||
mkEqProofCore a b (heq := false)
|
||||
|
||||
set_option compiler.ignoreBorrowAnnotation true in
|
||||
@[export lean_grind_mk_heq_proof]
|
||||
def mkHEqProofImpl (a b : Expr) : GoalM Expr :=
|
||||
mkEqProofCore a b (heq := true)
|
||||
|
||||
@@ -42,7 +42,6 @@ def dsimpCore (e : Expr) : GrindM Expr := do profileitM Exception "grind dsimp"
|
||||
modify fun s => { s with simp }
|
||||
return r
|
||||
|
||||
set_option compiler.ignoreBorrowAnnotation true in
|
||||
/--
|
||||
Preprocesses `e` using `grind` normalization theorems and simprocs,
|
||||
and then applies several other preprocessing steps.
|
||||
|
||||
@@ -202,7 +202,6 @@ protected def getSimpContext (config : Grind.Config) : MetaM Simp.Context := do
|
||||
(simpTheorems := #[thms])
|
||||
(congrTheorems := (← getSimpCongrTheorems))
|
||||
|
||||
set_option compiler.ignoreBorrowAnnotation true in
|
||||
@[export lean_grind_normalize]
|
||||
def normalizeImp (e : Expr) (config : Grind.Config) : MetaM Expr := do
|
||||
let (r, _) ← Meta.simp e (← Grind.getSimpContext config) (← Grind.getSimprocs)
|
||||
|
||||
@@ -52,12 +52,6 @@ builtin_dsimproc [simp, seval] reduceSingleton (String.singleton _) := fun e =>
|
||||
let some c ← Char.fromExpr? e.appArg! | return .continue
|
||||
return .done <| toExpr (String.singleton c)
|
||||
|
||||
builtin_dsimproc_decl reduceToSingleton ((_ : String)) := fun e => do
|
||||
let some s ← fromExpr? e | return .continue
|
||||
let l := s.toList
|
||||
let [c] := l | return .continue
|
||||
return .done <| mkApp (mkConst ``String.singleton) (toExpr c)
|
||||
|
||||
@[inline] def reduceBinPred (declName : Name) (arity : Nat) (op : String → String → Bool) (e : Expr) : SimpM Step := do
|
||||
unless e.isAppOfArity declName arity do return .continue
|
||||
let some n ← fromExpr? e.appFn!.appArg! | return .continue
|
||||
|
||||
@@ -512,7 +512,6 @@ Auxiliary `dsimproc` for not visiting `Char` literal subterms.
|
||||
-/
|
||||
private def doNotVisitCharLit : DSimproc := doNotVisit isCharLit ``Char.ofNat
|
||||
|
||||
set_option compiler.ignoreBorrowAnnotation true in
|
||||
@[export lean_dsimp]
|
||||
private partial def dsimpImpl (e : Expr) : SimpM Expr := do
|
||||
let cfg ← getConfig
|
||||
@@ -711,7 +710,6 @@ where
|
||||
r ← r.mkEqTrans (← simpLoop r.expr)
|
||||
cacheResult e cfg r
|
||||
|
||||
set_option compiler.ignoreBorrowAnnotation true in
|
||||
@[export lean_simp]
|
||||
def simpImpl (e : Expr) : SimpM Result := withIncRecDepth do
|
||||
checkSystem "simp"
|
||||
|
||||
@@ -240,8 +240,8 @@ def unfoldDeclsFrom (biggerEnv : Environment) (e : Expr) : CoreM Expr := do
|
||||
if env.contains declName then
|
||||
return .done e
|
||||
let some info := biggerEnv.find? declName | return .done e
|
||||
if info.hasValue (allowOpaque := true) then
|
||||
return .visit (← instantiateValueLevelParams info us (allowOpaque := true))
|
||||
if info.hasValue then
|
||||
return .visit (← instantiateValueLevelParams info us)
|
||||
else
|
||||
return .done e
|
||||
Core.transform e (pre := pre)
|
||||
@@ -282,7 +282,7 @@ def unfoldIfArgIsAppOf (fnNames : Array Name) (numSectionVars : Nat) (e : Expr)
|
||||
-/
|
||||
if revArgs.any isInterestingArg then
|
||||
if let some info@(.thmInfo _) := env.find? f.constName! then
|
||||
return .visit <| (← instantiateValueLevelParams info f.constLevels! (allowOpaque := true)).betaRev revArgs
|
||||
return .visit <| (← instantiateValueLevelParams info f.constLevels!).betaRev revArgs
|
||||
return .continue)
|
||||
where
|
||||
isInterestingArg (a : Expr) : Bool := a.withApp fun af axs =>
|
||||
|
||||
@@ -1100,7 +1100,6 @@ private def cache (useCache : Bool) (e r : Expr) : MetaM Expr := do
|
||||
modify fun s => { s with cache.whnf := s.cache.whnf.insert key r }
|
||||
return r
|
||||
|
||||
set_option compiler.ignoreBorrowAnnotation true in
|
||||
@[export lean_whnf]
|
||||
partial def whnfImp (e : Expr) : MetaM Expr :=
|
||||
withIncRecDepth <| whnfEasyCases e fun e => do
|
||||
|
||||
@@ -65,7 +65,6 @@ end Parser
|
||||
namespace PrettyPrinter
|
||||
namespace Parenthesizer
|
||||
|
||||
set_option compiler.ignoreBorrowAnnotation true in
|
||||
-- Close the mutual recursion loop; see corresponding `[extern]` in the parenthesizer.
|
||||
@[export lean_mk_antiquot_parenthesizer]
|
||||
def mkAntiquot.parenthesizer (name : String) (kind : SyntaxNodeKind) (anonymous := true) (isPseudoKind := true) : Parenthesizer :=
|
||||
@@ -81,7 +80,6 @@ def mkAntiquot.parenthesizer (name : String) (kind : SyntaxNodeKind) (anonymous
|
||||
|
||||
open Lean.Parser
|
||||
|
||||
set_option compiler.ignoreBorrowAnnotation true in
|
||||
@[export lean_pretty_printer_parenthesizer_interpret_parser_descr]
|
||||
unsafe def interpretParserDescr : ParserDescr → CoreM Parenthesizer
|
||||
| ParserDescr.const n => getConstAlias parenthesizerAliasesRef n
|
||||
@@ -103,7 +101,6 @@ end Parenthesizer
|
||||
|
||||
namespace Formatter
|
||||
|
||||
set_option compiler.ignoreBorrowAnnotation true in
|
||||
@[export lean_mk_antiquot_formatter]
|
||||
def mkAntiquot.formatter (name : String) (kind : SyntaxNodeKind) (anonymous := true) (isPseudoKind := true) : Formatter :=
|
||||
Parser.mkAntiquot.formatter name kind anonymous isPseudoKind
|
||||
@@ -116,7 +113,6 @@ def mkAntiquot.formatter (name : String) (kind : SyntaxNodeKind) (anonymous := t
|
||||
|
||||
open Lean.Parser
|
||||
|
||||
set_option compiler.ignoreBorrowAnnotation true in
|
||||
@[export lean_pretty_printer_formatter_interpret_parser_descr]
|
||||
unsafe def interpretParserDescr : ParserDescr → CoreM Formatter
|
||||
| ParserDescr.const n => getConstAlias formatterAliasesRef n
|
||||
|
||||
@@ -64,10 +64,11 @@ namespace ConstantInfo
|
||||
|
||||
/-- Return all names appearing in the type or value of a `ConstantInfo`. -/
|
||||
def getUsedConstantsAsSet (c : ConstantInfo) : NameSet :=
|
||||
c.type.getUsedConstantsAsSet ++ match c.value? (allowOpaque := true) with
|
||||
c.type.getUsedConstantsAsSet ++ match c.value? with
|
||||
| some v => v.getUsedConstantsAsSet
|
||||
| none => match c with
|
||||
| .inductInfo val => .ofList val.ctors
|
||||
| .opaqueInfo val => val.value.getUsedConstantsAsSet
|
||||
| .ctorInfo val => ({} : NameSet).insert val.name
|
||||
| .recInfo val => .ofList val.all
|
||||
| _ => {}
|
||||
|
||||
@@ -98,34 +98,18 @@ end Slice
|
||||
public theorem isInt_toSlice {s : String} : s.toSlice.isInt = s.isInt :=
|
||||
(rfl)
|
||||
|
||||
@[simp]
|
||||
public theorem isInt_comp_toSlice : String.Slice.isInt ∘ String.toSlice = String.isInt := by
|
||||
ext; simp
|
||||
|
||||
@[simp]
|
||||
public theorem toInt?_toSlice {s : String} : s.toSlice.toInt? = s.toInt? :=
|
||||
(rfl)
|
||||
|
||||
@[simp]
|
||||
public theorem toInt?_comp_toSlice : String.Slice.toInt? ∘ String.toSlice = String.toInt? := by
|
||||
ext; simp
|
||||
|
||||
@[simp]
|
||||
public theorem Slice.isInt_copy {s : Slice} : s.copy.isInt = s.isInt := by
|
||||
simpa [← isInt_toSlice] using Slice.isInt_congr (by simp)
|
||||
|
||||
@[simp]
|
||||
public theorem Slice.isInt_comp_copy : String.isInt ∘ String.Slice.copy = String.Slice.isInt := by
|
||||
ext; simp
|
||||
|
||||
@[simp]
|
||||
public theorem Slice.toInt?_copy {s : Slice} : s.copy.toInt? = s.toInt? := by
|
||||
simpa [← isInt_toSlice] using Slice.toInt?_congr (by simp)
|
||||
|
||||
@[simp]
|
||||
public theorem Slice.toInt?_comp_copy : String.toInt? ∘ String.Slice.copy = String.Slice.toInt? := by
|
||||
ext; simp
|
||||
|
||||
public theorem toInt?_eq_some_iff {s : String} {a : Int} :
|
||||
s.toInt? = some a ↔ (∃ b, s.toNat? = some b ∧ a = (b : Int)) ∨ ∃ t, s = "-" ++ t ∧ ∃ b, t.toNat? = some b ∧ a = -(b : Int) := by
|
||||
simp [← toInt?_toSlice, Slice.toInt?_eq_some_iff]
|
||||
|
||||
@@ -221,34 +221,18 @@ namespace String
|
||||
public theorem isNat_toSlice {s : String} : s.toSlice.isNat = s.isNat :=
|
||||
(rfl)
|
||||
|
||||
@[simp]
|
||||
public theorem isNat_comp_toSlice : String.Slice.isNat ∘ String.toSlice = String.isNat := by
|
||||
ext; simp
|
||||
|
||||
@[simp]
|
||||
public theorem toNat?_toSlice {s : String} : s.toSlice.toNat? = s.toNat? :=
|
||||
(rfl)
|
||||
|
||||
@[simp]
|
||||
public theorem toNat?_comp_toSlice : String.Slice.toNat? ∘ String.toSlice = String.toNat? := by
|
||||
ext; simp
|
||||
|
||||
@[simp]
|
||||
public theorem Slice.isNat_copy {s : Slice} : s.copy.isNat = s.isNat := by
|
||||
simpa [← isNat_toSlice] using Slice.isNat_congr (by simp)
|
||||
|
||||
@[simp]
|
||||
public theorem Slice.isNat_comp_copy : String.isNat ∘ String.Slice.copy = String.Slice.isNat := by
|
||||
ext; simp
|
||||
|
||||
@[simp]
|
||||
public theorem Slice.toNat?_copy {s : Slice} : s.copy.toNat? = s.toNat? := by
|
||||
simpa [← isNat_toSlice] using Slice.toNat?_congr (by simp)
|
||||
|
||||
@[simp]
|
||||
public theorem Slice.toNat?_comp_copy : String.toNat? ∘ String.Slice.copy = String.Slice.toNat? := by
|
||||
ext; simp
|
||||
|
||||
public theorem isNat_iff {s : String} :
|
||||
s.isNat = true ↔
|
||||
s ≠ "" ∧
|
||||
|
||||
@@ -224,10 +224,7 @@ public:
|
||||
bool is_mutual() const { return kind() == declaration_kind::MutualDefinition; }
|
||||
bool is_inductive() const { return kind() == declaration_kind::Inductive; }
|
||||
bool is_unsafe() const;
|
||||
/** \brief Only definitions have values for the purpose of reduction and
|
||||
type checking. Theorems used to be like that; now they are treated like
|
||||
opaque declations. */
|
||||
bool has_value() const { return is_definition(); }
|
||||
bool has_value() const { return is_theorem() || is_definition(); }
|
||||
|
||||
axiom_val const & to_axiom_val() const { lean_assert(is_axiom()); return static_cast<axiom_val const &>(cnstr_get_ref(raw(), 0)); }
|
||||
definition_val const & to_definition_val() const { lean_assert(is_definition()); return static_cast<definition_val const &>(cnstr_get_ref(raw(), 0)); }
|
||||
|
||||
@@ -111,18 +111,6 @@ public def Package.loadFromEnv
|
||||
but then redefined as a '{decl.kind}'"
|
||||
else
|
||||
return m.insert decl.name (.mk decl rfl)
|
||||
-- Check that executables have distinct root module names
|
||||
let _ ← targetDecls.foldlM (init := ({} : Lean.NameMap Name)) fun exeRoots decl => do
|
||||
if let some exeConfig := decl.config? LeanExe.configKind then
|
||||
let root := exeConfig.root
|
||||
if let some origExe := exeRoots.get? root then
|
||||
error s!"\
|
||||
{self.prettyName}: executable '{decl.name}' has the same root module '{root}' \
|
||||
as executable '{origExe}'"
|
||||
else
|
||||
return exeRoots.insert root decl.name
|
||||
else
|
||||
return exeRoots
|
||||
let defaultTargets ← defaultTargetAttr.getAllEntries env |>.mapM fun name =>
|
||||
if let some decl := constTargetMap.find? name then pure decl.name else
|
||||
error s!"{self.prettyName}: package is missing target '{name}' marked as a default"
|
||||
|
||||
@@ -415,57 +415,35 @@ local macro "gen_toml_decoders%" : command => do
|
||||
|
||||
gen_toml_decoders%
|
||||
|
||||
private structure DecodeTargetState (pkg : Name) where
|
||||
decls : Array (PConfigDecl pkg) := #[]
|
||||
map : DNameMap (NConfigDecl pkg) := {}
|
||||
exeRoots : Lean.NameMap Name := {}
|
||||
|
||||
private def decodeTargetDecls
|
||||
(pkg : Name) (prettyName : String) (t : Table)
|
||||
(pkg : Name) (t : Table)
|
||||
: DecodeM (Array (PConfigDecl pkg) × DNameMap (NConfigDecl pkg)) := do
|
||||
let r : DecodeTargetState pkg := {}
|
||||
let r := (#[], {})
|
||||
let r ← go r LeanLib.keyword LeanLib.configKind LeanLibConfig.decodeToml
|
||||
let r ← go r LeanExe.keyword LeanExe.configKind LeanExeConfig.decodeToml
|
||||
let r ← go r InputFile.keyword InputFile.configKind InputFileConfig.decodeToml
|
||||
let r ← go r InputDir.keyword InputDir.configKind InputDirConfig.decodeToml
|
||||
return (r.decls, r.map)
|
||||
return r
|
||||
where
|
||||
go (r : DecodeTargetState pkg) kw kind
|
||||
(decode : {n : Name} → Table → DecodeM (ConfigType kind pkg n)) := do
|
||||
go r kw kind (decode : {n : Name} → Table → DecodeM (ConfigType kind pkg n)) := do
|
||||
let some tableArrayVal := t.find? kw | return r
|
||||
let some vals ← tryDecode? tableArrayVal.decodeValueArray | return r
|
||||
vals.foldlM (init := r) fun r val => do
|
||||
let some t ← tryDecode? val.decodeTable | return r
|
||||
let some name ← tryDecode? <| stringToLegalOrSimpleName <$> t.decode `name
|
||||
| return r
|
||||
if let some orig := r.map.get? name then
|
||||
logDecodeErrorAt val.ref s!"{prettyName}: \
|
||||
target '{name}' was already defined as a '{orig.kind}', \
|
||||
let (decls, map) := r
|
||||
if let some orig := map.get? name then
|
||||
modify fun es => es.push <| .mk val.ref s!"\
|
||||
{pkg}: target '{name}' was already defined as a '{orig.kind}', \
|
||||
but then redefined as a '{kind}'"
|
||||
return r
|
||||
return (decls, map)
|
||||
else
|
||||
let config ← @decode name t
|
||||
let decl : NConfigDecl pkg name :=
|
||||
-- Safety: By definition, config kind = facet kind for declarative configurations.
|
||||
unsafe {pkg, name, kind, config, wf_data := lcProof}
|
||||
-- Check that executables have distinct root module names
|
||||
let exeRoots ← id do
|
||||
if h : kind = LeanExe.configKind then
|
||||
let exeConfig : LeanExeConfig name := cast (by rw [h]; rfl) config
|
||||
if let some origExe := r.exeRoots.get? exeConfig.root then
|
||||
logDecodeErrorAt val.ref s!"{prettyName}: \
|
||||
executable '{name}' has the same root module '{exeConfig.root}' as \
|
||||
executable '{origExe}'"
|
||||
return r.exeRoots
|
||||
else
|
||||
return r.exeRoots.insert exeConfig.root name
|
||||
else
|
||||
return r.exeRoots
|
||||
return {
|
||||
decls := r.decls.push decl.toPConfigDecl
|
||||
map := r.map.insert name decl
|
||||
exeRoots
|
||||
}
|
||||
return (decls.push decl.toPConfigDecl, map.insert name decl)
|
||||
|
||||
/-! ## Root Loader -/
|
||||
|
||||
@@ -480,9 +458,8 @@ public def loadTomlConfig (cfg: LoadConfig) : LogIO Package := do
|
||||
let wsIdx := cfg.pkgIdx
|
||||
let baseName := if cfg.pkgName.isAnonymous then origName else cfg.pkgName
|
||||
let keyName := baseName.num wsIdx
|
||||
let prettyName := baseName.toString (escape := false)
|
||||
let config ← @PackageConfig.decodeToml keyName origName table
|
||||
let (targetDecls, targetDeclMap) ← decodeTargetDecls keyName prettyName table
|
||||
let (targetDecls, targetDeclMap) ← decodeTargetDecls keyName table
|
||||
let defaultTargets ← table.tryDecodeD `defaultTargets #[]
|
||||
let defaultTargets := defaultTargets.map stringToLegalOrSimpleName
|
||||
let depConfigs ← table.tryDecodeD `require #[]
|
||||
|
||||
@@ -96,9 +96,6 @@ public def mergeErrors (x₁ : EDecodeM α) (x₂ : EDecodeM β) (f : α → β
|
||||
| .error _ es => .error () es
|
||||
| .error _ es => .error () es
|
||||
|
||||
@[inline] public def logDecodeErrorAt (ref : Syntax) (msg : String) : DecodeM Unit :=
|
||||
fun es => .ok () (es.push {ref, msg})
|
||||
|
||||
@[inline] public def throwDecodeErrorAt (ref : Syntax) (msg : String) : EDecodeM α :=
|
||||
fun es => .error () (es.push {ref, msg})
|
||||
|
||||
|
||||
BIN
stage0/src/kernel/declaration.h
generated
BIN
stage0/src/kernel/declaration.h
generated
Binary file not shown.
BIN
stage0/stdlib/Init/Control/Id.c
generated
BIN
stage0/stdlib/Init/Control/Id.c
generated
Binary file not shown.
BIN
stage0/stdlib/Init/Control/Reader.c
generated
BIN
stage0/stdlib/Init/Control/Reader.c
generated
Binary file not shown.
BIN
stage0/stdlib/Init/Control/StateRef.c
generated
BIN
stage0/stdlib/Init/Control/StateRef.c
generated
Binary file not shown.
BIN
stage0/stdlib/Init/Core.c
generated
BIN
stage0/stdlib/Init/Core.c
generated
Binary file not shown.
BIN
stage0/stdlib/Init/Data/BitVec/Bitblast.c
generated
BIN
stage0/stdlib/Init/Data/BitVec/Bitblast.c
generated
Binary file not shown.
BIN
stage0/stdlib/Init/Data/Float.c
generated
BIN
stage0/stdlib/Init/Data/Float.c
generated
Binary file not shown.
BIN
stage0/stdlib/Init/Data/Float32.c
generated
BIN
stage0/stdlib/Init/Data/Float32.c
generated
Binary file not shown.
Binary file not shown.
BIN
stage0/stdlib/Init/Data/Option/Instances.c
generated
BIN
stage0/stdlib/Init/Data/Option/Instances.c
generated
Binary file not shown.
BIN
stage0/stdlib/Init/Data/Ord/Basic.c
generated
BIN
stage0/stdlib/Init/Data/Ord/Basic.c
generated
Binary file not shown.
BIN
stage0/stdlib/Init/Data/Rat/Basic.c
generated
BIN
stage0/stdlib/Init/Data/Rat/Basic.c
generated
Binary file not shown.
BIN
stage0/stdlib/Init/Data/Repr.c
generated
BIN
stage0/stdlib/Init/Data/Repr.c
generated
Binary file not shown.
BIN
stage0/stdlib/Init/Data/SInt/Basic.c
generated
BIN
stage0/stdlib/Init/Data/SInt/Basic.c
generated
Binary file not shown.
BIN
stage0/stdlib/Init/Data/String/Basic.c
generated
BIN
stage0/stdlib/Init/Data/String/Basic.c
generated
Binary file not shown.
BIN
stage0/stdlib/Init/Data/String/Decode.c
generated
BIN
stage0/stdlib/Init/Data/String/Decode.c
generated
Binary file not shown.
BIN
stage0/stdlib/Init/Data/String/Defs.c
generated
BIN
stage0/stdlib/Init/Data/String/Defs.c
generated
Binary file not shown.
BIN
stage0/stdlib/Init/Data/String/Iter.c
generated
BIN
stage0/stdlib/Init/Data/String/Iter.c
generated
Binary file not shown.
BIN
stage0/stdlib/Init/Data/String/Iter/Basic.c
generated
BIN
stage0/stdlib/Init/Data/String/Iter/Basic.c
generated
Binary file not shown.
BIN
stage0/stdlib/Init/Data/String/Iter/Intercalate.c
generated
BIN
stage0/stdlib/Init/Data/String/Iter/Intercalate.c
generated
Binary file not shown.
BIN
stage0/stdlib/Init/Data/String/Iterate.c
generated
BIN
stage0/stdlib/Init/Data/String/Iterate.c
generated
Binary file not shown.
BIN
stage0/stdlib/Init/Data/String/Iterator.c
generated
BIN
stage0/stdlib/Init/Data/String/Iterator.c
generated
Binary file not shown.
BIN
stage0/stdlib/Init/Data/String/Lemmas.c
generated
BIN
stage0/stdlib/Init/Data/String/Lemmas.c
generated
Binary file not shown.
BIN
stage0/stdlib/Init/Data/String/Lemmas/Hashable.c
generated
BIN
stage0/stdlib/Init/Data/String/Lemmas/Hashable.c
generated
Binary file not shown.
BIN
stage0/stdlib/Init/Data/String/Lemmas/Intercalate.c
generated
BIN
stage0/stdlib/Init/Data/String/Lemmas/Intercalate.c
generated
Binary file not shown.
BIN
stage0/stdlib/Init/Data/String/Lemmas/Iter.c
generated
BIN
stage0/stdlib/Init/Data/String/Lemmas/Iter.c
generated
Binary file not shown.
Binary file not shown.
BIN
stage0/stdlib/Init/Data/String/Pattern/Basic.c
generated
BIN
stage0/stdlib/Init/Data/String/Pattern/Basic.c
generated
Binary file not shown.
BIN
stage0/stdlib/Init/Data/String/Pattern/String.c
generated
BIN
stage0/stdlib/Init/Data/String/Pattern/String.c
generated
Binary file not shown.
BIN
stage0/stdlib/Init/Data/String/PosRaw.c
generated
BIN
stage0/stdlib/Init/Data/String/PosRaw.c
generated
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user