簡単な 3 ステップの解決方法は次のとおりです。
- 事実を説明する(チェック)
- 結果として必要なものを生成しますが、プログラムに選択肢を残します
- 解決策が適用されないルールを与える
したがって、2から始めます。
可能な結果を生成します。簡単な言葉で考えてみてください。すべての引数について、私はそれを選択するかしないかです。may or not may
の部分は subsum で解決できます。{}
{choose(X)} :- argument(X).
またはさらに簡単:引数から部分和を選択します
{choose(X):argument(X)}.
Potasscoと#show choose/1.
、共鳴モード で解を確認してみましょうenumerate all
:
Answer: 1
Answer: 2
choose(b)
Answer: 3
choose(c).
..
Answer: 15
choose(a) choose(b) choose(c)
Answer: 16
choose(a) choose(b) choose(c) choose(d)
SATISFIABLE
すべての組み合わせが見つかりました。間違ったものを取り除く時が来ました。繰り返しますが、簡単な言葉で考えてみてください。一方が他方を攻撃する 2 つの引数を選択することはできません。(ヘッドが開いたままの場合、これは False として読み取られます。)
:- choose(X), attack(X,Y), choose(Y).
もう一度確認してください:
Answer: 1
Answer: 2
choose(a)
Answer: 3
choose(d)
Answer: 4
choose(a) choose(d)
Answer: 5
choose(c)
Answer: 6
choose(a) choose(c)
Answer: 7
choose(b)
Answer: 8
choose(b) choose(d)
SATISFIABLE
ここで、選択されていないすべての引数が、少なくとも 1 つの選択された要素によって攻撃されるようにする必要があります。
1 {choose(Y):attack(Y,X)} :- argument(X), not choose(X).
読み取り:選択されていないすべての引数についてX
、それを攻撃する選択された引数の数は少なくとも 1 つです。
それをチェックしましょう:
Answer: 1
choose(a) choose(d)
SATISFIABLE
良い。
制約は通常空の頭で定式化されるので、最後の規則を再定式化しましょう:
:- argument(X), not choose(X), {choose(Y):attack(Y,X)} 0.
読み取り: There is no argument X
, which is not selected であり、選択された引数が最大 0 個あり、 which attack X
. 同じ出力が得られます。
完全なコード:
argument (a;b;c;d).
attack (a,b).
attack (b,c).
attack (d,c).
{choose(X):argument(X)}.
:- choose(X), attack(X,Y), choose(Y).
:- argument(X), not choose(X), {choose(Y):attack(Y,X)} 0.
#show choose/1.