4.2. モジュールの内容(Module Contents)

ファイルの構文に関する節 で説明したように、Lean のモジュールはヘッダとそれに続く一連のコマンドで構成されます。

4.2.1. コマンドと宣言(Commands and Declaration)

ヘッダの後にある、Lean モジュールのトップレベルのフレーズはすべてコマンドです。コマンドは新しい型を追加したり、新しい定数を定義したり、Lean に情報を問い合わせたりします。コマンドは 後続のコマンドをパースするために使用される構文を変更する ことさえもできます。

Planned Content
  • Describe the various families of available commands (definition-like, #eval-like, etc).

  • Refer to specific chapters that describe major commands, such as inductive.

Tracked at issue #100

4.2.1.1. 定義に類するコマンド(Definition-Like Commands)

Planned Content
  • Precise descriptions of these commands and their syntax

  • Comparison of each kind of definition-like command to the others

Tracked at issue #101

以下の Lean のコマンドは定義に類するものです:

  • def

  • abbrev

  • example

  • theorem

これらのコマンドはすべて Lean によってシグネチャに応じた項へ エラボレート されます。結果を破棄する example を除き、Lean のコア言語での結果の式は将来の環境で使用するために保存されます。 Lean.Parser.Command.declaration : commandinstance コマンドについては インスタンス宣言の節 で記述します。

syntax
command ::= ...
    | `declModifiers` is the collection of modifiers on a declaration:
* a doc comment `/-- ... -/`
* a list of attributes `@[attr1, attr2]`
* a visibility specifier, `private` or `protected`
* `noncomputable`
* `unsafe`
* `partial` or `nonrec`

All modifiers are optional, and have to come in the listed order.

`nestedDeclModifiers` is the same as `declModifiers`, but attributes are printed
on the same line as the declaration. It is used for declarations nested inside other syntax,
such as inductive constructors, structure projections, and `let rec` / `where` definitions. declModifiers
      definition
syntax
definition ::= ...
    | def `declId` matches `foo` or `foo.{u,v}`: an identifier possibly followed by a list of universe names declId `optDeclSig` matches the signature of a declaration with optional type: a list of binders and then possibly `: type` optDeclSig := termTermination hints are `termination_by` and `decreasing_by`, in that order.
definition ::= ...
    | def `declId` matches `foo` or `foo.{u,v}`: an identifier possibly followed by a list of universe names declId `optDeclSig` matches the signature of a declaration with optional type: a list of binders and then possibly `: type` optDeclSig
        (| term => term)*Termination hints are `termination_by` and `decreasing_by`, in that order.
definition ::= ...
    | def `declId` matches `foo` or `foo.{u,v}`: an identifier possibly followed by a list of universe names declId `optDeclSig` matches the signature of a declaration with optional type: a list of binders and then possibly `: type` optDeclSig where
        structInstField*
syntax
theorem ::= ...
    | theorem `declId` matches `foo` or `foo.{u,v}`: an identifier possibly followed by a list of universe names declId `declSig` matches the signature of a declaration with required type: a list of binders and then `: type` declSig := termTermination hints are `termination_by` and `decreasing_by`, in that order.
theorem ::= ...
    | theorem `declId` matches `foo` or `foo.{u,v}`: an identifier possibly followed by a list of universe names declId `declSig` matches the signature of a declaration with required type: a list of binders and then `: type` declSig
        (| term => term)*Termination hints are `termination_by` and `decreasing_by`, in that order.
theorem ::= ...
    | theorem `declId` matches `foo` or `foo.{u,v}`: an identifier possibly followed by a list of universe names declId `declSig` matches the signature of a declaration with required type: a list of binders and then `: type` declSig where
        structInstField*
syntax
abbrev ::= ...
    | abbrev `declId` matches `foo` or `foo.{u,v}`: an identifier possibly followed by a list of universe names declId `optDeclSig` matches the signature of a declaration with optional type: a list of binders and then possibly `: type` optDeclSig := termTermination hints are `termination_by` and `decreasing_by`, in that order.
abbrev ::= ...
    | abbrev `declId` matches `foo` or `foo.{u,v}`: an identifier possibly followed by a list of universe names declId `optDeclSig` matches the signature of a declaration with optional type: a list of binders and then possibly `: type` optDeclSig
        (| term => term)*Termination hints are `termination_by` and `decreasing_by`, in that order.
abbrev ::= ...
    | abbrev `declId` matches `foo` or `foo.{u,v}`: an identifier possibly followed by a list of universe names declId `optDeclSig` matches the signature of a declaration with optional type: a list of binders and then possibly `: type` optDeclSig where
        structInstField*
syntax
example ::= ...
    | example `optDeclSig` matches the signature of a declaration with optional type: a list of binders and then possibly `: type` (ident  | A *hole* (or *placeholder term*), which stands for an unknown term that is expected to be inferred based on context.
For example, in `@id _ Nat.zero`, the `_` must be the type of `Nat.zero`, which is `Nat`.

The way this works is that holes create fresh metavariables.
The elaborator is allowed to assign terms to metavariables while it is checking definitional equalities.
This is often known as *unification*.

Normally, all holes must be solved for. However, there are a few contexts where this is not necessary:
* In `match` patterns, holes are catch-all patterns.
* In some tactics, such as `refine'` and `apply`, unsolved-for placeholders become new goals.

Related concept: implicit parameters are automatically filled in with holes during the elaboration process.

See also `?m` syntax (synthetic holes).
hole  | bracketedBinder )(ident  | A *hole* (or *placeholder term*), which stands for an unknown term that is expected to be inferred based on context.
For example, in `@id _ Nat.zero`, the `_` must be the type of `Nat.zero`, which is `Nat`.

The way this works is that holes create fresh metavariables.
The elaborator is allowed to assign terms to metavariables while it is checking definitional equalities.
This is often known as *unification*.

Normally, all holes must be solved for. However, there are a few contexts where this is not necessary:
* In `match` patterns, holes are catch-all patterns.
* In some tactics, such as `refine'` and `apply`, unsolved-for placeholders become new goals.

Related concept: implicit parameters are automatically filled in with holes during the elaboration process.

See also `?m` syntax (synthetic holes).
hole  | bracketedBinder ):= termTermination hints are `termination_by` and `decreasing_by`, in that order.
example ::= ...
    | example `optDeclSig` matches the signature of a declaration with optional type: a list of binders and then possibly `: type` (ident  | A *hole* (or *placeholder term*), which stands for an unknown term that is expected to be inferred based on context.
For example, in `@id _ Nat.zero`, the `_` must be the type of `Nat.zero`, which is `Nat`.

The way this works is that holes create fresh metavariables.
The elaborator is allowed to assign terms to metavariables while it is checking definitional equalities.
This is often known as *unification*.

Normally, all holes must be solved for. However, there are a few contexts where this is not necessary:
* In `match` patterns, holes are catch-all patterns.
* In some tactics, such as `refine'` and `apply`, unsolved-for placeholders become new goals.

Related concept: implicit parameters are automatically filled in with holes during the elaboration process.

See also `?m` syntax (synthetic holes).
hole  | bracketedBinder )(ident
         | A *hole* (or *placeholder term*), which stands for an unknown term that is expected to be inferred based on context.
For example, in `@id _ Nat.zero`, the `_` must be the type of `Nat.zero`, which is `Nat`.

The way this works is that holes create fresh metavariables.
The elaborator is allowed to assign terms to metavariables while it is checking definitional equalities.
This is often known as *unification*.

Normally, all holes must be solved for. However, there are a few contexts where this is not necessary:
* In `match` patterns, holes are catch-all patterns.
* In some tactics, such as `refine'` and `apply`, unsolved-for placeholders become new goals.

Related concept: implicit parameters are automatically filled in with holes during the elaboration process.

See also `?m` syntax (synthetic holes).
hole
         | bracketedBinder
        )(| term => term)*Termination hints are `termination_by` and `decreasing_by`, in that order.
example ::= ...
    | example `optDeclSig` matches the signature of a declaration with optional type: a list of binders and then possibly `: type` (ident  | A *hole* (or *placeholder term*), which stands for an unknown term that is expected to be inferred based on context.
For example, in `@id _ Nat.zero`, the `_` must be the type of `Nat.zero`, which is `Nat`.

The way this works is that holes create fresh metavariables.
The elaborator is allowed to assign terms to metavariables while it is checking definitional equalities.
This is often known as *unification*.

Normally, all holes must be solved for. However, there are a few contexts where this is not necessary:
* In `match` patterns, holes are catch-all patterns.
* In some tactics, such as `refine'` and `apply`, unsolved-for placeholders become new goals.

Related concept: implicit parameters are automatically filled in with holes during the elaboration process.

See also `?m` syntax (synthetic holes).
hole  | bracketedBinder )(ident  | A *hole* (or *placeholder term*), which stands for an unknown term that is expected to be inferred based on context.
For example, in `@id _ Nat.zero`, the `_` must be the type of `Nat.zero`, which is `Nat`.

The way this works is that holes create fresh metavariables.
The elaborator is allowed to assign terms to metavariables while it is checking definitional equalities.
This is often known as *unification*.

Normally, all holes must be solved for. However, there are a few contexts where this is not necessary:
* In `match` patterns, holes are catch-all patterns.
* In some tactics, such as `refine'` and `apply`, unsolved-for placeholders become new goals.

Related concept: implicit parameters are automatically filled in with holes during the elaboration process.

See also `?m` syntax (synthetic holes).
hole  | bracketedBinder )where
        structInstField*

不透明な定数 はそれらの定義へ簡約されない定義された定数です。

syntax
opaque ::= ...
    | opaque `declId` matches `foo` or `foo.{u,v}`: an identifier possibly followed by a list of universe names declId `declSig` matches the signature of a declaration with required type: a list of binders and then `: type` declSig
syntax
axiom ::= ...
    | axiom `declId` matches `foo` or `foo.{u,v}`: an identifier possibly followed by a list of universe names declId `declSig` matches the signature of a declaration with required type: a list of binders and then `: type` declSig

4.2.1.2. Modifiers🔗

Planned Content

A description of each modifier allowed in the production declModifiers, including documentation comments.

Tracked at issue #52

syntax
declModifiers ::= ...
    | `declModifiers` is the collection of modifiers on a declaration:
* a doc comment `/-- ... -/`
* a list of attributes `@[attr1, attr2]`
* a visibility specifier, `private` or `protected`
* `noncomputable`
* `unsafe`
* `partial` or `nonrec`

All modifiers are optional, and have to come in the listed order.

`nestedDeclModifiers` is the same as `declModifiers`, but attributes are printed
on the same line as the declaration. It is used for declarations nested inside other syntax,
such as inductive constructors, structure projections, and `let rec` / `where` definitions. A `docComment` parses a "documentation comment" like `/-- foo -/`. This is not treated like
a regular comment (that is, as whitespace); it is parsed and forms part of the syntax tree structure.

A `docComment` node contains a `/--` atom and then the remainder of the comment, `foo -/` in this
example. Use `TSyntax.getDocString` to extract the body text from a doc string syntax node. docComment
      attributes
      (private
       | protected
      )noncomputable
      unsafe
      (partial
       | nonrec)

4.2.1.3. Signatures

Planned Content

Describe signatures, including the following topics:

  • Explicit, implicit, instance-implicit, and strict implicit parameter binders

  • Optional and automatic parameters

  • Automatic implicit parameters

  • Argument names and by-name syntax

  • Which parts can be omitted where? Why?

Tracked at issue #53

4.2.1.4. ヘッダ(Headers)

定義または宣言の ヘッダ (header)は定義される新しい定数のシグネチャを指定します。

4.2.2. Namespaces🔗

Planned Content

Describe namespaces, aliases, and the semantics of export and open. Which language features are controlled by the currently open namespaces?

Tracked at issue #210

4.2.3. セクションスコープ(Section Scopes)🔗

多くのコマンドは現在の セクションスコープ (section scope)(明確な場合は単位「スコープ」と呼ばれることもあります)に対して効果を持ちます。Lean のすべてのモジュールはセクションスコープを持ちます。スコープを入れ子にするには Lean.Parser.Command.namespace : command`namespace <id>` opens a section with label `<id>` that influences naming and name resolution inside the section: * Declarations names are prefixed: `def seventeen : ℕ := 17` inside a namespace `Nat` is given the full name `Nat.seventeen`. * Names introduced by `export` declarations are also prefixed by the identifier. * All names starting with `<id>.` become available in the namespace without the prefix. These names are preferred over names introduced by outer namespaces or `open`. * Within a namespace, declarations can be `protected`, which excludes them from the effects of opening the namespace. As with `section`, namespaces can be nested and the scope of a namespace is terminated by a corresponding `end <id>` or the end of the file. `namespace` also acts like `section` in delimiting the scope of `variable`, `open`, and other scoped commands. namespaceLean.Parser.Command.section : commandA `section`/`end` pair delimits the scope of `variable`, `include, `open`, `set_option`, and `local` commands. Sections can be nested. `section <id>` provides a label to the section that has to appear with the matching `end`. In either case, the `end` can be omitted, in which case the section is closed at the end of the file. section コマンド、および Lean.Parser.Command.in : commandin コマンドコンビネータによって作成されます。

セクションスコープでは、以下のデータが追跡されます:

現在の名前空間

現在の名前空間 (current namespace)は新しく宣言されたものが定義される名前空間です。さらに、 名前解決 はグローバル名のスコープに現在の名前空間のすべての接頭辞を含めます。

開かれた名前空間

名前空間が 開かれる (opened)と、その名前は現在のスコープで明示的な接頭辞なしで利用可能になります。さらに、開かれた名前空間に対してのスコープ属性と スコープ構文拡張 は、現在のセクションスコープで有効になります。

オプション

コンパイラオプションの変更は、その変更が行われたスコープの終了時にもとの値に戻されます。

セクション変数

セクション変数 は、定義のパラメータとして自動的に追加される名前(もしくは インスタンス暗黙 のパラメータ)です。また、定理の文中に登場する場合は、全称量化された仮定として定理に追加されます。

4.2.3.1. セクションスコープの制御(Controlling Section Scopes)🔗

Lean.Parser.Command.section : commandA `section`/`end` pair delimits the scope of `variable`, `include, `open`, `set_option`, and `local` commands. Sections can be nested. `section <id>` provides a label to the section that has to appear with the matching `end`. In either case, the `end` can be omitted, in which case the section is closed at the end of the file. section コマンドは新しいセクションスコープを作成しますが、現在の名前空間・開かれた名前空間・セクション変数は変更しません。セクションスコープに加えられた変更は、そのセクションが終了するともとに戻ります。セクションにはオプションとして名前を付けることができます;名前付きセクションを閉じる Lean.Parser.Command.end : command`end` closes a `section` or `namespace` scope. If the scope is named `<id>`, it has to be closed with `end <id>`. The `end` command is optional at the end of a file. end コマンドでは、同じ名前を使用する必要があります。セクション名が複数のコンポーネントから構成される(つまり . で区切られた名前で構成される場合)、複数の入れ子になったセクションが導入されます。セクション名には可読性の目的以外の効果はありません。

syntax

Lean.Parser.Command.section : commandA `section`/`end` pair delimits the scope of `variable`, `include, `open`, `set_option`, and `local` commands. Sections can be nested. `section <id>` provides a label to the section that has to appear with the matching `end`. In either case, the `end` can be omitted, in which case the section is closed at the end of the file. section コマンドは end コマンドかファイルの終わりまで続くセクションスコープを作成します。

command ::= ...
    | A `section`/`end` pair delimits the scope of `variable`, `include, `open`, `set_option`, and `local`
commands. Sections can be nested. `section <id>` provides a label to the section that has to appear
with the matching `end`. In either case, the `end` can be omitted, in which case the section is
closed at the end of the file.
section ident?
名前付きスコープ

名前 englishGreetings 名前空間で定義されています。

def Greetings.english := "Hello"

名前空間の外からは評価することができません。

#eval unknown identifier 'english'english
unknown identifier 'english'

セクションを開くことで、グローバルスコープへの変更を含めることができます。このセクションの名前は Greetings です。

section Greetings

セクション名が定義の名前空間と一致していても、その名前はスコープに含まれません。なぜなら、セクション名は純粋に可読性を上げ、リファクタリングを容易にするためのものだからです。

#eval unknown identifier 'english'english
unknown identifier 'english'

名前空間 Greetings を開くと、 Greetings.englishenglish になります:

open Greetings "Hello"#eval english
"Hello"

このセクションを閉じるにはセクション名を使わなければなりません。

invalid 'end', name is missing (expected Greetings)end
invalid 'end', name is missing (expected Greetings)
invalid 'end', insufficient scopesend Greetings

セクションが閉じられると、 Lean.Parser.Command.open : commandMakes names from other namespaces visible without writing the namespace prefix. Names that are made available with `open` are visible within the current `section` or `namespace` block. This makes referring to (type) definitions and theorems easier, but note that it can also make [scoped instances], notations, and attributes from a different namespace available. The `open` command can be used in a few different ways: * `open Some.Namespace.Path1 Some.Namespace.Path2` makes all non-protected names in `Some.Namespace.Path1` and `Some.Namespace.Path2` available without the prefix, so that `Some.Namespace.Path1.x` and `Some.Namespace.Path2.y` can be referred to by writing only `x` and `y`. * `open Some.Namespace.Path hiding def1 def2` opens all non-protected names in `Some.Namespace.Path` except `def1` and `def2`. * `open Some.Namespace.Path (def1 def2)` only makes `Some.Namespace.Path.def1` and `Some.Namespace.Path.def2` available without the full prefix, so `Some.Namespace.Path.def3` would be unaffected. This works even if `def1` and `def2` are `protected`. * `open Some.Namespace.Path renaming def1 → def1', def2 → def2'` same as `open Some.Namespace.Path (def1 def2)` but `def1`/`def2`'s names are changed to `def1'`/`def2'`. This works even if `def1` and `def2` are `protected`. * `open scoped Some.Namespace.Path1 Some.Namespace.Path2` **only** opens [scoped instances], notations, and attributes from `Namespace1` and `Namespace2`; it does **not** make any other name available. * `open <any of the open shapes above> in` makes the names `open`-ed visible only in the next command or expression. [scoped instance]: https://lean-lang.org/theorem_proving_in_lean4/type_classes.html#scoped-instances (Scoped instances in Theorem Proving in Lean) ## Examples ```lean /-- SKI combinators https://en.wikipedia.org/wiki/SKI_combinator_calculus -/ namespace Combinator.Calculus def I (a : α) : α := a def K (a : α) : β → α := fun _ => a def S (x : α → β → γ) (y : α → β) (z : α) : γ := x z (y z) end Combinator.Calculus section -- open everything under `Combinator.Calculus`, *i.e.* `I`, `K` and `S`, -- until the section ends open Combinator.Calculus theorem SKx_eq_K : S K x = I := rfl end -- open everything under `Combinator.Calculus` only for the next command (the next `theorem`, here) open Combinator.Calculus in theorem SKx_eq_K' : S K x = I := rfl section -- open only `S` and `K` under `Combinator.Calculus` open Combinator.Calculus (S K) theorem SKxy_eq_y : S K x y = y := rfl -- `I` is not in scope, we have to use its full path theorem SKxy_eq_Iy : S K x y = Combinator.Calculus.I y := rfl end section open Combinator.Calculus renaming I → identity, K → konstant #check identity #check konstant end section open Combinator.Calculus hiding S #check I #check K end section namespace Demo inductive MyType | val namespace N1 scoped infix:68 " ≋ " => BEq.beq scoped instance : BEq MyType where beq _ _ := true def Alias := MyType end N1 end Demo -- bring `≋` and the instance in scope, but not `Alias` open scoped Demo.N1 #check Demo.MyType.val == Demo.MyType.val #check Demo.MyType.val ≋ Demo.MyType.val -- #check Alias -- unknown identifier 'Alias' end ``` open コマンドの効果は元に戻ります。

#eval unknown identifier 'english'english
unknown identifier 'english'

Lean.Parser.Command.namespace : command`namespace <id>` opens a section with label `<id>` that influences naming and name resolution inside the section: * Declarations names are prefixed: `def seventeen : ℕ := 17` inside a namespace `Nat` is given the full name `Nat.seventeen`. * Names introduced by `export` declarations are also prefixed by the identifier. * All names starting with `<id>.` become available in the namespace without the prefix. These names are preferred over names introduced by outer namespaces or `open`. * Within a namespace, declarations can be `protected`, which excludes them from the effects of opening the namespace. As with `section`, namespaces can be nested and the scope of a namespace is terminated by a corresponding `end <id>` or the end of the file. `namespace` also acts like `section` in delimiting the scope of `variable`, `open`, and other scoped commands. namespace コマンドは新しいセクションスコープを作成します。このセクションスコープ内では、現在の名前空間はコマンドで指定された名前となり、周囲のセクションスコープ内において現在の名前空間から相対的に解釈されます。セクションと同様に、セクションスコープに加えられた変更は、名前空間のスコープが終了するともとに戻ります。

名前空間を閉じるには、 Lean.Parser.Command.end : command`end` closes a `section` or `namespace` scope. If the scope is named `<id>`, it has to be closed with `end <id>`. The `end` command is optional at the end of a file. end コマンドで、削除する現在の名前空間の接尾辞を指定します。その接尾辞に含まれる Lean.Parser.Command.namespace : command`namespace <id>` opens a section with label `<id>` that influences naming and name resolution inside the section: * Declarations names are prefixed: `def seventeen : ℕ := 17` inside a namespace `Nat` is given the full name `Nat.seventeen`. * Names introduced by `export` declarations are also prefixed by the identifier. * All names starting with `<id>.` become available in the namespace without the prefix. These names are preferred over names introduced by outer namespaces or `open`. * Within a namespace, declarations can be `protected`, which excludes them from the effects of opening the namespace. As with `section`, namespaces can be nested and the scope of a namespace is terminated by a corresponding `end <id>` or the end of the file. `namespace` also acts like `section` in delimiting the scope of `variable`, `open`, and other scoped commands. namespace コマンドで導入されたセクションスコープは全て閉じられます。

syntax

namespace コマンドは、指定された識別子を追加して現在の名前空間を変更します。

Lean.Parser.Command.end : command`end` closes a `section` or `namespace` scope. If the scope is named `<id>`, it has to be closed with `end <id>`. The `end` command is optional at the end of a file. end コマンドかファイルの終わりまで続くセクションスコープを作成します。

command ::= ...
    | `namespace <id>` opens a section with label `<id>` that influences naming and name resolution inside
the section:
* Declarations names are prefixed: `def seventeen : ℕ := 17` inside a namespace `Nat` is given the
  full name `Nat.seventeen`.
* Names introduced by `export` declarations are also prefixed by the identifier.
* All names starting with `<id>.` become available in the namespace without the prefix. These names
  are preferred over names introduced by outer namespaces or `open`.
* Within a namespace, declarations can be `protected`, which excludes them from the effects of
  opening the namespace.

As with `section`, namespaces can be nested and the scope of a namespace is terminated by a
corresponding `end <id>` or the end of the file.

`namespace` also acts like `section` in delimiting the scope of `variable`, `open`, and other scoped commands.
namespace ident
syntax

識別子が無い場合、 Lean.Parser.Command.end : command`end` closes a `section` or `namespace` scope. If the scope is named `<id>`, it has to be closed with `end <id>`. The `end` command is optional at the end of a file. end は最近開いたセクションを閉じます。このセクションは無名でなければなりません。

command ::= ...
    | `end` closes a `section` or `namespace` scope. If the scope is named `<id>`, it has to be closed
with `end <id>`. The `end` command is optional at the end of a file.
end

識別子を指定すると、最も最近に開かれたセクションまたは名前空間を閉じます。セクションの場合、この識別子は、直近の Lean.Parser.Command.namespace : command`namespace <id>` opens a section with label `<id>` that influences naming and name resolution inside the section: * Declarations names are prefixed: `def seventeen : ℕ := 17` inside a namespace `Nat` is given the full name `Nat.seventeen`. * Names introduced by `export` declarations are also prefixed by the identifier. * All names starting with `<id>.` become available in the namespace without the prefix. These names are preferred over names introduced by outer namespaces or `open`. * Within a namespace, declarations can be `protected`, which excludes them from the effects of opening the namespace. As with `section`, namespaces can be nested and the scope of a namespace is terminated by a corresponding `end <id>` or the end of the file. `namespace` also acts like `section` in delimiting the scope of `variable`, `open`, and other scoped commands. namespace コマンド以降にオープンされたセクション名を連結した接尾辞でなければなりません。名前空間の場合、この識別子は、まだ開いている直近の Lean.Parser.Command.section : commandA `section`/`end` pair delimits the scope of `variable`, `include, `open`, `set_option`, and `local` commands. Sections can be nested. `section <id>` provides a label to the section that has to appear with the matching `end`. In either case, the `end` can be omitted, in which case the section is closed at the end of the file. section 以降の現在の名前空間の拡張子の接尾辞でなければなりません;その後、現在の名前空間ではこの接尾辞は削除されます。

command ::= ...
    | `end` closes a `section` or `namespace` scope. If the scope is named `<id>`, it has to be closed
with `end <id>`. The `end` command is optional at the end of a file.
end ident

Lean.Parser.Command.mutual : commandmutual ブロックを閉じる Lean.Parser.Command.mutual : commandend は、 Lean.Parser.Command.end : command`end` closes a `section` or `namespace` scope. If the scope is named `<id>`, it has to be closed with `end <id>`. The `end` command is optional at the end of a file. end コマンドではなく、 Lean.Parser.Command.mutual : commandmutual の構文の一部です。

名前空間とセクションの入れ子

名前空間とセクションは入れ子にすることができます。1つの Lean.Parser.Command.end : command`end` closes a `section` or `namespace` scope. If the scope is named `<id>`, it has to be closed with `end <id>`. The `end` command is optional at the end of a file. end コマンドで1つ以上の名前空間、または1つ以上のセクションを閉じることができますが、両者を混ぜたものを閉じることはできません。

2つの別々のコマンドで現在の名前空間を A.B.C に設定した後、1つの Lean.Parser.Command.end : command`end` closes a `section` or `namespace` scope. If the scope is named `<id>`, it has to be closed with `end <id>`. The `end` command is optional at the end of a file. endB.C を削除することができます:

namespace A.B namespace C end B.C

この時点で、現在の名前空間は A です。

次に、匿名のセクションと名前空間 D.E が開かれます:

section namespace D.E

この時点で、現在の名前空間は A.D.E です。1つの Lean.Parser.Command.end : command`end` closes a `section` or `namespace` scope. If the scope is named `<id>`, it has to be closed with `end <id>`. The `end` command is optional at the end of a file. end コマンドでは、間にセクションがあるため、3つすべてを閉じることはできません:

invalid 'end', name mismatch (expected «».D.E)end A.D.E
invalid 'end', name mismatch (expected «».D.E)

その代わり、名前空間とセクションは別々に終了しなければなりません。

end D.E end end A

単一のコマンドのためにセクションを開くのではなく、 Lean.Parser.Command.in : commandin コンビネータを使用して単一のコマンド用のセクションスコープを作成することができます。 Lean.Parser.Command.in : commandin は右結合であるため、複数のスコープの変更を重ねることができます。

syntax

in コマンドコンビネータは単一のコマンドにセクションスコープを導入します。

command ::= ...
    | command in
      command
ローカルスコープのための Lean.Parser.Command.in : commandin の使用

名前空間の内容は Lean.Parser.Command.in : commandin を使用して単一のコマンドで使用できるようにすることができます。

def Dessert.cupcake := "delicious" open Dessert in "delicious"#eval cupcake

単一のコマンドの後では、 Lean.Parser.Command.open : commandMakes names from other namespaces visible without writing the namespace prefix. Names that are made available with `open` are visible within the current `section` or `namespace` block. This makes referring to (type) definitions and theorems easier, but note that it can also make [scoped instances], notations, and attributes from a different namespace available. The `open` command can be used in a few different ways: * `open Some.Namespace.Path1 Some.Namespace.Path2` makes all non-protected names in `Some.Namespace.Path1` and `Some.Namespace.Path2` available without the prefix, so that `Some.Namespace.Path1.x` and `Some.Namespace.Path2.y` can be referred to by writing only `x` and `y`. * `open Some.Namespace.Path hiding def1 def2` opens all non-protected names in `Some.Namespace.Path` except `def1` and `def2`. * `open Some.Namespace.Path (def1 def2)` only makes `Some.Namespace.Path.def1` and `Some.Namespace.Path.def2` available without the full prefix, so `Some.Namespace.Path.def3` would be unaffected. This works even if `def1` and `def2` are `protected`. * `open Some.Namespace.Path renaming def1 → def1', def2 → def2'` same as `open Some.Namespace.Path (def1 def2)` but `def1`/`def2`'s names are changed to `def1'`/`def2'`. This works even if `def1` and `def2` are `protected`. * `open scoped Some.Namespace.Path1 Some.Namespace.Path2` **only** opens [scoped instances], notations, and attributes from `Namespace1` and `Namespace2`; it does **not** make any other name available. * `open <any of the open shapes above> in` makes the names `open`-ed visible only in the next command or expression. [scoped instance]: https://lean-lang.org/theorem_proving_in_lean4/type_classes.html#scoped-instances (Scoped instances in Theorem Proving in Lean) ## Examples ```lean /-- SKI combinators https://en.wikipedia.org/wiki/SKI_combinator_calculus -/ namespace Combinator.Calculus def I (a : α) : α := a def K (a : α) : β → α := fun _ => a def S (x : α → β → γ) (y : α → β) (z : α) : γ := x z (y z) end Combinator.Calculus section -- open everything under `Combinator.Calculus`, *i.e.* `I`, `K` and `S`, -- until the section ends open Combinator.Calculus theorem SKx_eq_K : S K x = I := rfl end -- open everything under `Combinator.Calculus` only for the next command (the next `theorem`, here) open Combinator.Calculus in theorem SKx_eq_K' : S K x = I := rfl section -- open only `S` and `K` under `Combinator.Calculus` open Combinator.Calculus (S K) theorem SKxy_eq_y : S K x y = y := rfl -- `I` is not in scope, we have to use its full path theorem SKxy_eq_Iy : S K x y = Combinator.Calculus.I y := rfl end section open Combinator.Calculus renaming I → identity, K → konstant #check identity #check konstant end section open Combinator.Calculus hiding S #check I #check K end section namespace Demo inductive MyType | val namespace N1 scoped infix:68 " ≋ " => BEq.beq scoped instance : BEq MyType where beq _ _ := true def Alias := MyType end N1 end Demo -- bring `≋` and the instance in scope, but not `Alias` open scoped Demo.N1 #check Demo.MyType.val == Demo.MyType.val #check Demo.MyType.val ≋ Demo.MyType.val -- #check Alias -- unknown identifier 'Alias' end ``` open の効果はもとに戻ります。

#eval unknown identifier 'cupcake'cupcake
unknown identifier 'cupcake'

4.2.3.2. セクション変数(Section Variables)

セクション変数 (section variable)はそれを言及する宣言に対して自動的に追加されるパラメータです。これは autoImplicit オプションが true であってもなくても発生します。セクション変数は暗黙・厳密な暗黙・明示的のいずれでもかまいません;インスタンス暗黙のセクション変数は特別に扱われます。

定理以外の宣言でセクション変数名が出現すると、パラメータとして追加されます。その変数に言及しているインスタンス暗黙のセクション変数も追加されます。追加された変数が他の変数に依存している場合は、それらの変数も追加されます;このプロセスは依存が無くなるまで繰り返されます。すべてのセクション変数は、宣言された順に他のすべてのパラメータよりも前に追加されます。セクション変数が追加されるのは、それが定理の の中に現れる時だけです。そうでなければ、証明項がセクション変数を使用している場合、定理の証明を変更によってその文が変更されてしまう可能性があります。

変数は Lean.Parser.Command.variable : commandDeclares one or more typed variables, or modifies whether already-declared variables are implicit. Introduces variables that can be used in definitions within the same `namespace` or `section` block. When a definition mentions a variable, Lean will add it as an argument of the definition. This is useful in particular when writing many definitions that have parameters in common (see below for an example). Variable declarations have the same flexibility as regular function parameters. In particular they can be [explicit, implicit][binder docs], or [instance implicit][tpil classes] (in which case they can be anonymous). This can be changed, for instance one can turn explicit variable `x` into an implicit one with `variable {x}`. Note that currently, you should avoid changing how variables are bound and declare new variables at the same time; see [issue 2789] for more on this topic. In *theorem bodies* (i.e. proofs), variables are not included based on usage in order to ensure that changes to the proof cannot change the statement of the overall theorem. Instead, variables are only available to the proof if they have been mentioned in the theorem header or in an `include` command or are instance implicit and depend only on such variables. See [*Variables and Sections* from Theorem Proving in Lean][tpil vars] for a more detailed discussion. [tpil vars]: https://lean-lang.org/theorem_proving_in_lean4/dependent_type_theory.html#variables-and-sections (Variables and Sections on Theorem Proving in Lean) [tpil classes]: https://lean-lang.org/theorem_proving_in_lean4/type_classes.html (Type classes on Theorem Proving in Lean) [binder docs]: https://leanprover-community.github.io/mathlib4_docs/Lean/Expr.html#Lean.BinderInfo (Documentation for the BinderInfo type) [issue 2789]: https://github.com/leanprover/lean4/issues/2789 (Issue 2789 on github) ## Examples ```lean section variable {α : Type u} -- implicit (a : α) -- explicit [instBEq : BEq α] -- instance implicit, named [Hashable α] -- instance implicit, anonymous def isEqual (b : α) : Bool := a == b #check isEqual -- isEqual.{u} {α : Type u} (a : α) [instBEq : BEq α] (b : α) : Bool variable {a} -- `a` is implicit now def eqComm {b : α} := a == b ↔ b == a #check eqComm -- eqComm.{u} {α : Type u} {a : α} [instBEq : BEq α] {b : α} : Prop end ``` The following shows a typical use of `variable` to factor out definition arguments: ```lean variable (Src : Type) structure Logger where trace : List (Src × String) #check Logger -- Logger (Src : Type) : Type namespace Logger -- switch `Src : Type` to be implicit until the `end Logger` variable {Src} def empty : Logger Src where trace := [] #check empty -- Logger.empty {Src : Type} : Logger Src variable (log : Logger Src) def len := log.trace.length #check len -- Logger.len {Src : Type} (log : Logger Src) : Nat variable (src : Src) [BEq Src] -- at this point all of `log`, `src`, `Src` and the `BEq` instance can all become arguments def filterSrc := log.trace.filterMap fun (src', str') => if src' == src then some str' else none #check filterSrc -- Logger.filterSrc {Src : Type} (log : Logger Src) (src : Src) [inst✝ : BEq Src] : List String def lenSrc := log.filterSrc src |>.length #check lenSrc -- Logger.lenSrc {Src : Type} (log : Logger Src) (src : Src) [inst✝ : BEq Src] : Nat end Logger ``` The following example demonstrates availability of variables in proofs: ```lean variable {α : Type} -- available in the proof as indirectly mentioned through `a` [ToString α] -- available in the proof as `α` is included (a : α) -- available in the proof as mentioned in the header {β : Type} -- not available in the proof [ToString β] -- not available in the proof theorem ex : a = a := rfl ``` After elaboration of the proof, the following warning will be generated to highlight the unused hypothesis: ``` included section variable '[ToString α]' is not used in 'ex', consider excluding it ``` In such cases, the offending variable declaration should be moved down or into a section so that only theorems that do depend on it follow it until the end of the section. variable コマンドを使って宣言します。

syntax
command ::= ...
    | Declares one or more typed variables, or modifies whether already-declared variables are
  implicit.

Introduces variables that can be used in definitions within the same `namespace` or `section` block.
When a definition mentions a variable, Lean will add it as an argument of the definition. This is
useful in particular when writing many definitions that have parameters in common (see below for an
example).

Variable declarations have the same flexibility as regular function parameters. In particular they
can be [explicit, implicit][binder docs], or [instance implicit][tpil classes] (in which case they
can be anonymous). This can be changed, for instance one can turn explicit variable `x` into an
implicit one with `variable {x}`. Note that currently, you should avoid changing how variables are
bound and declare new variables at the same time; see [issue 2789] for more on this topic.

In *theorem bodies* (i.e. proofs), variables are not included based on usage in order to ensure that
changes to the proof cannot change the statement of the overall theorem. Instead, variables are only
available to the proof if they have been mentioned in the theorem header or in an `include` command
or are instance implicit and depend only on such variables.

See [*Variables and Sections* from Theorem Proving in Lean][tpil vars] for a more detailed
discussion.

[tpil vars]:
https://lean-lang.org/theorem_proving_in_lean4/dependent_type_theory.html#variables-and-sections
(Variables and Sections on Theorem Proving in Lean) [tpil classes]:
https://lean-lang.org/theorem_proving_in_lean4/type_classes.html (Type classes on Theorem Proving in
Lean) [binder docs]:
https://leanprover-community.github.io/mathlib4_docs/Lean/Expr.html#Lean.BinderInfo (Documentation
for the BinderInfo type) [issue 2789]: https://github.com/leanprover/lean4/issues/2789 (Issue 2789
on github)

