次のファンキーなアイデアがありました。instof/2 のミラーである述語 isinst/2 があるとします。Xが小惑星であることを確認したい場合。私たちがする宇宙船:
isinst(asteroid, X). /* checks whether X is an asteroid */
isinst(spaceship, X). /* checks whether X is a spaceship */
したがって、Prolog コードは単純です。
collide_with(X, Y) :- isinst(asteroid, X), isinst(asteroid, Y), /* case 1 */
collide_with(X, Y) :- isinst(asteroid, X), isinst(spaceship, Y), /* case 2 */
collide_with(X, Y) :- isinst(spaceship, X), isinst(asteroid, Y), /* case 3 */
collide_with(X, Y) :- isinst(spaceship, X), isinst(spaceship, Y), /* case 4 */
ここで、Prolog システムが属性変数と、X{...} などの属性変数の読み取り可能な概念を提供すると仮定します。次に、次のように定義します。
collide_with(X{isinst(asteroid)}, Y{isinst(asteroid)}) :- /* case 1 */
collide_with(X{isinst(asteroid)}, Y{isinst(spaceship)}) :- /* case 2 */
collide_with(X{isinst(spaceship)}, Y{isinst(asteroid)}) :- /* case 3 */
collide_with(X{isinst(spaceship)}, Y{isinst(spaceship)}) :- /* case 4 */
属性変数は統合に直接役立つため、これによりコードがわずかに高速になる可能性があります。ボディで何かをチェックする必要があるわけではありません。
それがより良いインデックス作成にもつながるかどうかは、現時点ではまだ不明です。問題は、継承階層が実行時に変更される可能性があり、これがインデックスに影響を与え、再インデックスが必要になる可能性があることです。これは、クラスを final としてマークするなどして、継承階層がオープンワールドでないことを保証できる場合にも当てはまります。Prolog システムが動的であると見なされる場合、これも変化する可能性があります。
それに加えて、継承階層がオープンワールドではない場合、つまりサブクラスを列挙できる場合、インデックス作成に関するいくつかの明白なアイデアがあります。ここでの唯一の問題は、可能であれば、同じボディで異なるヘッドを効率的に共有することです。そうしないと、節が爆発的に増える可能性があります。
さよなら
PS: 属性変数はフックを延期する可能性があるため、本体チェックから属性変数に移行する場合、意味が少し変わります。
X と Y はインスタンス化されていないため、ボディ チェックを使用すると、collide_with(X,Y) が失敗し、属性変数を使用すると、collide_with(X,Y) が成功する可能性があります。
しかし、collide_with/2 の引数がインスタンス化された場合、結果は多かれ少なかれ同じになるはずです。