换句话说,它应该是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 Description
predicate_property(Prototype, Property)
is true in the
calling context of a moduleM
iff the procedure
associated with the
argumentPrototype
has predicate property
Property
.…
7.2.2.2 Template and modes
predicate_property(+prototype, ?predicate_property)
7.2.2.3 Errors
a)
Prototype
is a variable
—instantiation_error
.…
c)
Prototype
is neither a variable nor a callable term
—
type_error(callable, Prototype)
.…
7.2.2.4 Examples
06002
…
最佳答案 这是一个有趣的问题.首先我认为有两个
各种谓词_属性/ 2谓词.第一种
需要一个可赎回的,并打算顺利工作
例如,香草口译员和内置词汇等
写/ 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 meta参数说明符
会工作得很好.第二种是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已经理解的
例如在清单/ 1中.所以它可能有相同的meta参数
规格列表/ 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模块标准中所述.远
达到语义会在所有文字上输入模块名称
一个查询.本地语义只需要一个合格的语义
literal,只是将模块名称应用于该文字.
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不在用户中,但在系统中,它不会显示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的进口,
这可能会对仿函数产生相当大的影响.
远远的语义是用户:false意味着的原因
系统:假的.另一方面,在本地语义中,M:G
意思是M:G而不是别的,我们更经常地拥有代数属性.
在本地语义用户:false绝不意味着system:false.
再见