ここでは、建設的否定からのいくつかのアイデアが役立ちます。
仮説
論理的なカットを行う簡単な方法があります。制約は通常完全否定であるため、特に制約の場合。したがって、制約 C がある場合、通常、次のプロパティを持つ制約 C' を見つけることができます。
C' <=> ~C
次のように読み取れる 2 つの句の間で優先順位を課すには:
p :- C, q.
p :- r
次の手順を実行してください。
p :- C, q.
p :- C', r.
制約ソルバーが具体化された否定を提供する場合、(#\)/1
そのための演算子を定義することさえできます:
:- op(1050,xfy,#?).
:- op(1100,xfy,#:).
(A #? B #: C) :- (A, B); (#\ A, C).
そして、次のように書きます。
p :- C #? q #: r.
この戦略をあなたの例に適用しましょう:
例
現在、コードは次のようになっています。
result(Input, Result) :-
Input #> 10,
Result = decline.
result(Input, Result) :-
Input in 0..20,
Result = offer.
次に、次の操作を行います。
result(Input, Result) :-
Input #> 10,
Result = decline.
result(Input, Result) :-
Input #=< 10, Input in 0..20,
Result = offer.
実行例を次に示します。
?- result(15, X).
X = decline ;
false.
?- result(8, X).
X = offer.
(#?)/2
CLP(FD) ライブラリが具体化をサポートしているため、たとえば SWI-Prolog でこれを使用できるようになりました。(#:)/2
CLP(FD) ライブラリを参照し、上記のように定義したと仮定します。
result(Input, Result) :-
Input #> 10
#?
Result = decline
#:
Input in 0..20,
Result = offer.
実行例を次に示します。
?- result(15, X).
X = decline ;
false.
?- result(8, X).
X = offer.
免責事項
(#?)/2
andの後者の構文は、Java の if-then-else 演算子and(#:)/2
に触発されています。定義をオーバーライドまたは拡張できないため、より Prolog にインスパイアされた構文は使用できません。(?)/2
(:)/2
(;)/2
具体化の詳細については、たとえばここのセクション A.8.4 具体化を参照してください。私たちがしなかったことは、CLP(FD) if-then-else の定義で論理積と論理和を具体化することでした。なぜなら、then と else の部分には、CLP(FD) 制約以外の他の目標が含まれる可能性があるからです。
さよなら