プロログによるコーディング・ホラー。

2026/05/18 6:15

プロログによるコーディング・ホラー。

RSS: https://news.ycombinator.com/rss

要約

Japanese Translation:

本記事は、純粋で単調なコーディング慣行への厳格な遵守が、堅牢な Prolog プログラムにとって不可欠であるという主張を展開している。一般的な産業パターンへ偏离することは、言語の述語論的性質を破損させ、高価な欠陥をもたらす。

!/0
(->)/2
、および
var/1
などの非単調な構造は、意図された解の喪失か不適切な結果を生じる。
assertz/1
および
retract/1
でグローバルデータベースを改変することは、隠れた依存関係を創出し予期せぬ失敗を引き起こすため、状態は世界の改変を通じてではなく述語の引数を通じて伝達されるべきである。
(is)/2
(=:=)/2
、および比較演算子のような低水準のアリティム操作は、開発者に矛盾する述語論的および操作的意味を両立させるよう迫り、プログラムを理解しやすくし、学習・テスト・推論を行うことを難しくする。不純な出力操作もまた、解答を Prolog タームとして記号論的に考察することを阻止する。純粋で単調な Prolog 部分集合を採用し、
dif/2
のような近代の述語論的ツール、
if_/3
のようなメタ述語、およびクリーンなデータ構造を活用することで、開発者はパフォーマンスを維持しつつ一般性・柔軟性・厳格なテスト可能性を取り戻し、プロフェッショナル環境での利用を制限するレガシーの負担から Prolog を解放することができる。

本文

「恐ろしい!恐ろしい!」と囁かれるような叫びを聞かされたように思えた。(ジョゼフ・コンラート『闇の心』より)

なぜ、あなたはここにいますか?

Prolog プログラマーとして、あなたには反骨の精神が備わっているに違いありません。多くの場合、それは現在の業界全体が直面している問題の解決方法から離れ、さらに先にあるものを追求するための力となります。

しかし、このページの目的は、その反骨の精神を盲目的に発揮することが高くつくコストを伴い、実質的な利益をもたらさないと示唆することです。

優れた Prolog コードを作成するには、少数の原則に則るだけで十分です。これらの原則を守らないと、プログラムがいくつかの根本的な欠陥を抱えることになります。

恐ろしさ一:解を失うこと

効率的かつ正常終了する Prolog プログラムでも、大きく分けて二種類の欠陥が生じ得ます:

  • 誤った答えを返す。
  • 意図した解の一部または全部を報告しない。

どちらのケースがより深刻でしょうか。考えてみてください!

まず、プログラムは第一種の欠陥のみを持っていると仮定してみましょう。それでも正しい結果だけを入手する手段はあるでしょうか?次に、プログラムは第二種の欠陥のみを持っていると仮定してみましょう。その場合でも、意図されていたすべての解を入手する方法は何でしょうか?

プログラムを第二種の方法で欠陥させる主な要因は、不純な(non-pure)かつ非単調(non-monotonic)な言語構成要素を使用することです。具体的な例としては

!/0
(カット)、
(->)/2
(条件句)、
var/1
などがあります。宣言的(declarative)な解決策としては、クリーンなデータ構造の使用、制約演算子
dif/2
、そしてメタ述語
if_/3
の採用などが挙げられます。

恐ろしさ二:グローバル状態

初心者としては、Prolog のグローバルデータベースを修正したいという誘惑にかられることが多いものです。これはプログラム内に暗黙的な依存関係を発生させます。「暗黙的」というのは、プログラム内にそれらの依存関係を強制する仕組みが何もないことを意味します。例えば、もし意図と異なる順序で述語を使用すると、予期せず失敗するか、奇妙な結果を返すことがあります。

プログラムをこのように欠陥させる主な要因は、

assertz/1
retract/1
などの述語を使用することです。宣言的な解決策としては、状態を伝播させるために述語の引数やセミコンテキスト記法(semicontext notation) を用いることです。

恐ろしさ三:不純な出力

初心者としての段階では、システムターミナルに答えを印刷し、トップレベルから報告させず、自分で出力することに誘惑されることがあります。例えば、以下のようなコードを含めることがあります:

solve :-
    solution(S),
    format("the solution is: ~q\n", [S]).

このアプローチの重大な欠点は、そのような出力はシステムターミナル上でのみ生じ、プログラム内で Prolog 項としてアクセスできないため、容易にその出力について推論ができなくなることです。結果として、そうした出力に対するテストケースを作成しなくなる傾向があり、それが関連する述語を破壊する変更を引き起こす可能性を高めます。また、もう一つの深刻な短所は、このアプローチがコードを真の関係子(relation)として使用できないことを意味することにあります。

