# 中核概念: チェックポイントとワークフローモデル

[クイックスタート](quickstart.md) では `qc.chk.new(...).scf(ref="r").run()` と書いて `mychk.scf.energy` を
読みました。この 1 行が、qc-rs の大きな考え方をすべて使っています。この章では思い切り立ち止まってモデルを
詳しく説明します。これが腑に落ちれば、ツールキット*全体*が見通せます — どの機能も、追加する 1 つのステップか、
読む 1 つの結果にすぎません。

## チェックポイント

すべては 1 つのオブジェクト、**チェックポイント**を中心に回ります。1 つの分子のための小さな実験ノートだと
思ってください。3 つのものを保持します:

1. **分子** — `qc.chk.new(...)` に与えた構造・基底関数・電荷・スピン。固定の入力です。
2. **現在の電子状態** — 電子を生成した*直近の*ステップの結果:**分子軌道**（`current_mo`）と**電子密度**
   （`current_density`）。推定・SCF・CASSCF はいずれもこれを更新します。物性は*この*状態を読みます。
3. **結果レコード** — 実行したステップの成果:SCF エネルギーと収束したか、計算した物性、最適化の軌跡など。

作りたてのチェックポイントは分子を持ちますが、**まだ電子状態がありません** — 何も計算されていません。

## 2 つのフェーズ:*組み立て* → *実行*

qc-rs の計算は、明確に分かれた 2 つのフェーズで進みます。この分離こそ、理解すべき最重要点です。

### 1. 組み立て — pending ステップを追加

`qc.scf(mychk, ...)`（またはメソッド形 `mychk.scf(...)`）は**何も計算しません**。**pending ステップ**
（「ここで SCF がほしい」というメモ）を載せた*新しい*チェックポイントを返します。元のチェックポイントは
変更されません（チェックポイントは実質不変で、ステップは新しいものを返します）:

```python
base    = qc.chk.new(atom="O 0 0 0.1173; H 0 0.7572 -0.4692; H 0 -0.7572 -0.4692",
                     ao="cc-pvdz", unit="angstrom")
pending = base.scf(ref="r")     # pending SCF ステップを持つ新しいチェックポイント

pending is base          # False — base は不変
pending.scf.energy       # None — まだ何も実行していない
```

組み立ては安価で副作用がないので、複数ステップの計算を自由に組めます — 何ステップも連結し、分岐し、あるいは
チェックポイントを関数に渡す — 何も走らせる前に。

### 2. 実行 — 結果を実体化

`.run()` が実際に計算します。その後は結果アクセサが本物の値を返します:

```python
done = pending.run()
done.scf.energy          # -76.026772
done.scf.converged       # True
```

:::{important} pending ステップ vs 結果アクセサ
同じ名前が `.run()` の前後で異なる意味を持ちます。**`mychk.scf(...)` はステップを追加**し（引数を取り、新しい
チェックポイントを返す）、**`mychk.scf.energy` は完了したステップの結果を読み**ます（実行前は `None`）。
「作業を頼む」ことと「答えを読む」ことを分けているからこそ、計算を自由に組み立て、安全に再実行できます。
:::

## `.run()` が実際に行うこと

pending ステップは小さな**依存グラフ** — DAG（有向非巡回グラフ）— を成します。`.run()` を呼ぶと、qc-rs は
明確に定義された一連の動作を行います:

1. **依存を解決。** 各ステップが何を必要とするか割り出す。SCF は軌道の*初期推定*と*1 電子積分*を、物性は
   収束密度を、といった具合。
2. **妥当な既定値を自動挿入。** 明示的に要求しなかった依存には、安全な既定を挿入。特に、SCF に初期状態が
   なければ **`sad` 推定**（原子密度の重ね合わせ）を、そして既定の**積分**ステップを挿入。だから
   `mychk.scf(ref="r").run()` はそれだけで動きます — `guess(...)` や `ints(...)` を手で書くことはほとんど
   ありません。
3. **順序付けと実行。** グラフをトポロジカル順に並べ、各ステップを順に実行し、結果をチェックポイントに
   **記録**。
