Module 谓词\属性/2的第一个参数是什么样的元参数?

Module 谓词\属性/2的第一个参数是什么样的元参数?,module,prolog,iso-prolog,meta-predicate,Module,Prolog,Iso Prolog,Meta Predicate,换句话说,它应该是0还是:还是其他什么?Prolog系统SICStus、YAP和SWI都将其表示为:。这是否恰当?它不应该是一个0,意思是可以被call/1调用的术语吗 要检查系统类型,请执行以下操作: | ?- predicate_property(predicate_property(_,_),P). P = (meta_predicate predicate_property(:,?)) ? ; P = built_in ? ; P = jitted ? ; no 我应该补充一点,元参数

换句话说,它应该是
0
还是
还是其他什么?Prolog系统SICStus、YAP和SWI都将其表示为
。这是否恰当?它不应该是一个
0
,意思是可以被
call/1
调用的术语吗

要检查系统类型,请执行以下操作:

| ?- predicate_property(predicate_property(_,_),P).
P = (meta_predicate predicate_property(:,?)) ? ;
P = built_in ? ;
P = jitted ? ;
no
我应该补充一点,元参数——至少与这里使用的形式一样——不能保证我们从纯关系中期望的代数性质相同:

?- S=user:false, predicate_property(S,built_in).
S = user:false.

?- predicate_property(S,built_in), S=user:false.
false.
以下是ISO/IEC 13211-2的相关部分:

7.2.2谓词_属性/2 7.2.2.1说明
predicate\u属性(Prototype,property)
在过程中调用模块
M的
上下文中为true 与
参数
原型关联的
具有谓词属性
属性

7.2.2.2模板和模式
谓词属性(+prototype,?谓词属性)

7.2.2.3错误 a)
原型
是一个变量
-
实例化\u错误

c)
Prototype
既不是变量,也不是可调用的术语
-
类型\错误(可调用,原型)

7.2.2.4示例


这是一个有趣的问题。首先,我认为有两个
谓词\属性/2
谓词的种类。第一类 接受可调用的,旨在与 例如,普通解释器和内置程序,如
write/1
nl/0
等,即:

solve((A,B)) :- !, solve(A), solve(B).
solve(A) :- predicate_property(A, built_in), !, A.
solve(A) :- clause(A,B), solve(B).
对于第一类,我猜是0元参数说明符 那就行了。第二类
谓词\u属性/
2 谓词与谓词指示符一起工作。可调用 和谓词指示符都是已经定义的概念 在ISO核心标准中

谓词指示符的形式为F/N,其中F是原子 N是一个整数。事情变得有点复杂了 如果存在模块,尤其是因为操作员 (:)/2与(/)/2的优先级。如果谓词属性有效 使用谓词指示符,我们仍然可以编写 口译员:

solve((A,B)) :- !, solve(A), solve(B).
solve(A) :- functor(A,F,N), predicate_property(F/N, built_in), !, A.
solve(A) :- clause(A,B), solve(B).
在这里,我们失去了一个可能的元参数的连接 0,例如具有谓词属性的
solve/1
。因为
functor/3
通常没有元谓词声明。阿尔索 通过
functor/3
将模块信息传输到
谓词属性/2
是不可能的,因为
函子/3
对 模块,它通常没有可以处理的实现 包含模块限定的参数

现在有两个问题:
1) 我们可以给类型化和/或我们应该给谓词类型化吗 例如
函子/3

2) 我们是否可以扩展
函子/3
,以便它能够传递模块 资格

以下是我的想法:
1) 需要一个更精细的打字系统。一个 允许使用多种类型重载谓词。对于 示例
functor/3
可以有两种类型:

  :- meta_predicate functor(?,?,?).
  :- meta_predicate functor(0,?,?).
重载多个类型的真正功能只会 在诸如(=)/2之类的谓词中大放异彩。在这方面,我们将:

  :- meta_predicate =(?,?).
  :- meta_predicate =(0,0).
因此允许更多的类型推断,如果 (=)/2是一个进球,我们可以推断对方 这也是一个目标

但事情并不是那么简单,它可能会 还有一种类型cast的形式,或者其他形式 限制过载的机制。什么 仅仅引入一个元谓词并不能解决这个问题 指令。这需要进一步的内部构造 条款和目标

从lambda Prolog或某些依赖类型学习 系统,可能是有利的。例如(=)/2罐 被视为a型参数化,即:

 :- meta_predicate =(A,A).
2) 对于Jekejeke Prolog,我提供了一个替代方案 函子/3实现。谓词是sys\u modfunc\u site/2
。 它双向工作,就像
functor/3
,但返回 并接受谓词指示符作为一个整体。 以下是一些运行示例:

 ?- sys_modfunc_site(a:b(x,y), X).
 X = a:b/2
 ?- sys_modfunc_site(X, a:b/2).
 X = a:b(_A,_B)
谓词的结果可以称为广义 谓词指示符。这是SWI Prolog已经理解的 例如在
清单/1
中。所以它可以有相同的元参数 清单/1中的规范已被修改。哪个是当前的:在SWI Prolog中。 所以我们会有,然后
谓词_属性/2
会 以:为例,在其第一个参数中:

 :- meta_predicate sys_modfunc_site(?,?).
 :- meta_predicate sys_modfunc_site(0,:).
普通的解释器,也可以处理模块,然后 内容如下。不幸的是,还需要进一步的谓词,
sys\u indicator\u colon/2
,它压缩限定谓词 指示符转换为普通谓词指示符,因为
谓词\u属性/2
不理解广义谓词 基于效率原因的指标:

solve((A,B)) :- !, solve(A), solve(B).
solve(A) :- 
      sys_modfunc_site(A,I), 
      sys_indicator_colon(J,I), 
      predicate_property(J, built_in), !, A.
solve(A) :- clause(A,B), solve(B).
上面实现了冒号(:)/2的局部语义, 与意义相当深远的冒号相比 (:)/2如ISO模块标准中所述。远处 到达语义在所有文本上输入模块名称 一个问题的答案。本地语义只需要一个限定的 并将模块名应用于该文本

Jekejeke只使用进一步的 呼叫站点未更改的规定。所以在引擎盖下
sys\u modfunc\u site/2
sys\u indicator\u colon/2
也必须 转移调用站点,以便
谓词_属性/2
使 对非限定谓词的正确决策,即解析 谓词名称是根据导入等进行的

最后是一点结束语:
Jekejeke Prolog的调用站点转移是一个纯运行时 而且不需要一些编译时操作,尤其是 在编译时没有特别添加模块限定符。A.
solve((A,B)) :- !, solve(A), solve(B).
solve(A) :- 
      sys_modfunc_site(A,I), 
      sys_indicator_colon(J,I), 
      predicate_property(J, built_in), !, A.
solve(A) :- clause(A,B), solve(B).
 ?- [user].
 foo:bar.
 ^D
  ?- S = foo:bar/0, sys_indicator_colon(R,S), predicate_property(R,static).
  S = foo:bar/0,
  R = 'foo%bar'/0
  ?- predicate_property(R,static), sys_indicator_colon(R,S), S = foo:bar/0.
  R = 'foo%bar'/0,
  S = foo:bar/0
 ?- predicate_property(X, built_in), write(X), nl, fail; true.
 portray(_G2778)
 ignore(_G2778)
 ...
 ?- predicate_property(user:X, built_in), write(X), nl, fail; true.
 prolog_load_file(_G71,_G72)
 portray(_G71)
 ...
 ?- predicate_property(system:X, built_in), write(X), nl, fail; true.
 ...
 false
 ...