高效的 findall() 处理?

Efficient findall() processing?

我有以下结构"facts"。

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 所做的事情,但要逐一处理这些条件。 我仍然会处理所有条件,但我想使用更少的内存。


根据 "mat" 建议,这似乎可行:

is_true(Q,Ix) :-
   if(Cond, Q, Ix),
   check(Cond).

run(QI) :-
   findall([Q,Ix], is_true(Q,Ix), QI).

编写高效 Prolog 代码的关键是将尽可能多的工作委托给 引擎

您显式执行的所有操作(即在 Prolog 中)通常比核心引擎隐式更慢 ].如果不是这种情况,则意味着核心引擎有改进的机会。

在您的特定情况下,如果 findall/3 会占用太多内存,请考虑 findall/3 对于您的用例是否必要。

让开,将其全部委托给 Prolog 的内置回溯怎么样?

true_q_ix(Q, Ix) :-
    if(Cond, Q, Ix),
    cond_is_true(Cond).

没有 findall/3,什么都没有:只是简单的回溯,产生所有 QIx 在您的解释中 Cond 的计算结果为真。

Don't do anything! Nothing!

如有必要,您仍然可以将其包装在 findall/3 中,支付其各种费用。