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
...