0
votes

Why does this program does not work in Prolog ?

%  Goldbach's conjecture. 
% Goldbach's conjecture says that every positive even number greater 
% than 2 is the sum of two prime numbers. Example: 28 = 5 + 23.

:- ensure_loaded(p31).

% goldbach(N,L) :- L is the list of the two prime numbers that
%    sum up to the given N (which must be even).
%    (integer,integer) (+,-)

goldbach(4,[2,2]) :- !.
goldbach(N,L) :- N mod 2 =:= 0, N > 4, goldbach(N,L,3).

goldbach(N,[P,Q],P) :- Q is N - P, is_prime(Q), !.
goldbach(N,L,P) :- P < N, next_prime(P,P1), goldbach(N,L,P1).

next_prime(P,P1) :- P1 is P + 2, is_prime(P1), !.
next_prime(P,P1) :- P2 is P + 2, next_prime(P2,P1).

First off, I had to remove the code line :- ensure_loaded(p31). Otherwise marked an error saying that does not exist.

Second, when I run it on SWI-Prolog screen with ?-goldbach(4,X,Y). marked an error that says:

ERROR: Arguments are not sufficiently instantiated

Why?

Could someone please help me to fix the program?

Thank you.

1
You only need exactly two addends, so I would not bother with a list. It just makes the predicate a little more cumbersome. And what's p31? Note that is/2 is only for arithmetic evaluation when all of the variables of the 2nd argument are known numeric values. Try using CLP(FD). - lurker
? ? ?............ - Lw. K
Let me try another question, maybe this one is easier, although I assume you copied this code from somewhere else so you don't know how it works: why are you trying to call goldbach(4, X, Y)? The code comment clearly indicates that the top level is goldbach/2. You should be calling goldbach(4, L). - lurker
You probably think goldbach(4, X, Y) will give you the two primes in X and Y, but this is not so. goldbach(4, X) will give you the two primes in a list in X. Prolog is quite different from other languages and you need to start reading an introduction to logic programming and actively solving simpler exercises. What you are looking at is a solved exercise in the middle of a complex sequence of exercises with dependencies between them. - Rob Blanco
Your question was about why the program doesn't work and could it be fixed. The answer has been given: you need to call the correct top level predicate: goldbach(4, L). If you have a different specific question about a specific issue with programming in Prolog, you should post it separately. If you just want a 3-argument version of this program, you could write, my_goldbach(N, X, Y) :- goldbach(N, [X,Y]). and call my_goldbach(4, X, Y). - lurker

1 Answers

3
votes

Observe that goldbach/2 is the predicate being defined, which uses an auxiliary predicate goldbach/3. goldbach/3 is called by goldbach/2 when certain conditions on N are met in order to compute the doubleton L, using 3 as the initial value for the auxiliary parameter P of goldbach/3.

In fact, you can see that goldbach/3 will always be called with its first and third parameters instantiated. The requirement on the first parameter is clear from the documentation of goldbach/2, which marks it as +; the third parameter is provided when goldbach/2 calls its helper goldbach/3 to perform the computation.

A call like goldbach(4, X, Y) fails because it tries to perform arithmetic (Q is N - P) involving uninstantiated variables, which results in an error: arithmetic on logic variables does not make sense to Prolog. To clarify, the program should work fine, but you are not supposed to call goldbach/3 directly.

As it stands, the predicate is_prime/1 is missing. The ensure_loaded/1 directive you removed was looking for the file where this predicate would be defined (in this development).