unification, =, \=
When we write a goal like X = Y in Prolog, we are testing for more than simple equality in the mathematical sense. We are testing whether X (which might be a variable, an atom, or an arbitrarily complex term) unifies with Y (which might also be an atom, a variable, or a term). Two atoms, including numeric atoms, unify if they are the same. Two more complex terms unify if they have the same functor and their corresponding arguments unify. A variable always unifies with a term (provided that it is not previously unified with something different) by binding to that term. Examples:
?- fred = fred.
true.
  
fred unifies with fred - they are the same atom.
?- X = fred.
X = fred
  
X unifies with fred by binding X to fred.
?- X = likes(mary, pizza).
X = likes(mary, pizza).
  
X unifies with likes(mary, pizza) by binding X to likes(mary, pizza).
?- likes(
|        mary,
|        book(
|             title(Title),
|             author(
|                    given('Herman'),
|                    SurnameTerm)))
|  =
|  likes(
|        Who,
|        book(
|             title('Moby Dick'),
|             author(
|                    given('Herman'),
|                    surname('Melville')))).
Title = 'Moby Dick',
SurnameTerm = surname('Melville'),
Who = mary.
  
Note that the | characters at the start of each line are continuation prompts from Prolog because this query has been spread over more than one line.
Title, SurnameTerm, and Who are bound in order to achieve unification. The primary functors of the terms on either side of the = match, and unification proceeds by matching pairs of corresponding arguments, for example, by matching and unifying the first argument on the left, mary, with the first argument on the right, Who. Unification succeeds if all of the arguments match. This will include recursively matching the arguments of substructures such as the author/2 substructures.

The goal X \= Y succeeds if X = Y would fail; it is the negated form of =.

Unnecessary Use of "=" to Force Unification

This is basically a style issue. Consider the two following alternative pieces of Prolog code for computing the maximum of two numbers.

max1(X, Y, X) :- X > Y.
max1(X, Y, Y) :- X =< Y.
versus
max2(X, Y, Max) :- X > Y, Max = X.
max2(X, Y, Max) :- X =< Y, Max = Y.

The first version is to be preferred, particularly for a novice Prolog programmer, because it reinforces how Prolog works. It also does not involve the unnecessary Max = X or Max = Y.

Whenever you write "=" in a Prolog procedure, review the code to see whether you can get rid of the "=" clause by replacing the item on the left of "=" by the item to the right of it, elsewhere in the procedure. If you do this with max2, you get max1. Sometimes you may have written the "=" with the variable on the right, in which case you need to instead replace the item on the right of the "=" with the item to the left of it.

It should be possible to do this whenever there is a variable (rather than a more complex term) on at least one side of the "=".