Prolog 中 `if_/3` 运算符的目标扩展
Goal expansion for an `if_/3` operator in Prolog
我正在编写一个标记器,我想在我的代码中使用 if_/3
to preserve logical-purity。
左边的代码看起来像下面的代码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
之后我开始怀疑了:
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.
所以这是我的实际问题:我是否也需要一个真正的谓词定义?
脚注 1:实际代码有更长的 else if
链。
你需要一个 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 中的行为相同。您可以研究源代码以更好地理解为什么需要元谓词声明。
我正在编写一个标记器,我想在我的代码中使用 if_/3
to preserve logical-purity。
左边的代码看起来像下面的代码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
之后我开始怀疑了:
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.
所以这是我的实际问题:我是否也需要一个真正的谓词定义?
脚注 1:实际代码有更长的 else if
链。
你需要一个 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 中的行为相同。您可以研究源代码以更好地理解为什么需要元谓词声明。