Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
427 views
in Technique[技术] by (71.8m points)

prolog - Pairwise relation over list

The following higher order predicate succeeds if all pairs of the list's elements are true for a given relation. Is there a common or better, more intention revealing name for this relation?

My original motivation for this name was that in , there is often a constraint all_different/1 which is described as being true, iff the elements are pairwise different. In fact, rather preferred to say the elements are all different, but I have been frequently corrected (by fellow Prolog programmers) to use pairwise different. In fact, this constraint can now most naturally be expressed as pairwise(#=, Zs).

pairwise(Rel_2, Xs) :-
   i_pairwise(Xs, Rel_2).

i_pairwise([], _).
i_pairwise([X|Xs], Rel_2) :-
   maplist(call(Rel_2,X),Xs),
   i_pairwise(Xs, Rel_2).

As @aBathologist observed, pairwise is not the right word, because it might make sense for non-reflexive Rel too.

Also, the relation Rel is not a total relation, because call(Rel, X, X) might fail, but pairwise(Rel, Xs) could still succeed.

I even hoogled for (a->a->Bool)->[a]->Bool. But Hayoo found it: name pairwise in contrast to pointwise.

Looked at MO and mathematics:

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I like your question very much. I went digging around through wikipedia to try and find a fitting term. I'm thinking of the list as a set, in the sense that each member is a distinct and differentiable element, so that even if there were two instances of the same atom, would be different elements, qua their position or whatever. I think that the predicate you've described would, then, be a [connex] binary relation (https://en.wikipedia.org/wiki/Total_relation):

A binary relation R over X is called connex if for all a and b in X such that a ≠ b, a is related to b or b is related to a (or both)

On the other hand, if the relation is also meant to be reflexive, then it would describe a total binary relation (dicussed on the same page as connex).

However, I think that your predicate pairwise/2 doesn't actually fit the description you give, or (more likely) I don't quite understand.

You say that the predicate should succeed "if all pairs of the list's elements are true for a given relation". But pairwise(>, [1,2,3]) is false whereas pairwise(<, [1,2,3]) is true, while pairwise(>, [3,2,1]) is true but pairwise(<, [3,2,1]) is false. But out of each pair of elements from these lists, one is greater than the other.


Edits:

The following is the result of my misunderstanding, and turned out not to be relevant to the question.

I offered the following definition, thinking it might be a more accurate definition of what @false was describing, but he pointed out that it doesn't define the relation I thought it did. I have kept it for the sake of making our subsequent exchange in the comments intelligible.

Adding another clause that checks the list in reverse would solve this problem, but might there be other relations which can't be caught by reversing? Also, is there a more efficient way of implementing a genuine connex check?

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

After @false pointed out my error in the preceding, I wrote the following definition. I believe it does describe a connex over the elements of S:

actual_connex_over(Rel, S) :-
   foreach( ( select(X, S, T), member(Y, T) ),
            ( call(Rel, X, Y) ; call(Rel, Y, X) )
          ).

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...