2

私は述語を持っています

superclass('Horde', 'Blood Elf').
superclass('Horde', 'Orc').

element('Blood Elf', ['Paladin', 'Priest','Mage','Warlock','Death Knight','Rogue']).
element('Orc', ['Warrior', 'Shaman','Warlock','Death Knight','Hunter','Rogue']).

find(A):-
  (  element(_,B),member(A,B)
  -> forall(
        ( element(_,B), member(A,B) ),
        ( element(C,B), superclass(D,C), format('~w -> ~w -> ~w\n',[D,C,A])))
  ;  superclass(A, _)
  -> format('~w\n',A), forall(superclass(A,B),format('\t~w\n',B))
  ).  

および の結果の 2 つfind('Rogue').。結局、述語はそのうちの 1 つだけを出力します。ただし、forall(..)コンソールにコピーペーストすると、2 つの結果がすべて表示されます。なんで?

4

1 に答える 1

2

基本的に、あなたはシングルを持ってい(->)/2ますIf -> Then. あなたのIf場合は

( element(_,B), member(A,B) )

最初の回答を採用してコミットするため、他の回答は考慮されません。はThen1forall/2回成功するか失敗するかのいずれかです。したがって、複数の回答が得られる状況があってはなりません。


したがって、元のプログラムとクエリを比較しています。

?- forall(
      (  element(_,B), member('Rogue',B) ),
      (  element(C,B),
         superclass(D,C),
         format('~w -> ~w -> ~w\n',[D,C,'Rogue'])
      )).

でも、元のプログラムは違いました!それは本質的に次のとおりでした。

?- element(_,B),member(A,B)
    -> forall(
          (  element(_,B), member(A,B) ),
          (  element(C,B),
             superclass(D,C),
             format('~w -> ~w -> ~w\n',[D,C,A]))).

したがって、元のプログラムではA Bが修正されましたが、クエリでは のみAが修正されました。

このように書き出すことによるプログラミングは、Prolog 自体とは関係のないあらゆる種類のエラーにつながることが多いことに注意してください。Prolog の純粋で単調なサブセットに最初に固執することをお勧めします。

于 2014-10-28T17:19:35.567 に答える