2

リストからすべての変数重複を削除するクエリが必要です。

例:

?- L = [1,2,3,X,Y,3,2], my_awesome_predicate(L, Res).

その場合、Res は [1,2,3] になります。

順序は気にしません ([2,3,1]、[3,2,1] など)。

残念ながら、私は効率を気にしなければならないタスクを持っているので、私の主な質問は、それをより速く行うことができるかということです. 現在、次のコードがあります。

remove_variables([], []).
remove_variables([H|List], Res):- var(H), !, remove_variables(List, Res).
remove_variables([H|List], [H|Res]):- remove_variables(List, Res).

my_awesome_predicate([], []).
my_awesome_predicate(List, Res):-
  sort(List, Sorted),
  remove_variables(Sorted, Res).
4

3 に答える 3

3

SWIを使用している場合は、次のコードでさらに改善できます。

my_awesome_predicate(List, Res):-
  sort(List, MRes),
  remove_variables(MRes, Res).

remove_variables([Var|Tail], NTail):-
  var(Var),
  !,
  remove_variables(Tail, NTail).
remove_variables(Res, Res).

SWI のソートは最初に無制限の変数を残すように思われるため (この動作が他のプロローグの標準であるかどうかはわかりません)、最初の非変数を見つけたら、変数の削除を停止できます。

少しSWI のドキュメントを読むと、次のように述べられています。

4.7.1 Standard Order of Terms

Comparison and  unification of arbitrary  terms.   Terms are ordered  in
the so called ``standard order''.  This order is defined as follows:

 1. Variables < Numbers < Atoms < Strings < Compound Terms

したがって、最初の非変数を見つけたら、要素の削除を停止しても安全だと思われます...

于 2013-05-02T18:57:32.547 に答える