ERROR: Undefined procedure: (+)/2 - prolog

I'm new in SWI-Prolog and I want to check prime function in Prolog.
prime(N) :-
N > 1,
M is N - 1,
check(N, M).
check(_, 1).
check(N, M) :-
M > 1,
R is N - M * N / M,
R > 0,
P is M - 1,
check(N, P).
but when I ask 2 + 2 or another operator like (*)/2, (/)/2,... in Prolog it says: undefined procedure: (+)/2.
I think it is for see or tell. I reassign see(user) and tell(user) but this error occurs again.
why?

In SWI prolog 6.0.2 division as you used it returns floating point number. So prime(13) for example will fail, as remainder is 0. Integer division uses operator //. But check prolog SWI functions rem and mod.
Also you would like to have a cut after first definition of check, otherwise prolog will explore the second definition, which will return false. Cut ensures that after it checked all natural numbers smaller than N, it stops with success.
Here is the corrected code which behaves as desired in SWI Prolog 6.0.2.
prime(N) :-
N > 1,
M is N - 1,
check(N, M).
check(_, 1) :- !.
check(N, M) :-
M > 1,
R is N mod M,
R > 0,
P is M - 1,
check(N, P).

About your error, check this out:
?- 2+2.
ERROR: Undefined procedure: (+)/2
?- X is 2+2.
X = 4
You're supposed to use is in Prolog to force the evaluation of arithmetic expressions. Try typing "help(is)." at SWI-Prolog's prompt.
But your algorithm is massively inefficient, on two accounts. First, you check the candidate number for divisibility by all its preceding numbers, while only those not greater than its square root are enough (if a*b=n and a >= sqrt(n) then b =< sqrt(n)).
Then, you test in reversed order. Multiples of smaller factors are much more frequent than of larger ones, so the testing will get cut off much much earlier when done in ascending order, making the overall program run much much faster. Lastly, no need to test by any even number except 2:
prime(2).
prime(N) :- N > 1,
N mod 2 > 0, % is odd
M is floor(sqrt(N+1)), % round-off paranoia
check(N, M, 3).
check(N, M, F) :- F>M.
check(N, M, F) :- F=<M,
N mod F > 0,
F1 is F + 2, % test by odds only
check(N, M, F1).
primesFromTo(F,T,X):-
between(F,T,X), prime(X).

You are mentioning see and tell: These are very old-fashioned built-in predicates. Better avoid them. Use [file] to load a file, and make to reload it.
For a better implementation of testing primes, see this answer.

Related

Sum of random digits in Prolog

