Хвост пролога Рекурсивная процедура подсчета необоснованных переменных в списке - PullRequest
1 голос
/ 12 июля 2011

Я пытаюсь написать рекурсивную процедуру Tail для подсчета количества необработанных переменных в списке. Я немного застрял, где я иду не так.

Мой текущий запрос ниже:

count([S,L],N) :- var(S), !, N+1.
count([L],N).

Ответы [ 3 ]

2 голосов
/ 13 июля 2011

Вот хвостовая рекурсия для подсчета переменных в списке. Используется техника аккумуляторов:

count(L, N) :- count(L, 0, N).     % L=list, N=count, 0=value of the sum accumulator S
count([], S, S) :- !.              % the innermost call, the accumulator S (2nd arg) "copied" to final result (3rd arg)
count([H| T], S, N):- var(H), !, S1 is S+1, count(T, S1, N). % increase accumulator if H is var
count([H| T], S, N):- count(T, S, N).    % keep accumulator if H is not var

Никакие вызовы не следуют за последними рекурсивными вызовами во всех пунктах.

2 голосов
/ 12 июля 2011

Примечание: этот ответ представляет решение, которое является рекурсивным, но не хвостовой рекурсией .Для хвостового рекурсивного решения вы должны использовать аккумулятор, как показано в других ответах на этот вопрос.

Как и в случае любой рекурсивной процедуры, вы должны добавить надлежащий базовый случай.В этом случае это должно быть предложение с пустым списком, которое возвращает унифицированное 0 с количеством необработанных переменных:

count([], 0).

Проверьте написанное вами предложение.Он принимает в качестве входных данных список из двух элементов вместо списка, представленного в виде элемента Head и хвостового списка, и он действительно ничего не делает с N:

count([Head|Tail], M):- 
    var(Head), 
    !, 
    count(Tail, N), 
    M is N+1.

И, наконец, вам также следует добавить предложениеразберитесь со случаем, когда первый элемент списка не является неопознанной переменной:

count([_|Tail], N):- count(Tail, N).
0 голосов
/ 13 июля 2011

Здесь нет рекурсии, потому что для того, чтобы иметь рекурсию, вы должны определить что-то в терминах себя - вы заметите отсутствие правила count/2 в правой части кода.

% two paths, variable and non-variable
% and a base case to start the count
count([S|L], N) :- var(S), !, count(L, N0),  N is N0+1.
count([S|L], N) :- nonvar(S), !, count(L, N).
count([], 0).

Кроме того, это можно сделать просто с помощью findall/3.

count_alt(L, N) :- findall(S, (member(S, L), var(S)), D), length(D, N).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...