doc: further missing docstrings (#7613)

This PR adds a variety of docstrings for names that appear in the
manual.
This commit is contained in:
David Thrane Christiansen 2025-03-21 23:20:07 +01:00 committed by GitHub
parent 385c6db4ce
commit b768e44ba7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 172 additions and 7 deletions

View file

@ -135,6 +135,13 @@ instance : ToBool Bool where
| true => t
| false => f
/--
Converts the result of the monadic action `x` to a `Bool`. If it is `true`, returns it and ignores
`y`; otherwise, runs `y` and returns its result.
This a monadic counterpart to the short-circuiting `||` operator, usually accessed via the `<||>`
operator.
-/
@[macro_inline] def orM {m : Type u → Type v} {β : Type u} [Monad m] [ToBool β] (x y : m β) : m β := do
let b ← x
match toBool b with
@ -145,6 +152,13 @@ infixr:30 " <||> " => orM
recommended_spelling "orM" for "<||>" in [orM, «term_<||>_»]
/--
Converts the result of the monadic action `x` to a `Bool`. If it is `true`, returns `y`; otherwise,
returns the original result of `x`.
This a monadic counterpart to the short-circuiting `&&` operator, usually accessed via the `<&&>`
operator.
-/
@[macro_inline] def andM {m : Type u → Type v} {β : Type u} [Monad m] [ToBool β] (x y : m β) : m β := do
let b ← x
match toBool b with
@ -155,6 +169,9 @@ infixr:35 " <&&> " => andM
recommended_spelling "andM" for "<&&>" in [andM, «term_<&&>_»]
/--
Runs a monadic action and returns the negation of its result.
-/
@[macro_inline] def notM {m : Type → Type v} [Applicative m] (x : m Bool) : m Bool :=
not <$> x

View file

@ -265,13 +265,24 @@ instance (ε : Type u) (m : Type u → Type v) [Monad m] : MonadControl m (Excep
liftWith f := liftM <| f fun x => x.run
restoreM x := x
/--
Monads that provide the ability to ensure an action happens, regardless of exceptions or other
failures.
`MonadFinally.tryFinally'` is used to desugar `try ... finally ...` syntax.
-/
class MonadFinally (m : Type u → Type v) where
/-- `tryFinally' x f` runs `x` and then the "finally" computation `f`.
When `x` succeeds with `a : α`, `f (some a)` is returned. If `x` fails
for `m`'s definition of failure, `f none` is returned. Hence `tryFinally'`
can be thought of as performing the same role as a `finally` block in
an imperative programming language. -/
tryFinally' {α β} : m α → (Option α → m β) → m (α × β)
/--
Runs an action, ensuring that some other action always happens afterward.
More specifically, `tryFinally' x f` runs `x` and then the “finally” computation `f`. If `x`
succeeds with some value `a : α`, `f (some a)` is returned. If `x` fails for `m`'s definition of
failure, `f none` is returned.
`tryFinally'` can be thought of as performing the same role as a `finally` block in an imperative
programming language.
-/
tryFinally' {α β} : (x : m α) → (f : Option α → m β) → m (α × β)
export MonadFinally (tryFinally')

View file

@ -865,37 +865,55 @@ noncomputable def HEq.ndrecOn.{u1, u2} {α : Sort u2} {a : α} {motive : {β : S
noncomputable def HEq.elim {α : Sort u} {a : α} {p : α → Sort v} {b : α} (h₁ : HEq a b) (h₂ : p a) : p b :=
eq_of_heq h₁ ▸ h₂
/-- Substitution with heterogeneous equality. -/
theorem HEq.subst {p : (T : Sort u) → T → Prop} (h₁ : HEq a b) (h₂ : p α a) : p β b :=
HEq.ndrecOn h₁ h₂
/-- Heterogeneous equality is symmetric. -/
@[symm] theorem HEq.symm (h : HEq a b) : HEq b a :=
h.rec (HEq.refl a)
/-- Propositionally equal terms are also heterogeneously equal. -/
theorem heq_of_eq (h : a = a') : HEq a a' :=
Eq.subst h (HEq.refl a)
/-- Heterogeneous equality is transitive. -/
theorem HEq.trans (h₁ : HEq a b) (h₂ : HEq b c) : HEq a c :=
HEq.subst h₂ h₁
/-- Heterogeneous equality precomposes with propositional equality. -/
theorem heq_of_heq_of_eq (h₁ : HEq a b) (h₂ : b = b') : HEq a b' :=
HEq.trans h₁ (heq_of_eq h₂)
/-- Heterogeneous equality postcomposes with propositional equality. -/
theorem heq_of_eq_of_heq (h₁ : a = a') (h₂ : HEq a' b) : HEq a b :=
HEq.trans (heq_of_eq h₁) h₂
/-- If two terms are heterogeneously equal then their types are propositionally equal. -/
theorem type_eq_of_heq (h : HEq a b) : α = β :=
h.rec (Eq.refl α)
end
/--
Rewriting inside `φ` using `Eq.recOn` yields a term that's heterogeneously equal to the original
term.
-/
theorem eqRec_heq {α : Sort u} {φ : α → Sort v} {a a' : α} : (h : a = a') → (p : φ a) → HEq (Eq.recOn (motive := fun x _ => φ x) h p) p
| rfl, p => HEq.refl p
/--
If casting a term with `Eq.rec` to another type makes it equal to some other term, then the two
terms are heterogeneously equal.
-/
theorem heq_of_eqRec_eq {α β : Sort u} {a : α} {b : β} (h₁ : α = β) (h₂ : Eq.rec (motive := fun α _ => α) a h₁ = b) : HEq a b := by
subst h₁
apply heq_of_eq
exact h₂
/--
The result of casting a term with `cast` is heterogeneously equal to the original term.
-/
theorem cast_heq {α β : Sort u} : (h : α = β) → (a : α) → HEq (cast h a) a
| rfl, a => HEq.refl a

View file

@ -748,7 +748,10 @@ def mapM {α : Type u} {β : Type v} {m : Type v → Type w} [Monad m] (f : α
@[deprecated mapM (since := "2024-11-11")] abbrev sequenceMap := @mapM
/-- Variant of `mapIdxM` which receives the index `i` along with the bound `i < as.size`. -/
/--
Applies the monadic action `f` to every element in the array, along with the element's index and a
proof that the index is in bounds, from left to right. Returns the array of results.
-/
@[inline]
def mapFinIdxM {α : Type u} {β : Type v} {m : Type v → Type w} [Monad m]
(as : Array α) (f : (i : Nat) → α → (h : i < as.size) → m β) : m (Array β) :=
@ -763,6 +766,10 @@ def mapFinIdxM {α : Type u} {β : Type v} {m : Type v → Type w} [Monad m]
map i (j+1) this (bs.push (← f j as[j] j_lt))
map as.size 0 rfl (emptyWithCapacity as.size)
/--
Applies the monadic action `f` to every element in the array, along with the element's index, from
left to right. Returns the array of results.
-/
@[inline]
def mapIdxM {α : Type u} {β : Type v} {m : Type v → Type w} [Monad m] (f : Nat → α → m β) (as : Array α) : m (Array β) :=
as.mapFinIdxM fun i a _ => f i a

View file

@ -7,6 +7,7 @@ prelude
import Init.Data.Array.Basic
set_option linter.indexVariables true -- Enforce naming conventions for index variables.
set_option linter.missingDocs true
universe u v w
@ -25,7 +26,18 @@ structure Subarray (α : Type u) where
start : Nat
/-- The ending index of the region of interest (exclusive). -/
stop : Nat
/--
The starting index is no later than the ending index.
The ending index is exclusive. If the starting and ending indices are equal, then the subarray is
empty.
-/
start_le_stop : start ≤ stop
/-- The stopping index is no later than the end of the array.
The ending index is exclusive. If it is equal to the size of the array, then the last element of
the array is in the subarray.
-/
stop_le_array_size : stop ≤ array.size
namespace Subarray
@ -110,6 +122,12 @@ instance : EmptyCollection (Subarray α) :=
instance : Inhabited (Subarray α) :=
⟨{}⟩
/--
The run-time implementation of `ForIn.forIn` for `Subarray`, which allows it to be used with `for`
loops in `do`-notation.
This definition replaces `Subarray.forIn`.
-/
@[inline] unsafe def forInUnsafe {α : Type u} {β : Type v} {m : Type v → Type w} [Monad m] (s : Subarray α) (b : β) (f : α → β → m (ForInStep β)) : m β :=
let sz := USize.ofNat s.stop
let rec @[specialize] loop (i : USize) (b : β) : m β := do
@ -122,6 +140,10 @@ instance : Inhabited (Subarray α) :=
pure b
loop (USize.ofNat s.start) b
/--
The implementation of `ForIn.forIn` for `Subarray`, which allows it to be used with `for` loops in
`do`-notation.
-/
-- TODO: provide reference implementation
@[implemented_by Subarray.forInUnsafe]
protected opaque forIn {α : Type u} {β : Type v} {m : Type v → Type w} [Monad m] (s : Subarray α) (b : β) (f : α → β → m (ForInStep β)) : m β :=

View file

@ -17,6 +17,16 @@ import Init.Data.Nat.Log2
Note the use of `nat_lit`; there is no wrapping `OfNat.ofNat` in the resulting term.
-/
class OfScientific (α : Type u) where
/--
Produces a value from the given mantissa, exponent sign, and decimal exponent. For the exponent
sign, `true` indicates a negative exponent.
Examples:
- `1.23` is syntax for `OfScientific.ofScientific (nat_lit 123) true (nat_lit 2)`
- `121e100` is syntax for `OfScientific.ofScientific (nat_lit 121) false (nat_lit 100)`
Note the use of `nat_lit`; there is no wrapping `OfNat.ofNat` in the resulting term.
-/
ofScientific (mantissa : Nat) (exponentSign : Bool) (decimalExponent : Nat) : α
/-- Computes `m * 2^e`. -/

View file

@ -34,11 +34,15 @@ structure StdGen where
instance : Inhabited StdGen := ⟨{ s1 := 0, s2 := 0 }⟩
/-- The range of values returned by `StdGen` -/
def stdRange := (1, 2147483562)
instance : Repr StdGen where
reprPrec | ⟨s1, s2⟩, _ => Std.Format.bracket "⟨" (repr s1 ++ ", " ++ repr s2) "⟩"
/--
The next value from a `StdGen`, paired with an updated generator state.
-/
def stdNext : StdGen → Nat × StdGen
| ⟨s1, s2⟩ =>
let k : Int := Int.ofNat (s1 / 53668)
@ -51,6 +55,9 @@ def stdNext : StdGen → Nat × StdGen
let z' : Nat := if z < 1 then (z + 2147483562).toNat else z.toNat % 2147483562
(z', ⟨s1'', s2''⟩)
/--
Splits a `StdGen` into two separate states.
-/
def stdSplit : StdGen → StdGen × StdGen
| g@⟨s1, s2⟩ =>
let newS1 := if s1 = 2147483562 then 1 else s1 + 1

View file

@ -135,13 +135,21 @@ theorem getElem_congr_idx [GetElem coll idx elem valid] {c : coll} {i j : idx} {
(h' : i = j) : c[i] = c[j]'(h' ▸ w) := by
cases h'; rfl
/--
Lawful `GetElem?` instances (which extend `GetElem`) are those for which the potentially-failing
`GetElem?.getElem?` and `GetElem?.getElem!` operators succeed when the validity predicate is
satisfied, and fail when it is not.
-/
class LawfulGetElem (cont : Type u) (idx : Type v) (elem : outParam (Type w))
(dom : outParam (cont → idx → Prop)) [ge : GetElem? cont idx elem dom] : Prop where
/-- `GetElem?.getElem?` succeeds when the validity predicate is satisfied and fails otherwise. -/
getElem?_def (c : cont) (i : idx) [Decidable (dom c i)] :
c[i]? = if h : dom c i then some (c[i]'h) else none := by
intros
try simp only [getElem?] <;> congr
/-- `GetElem?.getElem!` succeeds and fails when `GetElem.getElem?` succeeds and fails. -/
getElem!_def [Inhabited elem] (c : cont) (i : idx) :
c[i]! = match c[i]? with | some e => e | none => default := by
intros

View file

@ -483,6 +483,7 @@ inductive HEq : {α : Sort u} → α → {β : Sort u} → β → Prop where
@[match_pattern] protected def HEq.rfl {α : Sort u} {a : α} : HEq a a :=
HEq.refl a
/-- If two heterogeneously equal terms have the same type, then they are propositionally equal. -/
theorem eq_of_heq {α : Sort u} {a a' : α} (h : HEq a a') : Eq a a' :=
have : (α β : Sort u) → (a : α) → (b : β) → HEq a b → (h : Eq α β) → Eq (cast h a) b :=
fun _ _ _ _ h₁ =>

View file

@ -1573,6 +1573,10 @@ end CancelToken
namespace FS
namespace Stream
/--
Creates a Lean stream from a file handle. Each stream operation is implemented by the corresponding
file handle operation.
-/
@[export lean_stream_of_handle]
def ofHandle (h : Handle) : Stream where
flush := Handle.flush h

View file

@ -122,6 +122,9 @@ end Prim
section
variable {σ : Type} {m : Type → Type} [Monad m] [MonadLiftT (ST σ) m]
/--
Creates a new mutable reference that contains the provided value `a`.
-/
@[inline] def mkRef {α : Type} (a : α) : m (Ref σ α) := liftM <| Prim.mkRef a
/--
Reads the value of a mutable reference.

View file

@ -52,10 +52,22 @@ a well founded relation, then the function terminates.
Well-founded relations are sometimes called _Artinian_ or said to satisfy the “descending chain condition”.
-/
inductive WellFounded {α : Sort u} (r : αα → Prop) : Prop where
/--
If all elements are accessible via `r`, then `r` is well-founded.
-/
| intro (h : ∀ a, Acc r a) : WellFounded r
/--
A type that has a standard well-founded relation.
Instances are used to prove that functions terminate using well-founded recursion by showing that
recursive calls reduce some measure according to a well-founded relation. This relation can combine
well-founded relations on the recursive function's parameters.
-/
class WellFoundedRelation (α : Sort u) where
/-- A well-founded relation on `α`. -/
rel : αα → Prop
/-- A proof that `rel` is, in fact, well-founded. -/
wf : WellFounded rel
namespace WellFounded
@ -88,6 +100,13 @@ end
variable {α : Sort u} {C : α → Sort v} {r : αα → Prop}
/--
A well-founded fixpoint. If satisfying the motive `C` for all values that are smaller according to a
well-founded relation allows it to be satisfied for the current value, then it is satisfied for all
values.
This function is used as part of the elaboration of well-founded recursion.
-/
-- Well-founded fixpoint
noncomputable def fix (hwf : WellFounded r) (F : ∀ x, (∀ y, r y x → C y) → C x) (x : α) : C x :=
fixF F x (apply hwf x)
@ -145,6 +164,9 @@ theorem wf (f : α → β) (h : WellFounded r) : WellFounded (InvImage r f) :=
⟨fun a => accessible f (apply h (f a))⟩
end InvImage
/--
The inverse image of a well-founded relation is well-founded.
-/
@[reducible] def invImage (f : α → β) (h : WellFoundedRelation β) : WellFoundedRelation α where
rel := InvImage h.rel f
wf := InvImage.wf f h.wf

View file

@ -35,7 +35,19 @@ structure Context where
-/
recover : Bool := true
/--
The tactic monad, which extends the term elaboration monad `TermElabM` with state that contains the
current goals (`Lean.Elab.Tactic.State`, accessible via `MonadStateOf`) and local information about
the current tactic's name and whether error recovery is enabled (`Lean.Elab.Tactic.Context`,
accessible via `MonadReaderOf`).
-/
abbrev TacticM := ReaderT Context $ StateRefT State TermElabM
/--
A tactic is a function from syntax to an action in the tactic monad.
A given tactic syntax kind may have multiple `Tactic`s associated with it, all of which will be
attempted until one succeeds.
-/
abbrev Tactic := Syntax → TacticM Unit
/-

View file

@ -56,6 +56,16 @@ def mkSimpAttr (attrName : Name) (attrDescr : String) (ext : SimpExtension)
modifyEnv fun env => ext.modifyState env fun _ => s
}
/--
Registers the given name as a custom simp set. Applying the name as an attribute to a name adds it
to the simp set, and using the name as a parameter to the `simp` tactic causes `simp` to use the
included lemmas.
Custom simp sets must be registered during [initialization](lean-manual://section/initialization).
The description should be a short, singular noun phrase that describes the contents of the custom
simp set.
-/
def registerSimpAttr (attrName : Name) (attrDescr : String)
(ref : Name := by exact decl_name%) : IO SimpExtension := do
let ext ← mkSimpExt ref

View file

@ -192,6 +192,9 @@ instance : BEq SimpTheorem where
abbrev SimpTheoremTree := DiscrTree SimpTheorem
/--
The theorems in a simp set.
-/
structure SimpTheorems where
pre : SimpTheoremTree := DiscrTree.empty
post : SimpTheoremTree := DiscrTree.empty
@ -423,6 +426,12 @@ inductive SimpEntry where
| toUnfoldThms : Name → Array Name → SimpEntry
deriving Inhabited
/--
The environment extension that contains a simp set, returned by `Lean.Meta.registerSimpAttr`.
Use the simp set's attribute or `Lean.Meta.addSimpTheorem` to add theorems to the simp set. Use
`Lean.Meta.SimpExtension.getTheorems` to get the contents.
-/
abbrev SimpExtension := SimpleScopedEnvExtension SimpEntry SimpTheorems
def SimpExtension.getTheorems (ext : SimpExtension) : CoreM SimpTheorems :=

View file

@ -28,6 +28,7 @@ abbrev LakeEnvT := ReaderT Lake.Env
/-- A monad equipped with a (read-only) Lake `Workspace`. -/
class MonadWorkspace (m : Type → Type u) where
/-- Gets the current Lake workspace. -/
getWorkspace : m Workspace
export MonadWorkspace (getWorkspace)
@ -128,6 +129,9 @@ variable [MonadLakeEnv m]
/-! ## Environment Helpers -/
/--
Gets the current Lake environment.
-/
@[inline] def getLakeEnv : m Lake.Env :=
read