-
-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1284 from lean-ja/Seasawher/issue276
暗黙の引数 `{x y : A}` を紹介する
- Loading branch information
Showing
7 changed files
with
136 additions
and
78 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,97 +1,52 @@ | ||
/- # \#check | ||
`#check` コマンドは、項の型を表示します。Lean ではすべての項に型があるので、どんな項にも使えます。`#check term` というコマンドで、`term` の型を表示します。逆に `term` の型が `T` であることを確かめるには [`example`](../Declarative/Example.md) コマンドを使用して `example : T := term` とします。 | ||
`#check` コマンドは、項の型を表示します。Lean ではすべての項に型があるので、どんな項にも使えます。`#check term` というコマンドで、`term` の型を表示します。-/ | ||
|
||
## 基本的な項の型 -/ | ||
|
||
-- 文字 | ||
-- 文字 `Char` | ||
#check 'a' | ||
|
||
-- 文字列 | ||
-- 文字列 String | ||
#check "Hello" | ||
|
||
-- 自然数 | ||
-- 自然数 Nat | ||
#check 1 | ||
|
||
-- 浮動小数点数 | ||
-- 浮動小数点数 Float | ||
#check 1.0 | ||
|
||
-- 整数 | ||
-- 整数 Int | ||
#check -2 | ||
|
||
-- `1` はそのままだと自然数扱いになるが、整数にキャストできる | ||
#check (1 : Int) | ||
|
||
-- 自然数のリスト | ||
#check [1, 2, 3] | ||
#check ([1, 2, 3] : List Nat) | ||
|
||
-- 自然数の配列 | ||
#check #[1, 2, 3] | ||
#check (#[1, 2, 3] : Array Nat) | ||
|
||
-- 関数 | ||
#check fun x ↦ x + 42 | ||
#check (fun x ↦ x + 42 : Nat → Nat) | ||
|
||
-- Bool, 真偽値 | ||
-- 真偽値 Bool | ||
#check true | ||
|
||
-- 命題 | ||
-- 命題 Prop | ||
#check True | ||
|
||
/- ## 型の型 | ||
「すべての」項には型があるので、型も型を持ちます。 | ||
-/ | ||
-- 宇宙変数を宣言する | ||
universe u | ||
|
||
#check (Prop : Type) | ||
|
||
-- Lean では `List` は Type を受け取って、Type を返す関数。 | ||
#check (List : (α : Type u) → Type u) | ||
/- 逆に `term` の型が `T` であることを確かめるには [`example`](../Declarative/Example.md) コマンドを使用して `example : T := term` とします。 -/ | ||
|
||
-- 配列も同じ。型を型に変換する関数。 | ||
#check (Array : (α : Type u) → Type u) | ||
example : Nat := 42 | ||
|
||
-- `Type` 自身も型を持っており… | ||
#check (Type : Type 1) | ||
|
||
#check (Type 1 : Type 2) | ||
|
||
-- この調子で限りなく続く | ||
#check (Type u : Type (u + 1)) | ||
|
||
/- ## 命題と証明 | ||
Lean では命題やその証明にも型があります。命題の型は `Prop` で、命題の項が証明になっています。逆に言えば、Lean ではある命題 `P : Prop` を証明するということは、`P` という型を持つ項 `proof : P` を構成することと同じです。 | ||
-/ | ||
example : Int := - 13 | ||
|
||
#check (1 + 1 = 2 : Prop) | ||
|
||
-- `1 + 1 = 2` の証明 `two_eq_add_one` を構成 | ||
theorem two_eq_add_one : 2 = 1 + 1 := by rfl | ||
|
||
-- 証明の型が命題になっている | ||
#check (two_eq_add_one : 2 = 1 + 1) | ||
|
||
/- ## 型としての True/False | ||
`True` は型としては一点集合であり、 | ||
`False` は型としては空集合です。 | ||
-/ | ||
|
||
-- `trivial : True` は `True` 型を持つ項 | ||
#check trivial | ||
|
||
/- ## 関数としての証明 | ||
命題 `P → Q` の証明は、`P → Q` という型を持つ項です。 | ||
つまり、`P` の証明 `h : P` に対して `Q` の証明を返す関数です。 | ||
/- ## 型の型 | ||
「すべての」項には型があるので、型も型を持ちます。多くの組み込み型の型は [`Type`](#{root}/Type/Type.md) になっています。 | ||
-/ | ||
|
||
theorem tautology : True -> True := fun a ↦ a | ||
|
||
-- 暗黙の変数を明示的にするために `@` を付けた。 | ||
-- `tautology : True → True` と出力されるので、 | ||
-- `tautology` は `True → True` という関数であることがわかる | ||
#check (@tautology : True → True) | ||
-- 文字列型の型は Type | ||
#check (String : Type) | ||
|
||
-- 実際に `trivial : True` を「代入」すると | ||
-- `tautology trivial : True` となり、 | ||
-- 確かに `True` 型の項が得られていることがわかる。 | ||
#check (tautology trivial : True) | ||
-- 自然数型の型は Type | ||
#check (Nat : Type) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
/- # 暗黙の引数 | ||
暗黙の引数とは、[`def`](#{root}/Declarative/Def.md) コマンドや [`theorem`](#{root}/Declarative/Theorem.md) コマンド、[`variable`](#{root}/Declarative/Variable.md) コマンドなどが受け取る構文の一つで、関数や定理の引数をユーザが明示的に与えなくても、Lean が文脈を読んで推論してくれるようになります。波括弧 `{}` で囲んで、`{x y : A}` のように書きます。 | ||
## 典型的な使用例 | ||
たとえば、暗黙の引数を使わなかった場合にどうなるかを見てみましょう。次の関数 `List.subs` は型パラメータ `α : Type` を受け取っていますが、第二引数 `xs : List α` を見れば `α : Type` が何であるかは分かるので、`List.subs` を使用する際に毎回 `α` を指定するのは冗長だと考えられます。 | ||
-/ | ||
import Lean --# | ||
|
||
/-- 与えられたリストの部分リストを全て返す(明示的引数バージョン) -/ | ||
def List.subsₑ (α : Type) (xs : List α) : List (List α) := | ||
match xs with | ||
| [] => [[]] | ||
| x :: xs => | ||
let xss := subsₑ α xs | ||
xss ++ xss.map (x :: ·) | ||
|
||
-- 型引数 α を明示的に与える必要がある | ||
#eval List.subsₑ Nat [1, 2] | ||
|
||
-- 型引数を与えないと(当然ながら)エラーになってしまう | ||
#guard_msgs (drop warning) in --# | ||
#check_failure List.subs [1, 2] | ||
|
||
/- 引数 `α` を暗黙の引数として受け取るように変更すれば、Lean が `α : Type` の内容を推論してくれるようになり、`α` を省略できるようになります。-/ | ||
|
||
/-- 与えられたリストの部分リストを全て返す(暗黙引数バージョン) -/ | ||
def List.subsᵢ {α : Type} (xs : List α) : List (List α) := | ||
match xs with | ||
| [] => [[]] | ||
| x :: xs => | ||
let xss := subsᵢ xs | ||
xss ++ xss.map (x :: ·) | ||
|
||
-- 型引数を省略できるようになった | ||
#eval List.subsᵢ [1, 2] | ||
|
||
-- 逆に今度は型引数を与えるとエラーになる | ||
#guard_msgs (drop warning) in --# | ||
#check_failure List.subsᵢ Nat [1, 2] | ||
|
||
/- ## 明示引数モード | ||
暗黙の引数を受け取るものとして定義された関数や定理に対して、`@` 記号を先頭に付けると全ての暗黙の引数が明示的引数に変化します。 | ||
-/ | ||
|
||
-- 2 つの暗黙引数を持つ関数 | ||
def List.map' {α β : Type} (f : α → β) : List α → List β | ||
| [] => [] | ||
| x :: xs => f x :: map' f xs | ||
|
||
-- 普通は次のように使う | ||
#check List.map' (fun x => x == 1) [1, 2, 3] | ||
|
||
-- `@` 記号を付けると全ての引数が明示的引数に変化 | ||
#check @List.map' Nat Bool (fun x => x == 1) [1, 2, 3] | ||
|
||
/- ## 構文についての補足 | ||
`Lean.Parser.Term.implicitBinder` というパーサが暗黙引数の構文に対応しています。-/ | ||
|
||
open Lean Elab Command in | ||
|
||
/-- ドキュメントコメントを取得して表示するコマンド -/ | ||
elab "#doc " x:ident : command => do | ||
let name ← liftCoreM do realizeGlobalConstNoOverload x | ||
if let some s ← findDocString? (← getEnv) name then | ||
logInfo m!"{s}" | ||
|
||
/-- | ||
info: 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. | ||
-/ | ||
#guard_msgs in | ||
#doc Lean.Parser.Term.implicitBinder | ||
|
||
/- 上記のドキュメントコメントにも書かれていますが、構文としては暗黙の引数に型を指定しないことも許されます。 -/ | ||
|
||
-- `x : α` と書いたので、`α` が何かの型であることは分かる | ||
def myId {α} (x : α) := x |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/- # 構文 -/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters