1

X、Y を (1,2)、(1,-2)、(-1,2)、(-1,-2)、(2,1)、(2,-1) で統一するエレガントな方法は何ですか? , (-2,1), (-2,-1)?

このようにすると、エラーが発生しやすく、退屈に思えます。

foo(1,2).
foo(1,-2).
foo(-1,-2).
...
...
...

そして、この方法は高すぎるようです:

foo(X,Y) :-
  L = [1,-1,2,-2],
  member(X,L),
  member(Y,L),
  abs(X,X1), abs(Y,Y1),
  X1 =\= Y1.
4

3 に答える 3

3
foo0(X,Y):-
    member(X,[1,-1]),
    member(Y,[2,-2]).

foo(X,Y):-
    foo0(X,Y);
    foo0(Y,X).
于 2009-10-06T13:56:28.387 に答える
1

コメントされた内容のさらなる発展:

generate_pairs_foo(X,Y) :-
  L = [1,-1,2,-2],
  member(X,L),
  member(Y,L),
  abs(X,X1), abs(Y,Y1),
  X1 =\= Y1.

assert_all_foo([]).

assert_all_foo([(X,Y)|T]) :-
  assert(foo(X,Y)), assert_all_foo(T).

find_all((X,Y),generate_pairs_foo(X,Y),L), assert_all_foo(L).

うーん...見て、すべてのケースを書く方が簡単で短いxD

于 2009-10-06T13:51:58.103 に答える
1

このように member/2 を使用することは、一種のProlog アンチ パターンです。member/2 は短いですが、通常、member/2 は節の索引付けを行うことができません。

あなたは自分自身を試して、これらの2つのソリューションを比較することができます:

フー メンバー:

foo_member0(X,Y):-
    member(X,[1,-1]),
    member(Y,[2,-2]).

foo_member(X,Y):-
    foo_member0(X,Y);
    foo_member0(Y,X).

フー句:

foo_clause0(1).
foo_clause0(-1).

foo_clause1(2).
foo_clause1(-2).

foo_clause2(X,Y) :- foo_clause0(X), foo_clause1(Y).

foo_clause(X,Y) :- foo_clause2(X,Y).
foo_clause(X,Y) :- foo_clause2(Y,X).

GNU Prolog で実行します。

| ?- between(1,1000000,_), foo_member(-2,-1), fail; true.
(516 ms) yes

| ?- between(1,1000000,_), foo_clause(-2,-1), fail; true.
(375 ms) yes

まあ、2 番目の引数がグラウンドのときに、一部の Prolog が自動的に member/1 を句にコンパイルし始めると、状況が変わる可能性があります。

于 2019-02-01T19:07:52.637 に答える