The scenario is to mimic rolling 3 six-sided die in Prolog while trying to obey the recursive nature of prolog. This is easily done with the Fibonacci series
n_factorial(N, F) :-
N #> 0,
F #= N*F1,
N1 #= N-1,
n_factorial(N1, F1).
I'm having difficulty translating this to the dice paradigm, where we add a random number to the sum.
# N = number of dice, S = number of sides, R = result
roll_dice(N, S, R) :-
N1 #> 0,
R = random_between(1, S, R1),
N1 #= N-1,
roll_dice(N1, S, R1).
throws an error but neglects the sum anyway. I would normally use += in other languages.
A few things not quite right there:
R = random_between(1, S, R1) stores that structure in R, it does not generate random numbers.
R1 is used for "the random number you get for rolling one die" and "the sum of all the random numbers from rolling all the remaining dice" and it is unlikely those will be the same value, and when they isn't the same, that will fail.
There is no code to do the summing. (The equivalent of the Factorial video using F #= N * F1)
No recursive base case (the first line of the factorial from the video is not shown in your question, it is n_factorial(0, 1).). When N dice remaining gets down to 0, there is nothing to handle that case.
Here is one implementation:
:- use_module(library(clpfd)).
roll_dice(0, _, 0).
roll_dice(NDice, Sides, Sum) :-
NDice #> 0,
random_between(1, Sides, Roll),
Sum #= Roll + RunningTotal,
NDiceLeft #= NDice - 1,
roll_dice(NDiceLeft, Sides, RunningTotal).
while trying to obey the recursive nature of Prolog.
I guess that's important to understand; this can be done with less bolierplate and fewer temporary variables to name, e.g.:
roll_dice(NDice, Sides, Sum) :-
length(Rolls, NDice),
maplist(random(1, Sides), Rolls),
sum_list(Rolls, Sum).
which makes a list Rolls the right size to hold all the rolls, fills them in using maplist to apply random on each of them, and sums that list for the answer.
I'd do something along the lines of:
roll(N,S,R) :- positive_int(N), positive_int(S), roller(N,S,0,R) .
positive_int(N) :- integer(N), N > 0 .
roller(0,_,R,R) .
roller(N,S,T,R) :-
T1 is 1+random(S),
N1 is N-1,
roller(N1,S,T1,R)
.

Sum to a number program in Prolog

Can someone explain how this code works. I am new to Prolog and I am having trouble thinking like a Prolog programmer.
When you input a number followed by a comma and any variable name, it gives you the sum up to that number
sum_to(1,1) :- !.
sum_to(N, R) :- N1 is N-1, sum_to(N1,TR), R is TR + N.
So sum_to(4, N) gives N = 10.
Your definition can be equivalently written as
sum_to( N, R) :- N = 1, R = 1, !.
sum_to( N, R) :- N1 is N-1, sum_to( N1, R1), R is R1+N.
This is a recursive definition -- it contains a call to the same predicate as the predicate itself. Under the condition that you're going to always call it with a free variable as the second argument and a concrete (hopefully positive) number as the first argument, it expresses a function which calculates the second argument's value from the given first argument.
Thus what you have is a recursive functional definition.
Now let's work through some examples, from the simplest to the progressively more and more complex:
sum_to( 1, R1) :- 1 = 1, R1 = 1, !.
\______________/
R1 = 1.
sum_to( 2, R2) :- N1 is 2-1, sum_to( N1, R1), R2 is R1+2.
\________/
N1 is 1, sum_to( 1, R1),
\____________/
R1 = 1, R2 is 1+2
\_____________________________________/
R2 = 3.
sum_to( 3, R3) :- N2 is 3-1, sum_to( N2, R2), R3 is R2+3.
\________/
N2 is 2, sum_to( 2, R2),
\____......____/
\__________________/
R2 = 3, R3 is 3+3
\_____________________________________________/
R3 = 6.
Right? As the execution progresses through the goals left to right, our variables take on their concrete values one after the other, thus enabling the execution of the next goal, and the next, which instantiate yet more variables, until the final value becomes known.
Now do sum_to( 4, R4).
This is a very imperative-style program implementing an inductive definition concidentally written in Prolog.
It relates two numbers:
In the first clause 1 is related to 1. The ! indicates that the interpreter should stop looking for further solutions in the sum_to/2 predicate.
If the first clause doesn't match (because any of the arguments in the call was different from 1) then the second clause is examined.
And now we simply:
Compute N1 as N-1
Make a recursive call with N1, and getting a value in TR such that N1 and TR are related via sum_to/2 (i.e. TR should be the sum of all integers up to N1). Once we get that, we compute R as the sum of TR and N.
The sum_to relation is correct for the first argument being 1.
The sum_to relation at N is correct if the sum_to relation is correct for N-1.
Computation will terminate if the recursive call "makes something smaller" on each call and will eventually hit a smallest value. It does indeed make N smaller on each call and will eventually hit 1. (Unless one calls this predicate with a 0 N or smaller. Then: catastrophe!)
Looking good.
(Incidentally, inductive definitions tend to go from a constant x to +oo, i.e. "going upwards"; above I am stating correctness moving from any N down towards 1. Am I justified in doing so?)

Check if element in a list of lists is equal prolog

I m trying to check if, in a list of lists, all sublist is equal to the length of the list of lists.
For example, if I have [[1,2],[3,4]] is true, because I have 2 lists
of 2 elements.
Otherwise, if I have
[[1],[2,3]] is false because have 2 lists but not all list has 2
elements
[[1,2],[2,3],[3,4]] is false because I have 2 lists and all list have
2 elements instead of two
.
I did these two function:
count([],0).
count([_H|T],N):-count(T,N1),N is N1+1 .
ma([],0).
ma([H|T],N):- count(H,M1),ma(T,N1), M1 is N1.
I did "count" (and work) for count element in a list and return N the number of elements in a list.
The "ma" function doesn't work because "count" is executed until 0, and return 2, after executing ma but until 1 step, and after making directly the M1 is N1, and obviously return false.
I wish to make M1 is N1 at end of the program (like in another programming language, but I think is the then't correct form.
EDIT:
Daniel suggest to use :
ma([H], N) :- length(H, N).
ma([H|T], N) :- length(H, N), ma(T, N).
But a list with 3 sublists all with 2 elements gives result 2, instead the result will be false(error) because N number of the list must be equal to N number of elements in ALL Sublist.
I will do on my own, without build-in predicate of prolog.
Here a very basic solution without built in predicates:
count_elements([],N,N).
count_elements([_|T],N,N0):-
N1 is N+1,
count_elements(T,N1,N0).
count_length_sub([],_).
count_length_sub([H|T],N):-
count_elements(H,0,N),
count_length_sub(T,N).
solve(L):-
count_elements(L,0,NO),
count_length_sub(L,NO).
?- solve([[1,2],[3,4]]).
true.
?- solve([[1,2],[2,3],[3,4]]).
false.
Your count/2 is like the length/2 builtin, except that the built-in has more instantiation patterns (try length(X, Y) and see). Prefer length/2.
You're right that your ma/2 predicate is unhelpful because 0 is not a length of a sublist. Basically, you've chosen the wrong base case here; your base case should be a list with exactly one item in it:
ma_1([H], N) :- length(H, N).
ma_1([H|T], N) :- length(H, N), ma(T, N).
You will need to wrap this in something that ensures the length matches the length of the outer list:
ma(L, N) :- length(L, N), ma_1(L, N).
Note that there is no need to obtain separate variables and assert their equality (your dance with N and N1). Prolog will simply fail, which is what you want, if N does not have the right value. (Side note, do not use is for unification. The purpose of is is to reduce an arithmetic expression on the right side to a value and assign it to the variable on the left, e.g. X is 2 + 3*4.)
Another approach would be to write your actual request in a logical form and write that instead. A logical form of this request would be something like "ma(L, N) holds if N is the length of L and for all items X of L, they are lists of length N as well". This looks like so:
ma(L, N) :-
length(L, N),
forall(member(X, L),
length(X, N)).
This has an advantage in that no spare choice points are left around, although worrying about that is usually premature optimization.
Another approach would be to employ maplist/N, which has the advantage that it will give you back lists with variables. Unfortunately, length/2 has its parameters in the wrong order so you can't do the really cute thing and just write maplist(length(2), L). However, you can make a flip/3 predicate that flips around the arguments:
flip(P, Y, X) :- call(P, X, Y).
ma(L, N) :- length(L, N), maplist(flip(length, N), L).
Or, you can import library(yall) and use its lambda expressions:
ma(L, N) :- length(L, N), maplist({N}/[X]>>length(X, N), L).
Both of these approaches allow solutions like these:
?- ma(X, N).
X = [],
N = 0 ;
X = [[_1976]],
N = 1 ;
X = [[_1982, _1988], [_1994, _2000]],
N = 2 ;
X = [[_1988, _1994, _2000], [_2006, _2012, _2018], [_2024, _2030, _2036]],
N = 3
...

Calculating whether number is prime in Prolog

I am trying to calculate if the input is a prime number but something goes wrong... here's my code:
primeNumber(X):-
prime_prime(A, 1).
prime_prime(A, B):-
R is A mod B,
R =:= 1,
R =:= A.
prime_prime(X, B):-
B < A,
Next is B + 1,
prime_prime(A, Next).
It gives me false every time. Anyone got any clues or idea on what I am doing wrong?
See http://www.swi-prolog.org/pldoc/man?function=mod/2:
+IntExpr1 mod +IntExpr2
Modulo, defined as Result = IntExpr1 - (IntExpr1 div IntExpr2) × IntExpr2, where div is floored division.
So R should be 0. mod has only one result.
A working solution would be:
primeNumber(A) :-
A > 1, % Negative numbers, 0 and 1 are not prime.
prime_prime(A, 2). % Begin iteration:
prime_prime(A, B) :- % Test if A divides by B without remainder
B >= A % The limit was reached?
-> true % Then it's prime.
; 0 is A mod B % B divides A without a remainder?
-> false % Then it's not prime.
; succ(B, C), % Otherwise: C is B + 1
prime_prime(A, C). % Test if C divides A.
By the way, primeNumber/1 (a predicate named primeNumber, with one argument) is a totally separate predicate from primeNumber/2 (same name, two arguments). A "subfunction" that only gets an extra argument for the start value, is usually given the same name. So instead of prime_prime you should just use primeNumber, though in Prolog you normally don't use camelCase.
Using the optimization that Sergei Lodyagin proposed in the comments:
primeNumber(A) :-
A > 1, % Negative numbers, 0 and 1 are not prime.
sqrt(A, L), % A prime factor of A is =< the square root of A.
prime_prime(A, 2, L). % Begin iteration:
prime_prime(A, B, L) :- % Test if A divides by B without remainder
B >= L % The limit was reached?
-> true % Then it's prime.
; 0 is A mod B % B divides A without a remainder?
-> false % Then it's not prime.
; succ(B, C), % Otherwise: C is B + 1
prime_prime(A, C, L). % Test if C divides A.
And if you use the predefined predicate between(+Low, +High, ?Value):
primeNumber(A) :-
L is floor(sqrt(A)),
\+ (between(2, L, X),
0 is A mod X).
And to reduce the number of iterations even further, you only need to test for odd modules:
primeNumber(2).
primeNumber(A) :-
A > 2,
\+ 0 is A mod 2,
L is floor(sqrt(A) / 2),
\+ (between(1, L, X),
0 is A mod (1 + 2*X)).
Kay already provided a working modification of the broken program. I'll provide a simple analysis of what's broken.
When solving a problem in Prolog, it's good to be able to write out logically what it is you want first. In this case, it appears that you want to declare that:
A number, A, is prime if, for each number B < A, the value of A mod B is non-zero.
There are probably a couple of ways to render this directly into Prolog, of which Kay shows one.
However, the way your original rules are written, they say:
A number, A, is prime if:
(Rule 1) The value of A mod B, for a given value of B, is 1 and is also A.
OR (Rule 2) B < A and Rule 1 is satisfied with A and B+1.
As you can see, the rules as defined have a few issues:
The rules don't match the logical definition of prime described in terms of the modulo relationship between the original number and all the numbers less than itself.
The first rule expects an impossible mathematical condition when A is not equal to 1 (remember, the comma [,] in Prolog is a conjunction)
The rules are initiated with starting divisor of 1, which is probably bad since 1 divides everything and is likely to become an exception to any rules that work
EDIT
Getting back to the first definition of a prime using the modulo operator, we can translate that into Prolog as follows:
is_prime(N) :- % N is prime if...
N > 1, % N > 1, and
non_divisible_from(N, 2). % N is non-divisible by everything from 2 to N-1
non_divisible_from(N, D) :- % N is non-divisible by D through N-1 if...
N =< D. % D >= N
% --OR--
non_divisible_from(N, D) :- % N is non-divisible from D to N-1 if...
N > D, % N > D, and
N mod D =\= 0, % N is non-divisible by D, and
D1 is D + 1, % N is non-divisible by D+1 to N-1
non_divisible_from(N, D1).
This logic is basically the same as Kay's except he's using a Prolog if-then-else construct.

Prolog: Simple program outputting solutions

I've got a predicate taking a single argument. When there is a solution, this single argument should equal some other argument I have (I have a predicate that goes from one argument to three).
I can print the solution easily to see that the algorithm works. However, I just get false/no when the program runs. I think this is something to do with me giving the program a variable and asking it to return the same variable but altered by the program's execution. I've never had this situation before.
Any ideas guys?
If anyone as any suggestions about the code as a whole then I would welcome comments about that too.
Thanks very much and happy new year :).
% Eulers totient function
phi( M ) :-
phi( 0, 0, M ).
phi( Count, Inter, M ) :-
Count = M,
print(Inter),
M is Inter.
phi( Count, Inter, M ) :-
Count \= M,
coprime( Count, M ),
InterNew is Inter + 1,
CountNew is Count + 1,
phi( CountNew, InterNew, M ).
phi( Count, Inter, M ) :-
Count \= M,
\+ coprime( Count, M ),
CountNew is Count + 1,
phi( CountNew, Inter, M ).
UPDATE: This problem is one of the '99 Prolog problems' at : http://sites.google.com/site/prologsite/prolog-problems/2 and it's question 2.09.
UPDATE: coprime/2 predicate was asked for:
% coprime is defined as two integers having a gcd of 1
coprime( X, Y ) :-
gcd( X, Y, 1 ).
which uses gcd predicate:
% calculating the greatest common divisor of two numbers
% recursive version of Euclidian algorithm
gcd( G, 0, G ).
gcd( Lo, Hi, G ) :-
Hi \= 0,
Inter is Lo mod Hi,
gcd( Hi, Inter, G ).
The false/no answer results from the call M is Inter, which tries to establish equality between the totient Inter and the input number M. Since φ(n) is never equal to n except when n = 1, this almost always fails.
You may have intended to assign the value of Inter to M, but this impossible because M is always bound.

Resources