2026年5月30日土曜日

バックトラックを言語仕様にうまく組み込んだ例

 

1. Prolog系ロジック言語

代表: Prolog, Mercury, Curry など

  • 基本アイデア

    • 事実とルールを書く

    • クエリに対して、

      • 左から右

      • 上から下
        の順に試す深さ優先探索が「仕様として」定義されている。

    • 失敗したら自動でバックトラックして別の候補を試す。

  • うまい点

    • *「述語を呼び出す」ことと「条件分岐+ループ+探索」*が一体化している。

    • ;(選言)や -> ;(if-then-else)など、構文レベルでバックトラックと整合している。

    • cut (!) などで探索空間を制御する手段も仕様に含まれる。

  • 弱点(設計上のトレードオフ)

    • 論理式の“見た目”と探索手順が強く結びつくので、

      • 文の並びを変えると意味(実行結果)が変わる

      • 実装依存の挙動を理解してないと予測しづらい

    • つまり「宣言的」と「手続き的」がかなり混ざっている。


2. Icon の「ゴール指向評価」

代表: Icon, その後継の Unicon など

個人的に「バックトラックを言語デザインとして一番きれいに統合している例のひとつ」です。

  • コアの発想

    • すべての式が「成功」か「失敗」を返し、

      • さらに複数の値を順次生成しうる(generator)。

    • ある式が失敗すると、その直前の式が「別の値を生成しなおす」かを試す。
      それがバックトラック。

  • 例のイメージ(かなり擬似コード)

    1. # s の中から "abc" を含む位置を順に返すような感じ every i := find("abc", s) do write(i)

  • うまい点

    • 「success / failure / multiple results」という概念を式レベルに落とし込んでいる。

    • 制御構造(if, while, every など)が成功・失敗に一貫して基づいて設計されている。

    • バックトラックが「パターンマッチ専用の機能」ではなく、
      言語全体の評価モデルに統合されている。


3. SNOBOL4 のパターンマッチ

代表: SNOBOL4 などの文字列処理言語

  • 特徴

    • 文字列パターンが第一級オブジェクトとして扱われる。

    • パターンマッチの過程で、

      • 区間の長さを変えたり

      • 選択肢を切り替えたりする時に
        自動的にバックトラックが行われる。

  • うまい点

    • 「パターンマッチ」という限定された領域に
      バックトラックを特化しているので、挙動を理解しやすい。

    • パターン言語自体がかなり表現力があり、
      正規表現よりもずっとリッチな“マッチ DSL”として機能する。


4. 正規表現エンジン(言語内DSLだが、設計としては好例)

代表: Perl, Ruby, JavaScript などの バックトラッキング型正規表現

  • 多くの言語の正規表現は、

    • |(オルタネーション)

    • *, +, ?(繰り返し)

    • ?=, ?!(先読み)
      などの記法に対し、
      仕様としてバックトラックするマッチングアルゴリズムを想定している。

  • うまい点

    • 「バックトラックを隠蔽しつつ、必要なときに制御できる」設計。

    • 量指定子(*? などの最短一致)や否定先読みで、
      パフォーマンスや意味をある程度制御できる。

    • メイン言語の中に、
      バックトラック付きの小さな言語(正規表現)が埋め込まれている形。

  • 注意点

    • 複雑なパターンで指数時間に落ちるなど、
      バックトラック特有の性能問題はつきまとう。


5. パーサコンビネータ系(Haskell など)

代表: Haskell の Parsec / Megaparsec、OCaml/F# の parser combinator など

  • 発想

    • Parser a のような型で「入力から値 a を抜き出す計算」を表現。

    • (<|>) などのコンビネータで
      「まず左のパーサを試し、失敗したら右にバックトラック」
      という挙動をライブラリレベルで抽象化している。

  • 仕様上の組み込み度合い

    • これは「言語仕様」というより「ライブラリ+型システム」ですが、

      • do 記法(モナド)と

      • バックトラック付きパーサ
        がかなり自然に合成されるので、
        言語の一部のような書き心地になります。

  • うまい点

    • 型で「どの程度バックトラックするのか」「どの情報を残すか」を制御できる。

    • 必要に応じて

      • LL(1) 的にバックトラックを抑制したり

      • エラーメッセージをリッチにしたり
        といった調整がしやすい。