## Examples

```lean
section
  variable
    {α : Type u}      -- implicit
    (a : α)           -- explicit
    [instBEq : BEq α] -- instance implicit, named
    [Hashable α]      -- instance implicit, anonymous

  def isEqual (b : α) : Bool :=
    a == b

  #check isEqual
  -- isEqual.{u} {α : Type u} (a : α) [instBEq : BEq α] (b : α) : Bool

  variable
    {a} -- `a` is implicit now

  def eqComm {b : α} := a == b ↔ b == a

  #check eqComm
  -- eqComm.{u} {α : Type u} {a : α} [instBEq : BEq α] {b : α} : Prop
end
```

The following shows a typical use of `variable` to factor out definition arguments:

```lean
variable (Src : Type)

structure Logger where
  trace : List (Src × String)
#check Logger
-- Logger (Src : Type) : Type

namespace Logger
  -- switch `Src : Type` to be implicit until the `end Logger`
  variable {Src}

  def empty : Logger Src where
    trace := []
  #check empty
  -- Logger.empty {Src : Type} : Logger Src

  variable (log : Logger Src)

  def len :=
    log.trace.length
  #check len
  -- Logger.len {Src : Type} (log : Logger Src) : Nat

  variable (src : Src) [BEq Src]

  -- at this point all of `log`, `src`, `Src` and the `BEq` instance can all become arguments

  def filterSrc :=
    log.trace.filterMap
      fun (src', str') => if src' == src then some str' else none
  #check filterSrc
  -- Logger.filterSrc {Src : Type} (log : Logger Src) (src : Src) [inst✝ : BEq Src] : List String

  def lenSrc :=
    log.filterSrc src |>.length
  #check lenSrc
  -- Logger.lenSrc {Src : Type} (log : Logger Src) (src : Src) [inst✝ : BEq Src] : Nat
end Logger
```

