Check whether prime or not in Prolog - recursion

I'm trying to learn Prolog and I've found an example where I need to implement a program to check whether a number is prime or not with a single predicate.
The logic I'm trying to follow is to make a recursive rule to divide by all the number less than that predicate till it reaches the base case which is either X>2 because 0 and 1 aren't primes and divisible by itself
My code till now is :
isPrime(2).
isPrime(X):-
X>2, %0,1 aren't primes
1 is mod(X,2),
Can someone help ?

It's pretty easy provided you don't care about efficiency.
isPrime(X) :-
X > 1,
succ(X0, X),
\+ (between(2, X0, N), 0 is X mod N).
:)

Related

How to find n as sum of dustinct prime numbers (when n is even number)

This problem gives you a positive integer number which is less than or equal to 100000 (10^5). You have to find out the following things for the number:
i. Is the number prime number? If it is a prime number, then print YES.
ii. If the number is not a prime number, then can we express the number as summation of unique prime numbers? If it is possible, then print YES. Here unique means, you can use any prime number only for one time.
If above two conditions fail for any integer number, then print NO. For more clarification please see the input, output section and their explanations.
Input
At first you are given an integer T (T<=100), which is the number of test cases. For each case you will be given a positive integer X which is less than or equal 100000.
Output
For every test case, print only YES or NO.
Sample
Input Output
3
7
6
10 YES
NO
YES
Case – 1 Explanation: 7 is a prime number.
Case – 2 Explanation: 6 is not a prime number. 6 can be expressed as 6 = 3 + 3 or 6 = 2 + 2 + 2. But you can’t use any prime number more than 1 time. Also there is no way to express 6 as two or three unique prime numbers summation.
Case – 3 Explanation: 10 is not prime number but 10 can be expressed as 10 = 3 + 7 or 10 = 2 + 3 + 5. In this two expressions, every prime number is used only for one time.
Without employing any mathematical tricks (not sure if any exist...you'd think as a mathematician I'd have more insight here), you will have to iterate over every possible summation. Hence, you'll definitely need to iterate over every possible prime, so I'd recommend the first step being to find all the primes at most 10^5. A basic (Sieve of Eratosthenes)[https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes] will probably be good enough, though faster sieves exist nowadays. I know your question is language agnostic, but you could consider the following as vectorized pseudocode for such a sieve.
import numpy as np
def sieve(n):
index = np.ones(n+1, dtype=bool)
index[:2] = False
for i in range(2, int(np.sqrt(n))):
if index[i]:
index[i**2::i] = False
return np.where(index)[0]
There are some other easy optimizations, but for simplicity this assumes that we have an array index where the indices correspond exactly to whether the number is prime or not. We start with every number being prime, mark 0 and 1 as not prime, and then for every prime we find we mark every multiple of it as not prime. The np.where() at the end just returns the indices where our index corresponds to True.
From there, we can consider a recursive algorithm for actually solving your problem. Note that you might feasibly have a huge number of distinct primes necessary. The number 26 is the sum of 4 distinct primes. It is also the sum of 3 and 23. Since the checks are more expensive for 4 primes than for 2, I think it's reasonable to start by checking the smallest number possible.
In this case, the way we're going to do that is to define an auxiliary function to find whether a number is the sum of precisely k primes and then sequentially test that auxiliary function for k from 1 to whatever the maximum possible number of addends is.
primes = sieve(10**5)
def sum_of_k_primes(x, k, excludes=()):
if k == 1:
if x not in excludes and x in primes:
return (x,)+excludes
else:
return ()
for p in (p for p in primes if p not in excludes):
if x-p < 2:
break
temp = sum_of_k_primes(x-p, k-1, (p,)+excludes)
if temp:
return temp
return ()
Running through this, first we check the case where k is 1 (this being the base case for our recursion). That's the same as asking if x is prime and isn't in one of the primes we've already found (the tuple excludes, since you need uniqueness). If k is at least 2, the rest of the code executes instead. We check all the primes we might care about, stopping early if we'd get an impossible result (no primes in our list are less than 2). We recursively call the same function for smaller k, and if we succeed we propagate that result up the call stack.
Note that we're actually returning the smallest possible tuple of unique prime addends. This is empty if you want your answer to be "NO" as specified, but otherwise it allows you to easily come up with an explanation for why you answered "YES".
partial = np.cumsum(primes)
def max_primes(x):
return np.argmax(partial > x)
def sum_of_primes(x):
for k in range(1, max_primes(x)+1):
temp = sum_of_k_primes(x, k)
if temp:
return temp
return ()
For the rest of the code, we store the partial sums of all the primes up to a given point (e.g. with primes 2, 3, 5 the partial sums would be 2, 5, 10). This gives us an easy way to check what the maximum possible number of addends is. The function just sequentially checks if x is prime, if it is a sum of 2 primes, 3 primes, etc....
As some example output, we have
>>> sum_of_primes(1001)
(991, 7, 3)
>>> sum_of_primes(26)
(23, 3)
>>> sum_of_primes(27)
(19, 5, 3)
>>> sum_of_primes(6)
()
At a first glance, I thought caching some intermediate values might help, but I'm not convinced that the auxiliary function would ever be called with the same arguments twice. There might be a way to use dynamic programming to do roughly the same thing but in a table with a minimum number of computations to prevent any duplicated efforts with the recursion. I'd have to think more about it.
As far as the exact output your teacher is expecting and the language this needs to be coded in, that'll be up to you. Hopefully this helps on the algorithmic side of things a little.

