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
4.2. モジュールの内容(Module Contents)
ファイルの構文に関する節 で説明したように、Lean のモジュールはヘッダとそれに続く一連のコマンドで構成されます。
4.2.1. コマンドと宣言(Commands and Declaration)
ヘッダの後にある、Lean モジュールのトップレベルのフレーズはすべてコマンドです。コマンドは新しい型を追加したり、新しい定数を定義したり、Lean に情報を問い合わせたりします。コマンドは 後続のコマンドをパースするために使用される構文を変更する ことさえもできます。
-
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)
-
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 : command
instance
コマンドについては インスタンス宣言の節 で記述します。
definition ::= ... | defdeclId
`declId` matches `foo` or `foo.{u,v}`: an identifier possibly followed by a list of universe names
optDeclSig := term
`optDeclSig` matches the signature of a declaration with optional type: a list of binders and then possibly `: type`
Termination hints are `termination_by` and `decreasing_by`, in that order.
definition ::= ... | defdeclId
`declId` matches `foo` or `foo.{u,v}`: an identifier possibly followed by a list of universe names
optDeclSig (| term => term)*
`optDeclSig` matches the signature of a declaration with optional type: a list of binders and then possibly `: type`
Termination hints are `termination_by` and `decreasing_by`, in that order.
definition ::= ... | defdeclId
`declId` matches `foo` or `foo.{u,v}`: an identifier possibly followed by a list of universe names
optDeclSig where structInstField*
`optDeclSig` matches the signature of a declaration with optional type: a list of binders and then possibly `: type`
theorem ::= ... | theoremdeclId
`declId` matches `foo` or `foo.{u,v}`: an identifier possibly followed by a list of universe names
declSig := term
`declSig` matches the signature of a declaration with required type: a list of binders and then `: type`
Termination hints are `termination_by` and `decreasing_by`, in that order.
theorem ::= ... | theoremdeclId
`declId` matches `foo` or `foo.{u,v}`: an identifier possibly followed by a list of universe names
declSig (| term => term)*
`declSig` matches the signature of a declaration with required type: a list of binders and then `: type`
Termination hints are `termination_by` and `decreasing_by`, in that order.
theorem ::= ... | theoremdeclId
`declId` matches `foo` or `foo.{u,v}`: an identifier possibly followed by a list of universe names
declSig where structInstField*
`declSig` matches the signature of a declaration with required type: a list of binders and then `: type`
abbrev ::= ... | abbrevdeclId
`declId` matches `foo` or `foo.{u,v}`: an identifier possibly followed by a list of universe names
optDeclSig := term
`optDeclSig` matches the signature of a declaration with optional type: a list of binders and then possibly `: type`
Termination hints are `termination_by` and `decreasing_by`, in that order.
abbrev ::= ... | abbrevdeclId
`declId` matches `foo` or `foo.{u,v}`: an identifier possibly followed by a list of universe names
optDeclSig (| term => term)*
`optDeclSig` matches the signature of a declaration with optional type: a list of binders and then possibly `: type`
Termination hints are `termination_by` and `decreasing_by`, in that order.
abbrev ::= ... | abbrevdeclId
`declId` matches `foo` or `foo.{u,v}`: an identifier possibly followed by a list of universe names
optDeclSig where structInstField*
`optDeclSig` matches the signature of a declaration with optional type: a list of binders and then possibly `: type`
example ::= ... | example(ident |
`optDeclSig` matches the signature of a declaration with optional type: a list of binders and then possibly `: type`
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
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).
Termination hints are `termination_by` and `decreasing_by`, in that order.
example ::= ... | example(ident |
`optDeclSig` matches the signature of a declaration with optional type: a list of binders and then possibly `: type`
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)*
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).
Termination hints are `termination_by` and `decreasing_by`, in that order.
example ::= ... | example(ident |
`optDeclSig` matches the signature of a declaration with optional type: a list of binders and then possibly `: type`
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*
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).
不透明な定数 はそれらの定義へ簡約されない定義された定数です。
opaque ::= ... | opaquedeclId
`declId` matches `foo` or `foo.{u,v}`: an identifier possibly followed by a list of universe names
declSig
`declSig` matches the signature of a declaration with required type: a list of binders and then `: type`
axiom ::= ... | axiomdeclId
`declId` matches `foo` or `foo.{u,v}`: an identifier possibly followed by a list of universe names
declSig
`declSig` matches the signature of a declaration with required type: a list of binders and then `: type`
4.2.1.2. Modifiers
A description of each modifier allowed in the production declModifiers
, including documentation comments.
Tracked at issue #52
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.
docComment attributes (private | protected )noncomputable unsafe (partial | nonrec)
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.
4.2.1.3. Signatures
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
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.
namespace
と Lean.Parser.Command.section : 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
コマンド、および Lean.Parser.Command.in : command
in
コマンドコンビネータによって作成されます。
セクションスコープでは、以下のデータが追跡されます:
- 現在の名前空間
現在の名前空間 (current namespace)は新しく宣言されたものが定義される名前空間です。さらに、 名前解決 はグローバル名のスコープに現在の名前空間のすべての接頭辞を含めます。
- 開かれた名前空間
名前空間が 開かれる (opened)と、その名前は現在のスコープで明示的な接頭辞なしで利用可能になります。さらに、開かれた名前空間に対してのスコープ属性と スコープ構文拡張 は、現在のセクションスコープで有効になります。
- オプション
コンパイラオプションの変更は、その変更が行われたスコープの終了時にもとの値に戻されます。
- セクション変数
セクション変数 は、定義のパラメータとして自動的に追加される名前(もしくは インスタンス暗黙 のパラメータ)です。また、定理の文中に登場する場合は、全称量化された仮定として定理に追加されます。
4.2.3.1. セクションスコープの制御(Controlling Section Scopes)
Lean.Parser.Command.section : 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
コマンドは新しいセクションスコープを作成しますが、現在の名前空間・開かれた名前空間・セクション変数は変更しません。セクションスコープに加えられた変更は、そのセクションが終了するともとに戻ります。セクションにはオプションとして名前を付けることができます;名前付きセクションを閉じる 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.section : 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
コマンドは 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?
名前付きスコープ
名前 english
は Greetings
名前空間で定義されています。
def Greetings.english := "Hello"
名前空間の外からは評価することができません。
#eval english
unknown identifier 'english'
セクションを開くことで、グローバルスコープへの変更を含めることができます。このセクションの名前は Greetings
です。
section Greetings
セクション名が定義の名前空間と一致していても、その名前はスコープに含まれません。なぜなら、セクション名は純粋に可読性を上げ、リファクタリングを容易にするためのものだからです。
#eval english
unknown identifier 'english'
名前空間 Greetings
を開くと、 Greetings.english
は english
になります:
open Greetings
#eval english
"Hello"
このセクションを閉じるにはセクション名を使わなければなりません。
end
invalid 'end', name is missing (expected Greetings)
end Greetings
セクションが閉じられると、 Lean.Parser.Command.open : command
Makes 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 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
コマンドで導入されたセクションスコープは全て閉じられます。
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
識別子が無い場合、 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 : 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
以降の現在の名前空間の拡張子の接尾辞でなければなりません;その後、現在の名前空間ではこの接尾辞は削除されます。
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 : command
mutual
ブロックを閉じる Lean.Parser.Command.mutual : command
end
は、 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 : command
mutual
の構文の一部です。
名前空間とセクションの入れ子
名前空間とセクションは入れ子にすることができます。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.
end
で B.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つすべてを閉じることはできません:
end A.D.E
invalid 'end', name mismatch (expected «».D.E)
その代わり、名前空間とセクションは別々に終了しなければなりません。
end D.E
end
end A
単一のコマンドのためにセクションを開くのではなく、 Lean.Parser.Command.in : command
in
コンビネータを使用して単一のコマンド用のセクションスコープを作成することができます。 Lean.Parser.Command.in : command
in
は右結合であるため、複数のスコープの変更を重ねることができます。
in
コマンドコンビネータは単一のコマンドにセクションスコープを導入します。
command ::= ... | command in command
ローカルスコープのための Lean.Parser.Command.in : command
in
の使用
Lean.Parser.Command.in : command
名前空間の内容は Lean.Parser.Command.in : command
in
を使用して単一のコマンドで使用できるようにすることができます。
def Dessert.cupcake := "delicious"
open Dessert in
#eval cupcake
単一のコマンドの後では、 Lean.Parser.Command.open : command
Makes 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 cupcake
unknown identifier 'cupcake'
4.2.3.2. セクション変数(Section Variables)
セクション変数 (section variable)はそれを言及する宣言に対して自動的に追加されるパラメータです。これは autoImplicit
オプションが true
であってもなくても発生します。セクション変数は暗黙・厳密な暗黙・明示的のいずれでもかまいません;インスタンス暗黙のセクション変数は特別に扱われます。
定理以外の宣言でセクション変数名が出現すると、パラメータとして追加されます。その変数に言及しているインスタンス暗黙のセクション変数も追加されます。追加された変数が他の変数に依存している場合は、それらの変数も追加されます;このプロセスは依存が無くなるまで繰り返されます。すべてのセクション変数は、宣言された順に他のすべてのパラメータよりも前に追加されます。セクション変数が追加されるのは、それが定理の 文 の中に現れる時だけです。そうでなければ、証明項がセクション変数を使用している場合、定理の証明を変更によってその文が変更されてしまう可能性があります。
変数は Lean.Parser.Command.variable : 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
コマンドを使って宣言します。
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*
variable
の後ろに許可される括弧付きの束縛子は、定義でのヘッダで使用される構文と一致します。
bracketedBinder ::=((ident |
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)`.
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)?)
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).
bracketedBinder ::= ... |{(ident |
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.
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}
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).
bracketedBinder ::= ... |⦃(ident |
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.
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⦄
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).
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 β) : β :=
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 : command
in
と一緒に使用すると良いでしょう。
セクション変数の 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:Nat → Prop⊢ ∀ (n : Nat), p n
p:Nat → Propn:Nat⊢ p n
p:Nat → Prop⊢ p 0p:Nat → Propn✝: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
theorem p_all : ∀ n, p n := p✝:Nat → ProppFifteen:p✝ 15p:Nat → ProppZero:p 0pStep:∀ (n : Nat), p n → p (n + 1)⊢ ∀ (n : Nat), p n
p✝:Nat → ProppFifteen:p✝ 15p:Nat → ProppZero:p 0pStep:∀ (n : Nat), p n → p (n + 1)n:Nat⊢ p n
p✝:Nat → ProppFifteen:p✝ 15p:Nat → ProppZero:p 0pStep:∀ (n : Nat), p n → p (n + 1)⊢ p 0p✝:Nat → ProppFifteen:p✝ 15p:Nat → ProppZero:p 0pStep:∀ (n : Nat), p n → p (n + 1)n✝:Nata✝:p n✝⊢ p (n✝ + 1) p✝:Nat → ProppFifteen:p✝ 15p:Nat → ProppZero:p 0pStep:∀ (n : Nat), p n → p (n + 1)⊢ p 0p✝:Nat → ProppFifteen:p✝ 15p:Nat → ProppZero:p 0pStep:∀ (n : Nat), p n → p (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:Nat → ProppZero:p 0pStep:∀ (n : Nat), p n → p (n + 1)⊢ ∀ (n : Nat), p n
p:Nat → ProppZero:p 0pStep:∀ (n : Nat), p n → p (n + 1)n:Nat⊢ p n
p:Nat → ProppZero:p 0pStep:∀ (n : Nat), p n → p (n + 1)⊢ p 0p:Nat → ProppZero:p 0pStep:∀ (n : Nat), p n → p (n + 1)n✝:Nata✝:p n✝⊢ p (n✝ + 1) p:Nat → ProppZero:p 0pStep:∀ (n : Nat), p n → p (n + 1)⊢ p 0p:Nat → ProppZero:p 0pStep:∀ (n : Nat), p n → p (n + 1)n✝:Nata✝:p n✝⊢ p (n✝ + 1) All goals completed! 🐙
end
4.2.3.3. スコープ属性(Scoped Attributes)
多くの属性は、適用するスコープを特定のものにすることができます。これによって属性の効果が、現在のセクションスコープでのみ・現在の名前空間を開いている名前空間のみ・どこからでも見ることができるかを決定します。これらのスコープ指定は 構文拡張 や 型クラスインスタンス を制御するためにも使用されます。
グローバルスコープ宣言(デフォルト)は、その宣言が確立された 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