The following example demonstrates availability of variables in proofs:
```lean
variable
  {α : Type}    -- available in the proof as indirectly mentioned through `a`
  [ToString α]  -- available in the proof as `α` is included
  (a : α)       -- available in the proof as mentioned in the header
  {β : Type}    -- not available in the proof
  [ToString β]  -- not available in the proof

theorem ex : a = a := rfl
```
After elaboration of the proof, the following warning will be generated to highlight the unused
hypothesis:
```
included section variable '[ToString α]' is not used in 'ex', consider excluding it
```
In such cases, the offending variable declaration should be moved down or into a section so that
only theorems that do depend on it follow it until the end of the section.
variable bracketedBinder bracketedBinder*
syntax

variable の後ろに許可される括弧付きの束縛子は、定義でのヘッダで使用される構文と一致します。

bracketedBinder ::=
    Explicit binder, like `(x y : A)` or `(x y)`.
Default values can be specified using `(x : A := v)` syntax, and tactics using `(x : A := by tac)`.
((ident  | A *hole* (or *placeholder term*), which stands for an unknown term that is expected to be inferred based on context.
For example, in `@id _ Nat.zero`, the `_` must be the type of `Nat.zero`, which is `Nat`.

The way this works is that holes create fresh metavariables.
The elaborator is allowed to assign terms to metavariables while it is checking definitional equalities.
This is often known as *unification*.

Normally, all holes must be solved for. However, there are a few contexts where this is not necessary:
* In `match` patterns, holes are catch-all patterns.
* In some tactics, such as `refine'` and `apply`, unsolved-for placeholders become new goals.

Related concept: implicit parameters are automatically filled in with holes during the elaboration process.

See also `?m` syntax (synthetic holes).
hole )((ident | A *hole* (or *placeholder term*), which stands for an unknown term that is expected to be inferred based on context.
For example, in `@id _ Nat.zero`, the `_` must be the type of `Nat.zero`, which is `Nat`.

The way this works is that holes create fresh metavariables.
The elaborator is allowed to assign terms to metavariables while it is checking definitional equalities.
This is often known as *unification*.

Normally, all holes must be solved for. However, there are a few contexts where this is not necessary:
* In `match` patterns, holes are catch-all patterns.
* In some tactics, such as `refine'` and `apply`, unsolved-for placeholders become new goals.

Related concept: implicit parameters are automatically filled in with holes during the elaboration process.

See also `?m` syntax (synthetic holes).
hole))* : term (:= term)?)
bracketedBinder ::= ...
    | Implicit binder, like `{x y : A}` or `{x y}`.
