# 機能設計書 25-Range（範囲）

## 概要

本ドキュメントは、Julia Base ライブラリが提供する Range（範囲）機能の設計について記述する。Range は等間隔に並んだ要素列を効率的に表現するための型群であり、要素を実際にメモリ上に展開せず、start / step / stop / length の情報のみで範囲を表現する。

### 本機能の処理概要

Range 機能は、`UnitRange` / `StepRange` / `StepRangeLen` / `LinRange` / `LogRange` などの Range 型群と、`(:)` 演算子（コロン）および `range` 関数による範囲オブジェクトの構築を提供する。これらはすべて `AbstractRange <: AbstractVector` のサブタイプであり、配列と同様にインデックスアクセスやイテレーションが可能である。

**業務上の目的・背景**：連番やステップ付き数列は、ループのインデックス生成、配列のスライス指定、数値計算での格子点生成など、プログラミングの基本操作として極めて頻繁に使用される。Range はこれらを O(1) メモリで表現し、要素の実体化なしに長さ・インデックスアクセス・イテレーションを提供する。浮動小数点の場合は TwicePrecision による高精度中間計算で丸め誤差を最小化する。

**機能の利用シーン**：forループのインデックス生成（`for i in 1:n`）、配列スライス（`A[1:3]`）、等差数列の生成（`range(0, 1, length=100)`）、対数スケールの点列生成（`LogRange(1, 1000, 10)`）、浮動小数点の等間隔格子（`LinRange(0, 1, 100)`）で利用される。

**主要な処理内容**：
1. `a:b` / `a:s:b` によるコロン演算子での Range 構築
2. `range(start; stop, length, step)` による柔軟な Range 構築
3. `UnitRange{T}` - ステップ1の整数範囲
4. `StepRange{T,S}` - 整数ステップ付き離散範囲
5. `StepRangeLen{T,R,S}` - 浮動小数点対応の精密範囲
6. `LinRange{T}` - 端点指定の等間隔範囲
7. `LogRange` - 対数スケールの範囲
8. インデックスアクセス・イテレーション・length・step 等の配列インタフェース

**関連システム・外部連携**：なし。Base モジュール内で完結する。

**権限による制御**：なし。すべてのユーザーが利用可能である。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 画面関連なし（ライブラリ関数） |

## 機能種別

計算処理（数列生成・表現）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| start | Real / Any | No | 範囲の開始値 | 数値型（または順序型） |
| stop | Real / Any | No | 範囲の終了値 | start と同じ型に変換可能 |
| step | Real / Any | No | ステップサイズ | 0でないこと（StepRangeの場合） |
| length | Integer | No | 要素数 | 0以上の整数 |

### 入力データソース

Julia プログラム内のリテラルまたは変数。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| range | AbstractRange | Range オブジェクト（UnitRange / StepRange / StepRangeLen / LinRange） |

### 出力先

呼び出し元への戻り値。

## 処理フロー

### 処理シーケンス

```
1. a:b が評価される（コロン演算子）
   └─ (:)(a, b) が呼ばれる
   └─ 整数の場合: UnitRange{T}(a, b) を構築
   └─ 浮動小数点の場合: a:T(1):b → StepRangeLen を構築
2. a:s:b が評価される（3引数コロン演算子）
   └─ (:)(a, s, b) が呼ばれる
   └─ _colon(OrderStyle, ArithmeticStyle, a, s, b) で分岐
   └─ 整数: StepRange(a, s, b) を構築
   └─ 浮動小数点: StepRangeLen(a, s, len) を構築（TwicePrecision使用）
3. range(start; stop, length, step) が呼ばれる
   └─ _range(start, step, stop, length) でパラメータ組み合わせに応じて分岐
   └─ 3つ以上の情報から残りを計算して適切な Range 型を構築
4. Range のインデックスアクセス
   └─ getindex(r, i) = r.start + (i-1)*step（数式計算、O(1)）
5. Range のイテレーション
   └─ iterate(r) = (first(r), first(r))
   └─ iterate(r, state) = state + step で次の値を計算
```

### フローチャート

