Каковы плюсы и минусы использования ручной итерации по списку по сравнению с рекурсией через отказ

Я сталкиваюсь с этим все время, и я никогда не уверен, каким образом атаковать его. Ниже приведены два метода обработки некоторых фактов сезона.

Я пытаюсь решить, использовать ли метод 1 или 2, и каковы плюсы и минусы каждого, особенно большого количества фактов.

Первый методкажется расточительным, поскольку факты доступны, зачем создавать их список (особенно большой список). Это также должно иметь последствия для памяти, если список достаточно велик? И он не использует естественную возможность возврата в Прологе.

methodtwoиспользует преимущества обратного отслеживания, чтобы выполнить рекурсию для меня, и я предполагаю, что это будет гораздо более эффективно использовать память, но является ли это хорошей практикой программирования в целом? Возможно, следовать этому уродливее, и могут ли быть какие-либо другие побочные эффекты?

Одна проблема, которую я вижу, заключается в том, что каждый раз, когда вызывается fail, мы теряем возможность передать что-либо обратно вызывающему предикату, например. если бы это было methodtwo(SeasonResults), поскольку мы намеренно постоянно теряем предикат. Таким образом, methodtwoдолжен будет утверждать факты для сохранения состояния.

Предположительно (?) метод 2 будет быстрее, поскольку он не требует обработки (больших) списков?

Я мог представить, что если бы у меня был список, то методонбыл бы подходящим способом… или это всегда так? Имеет ли смысл в каких-либо условиях утверждать список фактов, используя метод один, а затем обрабатывать их, используя второй метод? Полное безумие?

Но опять же, я читал, что утверждение фактов — очень «дорогое» дело, так что обработка списков может быть подходящим способом, даже для больших списков?

Есть мысли? Или иногда лучше использовать один, а не другой, в зависимости от (какой) ситуации? например. для оптимизации памяти используйте метод 2, включая утверждение фактов, а для скорости используйте метод 1?

season(spring).
season(summer).
season(autumn).
season(winter).

 % Season handling
showseason(Season) :-
    atom_length(Season, LenSeason),
    write('Season Length is '), write(LenSeason), nl.

% -------------------------------------------------------------
% Method 1 - Findall facts/iterate through the list and process each
%--------------------------------------------------------------
% Iterate manually through a season list
lenseason([]).
lenseason([Season|MoreSeasons]) :-
    showseason(Season),
    lenseason(MoreSeasons).


% Findall to build a list then iterate until all done
methodone :-
    findall(Season, season(Season), AllSeasons),
    lenseason(AllSeasons),
    write('Done').

% -------------------------------------------------------------
% Method 2 - Use fail to force recursion
%--------------------------------------------------------------
methodtwo :-
    % Get one season and show it
    season(Season),
    showseason(Season),

    % Force prolog to backtrack to find another season
    fail.

% No more seasons, we have finished
methodtwo :-
    write('Done').
8
задан Charles 10 March 2014 в 03:33
поделиться