Вывод рекурсивного предиката - PullRequest
0 голосов
/ 28 февраля 2019

Цель следующего предиката - выбрать первые N элементов списка.Это должно быть присвоено выходной переменной, однако это не тот случай.

firstx(N, [H|T], L) :-
    (
        length(L, Le), Le < N ->
        append(L, [H], O),
        firstx(N, T, O)
    ;
        write(L)
    ).

Это вывод вышеуказанного предиката

?- firstx(2, [1,2,3,4,5], X).
[1,2],
X = [].

Это то, что должно быть

?- firstx(2, [1,2,3,4,5], X).
[1,2],
X = [1,2].

Как показано, последняя переменная назначена неправильно.Есть ли у вас какие-либо предложения о том, как это должно быть запрограммировано?Заранее спасибо!

1 Ответ

0 голосов
/ 28 февраля 2019

Я немного озадачен кодом, который вы написали.Я не вижу базового случая для вашей рекурсии в firstx(N, T, O).N никогда не уменьшается, и хотя вы удаляете элементы из списка во второй позиции, у вас нет никакого случая, когда этот список пуст.Вы используете append/3, похоже, пытаетесь поместить элементы в конец списка результатов, но вы также создаете L.В конечном счете, я думаю, что ваша проблема , вероятно, связана с тем фактом, что вы передаете новую переменную для третьего аргумента рекурсивному вызову (который затем в конце концов выпишет ее), но вы не возвращаете O, вы возвращаетесь L.Я предполагаю, что это не сработает, если вы замените L на O, потому что переменная должна быть необработанной при запуске запроса, но вы создаете его в рекурсивном вызове.

Я не совсемуверен, что вы пытаетесь сделать с этим кодом.Я вижу два ясных способа реализовать это: рекурсивный предикат или использование append/3, и я вижу элементы обоих в вашем решении.Итак, позвольте мне поделиться с вами обоими подходами.

Рекурсивный метод будет выглядеть следующим образом:

firstx(0, _, []).
firstx(N1, [H|T], [H|R]) :- 
    succ(N0, N1), 
    firstx(N0, T, R).

В этом решении мы берем элементы один за другим изГлава списка в результате.Использование succ/2 - хорошая привычка, потому что в отличие от N0 is N1 - 1, оно будет работать в обоих направлениях.Это своего рода направление, в котором вы думаете, когда я вижу [H|T] в заголовке вашего предложения, но опять же я нахожу подозрительным, что вы не строите L подобным образом, и вы не уменьшаетеN в вашем рекурсивном вызове.

Метод append/3 будет выглядеть следующим образом:

firstx(N, L, FirstN) :- 
    length(FirstN, N),
    append(FirstN, _, L).

Это более элегантное решение из-за того, что вы можете составить списокпроизвольная длина переменных, используя length/2, а затем просто позвольте append/3 сделать все объединение за вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...