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
。