Complementing the existing answers, I would like to state a few additional points:

An operator is an operator

First of all, the operator =:= is, as the name indicates, an operator. In Prolog, we can use the predicate current_op/3 to learn more about operators. For example:

?- current_op(Prec, Type, =:=). Prec = 700, Type = xfx.

This means that the operator =:= has precedence 700 and is of type xfx . This means that it is a binary infix operator.

This means that you can, if you want, write a term like =:=(X, Y) equivalently as X =:= Y . In both cases, the functor of the term is =:= , and the arity of the term is 2. You can use write_canonical/1 to verify this:

?- write_canonical(a =:= b). =:=(a,b)

A predicate is not an operator

So far, so good! This has all been a purely syntactical feature. However, what you are actually asking about is the predicate (=:=)/2 , whose name is =:= and which takes 2 arguments.

As others have already explained, the predicate (=:=)/2 denotes arithmetic equality of two arithmetic expressions. It is true iff its arguments evaluate to the same number.

For example, let us try the most general query, by which we ask for any solution whatsoever, using variables as arguments:

?- X =:= Y. ERROR: Arguments are not sufficiently instantiated

Hence, this predicate is not a true relation, since we cannot use it for generating results! This is a quite severe drawback of this predicate, clashing with what you commonly call "declarative programming".

The predicate only works in the very specific situation that both arguments are fully instantiated. For example:

?- 1 + 2 =:= 3. true.

We call such predicates moded because they can only be used in particular modes of usage. For the vast majority of beginners, moded predicates are a nightmare to use, because they require you to think about your programs procedurally, which is quite hard at first and remains hard also later. Also, moded predicates severely limit the generality of your programs, because you cannot use them on all directions in which you could use pure predicates.

Constraints are a more general alternative

Prolog also provides much more general arithmetic predicates in the form of arithmetic constraints.

For example, in the case of integers, try your Prolog system's CLP(FD) constraints. One of the most important CLP(FD) constraints denotes arithmetic equality and is called (#=)/2 . In complete analogy to (=:=)/2 , the operator (#=)/2 is also defined as an infix operator, and so you can write for example:

| ?- 1 + 2 #= 3. yes

I am using GNU Prolog as one particular example, and many other Prolog systems also provide CLP(FD) implementations.

A major attraction of constraints is found in their generality. For example, in contrast to (=:=)/2 , we get with the predicate (#=)/2 :

| ?- X + 2 #= 3. X = 1 | ?- 1 + Y #= 3. Y = 2

And we can even ask the most general query:

| ?- X #= Y. X = _#0(0..268435455) Y = _#0(0..268435455)

Note how naturally these predicates blend into Prolog and act as relations between integer expressions that can be queried in all directions.

Depending on the domain of interest, my recommendition is to use CLP(FD), CLP(Q), CLP(B) etc. instead of using more low-level arithmetic predicates.

Also see clpfd, clpq and clpb for more information.

Coincidentally, the operator =:= is used by CLP(B) with a completely different meaning:

?- sat(A =:= B+1). A = 1, sat(B=:=B).