In regular applications, whenever all parameters before it have been specified,
then a `_` placeholder is automatically inserted for this parameter.
Implicit parameters should be able to be determined from the other arguments and the return type
by unification.

In `@` explicit mode, implicit binders behave like explicit binders.
{(ident  | A *hole* (or *placeholder term*), which stands for an unknown term that is expected to be inferred based on context.
For example, in `@id _ Nat.zero`, the `_` must be the type of `Nat.zero`, which is `Nat`.

The way this works is that holes create fresh metavariables.
The elaborator is allowed to assign terms to metavariables while it is checking definitional equalities.
This is often known as *unification*.

Normally, all holes must be solved for. However, there are a few contexts where this is not necessary:
* In `match` patterns, holes are catch-all patterns.
* In some tactics, such as `refine'` and `apply`, unsolved-for placeholders become new goals.

Related concept: implicit parameters are automatically filled in with holes during the elaboration process.

See also `?m` syntax (synthetic holes).
hole )((ident | A *hole* (or *placeholder term*), which stands for an unknown term that is expected to be inferred based on context.
For example, in `@id _ Nat.zero`, the `_` must be the type of `Nat.zero`, which is `Nat`.

The way this works is that holes create fresh metavariables.
The elaborator is allowed to assign terms to metavariables while it is checking definitional equalities.
This is often known as *unification*.

Normally, all holes must be solved for. However, there are a few contexts where this is not necessary:
* In `match` patterns, holes are catch-all patterns.
* In some tactics, such as `refine'` and `apply`, unsolved-for placeholders become new goals.

Related concept: implicit parameters are automatically filled in with holes during the elaboration process.

See also `?m` syntax (synthetic holes).
hole))* : term}
bracketedBinder ::= ...
    | Strict-implicit binder, like `⦃x y : A⦄` or `⦃x y⦄`.
