Ответ 1
Мне очень нравится ваш вопрос. Я пошел копаться через википедию, чтобы попытаться найти подходящий термин. Я думаю о списке как о наборе, в том смысле, что каждый член является четким и дифференцируемым элементом, так что даже если бы были два экземпляра одного и того же атома, это были бы разные элементы, qua их позиция или что-то еще. Я думаю, что предикат, который вы описали, будет тогда бинарным отношением [connex] (https://en.wikipedia.org/wiki/Total_relation):
Бинарное отношение R над X называется коннексом, если для всех a и b из X такое, что a ≠ b, a связано с b или b, связано с (или обоими)
С другой стороны, если это отношение также должно быть рефлексивным, тогда оно будет описывать полное двоичное отношение (на той же странице, что и коннекс).
Однако, я думаю, что ваш предикат pairwise/2
на самом деле не соответствует описанию, которое вы даете, или (более вероятно) я не совсем понимаю.
Вы говорите, что предикат должен преуспеть "если все пары элементов списка верны для данного отношения". Но pairwise(>, [1,2,3])
является ложным, тогда как pairwise(<, [1,2,3])
истинно, а pairwise(>, [3,2,1])
- true, но pairwise(<, [3,2,1])
- false. Но из каждой пары элементов из этих списков одна больше другой.
Изменения:
Ниже приводится результат моего недоразумения и оказалось, что это не относится к вопросу.
Я предложил следующее определение, считая, что это может быть более точное определение того, что @false описывало, но он указал, что он не определяет отношения, которые, как я думал, он сделал. Я сохранил это ради того, чтобы сделать наш последующий обмен в комментариях понятным.
Добавление другого предложения, которое проверяет список в обратном порядке, решит эту проблему, но могут ли быть другие отношения, которые невозможно поймать путем обращения вспять? Кроме того, существует ли более эффективный способ реализации подлинной проверки connex?
connex_over(Rel, Xs) :-
i_connex_over(Xs, Rel), !.
connex_over(Rel, Xs) :-
reverse(Xs, Sx),
i_connex_over(Sx, Rel).
i_connex_over([], _).
i_connex_over([X|Xs], Rel) :-
maplist(call(Rel,X),Xs),
i_connex_over(Xs, Rel).
После того, как @false указал мою ошибку в предыдущем, я написал следующее определение. Я считаю, что он описывает коннекцию над элементами S:
actual_connex_over(Rel, S) :-
foreach( ( select(X, S, T), member(Y, T) ),
( call(Rel, X, Y) ; call(Rel, Y, X) )
).