関係子の全般的な汎用性を活かすためには、Prolog コードを用いて解を記述し、出力の表示はトップレベルに任せるべきです:

solution(S) :-
    constraint_1(S),
    etc.

特別なフォーマットが必要となる場合があります。その場合は、依然として純粋な方法で出力を記述することができます。例えば、非項(nonterminal)

format_//2
を使用することで実現可能です。これにより、テストケースの作成が容易になります。

恐ろしさ四:低レベルの言語構成要素

一部の Prolog プログラマーは、より新しい言語構成要素の使用意義を見出しません。例えば、CLP(FD) の制約演算子は導入されてからわずか約 20 年しか経過しておらず、Prolog の歴史の中で比較的新しい開発です。低レベルの構成要素があなたをよく機能させてきたなら、なぜ最新の素材を学ぶ必要があるのでしょうか。数千万人の学生が低レベルの構成要素によって適切な教育を受けられなかった事実は、あなたの関心事とは限りません。

しかし、低レベルの構成要素に固執することには高い代償がかかります:言語を教えるのが困難になり、学ぶのが難しくなり、理解するのも不必要に複雑になります。学生は宣言的(semantics)と演算的(semantics)な意味論を実質的に同時に学ぶ必要があり、ほぼすべてのケースにおいてこれが多すぎます。

Prolog を不必要に教えにくくさせる主な要因は、初歩者を算術に関する低レベル述語

is/2
=:=/2
>/2
などの導入です。宣言的な解決策としては、制約演算子(CLP(FD) など)を教えることです。詳細は 宣言的整数算術 を参照してください。

ホラー・ファクトリアル

これらの欠陥の例を見るため、「ホラー・ファクトリアル」をご覧ください:

horror_factorial(0, 1) :- !.
horror_factorial(N, F) :-
    N > 0,
    N1 is N - 1,
    horror_factorial(N1, F1),
    F is N*F1.

最も一般的な問い合わせに対して実行すると、解を失うホラーに気づくでしょう:

?- horror_factorial(N, F).
% N = 0, F = 1. (唯一つの解)

!/0
を含まないバージョンもほぼ同様に恐ろしいものです:

horror_factorial(0, 1).
horror_factorial(N, F) :-
    N > 0,
    N1 is N - 1,
    horror_factorial(N1, F1),
    F is N*F1.

低レベルの言語構成要素によるホラーが蔓延しています:

?- horror_factorial(N, F).
% N = 0, F = 1 ;
% caught: error(instantiation_error,'(is)'/2)

これを受容するならば、あなたは以下のような状態にあることになります:

  • 陳腐な言語構成要素に制限されている。
  • 関係子(relation)を関数(function)と誤認している。
  • 最も一般的な問い合わせを顧みない。
  • 不純な構成要素を使用することで宣言的デバッグを妨げている。

解決策:純粋性

ホラーを止めるには、Prolog の純粋で単調なサブセットに留まることが重要です。

小さく始めましょう。例えば、低レベルの整数算術の代わりに、より宣言的な代替手段を使用してください:

horror_factorial(0, 1) :- !.
horror_factorial(N, F) :-
    N #> 0,
    N1 #= N - 1,
    horror_factorial(N1, F1),
    F #= N*F1.

「なにもないよりはマシ」です。そして、

!/0
を削除しましょう:

n_factorial(0, 1).
n_factorial(N, F) :-
    N #> 0,
    N1 #= N - 1,
    n_factorial(N1, F1),
    F #= N*F1.

このバージョンは、最も一般的な問い合わせに対しても機能します:

?- n_factorial(N, F).
% N = 0, F = 1 ; 
% N = 1, F = 1 ; 
% N = 2, F = 2 ; 
% N = 3, F = 6 ; 
% ... (無数の解が存在)

これは非常に良い結果です:数回の単純な変更で、極めて一般的なロジック・プログラムが誕生しました。

結論

まとめ而言いますと、私は、反骨の精神を発揮すべき場面で限定的にそれを発揮することを推奨します。

陳腐な機能に固執することは、方向性が間違えた反乱です。人生は過去へと逆戻りするものではなく、昨日に留まることもありませんから。

Prolog プログラムにおいて宣言的構成要素を使用することで、パフォーマンスを許容範囲内に保ちながら、より汎用的なプログラムを作り上げてください。


Prolog についてのさらに詳しい情報 | メインページへ

同じ日のほかのニュース

一覧に戻る →

2026/05/18 6:40

ジェンケイアド