6. 述語・関係プログラミング(miniKanren など)

代表: miniKanren(Scheme/CL系の関係プログラミング言語)

  • 特徴

    • 「関数」ではなく「関係」を書いて、
      その関係を満たす値をバックトラックで探す。

    • conde(条件の選択)、fresh(新しい論理変数の導入)といった
      小さなプリミティブに、探索とバックトラックの意味がきれいに落ちている。

  • うまい点

    • とても小さなコア仕様(数十行レベル)で
      完全なロジックプログラミングの探索とバックトラックを実現している。

    • 言語仕様としても「極小コア+マクロ」で説明できるのが美しい。


ざっくりまとめ

「バックトラックを言語仕様にうまく組み込んだ」例として挙げやすいのは:

  1. Prolog 系

    • ロジックプログラミングそのものとして統合。

    • ただし宣言的と手続き的が密着しがち。

  2. Icon(+SNOBOL4 パターン)

    • 成功/失敗と多値生成を評価規則の中心に据えた、とてもきれいな設計。

  3. バックトラッキング正規表現

    • 言語内 DSL として、パターンマッチに特化した成功例。

  4. パーサコンビネータ / miniKanren

    • 言語+ライブラリ+型(またはマクロ)で、
      少ないプリミティブからバックトラックの計算モデルを構成している。

SpecCは、組込みシステム(ハードウェア+ソフトウェア)をシステムレベルで記述するための設計言語です

 SpecCは、組込みシステム(ハードウェア+ソフトウェア)をシステムレベルで記述するための設計言語です。位置づけとしては ANSI C を拡張した言語で、Verilog/VHDL のような低レベルHDLに落とす前の、上流の仕様化と段階的な具体化(リファインメント)に使います。

何ができる言語か

  • 早い段階で仕様を書く(機能仕様、構成の当たり付け)

  • その仕様を、実装に近い形へ段階的にリファインしていく(アーキテクチャ設計、HW/SW分割など)

  • IPの組み込みや、抽象度の違う部品の統合を扱いやすくする

Cに足されている「システム記述」の要素

SpecCはCに対して、システム設計に必要な概念を追加します。代表的には次です。

  • 階層化(構造を入れ子で表現)

  • 並行性(複数の振る舞いを同時に進める)

  • 通信(計算と通信を分離して扱うための仕組み)

  • 同期(待ち合わせ、排他など)

  • 状態遷移(FSM的なモデル)

  • 例外処理

  • 時間(タイミングのモデル)

SystemCとのざっくり比較

  • SystemCはC++ベースで普及度が高い

  • SpecCは「C拡張」で、システムレベルに必要な概念を比較的シンプルにまとめた思想

SpecCはシステム記述言語(SDL)またはシステムレベル設計言語(SLDL)であり、ANSI Cプログラミング言語の拡張です。デジタル組込みシステムの設計と仕様策定を支援するために使用され、[1]VerilogやVHDLのようなHDLとは異なり、機能レベルおよび仕様レベルでの設計変更能力を維持しつつ生産性の向上を実現します。アーキテクチャモデルを作成することで、他のツールが設計を直接シリコンやFPGAにマッピングできるようになります。主な目的は、様々な抽象化レベルにおけるIPの再利用、交換、統合です。
この言語と設計手法は、2001年にカリフォルニア大学アーバイン校の組み込みコンピュータシステムセンターにおいて、ライナー・ドーマーとダニエル・ガジスキによって考案されました。
類似のプロジェクトや設計手法には、C++ベースのSDLであるSystemCがある。この競合言語は業界での普及度がはるかに高い(ただしSpecCは日本で人気がある)が、SpecCは簡潔さを保ちつつ、並行処理(SpecCはパイプライン化および並列フローを提供)、同期、状態遷移(Verilogでは利用不可)、複合データ型といったSDLの重要な機能を提供している。

