Какой элегантный способ объединить X, Y с (1,2), (1, -2), (-1,2), (-1, -2), (2,1), (2, -1) , (-2,1), (-2, -1)? - PullRequest
2 голосов
/ 06 октября 2009

Какой элегантный способ объединить 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 ]

2 голосов
/ 06 октября 2009
foo0(X,Y):-
    member(X,[1,-1]),
    member(Y,[2,-2]).

foo(X,Y):-
    foo0(X,Y);
    foo0(Y,X).
1 голос
/ 01 февраля 2019

Использование member / 2 таким образом является своего рода Прологом анти-паттерна . Хотя member / 2 является коротким, обычно member / 2 не может выполнить индексацию предложения.

Вы можете попробовать себя и сравнить эти два решения:

Член Foo:

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

Теперь запустите его в 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

Что ж, ситуация может измениться, если какой-нибудь Пролог начнет автоматическую компиляцию member / 1 в предложения, когда второй аргумент является заземленным.

0 голосов
/ 06 октября 2009

Дальнейшее развитие того, что было прокомментировано:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...