Recursion Confusion - Summation Symbol

I have an assignment with this symbol on it: [Image of unfamiliar symbol
Basically the question asks "Write a recursive Java method which, given a positive integer n, computes and returns the sum of the integers from 1 to n as follows".
I do not need any help on the recursion itself, I really just need to understand what that symbol means (Link Included), so I can answer the question properly.
My Question: What meaning does the symbol possess? What is my instructor expecting as a valid response?
NOTE: I do NOT want anyone to attempt to answer the actual assignment question. I ONLY want know understand what the symbol being used means and what should be returned in my recursion method.
IT is the sigma symbol which means take the sum from i = 1 to n.
so your output comes as 1 + 2 + 3 + ..... + n
This explanation is to left hand side of the equation. others are the same.
It's a summation symbol
The sum of each i starting from i = 1 to i == n equals the sum of each i starting from i = 1 to i == n/2 plus the sum of of each i starting from i = n/2 + 1 to i == n

Efficient Multiplication of Varying-Length #s [Conceptual]

EDIT
So it seems I "underestimated" what varying length numbers meant. I didn't even think about situations where the operands are 100 digits long. In that case, my proposed algorithm is definitely not efficient. I'd probably need an implementation who's complexity depends on the # of digits in each operands as opposed to its numerical value, right?
As suggested below, I will look into the Karatsuba algorithm...
Write the pseudocode of an algorithm that takes in two arbitrary length numbers (provided as strings), and computes the product of these numbers. Use an efficient procedure for multiplication of large numbers of arbitrary length. Analyze the efficiency of your algorithm.
I decided to take the (semi) easy way out and use the Russian Peasant Algorithm. It works like this:
a * b = a/2 * 2b if a is even
a * b = (a-1)/2 * 2b + a if a is odd
My pseudocode is:
rpa(x, y){
if x is 1
return y
if x is even
return rpa(x/2, 2y)
if x is odd
return rpa((x-1)/2, 2y) + y
}
I have 3 questions:
Is this efficient for arbitrary length numbers? I implemented it in C and tried varying length numbers. The run-time in was near-instant in all cases so it's hard to tell empirically...
Can I apply the Master's Theorem to understand the complexity...?
a = # subproblems in recursion = 1 (max 1 recursive call across all states)
n / b = size of each subproblem = n / 1 -> b = 1 (problem doesn't change size...?)
f(n^d) = work done outside recursive calls = 1 -> d = 0 (the addition when a is odd)
a = 1, b^d = 1, a = b^d -> complexity is in n^d*log(n) = log(n)
this makes sense logically since we are halving the problem at each step, right?
What might my professor mean by providing arbitrary length numbers "as strings". Why do that?
Many thanks in advance
What might my professor mean by providing arbitrary length numbers "as strings". Why do that?
This actually change everything about the problem (and make your algorithm incorrect).
It means than 1234 is provided as 1,2,3,4 and you cannot operate directly on the whole number. You need to analyze your algorithm in terms of #additions, #multiplications, #divisions.
You should expect a division to be a bit more expensive than a multiplication, and a multiplication to be lot more expensive than an addition. So a good algorithm try to reduce the number of divisions and multiplications.
Check out the Karatsuba algorithm, (ps don't copy it that's not what your teacher want) is one of the fastest for this specification.
Add 3): Native integers are limited in how large (or small) numbers they can represent (32- or 64-bit integers for example). To represent arbitrary length numbers you can choose strings, because then you are not really limited by this. The problem is then, of course, that your arithmetic units are not really made to add strings ;-)

Multiply without + or *

