【发布时间】:2012-04-02 10:21:17
【问题描述】:
我总是遇到这种情况,但我永远不知道用什么方法来解决它。以下是处理某些季节事实的两种方法。
我正在努力解决的是使用方法1还是2,以及每种方法的优缺点,尤其是大量的事实。
methodone 似乎很浪费,因为事实是可用的,为什么还要建立一个列表(尤其是一个大列表)。如果列表足够大,这也一定会影响内存?而且它没有利用 Prolog 的自然回溯功能。
methodtwo 利用回溯为我进行递归,我想这会更节省内存,但通常这样做是一种好的编程习惯吗?它可以说是更丑陋,并且可能有任何其他副作用?
我可以看到的一个问题是,每次调用 fail 时,我们都无法将任何内容传递回调用谓词,例如。如果是methodtwo(SeasonResults),因为我们不断地故意使谓词失败。所以methodtwo 需要断言事实来存储状态。
大概(?)方法2会更快,因为它没有(大)列表处理要做?
我可以想象,如果我有一个列表,那么methodone 将是正确的选择.. 还是总是这样?在任何情况下使用methodone 将列表声明为事实然后使用方法二处理它们是否有意义?完全疯了吗?
但话又说回来,我读到断言事实是一项非常“昂贵”的业务,所以列表处理可能是要走的路,即使对于大型列表也是如此?
有什么想法吗?或者有时根据(什么)情况使用一个而不是另一个更好?例如。对于内存优化,使用方法 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').
【问题讨论】:
标签: prolog prolog-dif prolog-toplevel