## 日本語訳: GenCAD は、画像から直接編集可能な 3D CAD デザインを生成する AI モデルを作成することで、エンジニアリング分野における画期的な突破を遂げています。以前の方法は複雑なデータ構造に苦戦していましたが、この新しいアプローチは Boundary Representation(B-rep)形式に関連する精度上の課題を克服します。これは、latent command representations と diffusion modeling を含む独自の 4 つのステップのプロセスを通じて実現されており、結果を静的な形状ではなく、実行可能なパラメトリックコマンドとしてデコードします。 この技術は、製造業者やエンジニア向けに設計ワークフローを変革し、完全にモディフィ可能で高精度なモデルを瞬時に作成することを可能にしています。以前は、簡易的な 3D ビジュアルを調整可能なエンジニアリングファイルに変換するには、きつ手間のかかる手作業が必要でしたが、GenCAD はこの障壁を取り除き、ユーザーが設計を容易に反復して改善できる完全な CAD プログラムへの即座のアクセスを提供します。その結果、産業全体が大幅な効率向上を実感し、自律的なツールによって現在、さらなる開発に必要な柔軟性を備えた洗練された編集可能な幾何形状が生成されています。

2026/05/18 6:56

ThinkPad:IBM の弁当箱から、レノボの AI ワークステーションへ

## Japanese Translation: ThinkPad ノートパソコンファミリーは、IBM での公式発売(1992 年 10 月 5 日)以降、同社の所有期間(1992–2005 年)および Lenovo による継承期間(2005 年〜現在)にわたり、連続した納品を実現している長年のエンジニアリングの遺産です。当初は 700C カップシェルとして発表され、Richard Sapper の象徴的なマットブラックケース、10.4 インチの有源マトリックスカラー TFT ディスプレイ、そして Ted Selker の開発した TrackPoint II——ホームROWから指を動かす時間を短縮するポインティングスティック——を搭載していました。2010 年までには納品台数が 6000 万台を超え、買収後のブランドの存続と IBM の元々のエンジニアリング原則の維持を証明しました。デザインは 30 年にわたり大きく進化しましたが、1992 年の時代から現代のモデルである 2025/2026 年製の P14s Gen 6 や X1 Carbon に至るまで視覚的な連続性を保ち続けています。これらの現行モデルは「Strix Point」CPU を採用し、高度な NPU とプレミアム OLED ディスプレイを備えています。初期モデルでは 2012 年まで 7 レーキストANDARD化されており、その後は Precision キーボードに置き換えられましたが、後期の世代では 2012 年から開始されたハンダ付けメモリ制限などの課題もありました。一方、近年の傾向としては、薄い筐体にユーザー交換可能な DDR5 SODIMM を採用するなど、修理可能性への再注力が進んでいます。また、専用ドックから汎用的な USB-C/Thunderbolt 規格へも円滑に移行しています。結局のところ、ThinkPad の成功は、元々のデザイン哲学を尊重しつつ最新技術を統合することで、長期的な市場優位性を維持できることを示しています。

2026/05/18 7:23

Fabricked:AMD SEV-SNP を破るために無限ファブリックの設定を誤ること

## Japanese Translation: 最も重要な教訓は、AMD SEV-SNP 機密コンピューティングを完全に侵害する、新しいソフトウェアだけの攻撃「Fabricked」が存在することです。この攻撃は、マルウェア製のハイパーバイザーが内部でコードを実行せずに安全な仮想マシンを完全に制御可能にし、システム起動前に無限ファブリックのルーティング規則への信頼性がない脆弱な UEFI または BIOS 設定から生じます。攻撃者は初期化中に必須のプロセッサ書き込みを停止させることができます。このエクスプロイトは、これらの信頼されていない構成に依存しており、UEFI とハイパーバイザーの特権が必要ですが、非機密の仮想マシンには影響せず、標準的な脅威モデルでは UEFI/ハイパーバイザーが信頼できると仮定されています。BreakFAST(制御ファブリック経由でのトラフィックのリダイレクト)といった過去の中継接続の脆弱性に関連しているものの、Fabricked は IOMS コンポーネントを独自に標的にし、RMP 初期化中に PSP 書き込みを停止させる点で、Intel TDX や Arm CCA および他のアーキテクチャとは異なります。この脆弱性は XCA インスタンスとして分類され、CVE-2025-54510 に割り当てられ、AMD Zen 5 EPYC プロセッサで確認されており、Zen 3、Zen 4、および Zen 4 システムに影響を与えます。同様の内部の脆弱性は Intel システムにも存在します(INTEL-SA-00960)。一般的にハイパーバイザーは信頼できると仮定されていることで AMD システムが保護されていますが、この特定のエクスプロイトは、脆弱なハードウェアに対してその保証を壊します。影響を受けた機器には、デプロイが安全であると見なされるまでにセキュリティの欠陥を修正するための即時のファームウェア更新が必要な勧告書(AMD-SB-3034)が発行されています。公開プロセスには 2026 年 4 月 14 日までのエンバーゴが含まれていました。

プロログによるコーディング・ホラー。 | そっか~ニュース