2

So I'm trying to determine if a number is prime using only one predicate. I don't really understand why every number is being declared false here.

is_prime(2).
is_prime(X) :-
    X > 2, %0 and 1 aren't primes, 2 is dealt with above
    1 is mod(X,2), %number is odd
    N is floor(X/2), %I want to only divide X from 1 to X/2
    forall( between(1,N,Z), mod(X,Z) > 0 ). %This should do X mod 1:X/2
false
  • 10,264
  • 13
  • 101
  • 209
user3427168
  • 21
  • 1
  • 2
  • I believe the proper fix to this is by changing the 1 in the forall to 2. That seems to have done it. – user3427168 Apr 21 '14 at 04:40
  • I recommend you submit it as an answer and accept it, if it works. – Daniel Lyons Apr 21 '14 at 05:01
  • I will as soon as it lets me. But one of the guys that commented on this submitted the answer as well. I was going to toggle his comment for the answer. – user3427168 Apr 21 '14 at 05:33
  • I wrote an answer (that using 1 as a start value was not correct) but realized that you already have found out it yourself and hence deleted my answer. Should I undelete it? – hakank Apr 21 '14 at 06:43

2 Answers2

2

The reason your code don't work is the start value of between/3: It should start with 2 (not 1), since X mod 1 is always 0.

hakank
  • 6,629
  • 1
  • 17
  • 27
2

A very straight-forward solution uses CLP(FD) constraints to express the desired properties.

We start with a simpler predicate, which is true iff the number is composite:

is_composite(N) :-
        N #= A*B,
        [A,B] ins 2..sup.

The exact usage details for CLP(FD) constraints differ slightly between Prolog systems. With at most small modifications, you will be able to run the above in all most widely used systems.

Done!

Because:

A prime number is an integer greater than 1 that is not composite.

Here are a few examples:

?- length([_,_|_], P), \+ is_composite(P).
P = 2 ;
P = 3 ;
P = 5 ;
P = 7 ;
P = 11 ;
P = 13 ;
P = 17 ;
P = 19 ;
P = 23 ;
P = 29 ;
etc.

In general, it is good practice to use CLP(FD) constraints when reasoning over integers in Prolog.

mat
  • 40,498
  • 3
  • 51
  • 78