高效的findall()处理?

时间:2018-02-04 21:07:58

标签: prolog clause prolog-findall

我有以下“事实”结构。

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).

1 个答案:

答案 0 :(得分:4)

编写高效的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中,并支付各种费用。