In contrast to `{ ... }` implicit binders, strict-implicit binders do not automatically insert
a `_` placeholder until at least one subsequent explicit parameter is specified.
Do *not* use strict-implicit binders unless there is a subsequent explicit parameter.
Assuming this rule is followed, for fully applied expressions implicit and strict-implicit binders have the same behavior.

Example: If `h : ∀ ⦃x : A⦄, x ∈ s → p x` and `hs : y ∈ s`,
then `h` by itself elaborates to itself without inserting `_` for the `x : A` parameter,
and `h hs` has type `p y`.
In contrast, if `h' : ∀ {x : A}, x ∈ s → p x`, then `h` by itself elaborates to have type `?m ∈ s → p ?m`
with `?m` a fresh metavariable.
(ident  | A *hole* (or *placeholder term*), which stands for an unknown term that is expected to be inferred based on context.
For example, in `@id _ Nat.zero`, the `_` must be the type of `Nat.zero`, which is `Nat`.

The way this works is that holes create fresh metavariables.
The elaborator is allowed to assign terms to metavariables while it is checking definitional equalities.
This is often known as *unification*.

Normally, all holes must be solved for. However, there are a few contexts where this is not necessary:
* In `match` patterns, holes are catch-all patterns.
* In some tactics, such as `refine'` and `apply`, unsolved-for placeholders become new goals.

Related concept: implicit parameters are automatically filled in with holes during the elaboration process.

See also `?m` syntax (synthetic holes).
hole )((ident | A *hole* (or *placeholder term*), which stands for an unknown term that is expected to be inferred based on context.
For example, in `@id _ Nat.zero`, the `_` must be the type of `Nat.zero`, which is `Nat`.

The way this works is that holes create fresh metavariables.
The elaborator is allowed to assign terms to metavariables while it is checking definitional equalities.
This is often known as *unification*.

Normally, all holes must be solved for. However, there are a few contexts where this is not necessary:
* In `match` patterns, holes are catch-all patterns.
* In some tactics, such as `refine'` and `apply`, unsolved-for placeholders become new goals.

Related concept: implicit parameters are automatically filled in with holes during the elaboration process.

See also `?m` syntax (synthetic holes).
hole))* : term
bracketedBinder ::= ...
    | Instance-implicit binder, like `[C]` or `[inst : C]`.
