换句话说,应该是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 predicate_property / 2
7.2.2.1说明
如果是程序,
predicate_property(Prototype, Property)
在模块M
的调用上下文中是正确的 与参数Prototype
相关联的具有谓词属性Property
。...
7.2.2.2模板和模式
predicate_property(+prototype, ?predicate_property)
7.2.2.3错误
a)
Prototype
是变量
-instantiation_error
。...
c)
Prototype
既不是变量也不是可赎回的词 -type_error(callable, Prototype)
。...
7.2.2.4示例
Goals attempted in the context of the module bar. predicate_property(q(X), exported). succeeds, X is not instantiated.
...
答案 0 :(得分:2)
这是一个有趣的问题。首先我认为有两个
各种predicate_property/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元参数说明符
会工作得很好。第二种predicate_property/
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).
这里我们松开了可能的meta参数的连接
0,例如solve/1
,具有谓词属性。因为
functor/3
通常没有元谓词声明。也
通过functor/3
传输模块信息
predicate_property/2
是不可能的,因为functor/3
是不可知的
模块,它通常没有可以处理的实现
包含模块限定的参数。
现在有两个问题:
1)我们可以给出打字和/或我们应该给谓词打字吗?
例如functor/3
。
2)我们可以扩展functor/3
以便它可以传达模块
资格。
以下是我的想法:
1)需要更复杂的类型系统。一个会
允许重载多种类型的谓词。对于
示例functor/3
可以有两种类型:
:- meta_predicate functor(?,?,?).
:- meta_predicate functor(0,?,?).
仅重载多种类型的真正威力 在诸如(=)/ 2之类的谓词中闪耀。我们在这里:
:- meta_predicate =(?,?).
:- meta_predicate =(0,0).
因此允许更多类型推断,如果一方 (=)/ 2是我们可以推断出另一方的目标 也是一个目标。
但事情并非如此简单,它可能会产生 感觉还有一种类型演员形式,或其他一些形式 限制超载的机制。什么东西 引入一个元谓词不包括在内 指示。这将需要内部的进一步构造 条款和目标。
学习形式lambda Prolog或某些依赖类型 系统,可能是有利的。例如(=)/ 2可以 被视为由A类参数化,即:
:- meta_predicate =(A,A).
2)对于Jekejeke Prolog,我提供了另一种选择
functor / 3实现。谓词是sys_modfunc_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已经理解的
例如在listing/1
中。所以它可能有相同的meta参数
规范为listing/1
。哪个是最新的:在SWI-Prolog中。
所以我们会,然后predicate_property/2
会
在第一个论点中采取:
:- meta_predicate sys_modfunc_site(?,?).
:- meta_predicate sys_modfunc_site(0,:).
香草翻译,也可以处理模块
内容如下。不幸的是,需要进一步的谓词,
sys_indicator_colon/2
,它压缩一个合格的谓词
指标成为一个普通的谓词指标,因为我们的
predicate_property/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_modfunc_site/2
和sys_indicator_colon/2
也必须这样做
转移呼叫网站,以便predicate_property/2
制作
对不合格谓词的正确决定,即解决
尊重进口等的谓词名称。
最后一点点结果:
Jekejeke Prolog的呼叫站点转移是一个纯粹的运行时
事情,并不需要一些编译时操作,尤其是
在编译时没有临时添加模块限定符。结果是
保留了某些代数性质。例如假设
我们有以下条款:
?- [user].
foo:bar.
^D
然后以下事情正常,因为不仅sys_modfunc_site/2
是双向的,但sys_indicator_colon/2
:
?- 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/2
适用于不同的输入和
输出模式。但我猜SWI-Prolog的phaenomenom首先是一个
问题是裸骨变量以当前模块为前缀。和
由于false
不在user
,而在system
,因此不会显示false
。
在输出模式下,它不会显示分辨率相等的谓词。
查看SWI-Prolog:
?- 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
...
但即使SWI-Prolog predicate_property/
2谓词也会
允许bar骨骼变量,即输出目标,我们会看到更少
交换性在深远的语义上比在本地
语义。在深远的语义中M:G
意味着解释G
在模块M
内部,即尊重模块M
的导入,
这可能会使算子转移得相当可观。
影响深远的语义是user:false
意味着什么的原因
system:false
。另一方面,在本地语义中,M:G
意味着M:G
而不是其他任何东西,我们更经常地拥有代数属性。
在本地语义中user:false
绝不意味着system:false
。
再见