# 機能設計書 80-呼び出し下降変換

## 概要

本ドキュメントは、F#コンパイラにおける呼び出し式の下降変換（Lowering）処理の設計を記述する。LowerCallsモジュールは、アリティ（引数の数）が静的に既知の値に対して、eta展開とベータ簡約を適用し、部分適用を最適化する。

### 本機能の処理概要

**業務上の目的・背景**：F#はカリー化された関数を広く使用する言語であり、関数が部分適用されることが多い。部分適用された関数は、クロージャの生成やラムダ式の作成など、実行時オーバーヘッドを伴う。LowerCallsは、コンパイル時に既知のアリティ情報を使用して、これらの部分適用を効率的なコードに変換する最適化パスを提供する。

**機能の利用シーン**：コンパイラの最適化フェーズで、型チェック済みの式木（TypedTree）を走査し、部分適用パターンを検出して変換する。これは、後続のピープホール最適化（opt.fs）の前処理として機能する。

**主要な処理内容**：
1. 式木の再帰的走査（RewriteImplFile）
2. Val式のアリティに基づく調整
3. App式の引数数とアリティの比較
4. 不足引数へのeta展開
5. ベータ簡約の適用

**関連システム・外部連携**：TypedTree（型付き構文木）、TypedTreeOps（式木操作）、DiagnosticsLogger（診断ログ）と連携する。

**権限による制御**：本機能に特別な権限制御は存在しない。

## 関連画面

本機能はコンパイラ内部機能であり、直接関連する画面は存在しない。

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | - |

## 機能種別

最適化 / 式変換 / コード生成前処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| g | TcGlobals | Yes | 型チェック用グローバル環境 | null不可 |
| assembly | CheckedImplFile | Yes | 型チェック済み実装ファイル | null不可 |

### 入力データソース

- 型チェック済み式木（TypedTree）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 変換済みassembly | CheckedImplFile | 下降変換された実装ファイル |

### 出力先

- 後続の最適化パス（opt.fs）

## 処理フロー

### 処理シーケンス

```
【LowerImplFile】
1. RewriteEnvを構築
   - PreIntercept: InterceptExpr g
   - PostTransform: なし
   - RewriteQuotations: false
2. RewriteImplFileで式木を再帰走査
3. 変換済み式木を返却

【InterceptExpr】
1. 式パターンマッチ
   - Expr.Val: ValReprInfoがあればAdjustValForExpectedValReprInfo
   - Expr.App(Expr.Val...): アリティと引数数を比較して必要に応じて調整
   - Expr.App(一般): MakeApplicationAndBetaReduceを適用
2. 変換結果またはNoneを返却
```

### フローチャート

