0

I'm writing a program to print factorial from 1 to N:

factorial(1, 1).
factorial(A, B) :-
    A > 0,
    C is A-1,
    factorial(C, D),
    B is A*D. 

print_fact(X) :-
    print_fact_iter(1, X).

print_fact_iter(X, Max) :-
    X < Max+1,
    factorial(X, N),
    write("factorial("),
    write(X),
    write(") = "),
    write(N),
    nl,
    Next is X+1,
    print_fact_iter(Next, Max).

factorial(1) = 1

factorial(2) = 2

factorial(3) = 6

factorial(4) = 24

factorial(5) = 120

But when I delete Next is X+1, and replace Next with X+1, it prints something strange:

print_fact_iter_weird(X, Max) :-
    X < Max+1,
    factorial(X, N),
    write("factorial("),
    write(X),
    write(") = "),
    write(N),
    nl,
    print_fact_iter_weird(X+1, Max).

factorial(1) = 1

factorial(1+1) = 2

factorial(1+1+1) = 6

factorial(1+1+1+1) = 24

factorial(1+1+1+1+1) = 120

The computing is correct indeed but it seems X+1 is not reduced during passing as an argument and interpreted as a string?

false
  • 10,264
  • 13
  • 101
  • 209
Rahn
  • 4,787
  • 4
  • 31
  • 57
  • Have a look at [this answer](http://stackoverflow.com/questions/37481942/counting-occurrences-in-list#answer-37483710). It explains your issue. – lurker May 28 '16 at 11:18

1 Answers1

0

As you say, prolog never evaluates integer expressions when checking predicates, like in foo(X+1).

Remember "X+1" is, in prolog, a term with "+" as type and two elements, X and 1. That is, X+1 <=> +(X,1). Another example is: 1+1+1 <=> +(1,+(1,1))

This term is what is unified with the statement variable.

In order to evaluate an integer expression, "is" should be used, like in your first example.

pasaba por aqui
  • 3,446
  • 16
  • 40