Reputation: 119
I am trying to make an invert/2
. I want it to ignore the order of its arguments, so that you don't need to worry about which half of the inversion is the one you know, and so that you don't have to repeat yourself when stating inversions as facts. I currently have
invert(Left, Right) :-
call_with_depth_limit(invert(Right, Left), 1, Result),
Result \= depth_limit_exceeded.
as the first invert
rule. This mostly works, but if invert(a, b).
, then ?- invert(b, X).
gives both X = a
and false
, which is not what I want at all.
Upvotes: 0
Views: 99
Reputation: 58244
There are two things I'd consider. First, make sure that the predicate you create for establishing the symmetry of the relationship in your facts has a different name than your facts. Having the name be the same usually leads to issues such as infinite recursion. Secondly, if the facts are under your control to declare, be consistent about whether the facts explicitly declare the symmetrical case or not. If they do, then you don't need the extra predicate. If they don't, then you need an extra predicate.
For example, with symmetries explicitly declared:
opposite(a, b).
opposite(b, a).
opposite(c, d).
opposite(d, c).
You don't need an extra predicate to get the symmetrical solutions for opposite
.
An example where the symmetries are not explicitly declared:
opposite(a, b).
opposite(c, d).
inverted(X, Y) :- opposite(X, Y).
inverted(X, Y) :- opposite(Y, X).
In this case, querying inverted/2
instead of opposite/2
will handle the symmetry in the relationships.
Upvotes: 1