Prolog print numbers from 1 to N? - prolog

Assume the user gives an input N to the function, how would I print these numbers from 1 to N (recursively or other wise).
example
print_numbers(40).
->1
->2
->…
->40

You want to print numbers from 1 to N so print_numbers(N) can be translated in print_numbers(1, N).
Now what is print_numbers from X to Y ?
print_numbers from X to Y is print(X) and print_numbers from X+1 to N!
In Prolog, you will get :
print_numbers(N) :-
print_numbers(1, N).
% general case X must be lower than Y
print_numbers(X, Y) :-
X =< Y,
writeln(X),
X1 is X + 1,
print_numbers(X1, Y).

Using between/3 and forall/2:
?- forall(between(1, 40, X), writeln(X))
1
2
3
...
39
40
true.

Related

define predicate prolog by requirements

I have to define a predicate p(X, Y), where Y = f(X) where
How could I define the predicate, according to this requirements?
Almost the same way it's written there, three cases for Y's value given different X conditions:
f(X, Y) :- X < 4, Y is X ^ 2 - 1.
f(X, Y) :- X >= 4, X =< 6, Y is sqrt(X) + 1.
f(X, Y) :- X > 6, Y is 9 - X.
or the middle case
f(X, Y) :- between(4, 6, X), Y is sqrt(X) + 1.
which I had originally and find more readable, but changes the behaviour for that case, which is a tradeoff.
Then:
:- f(3, Y).
Y = 8
( zcompare/3 hints at a way to get rid of the choice points without using cut !, but only if you restrict to integers ).
Another way that doesn't leave choice points behind...
f(X,Y) :- X < 4 -> Y is X^2 - 1 ;
X =< 6 -> Y is sqrt(X) + 1 ;
Y is 9 - X .

Prolog - print the sum of the EVEN numbers from 1 to 10

I am trying to print all the even numbers from 1 to 10 using Prolog, and here is what I have tried:
printn(10,0):- write(10),!.
printn(X,Sum):-
( X mod 2 =:= 0 -> Sum is X+Sum, Next is X+1, nl, printn(Next);
Next is X+1, printn(Next) ).
but it returns false.
You don't need to create the list with the numbers from the beginning, it is better to examine numbers once:
print(X,Y):-print_even(X,Y,0).
print_even(X, X, Sum):-
( X mod 2 =:= 0 -> Sum1 is X+Sum;
Sum1 = Sum
), print(Sum1).
print_even(X, Y, Sum):-
X<Y, Next is X+1,
( X mod 2 =:= 0 -> Sum1 is X+Sum, print_even(Next, Y, Sum1);
print_even(Next, Y, Sum)
).
Keep in mind that in Prolog Sum is Sum+1 always fails you need to use a new variable e.g Sum1.
Example:
?- print(1,10).
30
true ;
false.
The most useful way of obtaining Prolog output is to capture the solution in a variable, either individually through backtracking, or in a list. The idea of "printing", which carries over from using other languages allows for formatting, etc, but is not considered the best way to express a solution.
In Prolog, you want to express your problem as a relation. For example, we might say, even_with_max(X, Max) is true (or succeeds) if X is an even number less than or equal to Max. In Prolog, when reasoning with integers, the CLP(FD) library is what you want to use.
:- use_module(library(clpfd)).
even_up_to(X, Max) :-
X in 1..Max,
X mod 2 #= 0, % EDIT: as suggested by Taku
label([X]).
This will yield:
3 ?- even_up_to(X, 10).
X = 2 ;
X = 4 ;
X = 6 ;
X = 8 ;
X = 10.
If you then want to collect into a list, you can use: findall(X, even_up_to(X), Evens).
What error do you have? Here is my solution:
Create list [1...10]
Filter it, excluding odd numbers
Sum elements of the list
Code:
sumList([], 0).
sumList([Head|Tail], Sum) :-
sumList(Tail, Rest),
Sum is Head + Rest.
isOdd(X) :-
not((X mod 2) =:= 0).
sumOfEvenNums(A, B, Out) :-
numlist(A, B, Numbers),
exclude(isOdd, Numbers, Even_numbers),
sumList(Even_numbers, Out).
Now you can call sumOfEvenNums(1, 10, N)
In ECLiPSe, you can write with iterator:
sum_even(Sum):-
( for(I,1,10),fromto(0,In,Out,Sum)
do
(I mod 2 =:= 0 -> Out is In + I;Out is In)
)
With library(aggregate):
evens_upto(Sum) :-
aggregate(sum(E), (between(1, 10, E), E mod 2 =:= 0), Sum).
Thanks to #CapelliC for the inspiration.

How to write a prolog mathematical Function?

I am trying to convert a math function into prolog, but I keep getting error. Can anyone give me a hint that where is my mistake, please?
I want to convert f (x) = x ˆ 2 + f (x - 1). So I am assuming that this is a recursive procedure. Here is What I have done so far.
function(0,0) :- !.
function(1,1) :- !.
function(X,Y) :-
X1 is ((X * X) + (X - 1)),
function(X1, Y).
I have also tried
function(0,0) :- !.
function(1,1) :- !.
function(X,Y) :-
X1 is (X * X), X2 is (X - 1),
function(X1, N1),
function(X2, N2),
Y is N1 + N2.
Any help is appreciated.
Prolog works using predicate calculus.
A predicate can evaluate to true or false.
You need to write what is true (anything else is assumed false as prolog interpreters will use a closed world assumption).
for your function we can define a predicate:
func(X, Y)
where func is a predicate that evaluates to true if X is x and Y is f(X)
You need to tell prolog when func(X, Y) is true
func(0, 0).
func(X, Y) :- X > 0, U is X - 1, func(U, V), Y is X * X + V.
The above code can be thought of saying
your predicate func is true when X is 0 and Y is 0
This will be your base case. (You only need one since you only have 1 recursive call).
Next is your recursive case:
When is func true for a general X
we need X to be greater than 0
we need the result of f(x-1) which we called V
V is the result of f(X-1) when func(X-1, V) is true
prolog doesn't allow expressions inside predicates so we state U is X-1
Then we put everything together and state Y is X *X + V
Try this:
f(0,0) . % f(0) is 0.
f(X,Y) :- % otherwise...
integer(X) , % - constrain X to be an integer, and
X > 0 , % - constrain X to be positive,
X1 is X-1 , # - then decrement X
f(X1,Y1) , % - compute f(X-1) ,
Y is X*X + Y1 % - and add X*X to that to get the result.
. % Easy!

Display first 100 Integers in Prolog

I am very new to prolog and I am trying to code a simple program which will display the first 100 integers.
is_integer(0).
is_integer(X) :-
is_integer(Y),
( Y >= 100, ! ; X is Y + 1 ).
It works well but when we ask if 2.1 is an integer then it replies "true". This is because 2.1 is between 0 and 100.
But I want a program which will strictly display the first 100 Integers only.Could someone help me with this please.
Thanks!
I think this matches your style in the question if you don't want to use predefined functions like between(0, 100, X):
between0_100(X) :-
(var(X) -> true ; X >= 0), % either X is unbound or >= 0.
between0_100(0, X).
between0_100(X, X).
between0_100(X, Y) :-
Z is X + 1, % increment X
Z =< 100, % and test if it is <= 100
between0_100(Z, Y). % recurse
?- between0_100(X).
X = 0 ;
X = 1 ;
X = 2 ;
…
X = 98 ;
X = 99 ;
X = 100 ;
false.
?- between0_100(2.1).
false
What do you mean by "display"?
The (very standard) predicate between/3 is defined along the lines of:
between(Lower, Upper, N) is true when N >= Lower and N =< Upper. If N is an integer, it will succeed or fail, and throw an error if it is not an integer. If N is a free variable it will enumerate solutions by backtracking. I am quite certain you can find reasonable implementations of between/3 elsewhere on StackOverflow.
Or do you mean that you type in:
?- first_100_ints.
And you get:
0
1
2
3
4
...
99
?
You could do this as follows:
first_100_ints :-
next_int(0, 100).
next_int(X, Upper) :-
( X < Upper
-> format('~d~n', [X]),
succ(X, X1),
next_int(X1, Upper)
; true
).
This is one "cheap" way to do it. But keep in mind that this is not how you would want to write a Prolog program, normally. One somewhat better way would be to use the built-ins between/3 and forall/3:
?- forall(between(0, 99, X), format('~d~n', [X])).
This is equvalent to:
?- \+ (between(0, 99, X), \+ format('~d~n', [X])).
which reads something along the lines of, "There is no number between 0 and 99 (inclusive) for which you cannot print out the number". See here.
There are other things you can do, depending on what your exact goal is.
I second #Kay's answer. If it is possible, don't use side-effects and use the prolog-toplevel instead!
If your Prolog implementation offers clpfd, you could do it like this:
:- use_module(library(clpfd)).
?- X in 0..100, indomain(X).
X = 0. ;
X = 1 ;
X = 2 ;
% % ... lots of more answers ...
X = 99 ;
X = 100 ;
false. % query terminates universally

Checking circular primes in Prolog

I am new to Prolog and am having a hard time figuring out what is wrong with my code.
I am trying to find circular prime numbers
So far I have this code:
isCircularPrime(N):-
prime(N),
numDigits(N, Y),
Y2 is Y-1,
rotate(N,Y,N2),
circularPrime(N2, Y2, Y2).
circularPrime(_, 0, _).
circularPrime(N, 1, _):-prime(N).
circularPrime(N, I, J):-
I > 1,
prime(N),
I2 is I-1,
rotate(N,J,N2),
circularPrime(N2,I2,J).
Where:
numDigits makes Y the number of digits in N.
rotate makes N2 a rotation of N (e.g. 12 -> 21).
prime is true if N is prime, false otherwise
Currently it recurses infinitely whenever a number is prime but not a circular prime (e.g. 19, 23, etc). If someone could explain what I'm doing wrong, I would really appreciate it.
Here is the other code in case anyone wants to test this for themselves:
prime(2).
prime(3).
prime(N):-
N>3,
N mod 2 =\= 0,
\+ divisible(N,3).
divisible(N,I):- N mod I =:= 0.
divisible(N,I):-
I*I < N,
I2 is I + 2,
divisible(N, I2).
numDigits(N, 1):-
N<10, N>0.
numDigits(N, X):-
N2 is N/10,
numDigits(N2, Y),
X is (Y+1).
rotate(N, L, R):-
LastDigit is N mod 10,
Base is div(N, 10),
Exponent is L - 1,
Num is 10**Exponent,
NewBase is LastDigit*Num,
R is Base + NewBase.
I think the problem is in your numDigits/2 predicate.
It offers all kinds of answers, so the program keeps backtracking again and again:
numDigits(1, X).
X = 1 ;
X = 2 ;
X = 3 ;
X = 4 ;
X = 5 etc...
After adding cuts to numDigits/2 the programs seems to behave correctly:
isCircularPrime(19).
false.

Resources