0

Why this factorial implementation doesn't work:

factorial(0, B) :- B is 1.
factorial(A, B) :-
                   A > 0,
                   Ax is A-1,
                   B is A*Bx,
                   factorial(Ax, Bx).

And this works:

factorial2(0, B) :- B is 1.
factorial2(A, B) :-
                   A > 0,
                   Ax is A-1,
                   factorial2(Ax, Bx),
                   B is A*Bx.
ajuc
  • 590
  • 6
  • 12
  • 1
    mat posted an answer to this [some time ago](http://stackoverflow.com/a/2909528/772868) – false May 10 '12 at 14:46

1 Answers1

2

Because is/2 needs the right hand side to be fully instantiated.

In your first example Bx is not instantiated and is used in the right hand side whereas in your second example it is used after it gets instantiated.

gusbro
  • 22,357
  • 35
  • 46
  • 2
    Simply use finite domain constraints with library(clpfd): Replace > by #> and is by #=, and it works. – mat May 10 '12 at 07:08
  • I've thought > and is would work like regular rules in prolog. Because they doesn't I can't for example ask prolog to find such A, that factorial2(A, 6). Because this definition of factorial only works for specified A. I'd check this clpfd library, thanks mat. – ajuc May 10 '12 at 08:40
  • 3
    >/2 and is/2 are not complete relations in this sense, but the finite domain constraints are completely declarative and work in all directions, also if the arguments are variables. In fact, there is litte reason to use primitive integer arithmetic predicates (>, is etc.) at all in modern Prolog systems: You can simply use finite domain constraints and often get more general programs. – mat May 10 '12 at 09:29