```mermaid
flowchart TD
    A[LowerImplFile] --> B[RewriteEnv構築]
    B --> C[RewriteImplFile]
    C --> D{式の種類?}
    D -->|Expr.Val| E{ValReprInfoあり?}
    E -->|Yes| F[AdjustValForExpectedValReprInfo]
    E -->|No| G[None返却]
    D -->|Expr.App Val| H{引数不足?}
    H -->|Yes| I[AdjustVal + MakeApplicationAndBetaReduce]
    H -->|No| J[MakeApplicationAndBetaReduce]
    D -->|Expr.App 一般| K[MakeApplicationAndBetaReduce]
    D -->|その他| L[None返却]
    F --> M[Some変換結果]
    I --> M
    J --> M
    K --> M
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-80-01 | アリティ比較 | ValReprInfo.AritiesOfArgs.Length > argsl.Lengthで部分適用を検出 | App式処理時 |
| BR-80-02 | Eta展開 | 引数不足時にAdjustValForExpectedValReprInfoでラムダ展開 | 部分適用検出時 |
| BR-80-03 | ベータ簡約 | MakeApplicationAndBetaReduceで不要なラムダを除去 | 適用式変換時 |
| BR-80-04 | Quotation除外 | RewriteQuotations=falseでクォート式は変換しない | 常時 |
| BR-80-05 | スタックガード | StackGuardで深い再帰を防止 | 常時 |

### 計算ロジック

- 部分適用判定: `valReprInfo.AritiesOfArgs.Length > argsl.Length`
- 変換対象: Expr.Val（単独）、Expr.App（適用式）

## データベース操作仕様

本機能はデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| StackOverflow | 例外 | 深すぎる式木 | StackGuardで検出 |

### リトライ仕様

特になし。変換は一度のみ実行される。

## トランザクション仕様

本機能はトランザクション管理を必要としない。

## パフォーマンス要件

- 式木を1回のパスで走査
- 変換が必要な箇所のみ処理（Some返却）
- 変換不要な箇所はNone返却でスキップ

## セキュリティ考慮事項

- コンパイラ内部処理のため外部入力は関与しない
- 式木は型チェック済みで安全

## 備考

- 本変換の結果はopt.fsのピープホール最適化でさらに最適化される
- RewriteQuotations=falseにより、Quotation内の式は変換されない
- InterceptExprはPreInterceptとして設定され、式の評価前に呼び出される

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | LowerCalls.fs | `src/Compiler/Optimize/LowerCalls.fs` | LowerImplFile関数 |

**主要処理フロー**:
- **43-50行目**: LowerImplFile - エントリーポイント
- **44-49行目**: rwenv構築 - RewriteEnvの設定
- **45行目**: PreIntercept設定 - InterceptExpr g
- **49行目**: StackGuard - 再帰深度の制限
- **50行目**: RewriteImplFile呼び出し - 式木の再帰走査

**読解のコツ**: RewriteImplFileはTypedTreeOpsで定義されており、式木を再帰的に走査してPreInterceptを適用する。

#### Step 2: 式変換ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | LowerCalls.fs | `src/Compiler/Optimize/LowerCalls.fs` | InterceptExpr関数 |

**主要処理フロー**:
- **12-37行目**: InterceptExpr - 式のインターセプト
- **14-18行目**: Expr.Val処理 - 値参照の変換
- **21-32行目**: Expr.App(Expr.Val...)処理 - 関数適用の変換
- **27-29行目**: アリティ比較 - 部分適用の検出
- **34-35行目**: Expr.App一般処理 - ベータ簡約の適用

**読解のコツ**: パターンマッチの順序が重要。まずExpr.App(Expr.Val...)を処理し、マッチしなければExpr.App一般を処理。

#### Step 3: 依存関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | TypedTreeOps.fs | `src/Compiler/Checking/TypedTreeOps.fs` | AdjustValForExpectedValReprInfo |
| 3-2 | TypedTreeOps.fs | `src/Compiler/Checking/TypedTreeOps.fs` | MakeApplicationAndBetaReduce |

**主要処理フロー**:
- AdjustValForExpectedValReprInfo: 値のアリティ情報に基づいてラムダ式を構築
- MakeApplicationAndBetaReduce: 適用式を構築し、可能であればベータ簡約を適用

### プログラム呼び出し階層図

```
コンパイラ最適化パス
    │
    └─ LowerCalls.LowerImplFile(g, assembly)
           │
           ├─ RewriteEnv構築
           │      │
           │      ├─ PreIntercept = InterceptExpr g
           │      │
           │      └─ StackGuard("LowerCallsRewriteStackGuardDepth")
           │
           └─ TypedTreeOps.RewriteImplFile(rwenv)
                  │
                  └─ 式木を再帰走査
                         │
                         └─ InterceptExpr(g, cont, expr)
                                │
                                ├─ Expr.Val(vref, flags, m)
                                │      │
                                │      └─ AdjustValForExpectedValReprInfo
                                │
                                ├─ Expr.App(Expr.Val(...), ...)
                                │      │
                                │      ├─ cont(引数)で再帰処理
                                │      │
                                │      ├─ アリティ比較
                                │      │      │
                                │      │      └─ AdjustVal（必要時）
                                │      │
                                │      └─ MakeApplicationAndBetaReduce
                                │
                                └─ Expr.App(f0, ...)
                                       │
                                       └─ MakeApplicationAndBetaReduce
```

### データフロー図

```
[入力]                    [処理]                              [出力]

CheckedImplFile ────────▶ LowerImplFile ─────────────────────▶ CheckedImplFile
    │                        │                                    (変換済み)
    │                        ├─ Expr.Val検出
    │                        │      │
    │                        │      └─ ラムダ展開
    │                        │
    │                        ├─ Expr.App検出
    │                        │      │
    │                        │      ├─ 引数不足 → Eta展開
    │                        │      │
    │                        │      └─ ベータ簡約
    │                        │
    │                        └─ 他の式 → 変更なし

Expr.Val(f) ───────────▶ InterceptExpr ──────────────────────▶ λx. f x
(部分適用)                   │                                    (eta展開)
                              │
                              └─ AdjustValForExpectedValReprInfo

Expr.App(f, args) ─────▶ InterceptExpr ──────────────────────▶ Expr.App'
    │                        │                                    (最適化)
    │                        │
    │                        └─ MakeApplicationAndBetaReduce
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| LowerCalls.fs | `src/Compiler/Optimize/LowerCalls.fs` | ソース | 呼び出し下降変換の主実装 |
| TypedTreeOps.fs | `src/Compiler/Checking/TypedTreeOps.fs` | ソース | 式木操作ユーティリティ |
| TypedTreeOps.fsi | `src/Compiler/Checking/TypedTreeOps.fsi` | シグネチャ | 式木操作API定義 |
| TypedTree.fs | `src/Compiler/Checking/TypedTree.fs` | ソース | 型付き構文木の定義 |
| Optimizer.fs | `src/Compiler/Optimize/Optimizer.fs` | ソース | 最適化パスの統合 |
