Unknown procedure / not a function term

Why the second and the third forms of make_dice are returning errors:

% make_dice(Count, Sides, dice(Count, Sides)).
% WORKS FINE

% make_dice(Count, Sides) :-
%     integer(Count),
%     integer(Sides),
%     dice(Count, Sides).
% FAILS WITH: Unknown procedure: dice/2

% make_dice(Count, Sides, Dice) :-
%     integer(Count),
%     integer(Sides),
%     Dice is dice(Count, Sides).
% FAILS WITH: Arithmetic: `dice/2' is not a function

make_dice(Count, Sides, Dice) :-
    integer(Count),
    integer(Sides),
    make_dice_helper(Count, Sides, Dice).
% WORKS FINE

make_dice_helper(Count, Sides, dice(Count, Sides)).

Guessing we need a free variable to bind to, as the output (understanding roughly - it’s not really output, because it is two way matching). Still, not clear why for example the third form fails (with Arithmetic: dice/2 is not a function).

Just started with Prolog (not with programming) - went through some Prolog material; so far.

Using with is/2 will not work because dice is not an arithmetic function: SWI-Prolog -- Arithmetic Functions

The remainder is confusion between a term and a predicate, i.e. unifying a variable to a term, or calling a predicate (aka “procedure”).

1 Like

Thanks! Much appreciated.

You don’t need the service clause make_dice_helper/3, unification in clause body is handled efficiently by the compiler:

make_dice(Count, Sides, Dice) :-
    integer(Count),
    integer(Sides),
    Dice = dice(Count, Sides).
2 Likes