Reputation:
Basically I want to remove the first N
numbers from a list, the function that checks whether a number is prime or not seems to work well but the program itself doesn't
For example for input [2,4,5,7,6,9,11]
and N = 3
I should get [4, 6, 9, 11]
but I get only [4, 6, 9]
.
divisible(X,Y) :-
0 is X mod Y, !.
divisible(X,Y) :-
X > Y+1,
divisible(X, Y+1).
%isPrime function check whether or not the argument is a prime number
isPrime(2) :- true,!.
isPrime(X) :- X < 2,!,false.
isPrime(X) :- not(divisible(X, 2)).
%delFunction (input_list, N, output_list)
delFunction([],_,_).
delFunction(_,0,_).
delFunction([H|T], N, [H|Res]):-
not(isPrime(H)), !,
delFunction(T, N, Res).
delFunction([_|T], N, Res):-
N1 is N-1,
delFunction(T,N1,Res).
delFunction([2,4,5,7,6,9,11],3,X)
-> [4,6,9]
(which is not the correct answer)
Honestly, I don't know where I went wrong, the implementation idea seems pretty easy and straight forward, so is the code.
Also, when I run it it stops at [4]
and I have to keep on clicking next to get me to the end of the execution (thus the result). Any idea how to fix it? I'm thinking maybe I need some cuts but not sure where.
P.S: I'd rather not use built-in functions (if there are any that would help in this scenario)
Upvotes: 1
Views: 203
Reputation: 66220
Fists of all, instead of
delFunction([],_,_).
you should write
delFunction([],_,[]).
because when the input list (the left one) is empty, you have to construct the base for the output list: an empty list; with delFunction([], _, _)
you don't unify the output list with the empty list so the result end with an not unified variable.
Second. Instead of
delFunction(_,0,_).
you should write
delFunction(L,0,L).
The problem is the same: when number is zero you can "copy" the input in the output; that is, you can unify they; that is delFunction(L,0,L)
. With delFunction(_,0,_)
you don't unify and the result ends with a not unified variable.
Third. In the is-prime clause
delFunction([_|T], N, Res):-
N1 is N-1,
delFunction(T,N1,Res).
you should check that N
is greater than zero
delFunction([_|T], N, Res):-
N > 0,
N1 is N-1,
delFunction(T,N1,Res).
or, if you prefer, you should add a cut (!
) in the zero clause
delFunction(L,0,L) :- !.
Just to avoid that Prolog, via backtracking, can give multiple undesired answers.
--- EDIT ---
As Guy Coder, I avoid cuts like a plague; so I propose the following solution to avoid unwanted repetitions.
delFunction([], _, []).
delFunction([H | T], 0, [H | T]).
delFunction([H | T], N, [H | Res]) :-
N > 0,
not(isPrime(H)),
delFunction(T, N, Res).
delFunction([H | T], N, Res):-
N > 0,
isPrime(H),
N1 is N-1,
delFunction(T, N1, Res).
Upvotes: 2