私はいつもこれに立ち向かいますが、どの方法で攻撃すればよいかわかりません。以下は、いくつかのシーズン ファクトを処理するための 2 つの方法です。
私が解決しようとしているのは、方法 1 または 2 のどちらを使用するか、およびそれぞれの長所と短所、特に大量の事実です。
methodone
事実が利用可能であるため、わざわざそれらのリスト (特に大きなリスト) を作成するのは無駄に思えます。リストが十分に大きい場合、これにはメモリへの影響もあるはずです。また、Prolog の自然なバックトラッキング機能を利用していません。
methodtwo
私のために再帰を行うためにバックトラックを利用しています。メモリ効率がはるかに高いと思いますが、一般的にこれを行うのは良いプログラミング方法ですか? 従うのは間違いなく醜いです、そして他の副作用があるかもしれませんか?
私が見ることができる1つの問題は、呼び出されるたびfail
に、呼び出し元の述語に何かを返す能力を失うことです。だった場合methodtwo(SeasonResults)
、意図的に述語を継続的に失敗させるためです。そのmethodtwo
ため、状態を保存するにはファクトをアサートする必要があります。
おそらく(?)メソッド2は、(大きな)リスト処理を行う必要がないため、高速になりますか?
リストがあれば、それが進むべき道だと想像できmethodone
ます..またはそれは常に真実ですか?methodone
を使用してリストをファクトにアサートし、メソッド 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').