如何定位过度扩展目标的原因?
How can I localize the reasons for excessive goal expansion?
SICStus Prolog 4.5.1 的执行分析器给了我以下输出:
| ?- print_profile.
insns try/retry called name
----------------------------------------------------------------
4965857/4965857 prolog:wellformed_body_expand/11
201383839 4965857 4965857 prolog:call_goal_expansion/6
*4860319/4860363 prolog:choice/0
4860319/9720726 prolog:in_hook_flag/2
4860319/9006266 prolog:prolog_catch/3
----------------------------------------------------------------
4965868/4965868 prolog:wellformed_body_iso/11
178771039 19863439 4965868 prolog:wellformed_body_expand/11
4965857/4965857 prolog:call_goal_expansion/6
4965857/4965857 prolog:goal_exp/8
4965857/4965857 prolog:wf_source_module/2
----------------------------------------------------------------
165399306 5469803 ...
----------------------------------------------------------------
3044459/3044459 prolog:dcg_translate_dcg_safe/8
163441583 23688395 3044459 prolog:dcg_translate_dcg_atom/6
----------------------------------------------------------------
...
很费解!似乎所有工作的 3/4(table 中的第 1 列)是由于目标扩展。
但是为什么呢? 如何本地化导致所有这些目标扩展的代码?请帮忙!
编辑:新的分析结果
@PerMildner 的回答和评论指出了解决问题的方法。使用 library(clpz)
magic_square__no_sym(4)
的新执行分析结果(大小为 4x4 的魔方,角点之间有额外的约束以消除对称解决方案)看起来 很多 更合理:
| ?- print_profile.
insns try/retry called name
----------------------------------------------------------------
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
----------------------------------------------------------------
...
这种情况下目标扩展变化的性能影响非常可观:2X !
当没有可用的目标扩展时,SICStus 试图变得聪明。在这种情况下,通常可以避免调用 call_goal_expansion
。然而,如果有一个目标扩展可见(例如通过加载 clpz
)并且该目标扩展的索引很差,那么将尝试完整的目标扩展处理。后者可能是因为 clpz:goal_expansion/5
.
的 "defaulty" last clause 而发生的情况
请注意,在这种情况下,无法通过添加剪切来解决 "poor indexing"。在内部,SICStus 会查看 goal_expansion/5
谓词的索引数据结构,以确定其任何子句是否适用。包罗万象的子句,如链接的子句,会使此测试失败,并且将调用完整的、较慢的 call_goal_expansion
。
SICStus Prolog 4.5.1 的执行分析器给了我以下输出:
| ?- print_profile. insns try/retry called name ---------------------------------------------------------------- 4965857/4965857 prolog:wellformed_body_expand/11 201383839 4965857 4965857 prolog:call_goal_expansion/6 *4860319/4860363 prolog:choice/0 4860319/9720726 prolog:in_hook_flag/2 4860319/9006266 prolog:prolog_catch/3 ---------------------------------------------------------------- 4965868/4965868 prolog:wellformed_body_iso/11 178771039 19863439 4965868 prolog:wellformed_body_expand/11 4965857/4965857 prolog:call_goal_expansion/6 4965857/4965857 prolog:goal_exp/8 4965857/4965857 prolog:wf_source_module/2 ---------------------------------------------------------------- 165399306 5469803 ... ---------------------------------------------------------------- 3044459/3044459 prolog:dcg_translate_dcg_safe/8 163441583 23688395 3044459 prolog:dcg_translate_dcg_atom/6 ---------------------------------------------------------------- ...
很费解!似乎所有工作的 3/4(table 中的第 1 列)是由于目标扩展。
但是为什么呢? 如何本地化导致所有这些目标扩展的代码?请帮忙!
编辑:新的分析结果
@PerMildner 的回答和评论指出了解决问题的方法。使用 library(clpz)
magic_square__no_sym(4)
的新执行分析结果(大小为 4x4 的魔方,角点之间有额外的约束以消除对称解决方案)看起来 很多 更合理:
| ?- print_profile. insns try/retry called name ---------------------------------------------------------------- 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 ---------------------------------------------------------------- ...
这种情况下目标扩展变化的性能影响非常可观:2X !
当没有可用的目标扩展时,SICStus 试图变得聪明。在这种情况下,通常可以避免调用 call_goal_expansion
。然而,如果有一个目标扩展可见(例如通过加载 clpz
)并且该目标扩展的索引很差,那么将尝试完整的目标扩展处理。后者可能是因为 clpz:goal_expansion/5
.
请注意,在这种情况下,无法通过添加剪切来解决 "poor indexing"。在内部,SICStus 会查看 goal_expansion/5
谓词的索引数据结构,以确定其任何子句是否适用。包罗万象的子句,如链接的子句,会使此测试失败,并且将调用完整的、较慢的 call_goal_expansion
。