https://en.wikipedia.org/wiki/SpecC


日本的霊性とその周辺

 

■ 鈴木大拙『日本的霊性』

戦時期に書かれた思想書。国家のための日本精神ではなく、禅や浄土に見られる個の内面の宗教的覚醒を「霊性」として捉え、日本文化の深層を静かに描き直した。


■ 本居宣長

江戸中期の国学者。『古事記伝』などの注釈を通じ、日本には外来思想以前の「真心」「もののあはれ」があると主張。後の日本精神論や神道思想の源流を形づくった。


■ 山本常朝『葉隠』

佐賀藩内部で語られた武士道倫理。「武士道とは死ぬことと見つけたり」に象徴される、主君への即時的忠義を説く地方的・過激な行動規範で、全国的影響は後世。


■ 新渡戸稲造

『Bushido: The Soul of Japan』で武士道を英語化し、日本人の道徳として世界に紹介。キリスト教的倫理と近代教養を通じ、武士道を穏健で普遍的な物語へ再構成した。


■ 西田幾多郎

日本近代哲学の基礎を築いた思想家。「純粋経験」「絶対無」などを通じ、個と世界の関係を哲学的に定式化。日本的思考を世界哲学の文脈へ接続しようとした。


■ 和辻哲郎

『風土』『倫理学』で、人間を個ではなく「間柄」として捉え、日本文化と倫理を共同体・歴史・環境の構造から説明。日本精神論を理論的に整理した代表的存在。


■ 折口信夫

民俗学者・歌人。「まれびと」や祭祀研究を通じ、神話・民俗・性・死に宿る霊性を掘り下げた。国学を継承しつつ、より身体的で陰影のある日本像を提示。


■ 三島由紀夫

武士道・天皇・身体・美を主題に、小説と行動で日本精神を演じた作家。葉隠的倫理を個人の生と死に圧縮し、思想や歴史を一回的事件として可視化した存在。

ハルシネーションは誤謬ではない

 

ハルシネーションは「誤謬(ミス)」ではなく「生成的メカニズムの性質」である理由

ここでいう 誤謬(error) とは、
「本来あるべき唯一の正解から逸脱した結果」
を指します。しかし、LLMにおけるハルシネーションは、そもそも 正解を参照する仕組みではなく、確率的生成を通じて“もっともらしさ”を構築する仕組み に起因します。

1. AI研究の観点:誤謬とは前提が異なる

モデルは「世界の真理を保持」しているわけではなく、
「テキスト分布の統計的近似を行う関数」です。
そのため “誤りかどうか” は外部の評価基準であり、内部には「正解フラグ」がありません。

ハルシネーションは、
誤った記憶ではなく、欠損した文脈を“足す”ことによって連続性を保とうとする現象 です。
これは誤謬ではなく、むしろモデルの生成能力(coherence maker)が正常に動いている状態と言えます。

2. 認知科学の観点:人間の知覚も本質的に「補完」である

人間の知覚も、隙間を補い、欠損を埋め、状況を整合的に保つメカニズムを持ちます。
記憶の誤再生、ミューラー=リヤー錯視、夢、誤帰属、すべて補完の結果です。

つまり
錯覚は誤謬ではなく、認知を成立させているメカニズムの裏返し
という位置づけができます。

同様にLLMも、補完的生成をしなければ「文章がつながらない」ため、補完が先にある構造です。

3. 哲学的観点:誤謬は外在的・規範的な概念である

デリダ、フーコー、クワインなどの系譜では、
「誤り」という概念は、制度・権威・外部基準によって決定される“規範的なラベル”です。

ハルシネーションはモデル内部にとって

  • 正しくもない

  • 間違ってもいない

  • ただ“連続性を維持するもっともらしい生成”
    として成立しています。

