Well, I can't. You are asking the wrong question. The right question would be:
What relation does the predicate describe?
Actually, that is quite difficult to answer, as we would have go through it step-by-step. But there is a better and much cleaner way! As your program uses integers only, we can map the moded relations (<)/2
, (is)/2
and the like to their declarative counterparts in CLP(FD). So I change <
to #<
, is
to #=
, >=
to #>=
.
:- use_module(library(clpfd)).
divide_by(X,D,I,R):-
X #< D, I #= 0, R #= X.
divide_by(X,D,I,R):-
X #>= D, Q #= X - D,
I #= S +1,
divide_by(Q, D, S, R).
The big advantage now is that I can ask Prolog what it thinks the relation is describing. Simply ask: (Don't worry about the Q=Q
, it's just to reorder variables)
N
... dividend
D
... divisor
Q
... quotient
R
... remainder
?- Q=Q, divide_by(N,D,Q,R).
Q = 0, N = R, N#=<D+ -1
This answer reads as follows: The quotient is zero, the dividend and remainder is the same and the remainder is less than the divisor. So this describes all situations where 0 is the "result" or quotient.
Next answer:
; Q = 1, R+D#=N, R#=<D+ -1, N#>=D
The quotient is 1 and the dividend is the divisor plus remainder, and — as in all answers — the remainder is less than the divisor
; Q = 2, _A+D#=N, R+D#=_A, R#=<D+ -1, N#>=D, _A#>=D
This answer is the same as R+D+D#= N
. The system has introduced some extra variables. Not wrong, but a bit clumsy to read.
; Q = 3, _A+D#=N, _B+D#=_A, R+D#=_B, R#=<D+ -1, N#>=D, _A#>=D, _B#>=D
; Q = 4, _A+D#=N, _B+D#=_A, _C+D#=_B, R+D#=_C, R#=<D+ -1,
N#>=D, _A#>=D, _B#>=D, _C#>=D
; ... .
And so on. Let me summarize. All answers look like that:
N#>=D, R#< D, R+D+...+D#= N
^^^^^^^ Q times
or even better:
N#>=D, R #< D, R+Q*D #= N, Q #>= 0.
So what we have answered is what this relation is describing.
When you start Prolog, focus on the declarative side. As what (set/relation) a predicate describes. The procedural side will join without any effort later on.