Prolog中的`if_ / 3`运算符的目标扩展

时间:2019-03-28 18:01:13

标签: prolog meta-predicate logical-purity

我正在编写令牌生成器,我想使用if_/3在代码中保留

代码看起来像左侧的以下代码 1 -但我希望它看起来像右侧的代码。

if_(Cond1_1,                       %     (   Cond1_1
    Then1,                         %     *=> Then1
    if_(Cond2_1,                   %     ;   Cond2_1
        Then2,                     %     *=> Then2
        if_(Cond3_1,               %     ;   Cond3_1
            Then3,                 %     *=> Then3
            if_(Cond4_1,           %     ;   Cond4_1
                Then4,             %     *=> Then4
                if_(Cond5_1,       %     ;   Cond5_1
                    Then5,         %     *=> Then5
                    Else5          %     ;   Else5
   )   )   )   )   ).              %     ).

要在SWI-Prolog中将(*=>)/2重写为if_/3,我想到了:

:- op(1050,xfy,*=>).

:- multifile goal_expansion/2.
goal_expansion((Cond *=> Then ; Else), if_(Cond,Then,Else)).
goal_expansion( Cond *=> Then        , (call(Cond,true), call(Then))).

完成”,我想...

但是在阅读SWI-Prolog documentation for goal_expansion/2之后,我感到怀疑:

  

只有读取目标文件时出现在子句主体中的目标才使用此机制扩展,并且仅当目标出现在子句中时,或作为使用'0'注释的已定义元谓词的参数时(参见meta_predicate / 1)。 其他情况需要一个真实的谓词定义。

这是我的实际问题:我也需要一个真正的谓词定义吗?


脚注1 :实际代码具有更长的else if s链。

1 个答案:

答案 0 :(得分:1)

您需要一个if_ / 3谓词定义,至少要赋值 它是一个元谓词声明,否则扩展将停止, 如果if_ / 3本身没有元谓词声明。

您可以尝试一下,我仅使用此扩展功能:

:- op(1050,xfy,*=>).
:- multifile goal_expansion/2.
goal_expansion((Cond *=> Then ; Else), if_(Cond,Then,Else)).

没有元谓词声明:

Welcome to SWI-Prolog (threaded, 64 bits, version 8.1.4)

?- expand_goal((a *=> b; c *=> d; e), X).
X = if_(a, b,  (c*=>d;e)).

带有元谓词声明:

Welcome to SWI-Prolog (threaded, 64 bits, version 8.1.4)

:- meta_predicate if_(1,0,0).
?- expand_goal((a *=> b; c *=> d; e), X).
X = if_(a, b, if_(c, d, e)).

这与SWI-Prolog和Jekejeke Prolog中的行为相同。您可以研究源代码以更好地理解为什么需要元谓词声明。

在此处查看示例:
https://github.com/jburse/jekejeke-devel/blob/master/jekrun/headless/jekpro/frequent/standard/expand.p#L220