title: How to make a fact work both way in Prolog (takes arguments in any order)?
body: <p>I want to define facts which are true both ways (They all have an arity of 2). I had success with a fact expressing the relationship "opposite" this way:</p>
  
  <pre><code>oppositeDeclare(plus, minus).
  
  opposite(X, Y) :- oppositeDeclare(Y, X).
  opposite(X, Y) :- oppositeDeclare(X, Y).
  </code></pre>
  
  <p>I'm trying to make a simple equation solver, and I would also like to define that if A=B then B=A. I can't just write:</p>
  
  <pre><code>equal(A, B):-equal(B,A).
  </code></pre>
  
  <p>because I get out of local stack error. However I can't do the same as I did with the "opposite" fact because "equal" needs to work based on the some rules. ("opposite" got it's input from facts only).</p>
  
  <p>Is there a way I can avoid defining all the rules for "equal" twice?</p>
  
  <p><strong>Edit:</strong></p>
  
  <p>I only want to declare simple mathematical facts to see if I can use Prolog to solve other more complicated tasks where I don't know the mechanism for the solution only simple facts.</p>
  
  <p>So far I have used equal/2 to define things like: if A=B+C, then C=A-B. I want to define equal/2 two ways so that I don't have to define if B+C=A, then A-B=C. Ideally after the new rule it could solve an equation for c like this: a=(b+c)/d -> b+c=a/d -> c=(a/d)-b.</p>
  
  <p>The reason I can't use swap is because I have recursive rules for equal/2.</p>
  
  <p>Bear in mind that it will not always work even for simple equations, because not all necessary facts are defined.</p>
  
  <p>Here's the current program with a query:</p>
  
  <pre><code>5 ?- equal(v, X).
  X = opr(s, per, t) 
  
  % operators: per, times, plus, minus
  % equation(LHS, RHS): used to declare physics equations
  % equal(LHS, RHS): checks equality in a query
  
  equation(s, opr(v, times, t)). % s=v*t
  equation(a, opr(opr(b, plus, c), per, d)). %  a=(b+c)/d
  
  oppositeDeclare(plus, minus).
  oppositeDeclare(per, times).
  
  opposite(X, Y) :- oppositeDeclare(Y, X).
  opposite(X, Y) :- oppositeDeclare(X, Y).
  
  equal(R, opr(A, O, B)) :- equation(R, opr(A, O, B)).       
  % if there's an equation R=A O B , then R = A O B, where O is an operator (+-*/)
  
  equal(A, opr(R, OY, B)) :- equal(R, opr(A, OX, B)), opposite(OY, OX). 
  %declaring in one go: if R=A/B then A=R*B, if R=A-B then A=R+B, if R=A+B then A=R-B, if R=A-B then A=R+B
  </code></pre>