Skip to content
This repository was archived by the owner on Jan 5, 2025. It is now read-only.

Commit c0a76d5

Browse files
authored
ex_03_pretty_printing (#13)
* 翻訳開始 * 翻訳完了
1 parent 431f8ec commit c0a76d5

File tree

6 files changed

+92
-6
lines changed

6 files changed

+92
-6
lines changed

GROSSARY.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
| notation | 記法 |
2727
| parse | パース |
2828
| precedence | 優先順位 |
29+
| pretty print | プリティプリント |
2930
| priority | 優先度 |
3031
| proof term | 証明項 |
3132
| reduction | 簡約 |
@@ -46,5 +47,7 @@
4647
| 用語 |
4748
| --- |
4849
| loose |
50+
| parenthesizer |
4951
| syntax quotation |
5052
| synthetic metavariable |
53+
| unexpander |

lean/extra/03_pretty-printing.lean

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
/- # Extra: Pretty Printing
1+
/-
2+
--#--
3+
# Extra: Pretty Printing
4+
--#--
5+
# 付録:プリティプリント
6+
--#--
27
The pretty printer is what Lean uses to present terms that have been
38
elaborated to the user. This is done by converting the `Expr`s back into
49
`Syntax` and then even higher level pretty printing datastructures. This means
@@ -7,6 +12,10 @@ there has to be code that tells it how to do that.
712
In the big picture, the pretty printer consists of three parts run in the
813
order they are listed in:
914
15+
--#--
16+
プリティプリンタとは、Lean がエラボレートした項をユーザに提示するために使用されるものです。これは `Expr` を `Syntax` に変換し、さらに高レベルのプリティプリント用データ構造に戻すことで行われます。これは Lean が `Expr` を作成する際に使用した実際の `Syntax` を思い出すわけではないことを意味します:もしそうであればその方法を指示するコードがあるはずですから。全体像として、プリティプリンタは3つの部分から構成されています:
17+
18+
--#--
1019
- the **[delaborator](https://github.com/leanprover/lean4/tree/master/src/Lean/PrettyPrinter/Delaborator)**
1120
this will be our main interest since we can easily extend it with our own code.
1221
Its job is to turn `Expr` back into `Syntax`.
@@ -16,18 +25,35 @@ order they are listed in:
1625
responsible for turning the parenthesized `Syntax` tree into a `Format` object that contains
1726
more pretty printing information like explicit whitespaces
1827
28+
--#--
29+
- **[デラボレータ](https://github.com/leanprover/lean4/tree/master/src/Lean/PrettyPrinter/Delaborator)**、この部分は簡単に独自のコードで拡張ができることもあり最も興味深い部分です。このパートの仕事は `Expr` を `Syntax` に戻すことです。
30+
- **[parenthesizer](https://github.com/leanprover/lean4/blob/master/src/Lean/PrettyPrinter/Parenthesizer.lean)** は `Syntax` 木に便利だと思われる位置に括弧を追加する役割を持ちます。
31+
- **[フォーマッタ](https://github.com/leanprover/lean4/blob/master/src/Lean/PrettyPrinter/Formatter.lean)** は括弧が付けられた `Syntax` 木に明示的なスペースを入れるなどのよりプリティプリントな情報を含む `Format` オブジェクトに変換する役割を持ちます。
32+
33+
--#--
1934
## Delaboration
35+
--#--
36+
## デラボレーション
37+
--#--
2038
As its name suggests, the delaborator is in a sense the opposite of the
2139
elaborator. The job of the delaborator is to take an `Expr` produced by
2240
the elaborator and turn it back into a `Syntax` which, if elaborated,
2341
should produce an `Expr` that behaves equally to the input one.
2442
43+
--#--
44+
その名前が示すように、デラボレータはある意味においてエラボレータの反対です。デラボレータの仕事は、エラボレータが生成した `Expr` を受け取り、`Syntax` に戻すことです。ここで生成される `Syntax` はエラボレートされると、デラボレータに入力された `Expr` と同じものを出力しなければなりません。
45+
46+
--#--
2547
Delaborators have the type `Lean.PrettyPrinter.Delaborator.Delab`. This
2648
is an alias for `DelabM Syntax`, where `DelabM` is the delaboration monad.
2749
All of this machinery is defined [here](https://github.com/leanprover/lean4/blob/master/src/Lean/PrettyPrinter/Delaborator/Basic.lean).
2850
`DelabM` provides us with quite a lot of options you can look up in the documentation
2951
(TODO: Docs link). We will merely highlight the most relevant parts here.
3052
53+
--#--
54+
デラボレータは `Lean.PrettyPrinter.Delaborator.Delab` という型を持ちます。これは `DelabM Syntax` のエイリアスで、`DelabM` はデラボレーションのためのモナドです。この機構についてはすべて [ここ](https://github.com/leanprover/lean4/blob/master/src/Lean/PrettyPrinter/Delaborator/Basic.lean) にて定義されています。`DelabM` は非常に多くのオプションを提供しており、これはドキュメントから探すことができます(TODO: Docs link)。ここでは単に最も関連性のある部分を強調します。
55+
56+
--#--
3157
- It has a `MonadQuotation` instance which allows us to declare `Syntax` objects
3258
using the familiar quotation syntax.
3359
- It can run `MetaM` code.
@@ -36,13 +62,26 @@ All of this machinery is defined [here](https://github.com/leanprover/lean4/blob
3662
- You can obtain the current subexpression using `SubExpr.getExpr`. There is
3763
also an entire API defined around this concept in the `SubExpr` module.
3864
65+
--#--
66+
- `MonadQuotation` インスタンスを持っており、おなじみのquotation構文を使って `Syntax` オブジェクトを宣言することができます。
67+
- `MetaM` のコードを実行することができます。
68+
- 例外を投げるための `MonadExcept` インスタンスを持ちます。
69+
- `whenPPOption` のような関数を使うことで `pp` オプションを操作することができます。
70+
- 現在の部分式を取得するには `SubExpr.getExpr` を使用します。また、`SubExpr` モジュールには、この概念を扱う API 全体が定義されています。
71+
72+
--#--
3973
### Making our own
74+
--#--
75+
### 独自のデラボレータを作る
76+
--#--
4077
Like so many things in metaprogramming the elaborator is based on an attribute,
4178
in this case the `delab` one. `delab` expects a `Name` as an argument,
4279
this name has to start with the name of an `Expr` constructor, most commonly
4380
`const` or `app`. This constructor name is then followed by the name of the
4481
constant we want to delaborate. For example, if we want to delaborate a function
4582
`foo` in a special way we would use `app.foo`. Let's see this in action:
83+
--#--
84+
メタプログラミングの多くのものと同様に、エラボレータは属性に基づいており、今回の場合では `delab` です。`delab` は引数として `Name` を受け取り、この名前は `Expr` コンストラクタの名前で始まる必要があり、最も一般的あなのは `const` か `app` です。このコンストラクタ名の後にデラボレートしたい定数の名前が続きます。例えば、関数 `foo` を特別な方法でデラボレートしたい場合は `app.foo` を使います。これを実際にやってみましょう:
4685
-/
4786

4887
import Lean
@@ -59,9 +98,12 @@ def delabFoo : Delab := do
5998
#check foo 13 -- 1 : Nat, full applications are also pretty printed this way
6099

61100
/-!
101+
--#--
62102
This is obviously not a good delaborator since reelaborating this `Syntax`
63103
will not yield the same `Expr`. Like with many other metaprogramming
64104
attributes we can also overload delaborators:
105+
--#--
106+
この `Syntax` を再度エラボレートしても同じ `Expr` は得られないため、明らかに良いデラボレータではありません。他の多くのメタプログラミングの属性と同様に、デラボレータをオーバーロードすることもできます:
65107
-/
66108

67109
@[delab app.foo]
@@ -71,10 +113,13 @@ def delabfoo2 : Delab := do
71113
#check foo -- 2 : Nat → Nat
72114

73115
/-!
116+
--#--
74117
The mechanism for figuring out which one to use is the same as well. The
75118
delaborators are tried in order, in reverse order of registering, until one
76119
does not throw an error, indicating that it "feels unresponsible for the `Expr`".
77120
In the case of delaborators, this is done using `failure`:
121+
--#--
122+
それを使うかを判断するメカニズムも同じです。デラボレータは登録された順番の逆順に、「`Expr` に対して責任が無いと感じる」ことを示すエラーを投げないものまで試行されます。デラボレータの場合、これは `failure` を使って行われます:
78123
-/
79124

80125
@[delab app.foo]
@@ -85,8 +130,11 @@ def delabfoo3 : Delab := do
85130
#check foo -- 2 : Nat → Nat, still 2 since 3 failed
86131

87132
/-!
133+
--#--
88134
In order to write a proper delaborator for `foo`, we will have to use some
89135
slightly more advanced machinery though:
136+
--#--
137+
`foo` のための適切なデラボレータを書くためにはもう少し高度な機構を使う必要があります:
90138
-/
91139

92140
@[delab app.foo]
@@ -101,9 +149,14 @@ def delabfooFinal : Delab := do
101149
#check foo -- 2 : Nat → Nat, still 2 since 3 failed
102150

103151
/-!
152+
--#--
104153
Can you extend `delabFooFinal` to also account for non full applications?
105154
155+
--#--
156+
読者は `delabFooFinal` を拡張して、完全でない適用も考慮することができるでしょうか?
157+
106158
## Unexpanders
159+
--#--
107160
While delaborators are obviously quite powerful it is quite often not necessary
108161
to use them. If you look in the Lean compiler for `@[delab` or rather `@[builtin_delab`
109162
(a special version of the `delab` attribute for compiler use, we don't care about it),
@@ -115,21 +168,35 @@ they are of type `Lean.PrettyPrinter.Unexpander` which in turn is an alias for
115168
are supposed to be the inverse of macros. The `UnexpandM` monad is quite a lot
116169
weaker than `DelabM` but it still has:
117170
171+
--#--
172+
デラボレータは明らかに強力ですが、使う必要がないことも良くあります。Lean コンパイラにて `@[delab` か `@[builtin_delab`(コンパイラ用の特別バージョンの `delab` 属性)を探してみるとほとんど出てこないことがわかるでしょう。というのも、プリティプリントの大部分はいわゆる unexpander によって行われるからです。デラボレータとは異なり、これらは `Lean.PrettyPrinter.Unexpander` 型で、これは `Syntax → Lean.PrettyPrinter.UnexpandM Syntax` のエイリアスです。見ての通り、これらは `Syntax` から `Syntax` への変換で、マクロの逆であることを除けばマクロによく似ています。`UnexpandM` モナドは `DelabM` よりもかなり弱いですが、それでも下記の機能を持ちます:
173+
174+
--#--
118175
- `MonadQuotation` for syntax quotations
119176
- The ability to throw errors, although not very informative ones: `throw ()`
120177
is the only valid one
121178
179+
--#--
180+
- syntax quotation のための `MonadQuotation`
181+
- 例外の送出機能、ただこれはあまり有益なものではありません:唯一有効なのは `throw ()` だけです。
182+
183+
--#--
122184
Unexpanders are always specific to applications of one constant. They are registered
123185
using the `app_unexpander` attribute, followed by the name of said constant. The unexpander
124186
is passed the entire application of the constant after the `Expr` has been delaborated,
125187
without implicit arguments. Let's see this in action:
188+
--#--
189+
unexpander は常にある1つの定数の適用に対して固有です。これらは `app_unexpander` 属性と、それに続く対象の定数名を使って登録されます。unexpander には暗黙の引数無しで `Expr` がデラボレートされた後に、定数の適用全体が渡されます。これを実際に見てみましょう:
126190
-/
127191

128192
def myid {α : Type} (x : α) := x
129193

130194
@[app_unexpander myid]
131195
def unexpMyId : Unexpander
196+
--#--
132197
-- hygiene disabled so we can actually return `id` without macro scopes etc.
198+
--#--
199+
-- 健全性を無効にすることで、マクロスコープなどを使わずに `id` を実際に返すことができる。
133200
| `(myid $arg) => set_option hygiene false in `(id $arg)
134201
| `(myid) => pure $ mkIdent `id
135202
| _ => throw ()
@@ -138,15 +205,25 @@ def unexpMyId : Unexpander
138205
#check myid -- id : ?m.3870 → ?m.3870
139206

140207
/-!
208+
--#--
141209
For a few nice examples of unexpanders you can take a look at
142210
[NotationExtra](https://github.com/leanprover/lean4/blob/master/src/Init/NotationExtra.lean)
143211
212+
--#--
213+
unexpander についていくつかの良例は [NotationExtra](https://github.com/leanprover/lean4/blob/master/src/Init/NotationExtra.lean) を参照してください。
214+
215+
--#--
144216
### Mini project
217+
--#--
218+
### ミニプロジェクト
219+
--#--
145220
As per usual, we will tackle a little mini project at the end of the chapter.
146221
This time we build our own unexpander for a mini programming language.
147222
Note that many ways to define syntax already have generation of the required
148223
pretty printer code built-in, e.g. `infix`, and `notation` (however not `macro_rules`).
149224
So, for easy syntax, you will never have to do this yourself.
225+
--#--
226+
いつものように、章の最後にてちょっとしたミニプロジェクトに取り組んでみます。今回はミニプログラミング言語のための独自の unexpander を作ります。`infix` や `notation` のような構文を定義するための多くの方法には必要なプリティプリンタコードを生成する機能がすでに組み込まれていることに注意してください(ただし、`macro_rules` には含まれていません)。そのため、簡単な構文であれば、自分でこれを行う必要はないでしょう。
150227
-/
151228

152229
declare_syntax_cat lang
@@ -180,8 +257,11 @@ instance : Coe Ident (TSyntax `lang) where
180257
]
181258

182259
/-!
260+
--#--
183261
As you can see, the pretty printing output right now is rather ugly to look at.
184262
We can do better with an unexpander:
263+
--#--
264+
見ての通り、現時点の表示される出力はかなり醜いものになっています。unexpander を使えばもっとよくなります:
185265
-/
186266

187267
@[app_unexpander LangExpr.numConst]
@@ -218,7 +298,10 @@ def unexpandLet : Unexpander
218298
]
219299

220300
/-!
301+
--#--
221302
That's much better! As always, we encourage you to extend the language yourself
222303
with things like parenthesized expressions, more data values, quotations for
223304
`term` or whatever else comes to your mind.
305+
--#--
306+
この方がずっと良いです!いつものように読者は、括弧でくくられた式や、より多くのデータ値、`term` の引用など思いついたものを使って自分で言語を拡張することをお勧めします。
224307
-/

lean/main/05_syntax.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -672,7 +672,7 @@ it to match on your own syntax categories you will have to use `` `(category| ..
672672
--#--
673673
### Mini Project
674674
--#--
675-
### 小さいプロジェクト
675+
### ミニプロジェクト
676676
--#--
677677
As a final mini project for this chapter we will declare the syntax of a mini
678678
arithmetic expression language and a function of type `Syntax → Nat` to evaluate

lean/main/06_macros.lean

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -657,13 +657,13 @@ for a good user experience.
657657
--#--
658658
## Mini project
659659
--#--
660-
## 小さいプロジェクト
660+
## ミニプロジェクト
661661
--#--
662662
As a final mini project for this section we will re-build the arithmetic
663663
DSL from the syntax chapter in a slightly more advanced way, using a macro
664664
this time so we can actually fully integrate it into the Lean syntax.
665665
--#--
666-
この節の最後の小さいプロジェクトとして、構文の章で出てきた算術 DSL を、今回はマクロを使ってもう少し高度な方法で再構築し、実際に Lean の構文に完全に統合できるようにします。
666+
この節の最後のミニプロジェクトとして、構文の章で出てきた算術 DSL を、今回はマクロを使ってもう少し高度な方法で再構築し、実際に Lean の構文に完全に統合できるようにします。
667667
-/
668668
declare_syntax_cat arith
669669

lean/main/07_elaboration.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ This is actually extending the original `#check`
233233
--#--
234234
### Mini project
235235
--#--
236-
### 小さいプロジェクト
236+
### ミニプロジェクト
237237
--#--
238238
As a final mini project for this section let's build a command elaborator
239239
that is actually useful. It will take a command and use the same mechanisms

md/SUMMARY.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
- [オプション](./extra/01_options.md)
2323
<!-- - [Attributes]() -->
24-
- [Pretty Printing](./extra/03_pretty-printing.md)
24+
- [プリティプリント](./extra/03_pretty-printing.md)
2525

2626
<!-- # Solutions -->
2727

0 commit comments

Comments
 (0)