A

In Prolog, instead, by default we use prefix notation:
`smaller(mouse, rabbit)`

. See `op`

if you want to define an infix operator in a Prolog program.

This view of a relation is sometimes called the *extensional*
view - you can lay out the full "extent" of the relation, at
least in the case of a relation over a finite number of items,
like our "smaller" example. The alternative view is called
*intensional*, where we focus on the meaning of the relation.
In Prolog, this corresponds to a rule expressing the relation,
such as:

smaller(X, Y) :- volume(X, XVolume), volume(Y, YVolume), XVolume < YVolume.This, of course, only defines a meaning or intension for

`smaller`

relative to the unspecified meaning of the relation `volume(_,_)`

,
and the meaning of `<`

, which is defined by the Prolog
implementation.
When we come to non-binary relations, such as unary ones
(like `is_a_dog(fido)`

) or ternary ones (like
`gives(john, mary, book)`

or
`between(rock, john, hard_place)`

) the infix
relation doesn't make any sense, so prefix notation is
normal. (Postfix notation - `fido is_a_dog`

can work for unary relations.)

While we often don't think of it this way, a *function*
is a kind of relation. If you are thinking about the function
*f*(*x*) = *x*^{2}, then the essential thing
is that for each value of *x*, there is a value of *f*(*x*)
(namely *x*^{2}). In fact, there is a *unique* value
of *f*(*x*). So a function (of a single variable) can be
viewed as a binary relation such that for every relevant first component
*x*, there is exactly one pair in the relation that has that first
component^{*}: the pair is (*x*, *f*(*x*)). In the case
of *f*(*x*) = *x*^{2}, the pairs are
(*x*, *x*^{2}) for every applicable value of
*x*. We need to specify what the applicable values of *x*
are - the *domain* of the function. If the domain is {1, 2, 3},
then the pairs are {(1,1), (2,4), (3,9)}. If the domain is all
natural numbers, then we can't write out the
extension of the function in full, but we can use a set expression
such as {(*n*, *n*×*n*) | *n* ∈ *N*}
where *N* signifies the set of all natural numbers.

In Prolog, despite the fact that it uses a
relational notation (except for arithmetic expressions), functions
are common, but expressed using the relational notation that depends
on the definition/convention in the previous paragraph. In our Prolog
code defining `smaller(X, Y)`

, above, the relation called
`volume`

is in fact a function written relationally. We
are saying that for every relevant object `X`

there
is a value `XVolume`

that is the volume of `X`

.
This is a function-type relationship.

The notion of domain applies to relations as well as functions:
a more detailed definition of a binary relation *on a set A*
says that such a relation is a subset of the set *A*×*A*
of all pairs of elements of *A*. *A* is the *domain* of the
relation. A binary relation between sets *A* and *B* is a
subset of *A*×*B*. And so on for ternary relations
and beyond. A unary relation on *A* is just a subset of *A*.
Thus *is_a_dog* is a subset of the set of all *Animals*.
Or a subset of the set of all *Things*, depending on just how
broadly you want to consider the concept of being a dog.

However, in Prolog, domains of relations are not explicitly
addressed.^{#}
The notion of domain corresponds exactly to that of *type* in
typed programming languages like, C, C++, Java, Haskell, etc.
Prolog has no built-in way of confining the definition of a relation
(whether extensionally or by a rule) to a particular domain.
If you want to, you can build type-checking into your rules, e.g. by giving
an definition of a type as a unary relation. For example, if you wanted
to define the type of all popes, you could enumerate them all, though
the list would be long:

Then the goalpope(peter). … pope(john_paul_ii). pope(benedict_xvi). pope(francis).

`pope(X)`

would check if `X`

was/is a pope.
Another example: when defining the relation `sister`

in
Prolog, you would usually write something like:

sister(Person1, Person2) :- female(Person1), female(Person2), mother(Person1, Mother), mother(Person2, Mother), father(Person1, Father), father(Person2, Father), Person1 \== Person2.

`female(Person1)`

and `female(Person2)`

are type-checks
- without them, you are defining `sibling`

, not
`sister`

. In practice, you can't enumerate all females, unlike
all popes, but in many cases you would be able to enumerate all the relevant
ones.
In some cases, you might be able to write rules to do type-checking.
Prolog includes some built-in predicates for type-checking:
`number(X)`

succeeds if `X`

is a number,
while `integer(X)`

succeeds only if `X`

is a
an integral (whole) number. Here is a rule to check if a number
is divisible by 3.

div_by_3(X) :- X mod 3 =:= 0.

There is no special syntax for creating functions in Prolog (though there are special arrangements for built-in mathematical functions). To create a function in Prolog, you have to use the relation syntax and create a "relation that happens to be a function". You can do this extensionally, as in

beats(rock, scissors). beats(paper, rock). beats(scissors, paper).or intensionally, with a rule, as with the function

`square_of`

):
square_of(X, XSquared) :- number(X), XSquared is X * X.used as in the next examples:

?- square_of(3.2, Y). Y = 10.24The

`number(X)`

test implicitly limits the domain of the
function to numbers.
Note that while we defined `square_of`

with a functional usage
in mind, it can still be used in a relational sense if desired:

?- square_of(3, 9). true.There are limits to this - while some relations can be queried omnidirectionally:

?- beats(scissors, X). X = paper ?- beats(Y, scissors). Y = rock

`square_of`

cannot, because the goal `XSquared is X*X`

that is part of its definition cannot:
?- square_of(X, 4). fail.even though there are solutions (2 and –2).

*Footnotes:*

* if there is, not *exactly*, but *at most*
one pair in the relation that has *x* as its first member,
we say that the relation is a *partial function*. A partial
function is like a function that has "holes" in it - *f*(*x*)
never has more than one value, but for some *x* in the domain of the
function, *f*(*x*) might not have any value. A real-life
example is the partial function *eldest_child_of*, defined
on the domain of all adult humans.

# there are a couple of areas of Prolog where there is
some built-in type-checking - for example, the built-in predicate
`<`

will generate an error message if you try to use
it compare a string like `'mouse'`

with a number like
`9`

.

?- mouse < 9. ERROR: </2: Arithmetic: `mouse/0' is not a functionThat is, the only way Prolog could make sense of this would be if

`mouse`

were a built-in function, like `sin`

, `cos`

,
or `log`

, but with no arguments. Compare
?- pi < 9. true.Here

`pi/0`