模块 – 什么样的元参数是predicate_property / 2的第一个参数?

换句话说,它应该是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 module M iff the procedure
associated with the
argument Prototype 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.

再见

点赞