In regular applications without `@` explicit mode, it is automatically inserted
and solved for by typeclass inference for the specified class `C`.
In `@` explicit mode, if `_` is used for an instance-implicit parameter, then it is still solved for by typeclass inference;
use `(_)` to inhibit this and have it be solved for by unification instead, like an implicit argument.
[(ident :)? term]
セクション変数

このセクションでは、自動的な暗黙のパラメータは無効になっていますが、多くのセクション変数が定義されています。

section set_option autoImplicit false universe u variable {α : Type u} (xs : List α) [Zero α] [Add α]

自動の暗黙パラメータが無効になっているため、以下の定義は失敗します:

def addAll (lst : List unknown identifier 'β'β) : unknown identifier 'β'β := lst.foldr (init := 0) (· + ·)
unknown identifier 'β'

一方で、以下の定義では xs さえも直接書く必要はありません:

def addAll := xs.foldr (init := 0) (· + ·)

セクション変数が文の中で明示的に言及されていなくても定理に追加するには、 Lean.Parser.Command.include : command`include eeny meeny` instructs Lean to include the section `variable`s `eeny` and `meeny` in all theorems in the remainder of the current section, differing from the default behavior of conditionally including variables based on use in the theorem header. Other commands are not affected. `include` is usually followed by `in theorem ...` to limit the inclusion to the subsequent declaration. include コマンドでその変数をマークします。include としてマークされた変数はすべての定理に追加されます。 Lean.Parser.Command.omit : command`omit` instructs Lean to not include a variable previously `include`d. Apart from variable names, it can also refer to typeclass instance variables by type using the syntax `omit [TypeOfInst]`, in which case all instance variables that unify with the given type are omitted. `omit` should usually only be used in conjunction with `in` in order to keep the section structure simple. omit コマンドは変数から include マークを削除します;通常、これは Lean.Parser.Command.in : commandin と一緒に使用すると良いでしょう。

