Я немного озадачен кодом, который вы написали.Я не вижу базового случая для вашей рекурсии в 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
сделать все объединение за вас.