如何定位目标过度扩张的原因?



SICStus Prolog 4.5.1的执行分析器给了我以下输出:

| ?- print_profile。  insn 尝试/重试被叫名称 ----------------------------------------------------------------  4965857/4965857 序言:wellformed_body_expand/11  201383839 4965857 4965857序:call_goal_expansion/6 *4860319/4860363 序言:选择/0  4860319/9720726 序言:in_hook_flag/2  4860319/9006266 序言:prolog_catch/3 ----------------------------------------------------------------  4965868/4965868 序言:wellformed_body_iso/11  178771039 19863439 4965868序:wellformed_body_expand/11  4965857/4965857 序言:call_goal_expansion/6  4965857/4965857 序言:goal_exp/8  4965857/4965857 序言:wf_source_module/2 ----------------------------------------------------------------  165399306     5469803     ... ----------------------------------------------------------------  3044459/3044459 序言:dcg_translate_dcg_safe/8  163441583 23688395 3044459 序言:dcg_translate_dcg_atom/6 ----------------------------------------------------------------  ...

相当令人费解!似乎所有工作的 3/4(表中的 #1 列(是由于目标扩展。

但是为什么?如何本地化导致所有这些目标扩展的代码?请帮忙!


编辑:新的分析结果

@PerMildner的回答和评论指出了解决问题的方法。使用magic_square__no_sym(4)(大小为 4x4 的魔方,角点之间有额外的约束以消除对称解(的新执行分析结果看起来更合理library(clpz)

| ?- print_profile。  insn 尝试/重试被叫名称 ----------------------------------------------------------------  1197973/2041757 CLPZ:fd_put/3 843784/2041757 CLPZ:fd_put/5  153514528 5339777 2041757 CLPZ:put_terminating_q/4  34012/8145271 CLPZ:domain_infimum/2  34012/8263457 CLPZ:domain_supremum/2 16/1224480 CLPZ:new_queue/1  51821/51821 CLPZ:queue_goal_q/2 620022/620022 CLPZ:trigger_props_q/5 ----------------------------------------------------------------  1197973/1224480 CLPZ:fd_put/3 16/1224480 CLPZ:put_terminating_q/4  26357/1224480 CLPZ:trigger_once/1  134/1224480 CLPZ:variables_same_queue/1  113876576 0 1224480 CLPZ:new_queue/1 ----------------------------------------------------------------  ...

在这种情况下,目标扩展变化对性能的影响非常令人印象深刻:2 倍

SICStus 在没有适用的目标扩展时试图变得聪明。在这种情况下,通常可以避免调用call_goal_expansion。但是,如果存在可见的目标扩展(例如,通过加载clpz(,并且该目标扩展的索引较差,则尝试完整的目标扩展处理。后者可能是因为clpz:goal_expansion/5的"默认"最后一条而发生的事情。

请注意,在这种情况下,无法通过添加削减来解决"不良索引"。在内部,SICStus 会研究goal_expansion/5谓词的索引数据结构,以确定其任何子句是否适用。一个 catch-all 子句(如链接子句(会使此测试失败,并且将调用完整、较慢的call_goal_expansion

最新更新