私が直面している問題は、少し些細なことです。Prolog で論理的ではなく使用したいのですが、それnot/1
は私が望むものではないようです:
course(ai).
course(pl).
course(os).
have(X,Y) :- course(X),course(Y),not(X = Y).
私は質問します:
have(X,Y), write(X-Y), nl , fail.
そして、私が望む結果が得られません:(
私が直面している問題は、少し些細なことです。Prolog で論理的ではなく使用したいのですが、それnot/1
は私が望むものではないようです:
course(ai).
course(pl).
course(os).
have(X,Y) :- course(X),course(Y),not(X = Y).
私は質問します:
have(X,Y), write(X-Y), nl , fail.
そして、私が望む結果が得られません:(
の代わりにornot(X = Y)
を書く必要があります。ただし、代わりに使用することを検討してください。B、SWI、YAP、SICStus に存在します。違いを確認するには:\+ X = Y
X \= Y
dif(X,Y)
dif/2
?- X = b, dif(a, X).
X = b.
?- X = b, \+ a = X.
X = b.
だから今のところ、すべてがうまくいっているようです。しかし、単純に 2 つの目標の順序を入れ替えるとどうなるでしょうか。
?- \+ a = X, X = b.
false.
?- dif(a, X), X = b.
X = b.
(\+)/1
の答えがあるためa = X
、ゴール\+ a = X
は失敗します。
(\+)/1
したがって、 は否定ではなく、現時点では証明できないことを意味します。
dif/2
ISO Prolog でも安全な近似が可能です。
SWI-Prolog と GNU Prolog の両方で、次のように動作するはずです。
have(X, Y) :- course(X), course(Y), X \= Y.
SWI-Prolog では、 も使用dif/2
できます。これは、述語の前半で使用できるため、より便利です。
have(X, Y) :- dif(X, Y), course(X), course(Y).
上記のユーザー「false」による回答の補助として、つまり
「not(X = Y) の代わりに \+ X = Y と書く必要があります。」
これは、次のような印象を与える可能性があります。
を。「not」と「\+」は別物
b. \+ は機能しますが、そうではありません。
私の理解では、「not」と「\+」は同等ですが、より直感的な意味を伝えるため、最新の Prolog プログラムでは \+ が好まれます。具体的には、「not」は不注意なコーダーに「真実ではない」ことを示唆するかもしれませんが、「\+」は「証明できない」ことを示唆し、その操作が実際に言っていることの真実にはるかに近くなります。Prolog では、「not」は「失敗としての否定」の例ですが、\+ を使用すると、特定のルールで正確に何が主張されているかがプログラマーに明確になると思われます。したがって、「not」を使用することはできますが (ほとんどの PL 実装では下位互換性のために保持されています)、慣用的な最新の PL プログラマーになるには、おそらく \+ を使用することをお勧めします。
あなたが言ったように、OP、これは些細なことです。
試す
course(ai).
course(pl).
course(os).
have(X,Y) :- course(X), course(Y), X \== Y).
これで述語が修正されるはずです。
ただし、一歩先を見て、数学的に言い回しすると、述語が現在提供している (n P 2) ではなく (n C 2)の解決策を探している可能性があります。順列ではなく組み合わせ、選択肢の配置ではなく選択の選択です。選択の。これが私の考えです。
これがあなたが望むものなら、試してみることをお勧めします
course(ai).
course(pl).
course(os).
have(X,Y) :- course(X), course(Y), X @< Y).
これにより、逆の結果が重複するのを防ぐことができます。
@<
原子的により小さいことを意味します。<
は整数用、@<
はアトム用です。