什么是将X,Y与(1,2),(1,-2),( - 1,2),( - 1,-2),(2,1),(2,-1)统一的优雅方法,(-2,1),( - 2,-1)?

时间:2009-10-06 13:33:26

标签: prolog unification

将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.

3 个答案:

答案 0 :(得分:2)

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

foo(X,Y):-
    foo0(X,Y);
    foo0(Y,X).

答案 1 :(得分:1)

以这种方式使用member / 2是 Prolog反模式。虽然 member / 2简短,通常member / 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

那么,情况可能如果一些Prolog的自动开始编译构件/ 1到条款,当第二个参数是地改变。

答案 2 :(得分:0)

对评论内容的进一步发展:

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

就更容易也更短