我有以下“事实”结构。
if( conds, score, idx).
然后我希望有成千上万的人。 'conds'是在处理事实时将被评估的条件。对于每一个真实的事实,我将得分和索引存储在列表中以供进一步处理。
一般的想法是findall/3
事实,然后审视它们......
findall([Cond, Q, Ix], clause(if(Cond, Q, Ix), true), Conds)
check(Conds, True_QIxLst) ...
我担心findall/3
会吞噬每一次运行的所有数千个事实,即使用太多内存。
我如何做findall
所做的事情,但是逐个处理条件。
我仍将处理所有条件,但我想使用更少的内存。
按照“垫子”的建议,这似乎有用了:
is_true(Q,Ix) :-
if(Cond, Q, Ix),
check(Cond).
run(QI) :-
findall([Q,Ix], is_true(Q,Ix), QI).
答案 0 :(得分:4)
编写高效的Prolog代码的关键是尽可能多地将工作委托给引擎。
您明确执行的所有操作(即在Prolog中)通常较慢,而不是核心引擎隐式完成同样的操作。如果情况并非如此,则意味着核心引擎有改进的机会。
在您的特定情况下,如果findall/3
会占用太多内存,请考虑您的用例是否需要findall/3
。
如何摆脱困境,并将其全部委托给Prolog的内置回溯?
true_q_ix(Q, Ix) :- if(Cond, Q, Ix), cond_is_true(Cond).
没有findall/3
,没有任何内容:只是简单的回溯,产生Q
和Ix
所有Cond
在您的解释中评估为真。
如有必要,您仍然可以将其包含在findall/3
中,并支付各种费用。