Рекурсивность |Натуральные числа в списке swish пролог - PullRequest
0 голосов
/ 02 октября 2019

у меня следующая проблема: «вернуть числа натуральных чисел массива»

ex. Naturales (R, [6, -7, -4,3,2,8]). R = 4

, когда появляются отрицательные числа, возвращают false и нарушают мою рекурсивность

naturales(R,[Head|Tail]):-naturales(R1,Tail), Head >= 0, R is R1+1.
naturales(0,[]).

Ответы [ 5 ]

1 голос
/ 03 октября 2019

Вот очень короткое решение:

naturales(In, Out) :-
    aggregate(count,X^(member(X, In), X >= 0), Out).
0 голосов
/ 03 октября 2019

Как отмечали другие, рекурсивный вызов не может завершиться при наличии отрицательных чисел. Таким образом, вы можете просто пропатчить вашу программу таким образом

naturales(R,[Head|Tail]):-naturales(R1,Tail), (Head >= 0, R is R1+1 ; R=R1).
naturales(0,[]).

Теперь почти каждый Пролог (кроме mine :) реализует (->) / 2, также известный как 'если-то-иначе. Таким образом, патч также может быть написан как

naturales(R,[Head|Tail]):-naturales(R1,Tail), (Head >= 0 -> R is R1+1 ; R=R1).
naturales(0,[]).

Учитывая, что naturales / 2 в любом случае не является хвостовой рекурсивной (см. Ответ @NicholasCarey), я думаю, что он не имеет практического значения для вас.

0 голосов
/ 02 октября 2019

Если ваш предикат действительно должен иметь только 2 аргумента, один из которых является результатом, R, а другой - заданным списком, [H | T], вы можете сделать что-то вроде этого. Обратите внимание, что первый предикат вызывает второй «naturales» с 3 аргументами, а затем запускает рекурсивный процесс. C является только счетчиком, где вы можете добавить количество положительных элементов и затем скопировать это значение в результат в последней строке кода. Первая строка просто для того, чтобы убедиться, что пустой список возвращает 0 положительных элементов. Вероятно, есть лучшие способы сделать это, этот, вероятно, самый интуитивный.

naturales(X, []):- X = 0.
naturales(R, [H|T]):- naturales(R, [H|T], 0).

naturales(R, [H|T], C):- (H > 0, C1 is C + 1, naturales(R1, T, C1), R = R1) ; naturales(R1, T, C), R = R1.
naturales(X, [], X).
0 голосов
/ 02 октября 2019

Распространенной идиомой пролога является использование вспомогательного предиката с аккумуляторной (дополнительной) переменной. Попробуйте что-то вроде этого:

natural_numbers( Xs, N ) :- natural_numbers( Xs, 0, N ).

natural_numbers( []     , N , N ) .
natural_numbers( [X|Xs] , T , N ) :-
  ( X > 0 -> T1 is T+1 ; T1 = T ) ,
  natural_numbers( Xs, T1, N ).
0 голосов
/ 02 октября 2019

Ну, есть две проблемы. Во-первых, у вас нет правила для негативного случая, поэтому рекурсия останавливается на негативах. Во-вторых, у вас нет аргумента thrid в качестве выходного списка для возврата списка с результатами:

naturales(R,[Head|Tail],OutList):-naturales(R1,Tail,OutList), Head < 0, R is R1+1.
naturales(R,[Head|Tail],[Head|T]):-naturales(R1,Tail,T), Head >= 0, R is R1+1.
naturales(0,[],[]).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...