Я сталкиваюсь с этим все время, и я никогда не уверен, каким образом атаковать его. Ниже приведены два метода обработки некоторых фактов сезона.
Я пытаюсь решить, использовать ли метод 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').