2

我正在编写一个标记器,我想用它if_/3来保持我的代码中

代码看起来像下面左边的代码1,但我希望它看起来像右边的代码。

if_(Cond1_1, % ( Cond1_1
    然后1, % *=> 然后1
    if_(Cond2_1, % ; Cond2_1
        然后2, % *=> 然后2
        if_(Cond3_1, % ; Cond3_1
            然后3, % *=> 然后3
            if_(Cond4_1, % ; Cond4_1
                然后4, % *=> 然后4
                if_(Cond5_1, % ; Cond5_1
                    然后5, % *=> 然后5
                    否则5%;其他5
   ))))))。%)。

为了在 SWI-Prolog 中重写(*=>)/2toif_/3我想出了:

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

:- 多文件目标扩展/2。
目标扩展((Cond *=> Then ; Else), if_(Cond,Then,Else))。
目标扩展(Cond *=> Then,(调用(Cond,true),调用(Then)))。

完成了,”我想……

但是在阅读了SWI-Prolog 文档goal_expansion/2后,我开始怀疑:

只有在读取源文件时出现在子句主体中的目标才会使用这种机制进行扩展,并且仅当它们按字面意思出现在子句中时,或者作为使用 '0' 注释的已定义元谓词的参数时(参见 meta_predicate/ 1)。其他情况需要一个真正的谓词定义。

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


脚注 1:实际代码有更长的else ifs 链。

4

1 回答 1

2

您需要一个 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

于 2019-04-06T16:45:30.867 回答