```mermaid
flowchart TD
    A[Range 構築] --> B{構築方法}
    B -->|a:b| C{型判定}
    B -->|a:s:b| D{型判定}
    B -->|range(...)| E[_range パラメータ解析]
    C -->|Integer| F[UnitRange]
    C -->|AbstractFloat| G[StepRangeLen via TwicePrecision]
    D -->|Ordered + Integer| H[StepRange]
    D -->|Float| I[StepRangeLen via TwicePrecision]
    E --> J{指定パラメータ数}
    J -->|start+stop| K[UnitRange / StepRangeLen]
    J -->|start+stop+length| L[LinRange / StepRangeLen]
    J -->|start+step+length| M[StepRange / StepRangeLen]
    J -->|start+step+stop| N[StepRange]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 空範囲 | b < a の場合、空の範囲が生成される（a:a-1 に正規化） | UnitRange の場合 |
| BR-02 | ステップ符号 | StepRange ではステップの符号が start→stop の方向と一致しない場合、空範囲 | 常時 |
| BR-03 | 浮動小数点精度 | Float64 の場合 TwicePrecision による中間計算で丸め誤差を最小化 | Float16/32/64 |
| BR-04 | 型昇格 | start と stop が異なる型の場合 promote で共通型に変換 | 常時 |
| BR-05 | O(1) メモリ | Range は要素を格納せず、パラメータのみ保持 | 常時 |

### 計算ロジック

- `UnitRange(start, stop)`: 要素 = start, start+1, ..., stop。length = max(0, stop - start + 1)
- `StepRange(start, step, stop)`: 最後の要素は `steprange_last(start, step, stop)` で計算
- `StepRangeLen(ref, step, len, offset)`: i番目の要素 = ref + (i - offset) * step
- `LinRange(start, stop, len)`: i番目の要素 = start + (i-1)/(len-1) * (stop - start)

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

### 操作別データベース影響一覧

該当なし（インメモリデータ構造）。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ArgumentError | StepRange に浮動小数点を使用 | StepRangeLen / LinRange を使用 |
| - | ArgumentError | range() に不十分なパラメータ | start/stop/step/length のうち3つ以上を指定 |
| - | ArgumentError | 無効な次元指定 | 正しいパラメータ組み合わせを指定 |

### リトライ仕様

リトライは不要。

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

Range は不変（immutable）なデータ構造であり、トランザクション管理は不要。

## パフォーマンス要件

- O(1) メモリ使用量（要素数に依存しない）
- O(1) のインデックスアクセス（算術計算のみ）
- O(n) のイテレーション
- コンパイラによる最適化（ループ範囲の静的解析、SIMD化の促進）

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

特になし。

## 備考

- Range は `AbstractVector` のサブタイプだが、不変（setindex! 不可）
- `LogRange` は Julia 1.12 で追加予定
- TwicePrecision による精密計算は `base/twiceprecision.jl` で実装
- `OneTo(n)` は 1:n の軽量版で、axes の戻り値として使用

---

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

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

### 推奨読解順序

#### Step 1: データ構造を理解する

Range の型階層と各型の内部フィールドを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | range.jl | `base/range.jl` | AbstractRange, OrdinalRange, AbstractUnitRange, StepRange, UnitRange 等の型階層 |

**読解のコツ**: Range の型階層は `AbstractRange{T} <: AbstractArray{T,1}` を頂点とし、OrdinalRange（離散型）と非OrdinalRange（連続型 LinRange 等）に大別される。各型のフィールド（start, step, stop, len 等）の組み合わせが異なる。

- **273行目**: `AbstractRange{T} <: AbstractArray{T,1}` - 基底抽象型
- **293行目**: `OrdinalRange{T,S}` - 離散型範囲の抽象型
- **301行目**: `AbstractUnitRange{T}` - ステップ1の抽象型
- **329-340行目**: `StepRange{T,S}` - ステップ付き離散範囲の構造体

#### Step 2: コロン演算子を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | range.jl | `base/range.jl` | (:) 関数のオーバーロードとディスパッチ |

**主要処理フロー**:
1. **2行目**: `(:)(a::Real, b::Real)` - promote して型統一
2. **5行目**: `(:)(start::T, stop::T) where {T<:Real}` - UnitRange 構築
3. **20-23行目**: `(:)(start::T, step::T, stop::T)` - _colon への委譲
4. **24-29行目**: `_colon` - OrderStyle/ArithmeticStyle による分岐

#### Step 3: range 関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | range.jl | `base/range.jl` | range 関数と _range のパラメータ解析 |

**主要処理フロー**:
- **155-163行目**: `range` 関数のオーバーロード群
- **165-180行目**: `_range` - 16通りのパラメータ組み合わせに対するディスパッチ
- **209-218行目**: `range_start_length` - start と length から Range を構築
- **220行目**: `range_start_stop` - start:stop への委譲

#### Step 4: steprange_last を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | range.jl | `base/range.jl` | StepRange の最終要素計算 |

**主要処理フロー**:
- **343-349行目**: `steprange_last` - ステップと方向の整合性チェック、最終要素の正確な計算

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

```
1:10 / 1:2:10 / range(1, 10; length=5)
    |
    +-- (:)(a, b) [2引数]
    |       +-- promote(a, b)
    |       +-- [Integer] UnitRange{T}(a, b)
    |       +-- [Float] (:)(a, T(1), b) → StepRangeLen
    |
    +-- (:)(a, s, b) [3引数]
    |       +-- _colon(OrderStyle(T), ArithmeticStyle(T), a, s, b)
    |       +-- [Ordered] StepRange(a, s, steprange_last(a, s, b))
    |       +-- [ArithmeticRounds] StepRangeLen(a, s, len)
    |
    +-- range(start; stop, length, step)
            +-- _range(start, step, stop, length)
                +-- [start+stop] range_start_stop → a:b
                +-- [start+length] range_start_length → UnitRange/StepRangeLen
                +-- [start+step+length] range_start_step_length → StepRange/StepRangeLen
                +-- [start+stop+length] range_start_stop_length → LinRange/StepRangeLen
```

### データフロー図

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

start, stop         ---->  (:)(start, stop)
                           +-- promote → UnitRange          ---->  UnitRange{T}

start, step, stop   ---->  (:)(start, step, stop)
                           +-- _colon → StepRange           ---->  StepRange{T,S}

start, stop, length ---->  range(start, stop; length)
                           +-- _range → LinRange            ---->  LinRange{T}
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| range.jl | `base/range.jl` | ソース | Range 型定義、コロン演算子、range 関数、インデックスアクセス |
| twiceprecision.jl | `base/twiceprecision.jl` | ソース | TwicePrecision 型による浮動小数点の高精度中間計算 |
| abstractarray.jl | `base/abstractarray.jl` | ソース | AbstractArray インタフェース（Range はサブタイプ） |