I'm working my way through How to Design Programs on my own. I haven't quite grasped complex linear recursion, so I need a little help.
The problem:
Define multiply, which consumes two natural numbers, n and x, and produces n * x without using Scheme's *. Eliminate + from this definition, too.
Straightforward with the + sign:
(define (multiply n m)
(cond
[(zero? m) 0]
[else (+ n (multiply n (sub1 m)))]))
(= (multiply 3 3) 9)
I know to use add1, but I can't it the recursion right.
Thanks.
Split the problem in two functions. First, you need a function (add m n) which adds m to n. What is the base case? when n is zero, return m. What is the recursive step? add one to the result of calling add again, but decrementing n. You guessed it, add1 and sub1 will be useful.
The other function, (mul m n) is similar. What is the base case? if either m or n are zero, return 0. What is the recursive step? add (using the previously defined function) m to the result of calling mul again, but decrementing n. And that's it!
Since this is almost certainly a homework-type question, hints only.
How do you add 7 and 2? While most people just come up with 9, is there a more basic way?
How about you increment the first number and decrement the second number until one of them reaches zero?
Then the other one is the answer. Let's try the sample:
7 2
8 1
9 0 <- bingo
This will work fine for natural numbers though you need to be careful if you ever want to apply it to negatives. You can get into the situation (such as with 10 and -2) where both numbers are moving away from zero. Of course, you could check for that before hand and swap the operations.
So now you know can write + in terms of an increment and decrement instruction. It's not fantastic for recursion but, since your multiply-by-recursive-add already suffers the same problem, it's probably acceptable.
Now you just have to find out how to increment and decrement in LISP without using +. I wonder whether there might be some specific instructions for this :-)

Why is 0 divided by 0 an error?

