Prolog 中`if_/3` 运算符的目标扩展 [英] Goal expansion for an `if_/3` operator in Prolog
问题描述
我正在编写一个标记器,我想使用 if_/3
来保留logical-purity 在我的代码中.
左边的代码看起来像下面的代码1—但我希望它看起来像右边的.
<预>if_(Cond1_1, % ( Cond1_1然后1, % *=> 然后1if_(Cond2_1, % ; Cond2_1然后2, % *=> 然后2if_(Cond3_1, % ; Cond3_1然后3, % *=> 然后3if_(Cond4_1, % ; Cond4_1然后4, % *=> 然后4if_(Cond5_1, % ; Cond5_1然后 5, % *=> 然后 5其他 5 % ;其他5) ) ) ) ) .%).为了在 SWI-Prolog 中将 (*=>)/2
重写为 if_/3
,我想出了:
完成,"我想……
但是在阅读了 SWI-Prolog 文档后,我开始怀疑 SWI-Prolog 文档代码>goal_expansion/2:
<块引用>只有在读取源文件时出现在子句主体中的目标才会使用此机制进行扩展,并且仅当它们字面出现在子句中,或者作为使用0"注释的已定义元谓词的参数时(见元谓词/1).其他情况需要真正的谓词定义.
所以这是我的实际问题:我也需要一个真正的谓词定义吗?
<小时>脚注 1:实际代码有更长的 else if
链.
你需要一个 if_/3 谓词定义,至少要赋值它是元谓词声明,否则扩展将停止,如果 if_/3 本身没有元谓词声明.
你可以自己试试,我只用这个扩展:
:- op(1050,xfy,*=>).:- 多文件目标_扩展/2.goal_expansion((Cond *=> Then ; Else), if_(Cond,Then,Else)).
没有元谓词声明:
欢迎使用 SWI-Prolog (threaded, 64 bits, version 8.1.4)?- expand_goal((a *=> b; c *=> d; e), X).X = if_(a, b, (c*=>d;e)).
使用元谓词声明:
欢迎使用 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 中的行为相同.您可以研究源代码以更好地理解为什么需要元谓词声明.
I'm writing a tokeniser and I want to use if_/3
to preserve logical-purity in my code.
The code looks like the following code1 on the left—but I want it to look like the one on the right.
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 ) ) ) ) ). % ).
To do the rewriting of (*=>)/2
to if_/3
in SWI-Prolog I came up with:
:- 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))).
"Done," I thought...
But I became doubtful after reading the SWI-Prolog documentation for goal_expansion/2
:
Only goals appearing in the body of clauses when reading a source file are expanded using this mechanism, and only if they appear literally in the clause, or as an argument to a defined meta-predicate that is annotated using `0' (see meta_predicate/1). Other cases need a real predicate definition.
So here's my actual question: Do I need a real predicate definition, too?
Footnote 1: The actual code has an even longer chain of else if
s.
You need a if_/3 predicate definition, to at least assign it a meta predicate declaration, otherwise expansion will stop, if there is no meta predicate declaration for if_/3 itself.
You can try yourself, I am using only this expansion:
:- op(1050,xfy,*=>).
:- multifile goal_expansion/2.
goal_expansion((Cond *=> Then ; Else), if_(Cond,Then,Else)).
Without meta predicate declaration:
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)).
With meta predicate declaration:
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)).
This is same behaviour in SWI-Prolog and Jekejeke Prolog. You could study the source code to better understand why the meta predicate declaration is needed.
See for example here:
https://github.com/jburse/jekejeke-devel/blob/master/jekrun/headless/jekpro/frequent/standard/expand.p#L220
这篇关于Prolog 中`if_/3` 运算符的目标扩展的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!