Обеспечение неравенства списков? - PullRequest
2 голосов
/ 28 апреля 2019

Для данного CSP я использовал множество точек зрения, одна из которых - несколько более экзотическая логическая модель, которая использует переменный массив размером NxNxN. Затем я навязываю неравенство различных подмассивов с помощью этого фрагмента:

(foreach(X, List1), 
 foreach(Y, List2), 
 foreach((X #\= Y), Constraints) 
 do true),
1 #=< sum(Constraints).

Производительность модели плохая, поэтому мне было любопытно узнать больше о том, что происходит за кулисами. Это правильный способ гарантировать, что два заданных списка различны? Правильно ли я понимаю, что каждое ограничение (X #\= Y) в списке Constraints должно быть создано перед вычислением суммы, а это означает, что все соответствующие переменные тоже должны быть созданы?

1 Ответ

1 голос
/ 29 апреля 2019

В библиотеке ограничений library(ic_global) действительно отсутствует ограничение; он должен предоставить lex_ne/2, аналогично lex_lt / 2 . Это будет иметь такое же логическое и рабочее поведение, как и код, который вы написали, то есть распространяться, когда в его списках аргументов остается только одна переменная:

?- B#::0..1, lex_ne([1,0,1], [1,B,1]).
B = 1

Для сравнения, вы можете попробовать оператор различия звука ~ = / 2 (в некоторых прологах он называется dif / 2). Это эффективно реализовано, но оно не знает о доменах и поэтому не будет распространяться; он просто ждет, пока обе стороны будут созданы, а затем потерпит неудачу или преуспеет:

?- B#::0..1, [1,0,1] ~= [1,B,1].
B = B{[0, 1]}
There is 1 delayed goal.

?- B#::0..1, [1,0,1] ~= [1,B,1], B = 0.
No (0.00s cpu)

Будет ли это в целом быстрее, зависит от вашего приложения.

...