I have come across this problem in a calculation I do in my code, where the divisor is 0 if the divident is 0 too. In my code I return 0 for that case. I am wondering, while division by zero is generally undefined, why not make an exception for this case? My understanding why division by zero is undefined is basically that it cannot be reversed. However, I do not see this problem in the case 0/0.
EDIT OK, so this question spawned a lot of discussion. I made the mistake of over-eagerly accepting an answer based on the fact that it received a lot of votes. I now accepted AakashM's answer, because it provides an idea on how to analyze the problem.
Let's say:
0/0 = x
Now, rearranging the equation (multiplying both sides by 0) gives:
x * 0 = 0
Now do you see the problem? There are an infinite number of values for x as anything multiplied by 0 is 0.
This is maths rather than programming, but briefly:
It's in some sense justifiable to assign a 'value' of positive-infinity to some-strictly-positive-quantity / 0, because the limit is well-defined
However, the limit of x / y as x and y both tend to zero depends on the path they take. For example, lim (x -> 0) 2x / x is clearly 2, whereas lim (x -> 0) x / 5x is clearly 1/5. The mathematical definition of a limit requires that it is the same whatever path is followed to the limit.
(Was inspired by Tony Breyal's rather good answer to post one of my own)
Zero is a tricky and subtle beast - it does not conform to the usual laws of algebra as we know them.
Zero divided by any number (except zero itself) is zero. Put more mathematically:
0/n = 0 for all non-zero numbers n.
You get into the tricky realms when you try to divide by zero itself. It's not true that a number divided by 0 is always undefined. It depends on the problem. I'm going to give you an example from calculus where the number 0/0 is defined.
Say we have two functions, f(x) and g(x). If you take their quotient, f(x)/g(x), you get another function. Let's call this h(x).
You can also take limits of functions. For example, the limit of a function f(x) as x goes to 2 is the value that the function gets closest to as it takes on x's that approach 2. We would write this limit as:
lim{x->2} f(x)
This is a pretty intuitive notion. Just draw a graph of your function, and move your pencil along it. As the x values approach 2, see where the function goes.
Now for our example. Let:
f(x) = 2x - 2
g(x) = x - 1
and consider their quotient:
h(x) = f(x)/g(x)
What if we want the lim{x->1} h(x)? There are theorems that say that
lim{x->1} h(x) = lim{x->1} f(x) / g(x)
= (lim{x->1} f(x)) / (lim{x->1} g(x))
= (lim{x->1} 2x-2) / (lim{x->1} x-1)
=~ [2*(1) - 2] / [(1) - 1] # informally speaking...
= 0 / 0
(!!!)
So we now have:
lim{x->1} h(x) = 0/0
But I can employ another theorem, called l'Hopital's rule, that tells me that this limit is also equal to 2. So in this case, 0/0 = 2 (didn't I tell you it was a strange beast?)
Here's another bit of weirdness with 0. Let's say that 0/0 followed that old algebraic rule that anything divided by itself is 1. Then you can do the following proof:
We're given that:
0/0 = 1
Now multiply both sides by any number n.
n * (0/0) = n * 1
Simplify both sides:
(n*0)/0 = n
(0/0) = n
Again, use the assumption that 0/0 = 1:
1 = n
So we just proved that all other numbers n are equal to 1! So 0/0 can't be equal to 1.
walks on back to her home over at mathoverflow.com
Here's a full explanation:
http://en.wikipedia.org/wiki/Division_by_zero
( Including the proof that 1 = 2 :-) )
You normally deal with this in programming by using an if statement to get the desired behaviour for your application.
The problem is with the denominator. The numerator is effectively irrelevant.
10 / n
10 / 1 = 10
10 / 0.1 = 100
10 / 0.001 = 1,000
10 / 0.0001 = 10,000
Therefore: 10 / 0 = infinity (in the limit as n reaches 0)
The Pattern is that as n gets smaller, the results gets bigger. At n = 0, the result is infinity, which is a unstable or non-fixed point. You can't write infinity down as a number, because it isn't, it's a concept of an ever increasing number.
Otherwise, you could think of it mathematically using the laws on logarithms and thus take division out of the equation altogther:
log(0/0) = log(0) - log(0)
BUT
log(0) = -infinity
Again, the problem is the the result is undefined because it's a concept and not a numerical number you can input.
Having said all this, if you're interested in how to turn an indeterminate form into a determinate form, look up l'Hopital's rule, which effectively says:
f(x) / g(x) = f'(x) / g'(x)
assuming the limit exists, and therefore you can get a result which is a fixed point instead of a unstable point.
Hope that helps a little,
Tony Breyal
P.S. using the rules of logs is often a good computational way to get around the problems of performing operations which result in numbers which are so infinitesimal small that given the precision of a machine’s floating point values, is indistinguishable from zero. Practical programming example is 'maximum likelihood' which generally has to make use of logs in order to keep solutions stable
Look at division in reverse: if a/b = c then c*b = a. Now, if you substitute a=b=0, you end up with c*0 = 0. But ANYTHING multiplied by zero equals zero, so the result can be anything at all. You would like 0/0 to be 0, someone else might like it to be 1 (for example, the limiting value of sin(x)/x is 1 when x approaches 0). So the best solution is to leave it undefined and report an error.
You may want to look at Dr. James Anderson's work on Transarithmetic. It isn't widely accepted.
Transarithmetic introduces the term/number 'Nullity' to take the value of 0/0, which James likens to the introduction 'i' and 'j'.
The structure of modern math is set by mathematicians who think in terms of axioms.
Having additional axioms that aren't productive and don't really allow one to do more stuff is against the ideal of having clear math.
How many times does 0 go into 0? 5. Yes - 5 * 0 = 0, 11. Yes - 11 * 0 = 0, 43. Yes - 43 * 0 = 0. Perhaps you can see why it's undefined now? :)
Since x/y=z should be equivalent to x=yz, and any z would satisfy 0=0z, how useful would such an 'exception' be?
Another explanation of why 0/0 is undefined is that you could write:
0/0 = (4 - 4)/0 = 4/0 - 4/0
And 4/0 is undefined.
If a/b = c, then a = b * c.
In the case of a=0 and b=0, c can be anything because 0 * c = 0 will be true for all possible values of c. Therefore, 0/0 is undefined.
This is only a Logical answer not a mathamatical one,
imagine Zero as empty how can you Divide an empty by an empty this is the case in division by zero also how can you divide by something which is empty.
0 means nothing, so if you have nothing, it does not imply towards anything to distribute to anything. Some Transit Facilities when they list out the number of trips of a particular line, trip number 0 is usually the special route that is routed in a different way. Typically, a good example would be in the Torrance Transit Systems where Line 2 has a trip before the first trip known as trip number 0 that operates on weekdays only, that trip in particular is trip number 0 because it is a specialized route that is routed differently from all the other routes.
See the following web pages for details:
http://transit.torrnet.com/PDF/Line-2_MAP.pdf
http://transit.torrnet.com/PDF/Line-2_Time_PDF.pdf
On the map, trip number 0 is the trip that is mapped in dotted line, the solid line maps the regular routing.
Sometimes 0 can be used on numbering the trips a route takes where it is considered the "Express Service" route.
why not make an exception for this
case?
Because:
as others said, it's not that easy;)
there's no application for defining 0/0 - adding exception would complicate mathematics for no gains.
This is what I'd do:
function div(a, b) {
if(b === 0 && a !== 0) {
return undefined;
}
if(b === 0 && a === 0) {
return Math.random;
}
return a/b;
}
When you type in zero divided by zero, there's an error because whatever you multiply zero from will be zero so it could be any number.
As Andrzej Doyle said:
Anything dived by zero is infinity. 0/0 is also infinity. You can't get 0/0 = 1. That's the basic principle of maths. That's how the whole world goes round. But you can sure edit a program to say "0/0 is not possible" or "Cannot divide by zero" as they say in cell phones.

Resources