つまり
誤謬というカテゴリーは、人間の評価フレームであり、モデルの内的過程とは異なるレイヤーの概念
なのです。


1400万605分の1ってなにか意味ありましたか?

 「いわゆる“天文学的数字 (astronomical odds/astronomical numbers)”」だと考えるなら、確かに 1/14,000,605(約1400万分の1)は その“天文学的”の中では比較的小さい部類 で、宇宙や生命、偶然の産物などを論ずる場で使われる“桁違いに大きな確率分母”には遠く及ばない、という見方が多いです。

「1400万605分の1」= “時間や計算リソースが限られた状況でドクター・ストレンジが探索できた“未来の枝”の総数”
という解釈がもっとも合理的です。

ブルームフィルター的に考えると、ストレンジの未来探索はこう見える

Bloom Filter の本質は:

  • 巨大な集合をすべて列挙せずに

  • 確率的に membership(含まれているか)を判定する

  • 偽陽性はある/偽陰性はない

というアルゴリズムです。

この構造を未来予知にあてはめると、非常に自然な解釈ができます。


🔍 1. “全未来を列挙できない”という前提に合う

未来の全可能性は指数関数的/無限に近い。

しかしストレンジは Time Stone で未来全体を brute force することはできない
よって「部分的サンプリング+ハッシュ的圧縮」で未来をおおまかに分類している、
というモデルが合理的です。

ブルームフィルターが
“全データは保存せず、要点だけを確率的に保持する”
のと同じ。


🔍 2. “成功未来”をハッシュするモデルが成立する

ブルームフィルターは「この要素が“集合に属しているか”」を判定します。

ストレンジの場合:

  • 入力:未来のある分岐点の state

  • ハッシュ:Time Stone の未来写像

  • クエリ:「この未来は“勝利集合”に属するか?」

という構造になる。

つまり、

◆ 未来を“勝利/敗北”へ分類するための

確率的 membership test

と考えることができます。


🔍 3. 偽陽性(false positive)という概念が“1 つの勝利ルート”と整合する

ブルームフィルターでは:

  • 偽陽性(実際は集合にないのに“ある”と判定される)は存在

  • 偽陰性(あるのに“ない”と判定する)は基本存在しない

これを未来探索に当てはめると:

◆ ストレンジの探索では

“本当の勝利ルートを見落とす(偽陰性)は発生しない”

これは物語設定に合う。
なぜなら、ストレンジは
「勝利ルートは 1 通りしかない」
と確信していた。

反対に、

◆ “勝利に見えるが実際は違う(偽陽性)”はあり得る

つまり「成功に見えたけど途中で破綻する未来」が混じっている可能性もある。

これは 14,000,605 通り見たが、真の勝利は 1 つだけ
という話と一致する。


🔍 4. 未来をハッシュ圧縮して扱ったため、分岐数はそこまで大きくならないという説明にもなる

ブルームフィルターは元データのサイズから見ると
「驚異的に小さいメモリ」で集合を扱う。

これをストレンジに当てはめると:

  • 宇宙全体の分岐は実際には膨大

  • Time Stone はその巨大集合を“ハッシュ圧縮した概念空間”で扱う

  • その結果、「調べるべき未来の代表点が1400万オーダーに収まった」

という合理化ができる。


🔍 5. “時間制限下での近似探索”という性質も同じ

ブルームフィルターは超高速。
時間制限下で巨大な集合を扱うときの典型的な手法です。

ストレンジの場面はまさにそれ:

  • 数十秒以内

  • 膨大な未来情報

  • 確率的・圧縮的にスクリーニングし

  • 勝利ルートの membership を判定した

これはブルームフィルターの精神構造と完全に一致する。

「時間制限下の最適探索」

「確率的データ構造(ブルームフィルター)的な圧縮判定」

というモデルで“14,000,605”を説明するのが、
最も整合的で美しい解釈です。

未来を“全列挙”したのではなく、Time Stone による“確率的フィルタリング”の結果が 14,000,605 だった。

という理解は、SF考証として非常に上質です。