セクション変数の include と omit

このセクションの変数には述語と、それが普遍的に成立するために必要なすべての情報、役に立たない余分な仮定が含まれています。

section variable {p : Nat Prop} variable (pZero : p 0) (pStep : n, p n p (n + 1)) variable (pFifteen : p 15)

しかし、以下の定理には p しか追加されないため、証明することができません。

theorem p_all : n, p n := p:NatProp∀ (n : Nat), p n p:NatPropn:Natp n p:NatPropp 0p:NatPropn✝:Nata✝:p n✝p (n✝ + 1)

Lean.Parser.Command.include : command`include eeny meeny` instructs Lean to include the section `variable`s `eeny` and `meeny` in all theorems in the remainder of the current section, differing from the default behavior of conditionally including variables based on use in the theorem header. Other commands are not affected. `include` is usually followed by `in theorem ...` to limit the inclusion to the subsequent declaration. include コマンドは無条件に仮定の追加を行います:

include pZero pStep pFifteen automatically included section variable(s) unused in theorem 'p_all': pFifteen consider restructuring your `variable` declarations so that the variables are not in scope or explicitly omit them: omit pFifteen in theorem ... note: this linter can be disabled with `set_option linter.unusedSectionVars false`theorem p_all : n, p n := p✝:NatProppFifteen:p✝ 15p:NatProppZero:p 0pStep:∀ (n : Nat), p np (n + 1)∀ (n : Nat), p n p✝:NatProppFifteen:p✝ 15p:NatProppZero:p 0pStep:∀ (n : Nat), p np (n + 1)n:Natp n p✝:NatProppFifteen:p✝ 15p:NatProppZero:p 0pStep:∀ (n : Nat), p np (n + 1)p 0p✝:NatProppFifteen:p✝ 15p:NatProppZero:p 0pStep:∀ (n : Nat), p np (n + 1)n✝:Nata✝:p n✝p (n✝ + 1) p✝:NatProppFifteen:p✝ 15p:NatProppZero:p 0pStep:∀ (n : Nat), p np (n + 1)p 0p✝:NatProppFifteen:p✝ 15p:NatProppZero:p 0pStep:∀ (n : Nat), p np (n + 1)n✝:Nata✝:p n✝p (n✝ + 1) All goals completed! 🐙

