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

Commit 0537885

Browse files
authored
08_dsls (#9)
* 翻訳開始 * 翻訳完了
1 parent d8a0d6e commit 0537885

File tree

2 files changed

+95
-3
lines changed

2 files changed

+95
-3
lines changed

lean/main/08_dsls.lean

Lines changed: 94 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,53 @@
11
/-
2+
--#--
23
# Embedding DSLs By Elaboration
34
5+
--#--
6+
# エラボレーションによる DSL の埋め込み
7+
8+
--#--
49
In this chapter we will learn how to use elaboration to build a DSL. We will not
510
explore the full power of `MetaM`, and simply gesture at how to get access to
611
this low-level machinery.
712
13+
--#--
14+
この章では DSL を構築するためにどのようにエラボレーションを使うかについて学びます。ここでは `MetaM` の全機能を探求することはせずに、単にこの低レベルの機構にアクセスする方法を紹介します。
15+
16+
--#--
817
More precisely, we shall enable Lean to understand the syntax of
918
[IMP](http://concrete-semantics.org/concrete-semantics.pdf),
1019
which is a simple imperative language, often used for teaching operational and
11-
denotational semantics.
20+
denotational semantics.
21+
22+
--#--
23+
具体的には、[IMP](http://concrete-semantics.org/concrete-semantics.pdf) の構文を Lean が理解できるようにします。これは単純な命令型言語で、操作的意味論・表示的意味論の教育によく用いられます。
1224
25+
--#--
1326
We are not going to define everything with the same encoding that the book does.
1427
For instance, the book defines arithmetic expressions and boolean expressions.
1528
We, will take a different path and just define generic expressions that take
1629
unary or binary operators.
1730
31+
--#--
32+
この本と同じエンコーディングですべてを定義するつもりはありません。例えば、この本では算術式や真偽値の式を定義しています。本章では別の方針を取り、単項演算子や二項演算子を取る一般的な式を定義します。
33+
34+
--#--
1835
This means that we will allow weirdnesses like `1 + true`! But it will simplify
1936
the encoding, the grammar and consequently the metaprogramming didactic.
2037
38+
--#--
39+
つまり、`1 + true` のような奇妙さを許容します!しかし、これはエンコーディングや文法、ひいてはメタプログラミングの教材として単純化することになります。
40+
41+
--#--
2142
## Defining our AST
2243
44+
--#--
45+
## AST の定義
46+
47+
--#--
2348
We begin by defining our atomic literal value.
49+
--#--
50+
まず、アトミックなリテラルの値を定義します。
2451
-/
2552

2653
import Lean
@@ -31,16 +58,31 @@ inductive IMPLit
3158
| nat : Nat → IMPLit
3259
| bool : Bool → IMPLit
3360

61+
--#--
3462
/- This is our only unary operator -/
63+
--#--
64+
/-
65+
次は唯一の単項演算子です。
66+
-/
3567
inductive IMPUnOp
3668
| not
3769

70+
--#--
3871
/- These are our binary operations. -/
72+
--#--
73+
/-
74+
これらは二項演算子です。
75+
-/
3976

4077
inductive IMPBinOp
4178
| and | add | less
4279

80+
--#--
4381
/- Now we define the expressions that we want to handle. -/
82+
--#--
83+
/-
84+
ここで、今回扱いたい式を定義します。
85+
-/
4486

4587
inductive IMPExpr
4688
| lit : IMPLit → IMPExpr
@@ -49,8 +91,11 @@ inductive IMPExpr
4991
| bin : IMPBinOp → IMPExpr → IMPExpr → IMPExpr
5092

5193
/-
94+
--#--
5295
And finally the commands of our language. Let's follow the book and say that
5396
"each piece of a program is also a program":
97+
--#--
98+
そして最後に、言語のコマンドです。この本に従って、「プログラムの各部分もプログラムである」としましょう:
5499
-/
55100

56101
inductive IMPProgram
@@ -61,11 +106,18 @@ inductive IMPProgram
61106
| While : IMPExpr → IMPProgram → IMPProgram
62107

63108
/-
109+
--#--
64110
## Elaborating literals
65111
112+
--#--
113+
### リテラルのエラボレート
114+
115+
--#--
66116
Now that we have our data types, let's elaborate terms of `Syntax` into
67117
terms of `Expr`. We begin by defining the syntax and an elaboration function for
68118
literals.
119+
--#--
120+
さて、データ型ができたので、`Syntax` の項を `Expr` の項にエラボレートしましょう。まずはリテラルの構文とそのエラボレーション関数を定義します。
69121
-/
70122

71123
declare_syntax_cat imp_lit
@@ -74,8 +126,12 @@ syntax "true" : imp_lit
74126
syntax "false" : imp_lit
75127

76128
def elabIMPLit : Syntax → MetaM Expr
129+
--#--
77130
-- `mkAppM` creates an `Expr.app`, given the function `Name` and the args
78131
-- `mkNatLit` creates an `Expr` from a `Nat`
132+
--#--
133+
-- `mkAppM` は対象の関数の `Name` とその引数から `Expr.app` を作成する
134+
-- `mkNatLit` は `Nat` から `Expr` を作成する
79135
| `(imp_lit| $n:num) => mkAppM ``IMPLit.nat #[mkNatLit n.getNat]
80136
| `(imp_lit| true ) => mkAppM ``IMPLit.bool #[.const ``Bool.true []]
81137
| `(imp_lit| false ) => mkAppM ``IMPLit.bool #[.const ``Bool.false []]
@@ -88,14 +144,26 @@ elab "test_elabIMPLit " l:imp_lit : term => elabIMPLit l
88144
#reduce test_elabIMPLit false -- IMPLit.bool true
89145

90146
/-
147+
--#--
91148
## Elaborating expressions
92149
150+
--#--
151+
## 式のエラボレート
152+
153+
--#--
93154
In order to elaborate expressions, we also need a way to elaborate our unary and
94155
binary operators.
95156
157+
--#--
158+
式をエラボレートするために、単項演算子と二項演算子をエラボレートする方法も必要です。
159+
160+
--#--
96161
Notice that these could very much be pure functions (`Syntax → Expr`), but we're
97162
staying in `MetaM` because it allows us to easily throw an error for match
98-
completion.-/
163+
completion.
164+
--#--
165+
これらは純粋関数(`Syntax → Expr`)にすることもできますが、マッチの網羅時に例外を簡単に投げられるように `MetaM` に留まることとします。
166+
-/
99167

100168
declare_syntax_cat imp_unop
101169
syntax "not" : imp_unop
@@ -115,7 +183,12 @@ def elabIMPBinOp : Syntax → MetaM Expr
115183
| `(imp_binop| <) => return .const ``IMPBinOp.less []
116184
| _ => throwUnsupportedSyntax
117185

186+
--#--
118187
/-Now we define the syntax for expressions: -/
188+
--#--
189+
/-
190+
ここで式の構文を定義します:
191+
-/
119192

120193
declare_syntax_cat imp_expr
121194
syntax imp_lit : imp_expr
@@ -124,24 +197,33 @@ syntax imp_unop imp_expr : imp_expr
124197
syntax imp_expr imp_binop imp_expr : imp_expr
125198

126199
/-
200+
--#--
127201
Let's also allow parentheses so the IMP programmer can denote their parsing
128202
precedence.
203+
--#--
204+
IMP プログラマがパースの優先順位を示せるように括弧も許可しましょう。
129205
-/
130206

131207
syntax "(" imp_expr ")" : imp_expr
132208

133209
/-
210+
--#--
134211
Now we can elaborate our expressions. Note that expressions can be recursive.
135212
This means that our `elabIMPExpr` function will need to be recursive! We'll need
136213
to use `partial` because Lean can't prove the termination of `Syntax`
137214
consumption alone.
215+
--#--
216+
これで式をエラボレートできます。式は再帰的であることに注意してください。これは `elabIMPExpr` 関数が再帰的である必要があることを意味します!Lean は `Syntax` の消費だけでは終了を証明できないため `partial` を使う必要があります。
138217
-/
139218

140219
partial def elabIMPExpr : Syntax → MetaM Expr
141220
| `(imp_expr| $l:imp_lit) => do
142221
let l ← elabIMPLit l
143222
mkAppM ``IMPExpr.lit #[l]
223+
--#--
144224
-- `mkStrLit` creates an `Expr` from a `String`
225+
--#--
226+
-- `mkStrLit` は `String` から `Expr` を作成する
145227
| `(imp_expr| $i:ident) => mkAppM ``IMPExpr.var #[mkStrLit i.getId.toString]
146228
| `(imp_expr| $b:imp_unop $e:imp_expr) => do
147229
let b ← elabIMPUnOp b
@@ -167,9 +249,16 @@ elab "test_elabIMPExpr " e:imp_expr : term => elabIMPExpr e
167249
-- IMPExpr.bin IMPBinOp.add (IMPExpr.lit (IMPLit.nat 1)) (IMPExpr.lit (IMPLit.bool true))
168250

169251
/-
252+
--#--
170253
## Elaborating programs
171254
255+
--#--
256+
## プログラムのエラボレート
257+
258+
--#--
172259
And now we have everything we need to elaborate our IMP programs!
260+
--#--
261+
そしてこれで IMP プログラムをエラボレートするために必要なものがすべて手に入りました!
173262
-/
174263

175264
declare_syntax_cat imp_program
@@ -203,8 +292,11 @@ partial def elabIMPProgram : Syntax → MetaM Expr
203292
| _ => throwUnsupportedSyntax
204293

205294
/-
295+
--#--
206296
And we can finally test our full elaboration pipeline. Let's use the following
207297
syntax:
298+
--#--
299+
そしてついにエラボレーションのパイプラインを完全にテストすることができます。以下の構文を使ってみましょう:
208300
-/
209301

210302
elab ">>" p:imp_program "<<" : term => elabIMPProgram p

md/SUMMARY.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
- [構文](./main/05_syntax.md)
1212
- [マクロ](./main/06_macros.md)
1313
- [エラボレーション](./main/07_elaboration.md)
14-
- [Embedding DSLs By Elaboration](./main/08_dsls.md)
14+
- [エラボレーションによる DSL の埋め込み](./main/08_dsls.md)
1515
- [Tactics](./main/09_tactics.md)
1616
- [Lean4 Cheat-sheet](./main/10_cheat-sheet.md)
1717

0 commit comments

Comments
 (0)