1

次の事実を考えると:

route(TubeLine, ListOfStations).

route(green, [a,b,c,d,e,f]).
route(blue, [g,b,c,h,i,j]).
...

共通のステーションを持たないチューブ ラインのすべてのペアを見つける必要があり、次の結果が得られます。

| ?- disjointed_lines(Ls).
Ls = [(yellow,blue),(yellow,green),(yellow,red),(yellow,silver)] ? ;
no

私は以下の答えを思いつきましたが、それは間違った答えを与えるだけでなく、私の X^ 条件も適用しません - つまり、ステーションリストのメンバーごとに結果を別々に出力します:

disjointed_lines(Ls) :- 
                        route(W, Stations1),
                        route(Z, Stations2),
                        setof(
                        (W,Z),X^
                        (member(X, Stations1),nonmember(X, Stations2)),
                         Ls).

これは、定義が生成する出力です。

| ?- disjointed_lines(L).
L = [(green,green)] ? ;
L = [(green,blue)] ? ;
L = [(green,silver)] ? ;
...

メンバーシップに関する私の論理は間違っていると思いますが、何が間違っているのかわかりません。誰でも私が失敗しているのを見ることができますか?

ここで提案されているように、結果収集に関する Learn Prolog Now の第 11 章も読みましたが、まだ ^ 演算子を正しく使用できないようです。どんな助けでも大歓迎です!


アップデート:

ユーザー CapelliC の提案に従って、コードを次のように変更しました。

disjointed_lines(Ls) :- 
                        setof(
                        (W,Z),(Stations1, Stations2)^
                        ((route(W, Stations1),
                        route(Z, Stations2),notMembers(Stations1,Stations2))),
                         Ls).

notMembers([],_).
notMembers([H|T],L):- notMembers(T,L), nonmember(H,L).

ただし、以下では (X,Y) と (Y,X) の重複が得られますが、次のステップでは別のルールでそれらを削除します。お手伝いありがとう!

4

2 に答える 2

2

route/2 呼び出しを setof' ゴール内に配置し、分離をより明確に表現して、個別にテストできるようにする必要があると思います。^演算子については、変数が目標スコープで普遍的に量化されるように要求します。bagof/3のマニュアルページにあるような簡潔な説明が役立つかもしれません...

disjointed_lines(Ls) :- 
  setof((W,Z), Stations1^Stations2^(
    route(W, Stations1),
    route(Z, Stations2),
    disjoint(Stations1, Stations2)
  ), Ls).

disjoint(Stations1, Stations2) :-
  ... % could be easy as intersection(Stations1, Stations2, [])
      % or something more efficient: early fail at first shared 'station'
于 2017-01-08T08:52:19.517 に答える
1

setof/3関心のある関係を表す補助述語を作成すると、より使いやすくなります。

disjoint_routes(W, Z) :-
    route(W, Stations1),
    route(Z, Stations2),
    disjoint(Stations1, Stations2).

これにより、 の定義はdisjointed_lines/1より短くシンプルになり、演算子は不要になります^

disjointed_lines(Ls) :-
    setof((W, Z), disjoint_routes(W, Z), Ls).

結果に含めたくない変数はsetof/3、補助述語定義内に自動的に隠されます。

于 2017-01-08T14:05:29.283 に答える