pFifteen という偽の仮定が挿入されたため、Lean は警告を発します:

automatically included section variable(s) unused in theorem 'p_all':
  pFifteen
consider restructuring your `variable` declarations so that the variables are not in scope or explicitly omit them:
  omit pFifteen in theorem ...
note: this linter can be disabled with `set_option linter.unusedSectionVars false`

これは Lean.Parser.Command.omit : command`omit` instructs Lean to not include a variable previously `include`d. Apart from variable names, it can also refer to typeclass instance variables by type using the syntax `omit [TypeOfInst]`, in which case all instance variables that unify with the given type are omitted. `omit` should usually only be used in conjunction with `in` in order to keep the section structure simple. omit を使って pFifteen を削除することで回避できます:

include pZero pStep pFifteen omit pFifteen in theorem p_all : n, p n := p:NatProppZero:p 0pStep:∀ (n : Nat), p np (n + 1)∀ (n : Nat), p n p:NatProppZero:p 0pStep:∀ (n : Nat), p np (n + 1)n:Natp n p:NatProppZero:p 0pStep:∀ (n : Nat), p np (n + 1)p 0p:NatProppZero:p 0pStep:∀ (n : Nat), p np (n + 1)n✝:Nata✝:p n✝p (n✝ + 1) p:NatProppZero:p 0pStep:∀ (n : Nat), p np (n + 1)p 0p:NatProppZero:p 0pStep:∀ (n : Nat), p np (n + 1)n✝:Nata✝:p n✝p (n✝ + 1) All goals completed! 🐙 end

4.2.3.3. スコープ属性(Scoped Attributes)

多くの属性は、適用するスコープを特定のものにすることができます。これによって属性の効果が、現在のセクションスコープでのみ・現在の名前空間を開いている名前空間のみ・どこからでも見ることができるかを決定します。これらのスコープ指定は 構文拡張型クラスインスタンス を制御するためにも使用されます。

syntax

グローバルスコープ宣言(デフォルト)は、その宣言が確立された module が遷移的にインポートされた場所ならどこででも有効です。この宣言は他のスコープ修飾子がないことで指示されます。

attrKind ::=
    `attrKind` matches `("scoped" <|> "local")?`, used before an attribute like `@[local simp]`. 

ローカルスコープの宣言は、それが確立された セクションスコープ の範囲でのみ有効です。

attrKind ::= ...
    | `attrKind` matches `("scoped" <|> "local")?`, used before an attribute like `@[local simp]`. local

スコープ宣言は、その宣言が確立されている 名前空間 が開かれるたびに有効になります。

attrKind ::= ...
    | `attrKind` matches `("scoped" <|> "local")?`, used before an attribute like `@[local simp]`. scoped