優れた Prolog を作成するためにマスターしなければならない設計ヒューリスティックは何ですか? 経験豊富なプログラマーが Prolog に習熟するには、約 2 年かかると聞きました。再帰を効果的に使用することもその一部ですが、それは比較的小さなハードルのようです。プログラマーをこれほどまでに悩ませているのは、一体何なのでしょうか? その品質を判断するには、サンプル コードで何を探す必要がありますか?
1 に答える
優れた Prolog コードを作成する上での主な困難は、プログラムの意図や目的を理解するだけでなく、適切に伝えることにあります。他のプログラミング言語とは対照的に、多くの場合、同じプログラム内にまったく異なる種類の Prolog コードがいくつかあります。このようなレベルを混同することで、バグや問題が発生します。
純粋で単調なコード。
このコードは Prolog の中心にあります。このようなコードでは、多くの代数的性質が保持され、実際の問題は、Prolog がよく宣伝される純粋で理想的な方法で記述されます。しかし、そのような部分でも、非終了など、特定の手続き上のプロパティが表面化する場合があります。例として、結合の可換性を取り上げます。純粋で単調なコードで、同じ関係( A, B )
を記述します。( B, A )
唯一の違いは、異なる終了動作と、回答がどのように表示されるかの順序にあります。理想的には、純粋述語の名前は、述語が関係であることを伝えます。命令は、ここでは間違いなく良い選択ではありません。
副作用のあるコード。 もう 1 つの極端な例は、機械または頭の中で効果的に実行することによってのみ理解できるコードです。プログラムには単純な不変条件はありません。しかし、そのような部分でも、不動などの特定の特性が観察される場合があります。事実上、そのようなコードは他のプログラミング言語と大差ありません。
多くの場合、プログラマーは命令型のコマンド指向の do-this do-that の考え方に慣れているため、副作用のある部分が純粋な部分を「食い尽くし」ます。他の方向に傾くには、どの特性を失うか、または得るかを考えてください。プログラムのテストがどれほど簡単になるかを考えてみてください。プログラムが純粋であればあるほど、余分なサンドボックスがなくても簡単にテストできます。単純なトップレベル クエリで十分です。
一見必要な副作用を犠牲にして純粋な側を拡張する方法の例:
または単にこれらの答え。
編集:あなたのコメントでは、「学習のためのアドバイス」を求めています。だからここにいくつかあります:
純粋で単調なコードだけを書くようにしてください。両方を知っている場合にのみ、どちらか一方を選択するように判断できます。コマンド指向の言語で副作用を生成した経験はあると思いますが、純粋なコードでは経験がありません。結果として、これは、本質的に非単調なコードを書くことを控えることを意味します。
トップレベルで遊ぶ。トップレベルがプログラムにアクセスする唯一の方法であると想像してください。この形式に収まるように、問題をどのように定式化しますか? SWI トップレベルは、このような軽量の相互作用を可能にするように特別に設計されています。
演算にはclpfdを使用します。を使用しない
(is)/2
でください。コードが過度にモディファイされます。純粋で単調なコードの代数的性質をお楽しみください。考えてみてください。どこに目標を追加しても、この目標がプログラムを専門化する (せいぜいそのままにしておく) と予測できます。やみくもに目標を削除しても、その効果 (の一部) はわかります。
非終了をマスターするために、障害スライスの概念を研究してください。
多くのプロローグで提供されているため、ステップバイステップのトレーサ/デバッガを使用しないでください。Prolog が実行する正確な手順のみが表示されます。プログラムの意味に直接関係するものは表示されません。段階的な思考を強化します。
あなたの言語に注意してください。プログラムについてどのように話すかは、プログラムについての考え方に影響を与えます。したがって、多くの操作言語を使用する場合 (例: This do this など)、コマンド指向のビューを強化する可能性があります。物事についてもっときれいに話す方法がありますが、それを見つける必要があります。これはおそらく最も難しい部分です。