在扩展过程中,fixpoint 既是一个集合,又是一个特定级别的管道。它的 expand_term/2 只是一步 term_expansion/2 子句的传递闭包。但这仅在下降到一个术语时才有效,在我看来,我们在再次组装该术语时也需要一些东西。
在极少数情况下,这种传递闭包甚至需要像某些 Prolog 系统中那样进行 (==)/2 检查。如果 term_expansions/2 没有做任何事情,它很可能会简单地停止。所以我们基本上没有 (==)/2 检查:
expand_term(X, Y) :- term_expansion(X, H), !, expand_term(H, Y).
expand_term(.. ..) :- /* possibly decend into meta predicate */
但我更希望看到的是在扩展框架中添加了一种简化框架。所以当我们下降到一个元谓词并返回时,我们应该调用一个简化钩子。
它符合一些术语重写理论,即:复合词的范式 (nf) 是其部分范式的函数。因此,扩展框架不会处理范式,只提供谓词的重新定义,但简化框架会做范式工作:
nf(f(t_1,..,t_n)) --> f'(nf(t_1),..nf(t_n))
因此,简化钩子将采用f(nf(t_1), .., nf(t_n))
,假设 expand_term 在下降到元谓词时已经为元参数产生了nf(t_1)
.. nf(t_n)
,然后简单地给f(nf(t_1), .., nf(t_n))
简化器。
然后,简化器将返回f'(nf(t_1), .., nf(t_n))
,即根据参数已经简化的假设,完成其工作并返回简化形式。这样的简化器可能非常强大。Jekejeke Prolog 提供诸如扩展后的阶段。
Jekejeke Prolog 简化器及其与扩展框架的集成在此处和此处是开源的。例如,它用于重新排序连词,以下是用于此目的的示例规则:
/* Predefined Simplifications */
sys_goal_simplification(( ( A, B), C), J) :-
sys_simplify_goal(( B, C), H),
sys_simplify_goal(( A, H), J).
Example:
(((a, b), c), d) --> (a, (b, (c, d)))
Jekejeke Prolog 简化器非常有效,因为它可以在假设它接收到已经规范化的项的情况下工作。它不会在整个给定术语上不必要地重复进行模式匹配。
但是编写简化规则需要一些重写系统的惯例。简化规则在构造一个新术语时应该调用简化。
在上面的示例中,这是两个sys_simplify_goal/2
调用,例如,我们不会(B,C)
像扩展规则那样简单地返回一个包含其中的新术语。由于(B,C)
不是 的规范化参数的一部分sys_goal_simplification/2
,我们必须首先对其进行规范化。
但是由于简化器框架与扩展框架交织在一起,我怀疑它是否可以称为工作流架构。没有特定的流动方向,结果是乒乓球。然而,简化框架可以以模块化方式使用。
Jekejeke Prolog 简化器也用于前向链接子句重写。它确实从一个前向子句生成多个增量计算子句。
再见