Да, вы были правы, когда хотели обобщить ваше определение.Вместо
clist([[],[]],0).
(ну, во-первых, это должно быть
clist( [] , 0).
Продолжение ...) и
clist([Xs,Ys], N):- len1(Xs,N1), len1(Ys,N2), N is N1+N2.
, который обрабатывает два списки в списке, измените его на
clist([Xs|YSs], N):- len1(Xs,N1), len1(YSs,N2), N is N1+N2.
для обработки любого количества списков в списке.Но теперь второй len1
является неправильно примененным .Он получает список списков, а не просто список, как раньше.Столкнувшись с необходимостью обработки списка списков (YSs
), чтобы иметь возможность обрабатывать список списков ([Xs|YSs]
), мы вернулись к тому, с чего начали.Не правда ли?
Не совсем.У нас уже есть предикат для обработки списка списков - это clist
, который мы определяем!Чего ждать?Мы уже определили это?Да, мы еще не закончили это записывать, но мы сделаем это;и когда мы закончим записывать это, мы определим .Рекурсия - это прыжок веры:
clist([Xs|YSs], N):- len1(Xs,N1), clist(YSs,N2), N is N1+N2.
Более того, этот второй список списков YSs
на короче , чем [Xs|YSs]
., что является ключом.
И если бы списки были произвольно глубоко вложенными, рекурсия была бы
clist([XSs|YSs], N):- clist(XSs,N1), clist(YSs,N2), N is N1+N2.
с соответствующим образом исправленнымбазовый (-ые) случай (-ы).
Рекурсия - это прыжок веры: предположим, что у нас уже есть решение, используйте его для обработки небольших случаев рассматриваемой проблемы, просто объедините результаты- вот оно! Решение , которое мы предположили, возникло, потому что мы использовали его, как если бы оно уже существовало.
recursion( Whole, Solution ) :-
problem( Whole, Shell, NestedCases),
maplist( recursion, NestedCases, SolvedParts),
problem( Solution, Shell, SolvedParts).
Русская матрешка проблем на всем путивниз, превратился в решения вплоть до самого глубокого уровня.Но дело в том, что мы полагаемся на рекурсию для обработки внутренней матрешки, однако многие уровни it могут быть вложены в нее.Мы только разбираем и собираем один - самый верхний.