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

发布于 2024-08-07 01:18:06 字数 328 浏览 7 评论 0原文

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

What's an elegant way to unify X,Y with (1,2), (1,-2), (-1,2), (-1,-2), (2,1), (2,-1) , (-2,1), (-2,-1)?

Doing it this way seems error prone and tedious:

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

And this way seems too expensive:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梦幻的心爱 2024-08-14 01:18:06
foo0(X,Y):-
    member(X,[1,-1]),
    member(Y,[2,-2]).

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

foo(X,Y):-
    foo0(X,Y);
    foo0(Y,X).
本宫微胖 2024-08-14 01:18:06

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

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

A further development on what was commented:

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

Hmmmmmm... look, it's easier and shorter to just write all the cases xD

蓝天白云 2024-08-14 01:18:06

以这种方式使用member/2 是一种Prolog 反模式。虽然
member/2 很短,通常member/2 不能做子句索引。

您可以自己尝试并比较这两个解决方案:

Foo Member:

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 Clause:

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

Now run it in 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 开始自动将 member/1 编译为子句,情况可能会发生变化。

Using member/2 this way is kind of a Prolog anti pattern. Although
member/2 is short, usually member/2 cannot do clause indexing.

You can try your self and compare these two solutions:

Foo Member:

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 Clause:

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

Now run it in 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

Well, the situation might change if some Prolog starts automatically compiling member/1 into clauses, when the second argument is ground.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文