4. **済みはスキップ。** まだ有効な結果は**再利用し、再計算しない**;欠けている/*古い*ステップだけ実行。
5. **刈り込み。** 完了した pending ノードは消され、チェックポイントは次のステップを受け入れられる状態に。

覚えておく価値のある帰結が 2 つ:

- **`.run()` は再度呼んでも安全。** 有効な結果は再利用されるので、再実行で完了済みの作業は繰り返されません。
  中断後の**リスタート**もこの仕組み:チェックポイントを読み込み `.run()` すれば止まった所から続きます。
- **気にかけるものだけ指定すればよい。** 推定と積分は補われます。*制御したい*場合 — 別の推定、特定の積分戦略 —
  はそれらのステップを明示的に追加し、`.run()` は既定の代わりにそれらを使います。

:::{note} 古さ（staleness）
結果は*世代*の概念を持ちます。ステップが依存するものを変えると、下流の結果は**古い**と印付けされ次の
`.run()` で再計算され、影響のないものは保持されます。正しさ（古いものは残らない）を、影響のない作業の
やり直しなしに得られます。
:::

## 同じことの 2 通りの書き方

すべてのワークフロー動詞に、**関数形**と**メソッドチェーン形**があります。等価なので、文脈で読みやすい方を:

```python
# 関数形                            # メソッドチェーン形
qc.scf(mychk, ref="r").run()      mychk.scf(ref="r").run()
```

メソッドチェーン形は 1 行に、関数形はチェックポイントがヘルパー関数を流れるときに明快です。

## 結果を読む、物性を計算する

`.run()` の後、結果はステップに対応した名前付きアクセサにあります:

```python
done.scf.energy       # 全エネルギー
done.scf.converged    # SCF は収束したか
```

解析は別です:`qc.prop.<group>.<leaf>` 名前空間にあり、最初に要求したとき**遅延計算**され、以後キャッシュ。
チェックポイントの*現在の電子状態*を読みます:

```python
qc.prop.chrg.mulliken(done)       # {'charges': [...], 'atom_labels': [...]}
done.prop.chrg.mulliken()         # 同じもの、メソッドチェーン形
```

物性グループは 14 個あります（電荷、結合次数、芳香族性、軌道、QTAIM、ELF、多重極、スピン、概念 DFT、ESP、
実空間場、スペクトル、ジオメトリ …）— スイート全体は [分子物性](../20-guide/properties/index.md)。実行時に
まとめて先行計算する `scf(prop=...)` もあります。

## 保存と読み込み

チェックポイント — 分子・現在の電子状態・すべての結果 — はディスクに書き出し、あとで**再計算なしに**復元
できます:

```python
done.save("water")                # チェックポイントを保存（HDF5 .qch5 ファイル）
later = qc.chk.load("water")      # 復元（例:新しいセッションで）
later.scf.energy                  # -76.026772 — 直に読み戻し、再計算なし
```

読み込んだチェックポイントは結果を保持しているので、*さらに*ステップを追加して `.run()` もできます — 既存の
結果は再利用され、新しい作業だけが走ります。

## なぜこの設計か

*組み立て*と*実行*を、そして pending ステップと結果を分けることで、初学者が後で恩恵を感じる 3 つが得られます:

- **組み立て可能性** — 計算は 1 ステップずつ拡張する短いパイプライン;組み立ては安価で驚きがない。
- **リスタート可能性** — `.run()` は有効な結果を再利用するので、長いジョブは最初からでなく再開;保存した
  チェックポイントは再開可能なスナップショット。
- **来歴（provenance）** — どの電子状態がどの結果を生んだかを記録するので、解析が*何から*計算されたか曖昧に
  なりません。

このモデルを手にすれば、マニュアルの残りは本質的にカタログです:追加できる**ステップ**（guess, ints, scf,
opt, lct, td, …）と、読める**結果**（エネルギー、勾配、物性スイート）。次はその背後の理論を
[Part II — 基礎](../10-foundations/index.md) で、あるいは [ユーザーガイド](../20-guide/molecular-input.md)
に飛び込んでください。
