2017-01-13 3 views
1

В основном я хочу удалить первые цифры N из списка, функция, которая проверяет, является ли число простым или нет, работает хорошо, но сама программа неУдаление первых N простых чисел из списка (Prolog)

Например, для ввода [2,4,5,7,6,9,11] и N = 3 Я должен получить [4, 6, 9, 11], но я получаю только [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] (который не является правильным ответом)

Честно говоря, я не знаю, где я пошел не так, идея реализации кажется довольно легко и прямо вперед, так что это код.

Кроме того, когда я запускаю его, он останавливается на [4], и я должен продолжать нажимать рядом, чтобы привести меня к концу выполнения (таким образом, результат). Любая идея, как это исправить? Я думаю, может быть, мне нужны некоторые сокращения, но не знаю, где.

PS: Я предпочел бы не использовать встроенные функции (если таковые имеются, которые помогли бы в этом сценарии)

+0

Да, это мои проблемы. Конечный результат не правильный, и он дает мне несколько ответов (когда он должен дать только один, очевидно). Все еще думайте, что это неправильное использование! где-то ... – Hansewl

ответ

2

Кулаки всех, вместо

delFunction([],_,_). 

вы должны написать

delFunction([],_,[]). 

потому что, когда список ввода (левый) пуст, вы должны построить базу для выходного списка: пустой список; с delFunction([], _, _) вы не объединяете выходной список с пустым списком, чтобы результат заканчивался не унифицированной переменной.

Второй. Вместо

delFunction(_,0,_). 

вы должны написать

delFunction(L,0,L). 

Проблема та же: когда число равно нулю вы можете «копировать» вход в выход; то есть вы можете их унифицировать; это delFunction(L,0,L). С delFunction(_,0,_) вы не объединяетесь, а результат заканчивается не унифицированной переменной.

В-третьих. В IS-премьер п о

delFunction([_|T], N, Res):- 
    N1 is N-1, 
    delFunction(T,N1,Res). 

вы должны проверить, что N больше нуля

delFunction([_|T], N, Res):- 
    N > 0, 
    N1 is N-1, 
    delFunction(T,N1,Res). 

или, если вы предпочитаете, вы должны добавить надрез (!) в пункте нулевой

delFunction(L,0,L) :- !. 

Просто, чтобы избежать того, что Prolog с помощью обратного отслеживания может дать несколько нежелательных ответов.

--- EDIT ---

Как Guy Coder, избежать сокращений, как чума; поэтому я предлагаю следующее решение, чтобы избежать нежелательных повторений.

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). 
+0

@GuyCoder - с помощью вызова? С 'delFunction ([2,4,5,7,6,9,11], 3, X)'? – max66

+0

Спасибо, человек, действительно помог, теперь он работает и дает только 1 ответ. – Hansewl

+0

@GuiCoder - с swi-прологом Я получаю только один ответ, но с gprolog я получаю 3. Нужно добавить 'N> 0' che перед' not (isPrime()) ' – max66

Смежные вопросы