我一直反对这一点,我无法确定攻击它的方法.以下是处理一些季节事实的两种方法.
我想弄清楚的是,是否使用方法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), …
Run Code Online (Sandbox Code Playgroud)