While reading SICP I came across logic programming chapter 4.4. Then I started looking into the Prolog programming language and tried to understand some simple assignments in Prolog. I found that Prolog seems to have troubles with numerical calculations.
Here is the computation of a factorial in standard Prolog:
f(0, 1).
f(A, B) :- A > 0, C is A-1, f(C, D), B is A*D.
The issues I find is that I need to introduce two auxiliary variables (C and D), a new syntax (is) and that the problem is non-reversible (i.e., f(5,X) works as expected, but f(X,120) does not).
Naively, I expect that at the very least C is A-1, f(C, D) above may be replaced by f(A-1,D), but even that does not work.
My question is: Why do I need to do this extra “stuff” in numerical calculations but not in other queries?
I do understand (and SICP is quite clear about it) that in general information on “what to do” is insufficient to answer the question of “how to do it”. So the declarative knowledge in (at least some) math problems is insufficient to actually solve these problems. But that begs the next question: How does this extra “stuff” in Prolog help me to restrict the formulation to just those problems where “what to do” is sufficient to answer “how to do it”?
Forget about variables and think that
AandB– is just a name for value which can be placed into that clause(X :- Y).to make it reachable. Think aboutX = (2 + (3 * 4))in the way of data structures which represent mathematical expression. If you will ask prolog to reach goalf(A-1, B)it will try to find such atomf(A-1,B).or a rule(f(A-1,B) :- Z), Z.which will be unified to “success”.is/2tries to unify first argument with result of interpreting second argument as an expression. Considereval/2as variant ofis/2:The reason why
f(X,120)doesn’t work is simple>/2works only when its arguments is bound (i.e. you can’t compare something not yet defined likeXwith anything else). To fix that you have to split that rule into:Update: (fixed
f_rev/4)You may be interested in finite-domain solver. There was a question about using such things. By using
#>/2and#=/2you can describe some formula and restrictions and then resolve them. But these predicates uses special abilities of some prolog systems which allows to associate name with some attributes which may help to narrow set of possible values by intersection of restriction. Some other systems (usually the same) allows you to reorder sequence of processing goals (“suspend”).Also
member(X,[1,2,3,4,5,6,7]), f(X, 120)is probably doing the same thing what your “other queries” do.If you are interested in logical languages in general you may also look at Curry language (there all non-pure functions is “suspended” until not-yed-defined value is unified).