Me topa con esto todo el tiempo, y nunca estoy seguro de qué manera atacarlo. A continuación hay dos métodos para procesar algunos datos de la temporada.¿Cuáles son los pros y los contras de usar la iteración manual de la lista frente a la recursión a través del error
Lo que estoy tratando de determinar es si usar el método 1 o 2, y cuáles son los pros y los contras de cada uno, especialmente grandes cantidades de información.
methodone
parece un desperdicio ya que los hechos están disponibles, ¿por qué molestarse en construir una lista de ellos (especialmente una gran lista). Esto también debe tener implicaciones de memoria si la lista es lo suficientemente grande. Y no aprovecha la función de rastreo natural de Prolog.
methodtwo
aprovecha el retroceso para hacer la recursión para mí, y supongo que sería mucho más eficiente en cuanto a la memoria, pero ¿es una buena práctica de programación en general hacer esto? Podría decirse que es más feo seguirlo, y ¿podría haber otros efectos secundarios?
Un problema que puedo ver es que cada vez que se llama fail
, perdemos la capacidad de devolver algo al predicado de llamada, por ejemplo. si fue methodtwo(SeasonResults)
, ya que fallamos continuamente el predicado a propósito. Entonces methodtwo
necesitaría afirmar hechos para almacenar el estado.
Probablemente (?) El método 2 sería más rápido ya que no tiene (grandes) listas de procesamiento que hacer?
Me imagino que si tuviera una lista, entonces methodone
sería el camino a seguir ... ¿o siempre es así? ¿Podría tener sentido en cualquier condición afirmar la lista de hechos usando methodone
y luego procesarlos usando el método dos? Completa locura?
Pero, de nuevo, he leído que afirmar los hechos es un negocio muy "caro", por lo que el manejo de la lista podría ser el camino a seguir, incluso para listas grandes?
¿Alguna idea? ¿O a veces es mejor usar uno y no el otro, dependiendo de (qué) situación? p.ej. para la optimización de la memoria, use el método 2, incluidos los hechos de afirmación y, para el método de uso de velocidad 1? Método
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').
gracias - no sabía sobre el forall() - ese se me escapó. Bonito, eso es útil para mí en este momento. – magus
@larsmans: Pero forall/2 esencialmente es un bucle impulsado por fallas. ¡No hay forma de retener las ataduras de Forall! Eso es 'forall (A, B)' ≡ '\ + \ + forall (A, B)' – false
@false: sí, pero con la diferencia de que un FDL siempre falla, mientras que 'forall' podría tener éxito. Para implementar un ciclo, es suficiente. –