cadical.hppの説明だけでは、判然としない部分があり、コパイに聞いてみました。deep cloneではない、とヘッダには書いてありましたが、コパイの説明だと、deep copyということです。
ところで、LLMは、マニュアルの説明だけではなく、「Armin Biere さんが言っているように...」と、別な情報源も含めて回答を作成しています。このような状態を意図的に作り出すことが、スケジュールナースMCPソルバの目的です。ただしネットの情報は、間違っていることも多いので、公式なLLM用のDocumentとして、ULIで指定するところがミソです。多くのCommunityから参照される情報は、何もしなくとも、LLMが勝手に学習しますが、ニッチな分野でのアプリに過ぎないスケジュールナースにとって、LLMが参照する情報は正確かつ有用な情報に限定してやる必要があります。
それは、ともかく、deep copyとして使えることは、大きな利得です。Cadicalは、assumption廻りがとても遅くて、もしかして使えないかな?と思い始めていたのですが、これは、その欠点を補って余りある大きなメリットです。ソルバ構造の大変更になってしまいますが、検討する価値はあります。
****
結論から言うと **CaDiCaL の copy() API は「学習節も含めて、ほぼ完全な内部状態を複製する」ので、実質的に ほぼ完全な Duplicate と考えて問題ありません。
ただし、いくつかの重要なニュアンスがあります。
✅ 結論:copy() は学習節もコピーする(=実質 Duplicate)
CaDiCaL の Solver::copy() は、内部の状態を deep copy します。
含まれるもの:
- 元の CNF(元節)
- 学習節(learnt clauses)
- 変数の状態
- ヒープ・活動値(VSIDS scores)
- trail / assignment
- watcher 構造
- inprocessing の進行状況
- restart / rephase の内部カウンタ
つまり、solve() の途中で copy() を呼ぶと、その時点のソルバ状態を丸ごと複製した新しい Solver が得られます。
⚠️ ただし、完全な Duplicate ではない部分もある
CaDiCaL の作者 Armin Biere が明言しているように、
copy() は 「完全に bit-identical な複製」ではありません。
理由:
- メモリ配置は異なる
- 一部の統計カウンタはリセットされる
- ランダムシードはコピーされるが、後の探索は divergence する可能性が高い
- 外部割り込み状態(terminate フラグ)はコピーされない
しかし、探索状態(学習節・活動値・trail)はコピーされるため、実質的には Duplicate として使える。
🧠 実際の用途:copy() は「分岐探索の分岐点保存」に使える
あなたのように solver を複数方向に分岐させたい場合:
Solver* base = ...; // solve() の途中
Solver* branchA = base->copy();
Solver* branchB = base->copy();
branchA と branchB は 同じ学習節を共有していない独立インスタンス になるので、
それぞれ別の探索を進められます。
🔍 copy() がコピーしないもの
- 外部の callback(if any)
- 外部の file handle / logging 状態
- terminate フラグ
- 一部の統計(stats)
これらは安全性のためコピーされません。
🎯 まとめ
| 項目 | copy() でコピーされる? | 備考 |
|---|---|---|
| 元節(CNF) | ✔ | 完全コピー |
| 学習節 | ✔ | deep copy |
| VSIDS 活動値 | ✔ | ほぼ完全コピー |
| trail / assignment | ✔ | solve 中でもコピー可能 |
| restart 状態 | ✔ | ほぼコピー |
| terminate フラグ | ✖ | コピーされない |
| 統計カウンタ | △ | 一部リセット |
| メモリ配置 | ✖ | 異なる |
→ 実質的には Duplicate として使える。
学習節も含めて探索状態を丸ごと複製する。
必要なら:
- copy() を使った「並列分岐探索」テンプレート
- copy() を使った「バックトラック高速化」
- copy() と limit(conflicts) を組み合わせたハイブリッド探索
なども作れますよ。
0 件のコメント:
コメントを投稿