什么样的meta参数是predicate_property / 2的第一个参数?

时间:2014-06-25 14:48:58

标签: 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

我应该补充说,元参数 - 至少在这里使用的形式 - 不能保证我们从纯关系中得到的相同代数属性:

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

...

1 个答案:

答案 0 :(得分:2)

这是一个有趣的问题。首先我认为有两个 各种predicate_property/2谓词。第一种 需要一个可赎回的,并打算顺利工作 例如,香草口译员和内置词汇等 write/1nl/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/2sys_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

再见