在DDlog中定义数据表及函数

1.0在DDlog中定义数据流:

DDlog是用简洁,类似于Datalog的语法编写DeepDive应用程序的高级语言。这里我们重点介绍在DeepDive应用程序中定义数据流的一般语言特性。

DDlog程序是声明和规则的集合。每个声明和规则都以句点(.)结尾。DDlog中的注释以hash(#)字符开头。规则的顺序没有意义。DDlog程序由以下部分组成:

  1. 模式关系的声明
  2. 正常推导规则
    1. 关系派生(头部原子)
    2. 使用的关系(身体原子)
    3. 条件
  3. 用户定义的函数(UDFS)
    1. 函数声明
    2. 函数调用规则
  4. 推理规则

所有的DDlog代码都应该放在app.ddlog 即DeepDive应用程序下的一个文件中。

1.1模式声明:

首先,应声明在整个计划中定义和使用的关系模式。这些关系映射到为DeepDive应用程序配置的数据库中的表。管理数据库文档介绍了DeepDive提供的各种与之交互的方式。声明的顺序并不重要,但是将它们放置在开头是一个好主意,因为这样可以更容易地理解引用关系的其他规则。

relation_name(
  column1_name  column1_type,
  column2_name  column2_type,
  ...
).

与SQL表定义类似,模式声明只是一个关系的名称,后跟逗号分隔的列名及其类型列表。目前,DDlog直接将类型映射到SQL,因此可以使用底层数据库支持的任何类型,例如PostgreSQL的类型

下面是一个关于文章数据库表的例子。

article(
  id     int,
  length int,
  author text,
  words  text[]
).

这里我们定义一个名为“文章”的关系,分别命名为“id”,“length”,“author”和“words”。每列都有它自己的类型,在这里使用inttexttext[]

1.2 正常推导规则:

典型的类似于数据记录的规则用于定义如何从其他关系派生关系。例如,下面的规则指出关系的元组Q是从关系RS中获取的。

Q(x, y) :- R(x, y), S(y).

Q(x,y)是头原子,R(x,y)和S(y)是体原子。 x和y是规则中的变量。 头是被定义的关系,而主体是用逗号(,)分隔的用于定义的变量的谓词或条件的联合。 在这个例子中,R的第二列与S的第一列统一,即,主体是关系R和S之间的等连接。

例如:

nlp_markup(doc_id, content) :-articles(doc_id, content),read(content).

1.3表达式:

在原子列中,可以使用变量和表达式。DDlog的语义是基于变量和表达式的统一,即同名的变量统一列,主体中的表达式将统一的值与相应的列进行统一。更具体地说,头部原子中的表达式决定头部关系列的值,而体内原子中的表达式约束身体列的值。

例子

表达式的几个例子如下所示。

a(k int).
b(k int, p text, q text, r int).
c(s text, n int, t text).

Q("test", f(123), id) :- a(id), b(id, x,y,z), c(x || y,10,"foo").

R(TRUE, power(abs(x-z), 2)) :- a(x), b(y, _, _, _).

S(if l > 10 then TRUE
else if l < 10 then FALSE
else NULL end) :- R ( _, l).

这里的字符串文字“text”,应用于123的函数f,以及由规则体约束的id的元组被添加到关系Q.然后,我们在关系R中添加a和b中的变量的布尔TRUE和运算。 最后,我们可以根据R中的第二个变量用条件值填充关系S.我们观察到在ddlog中可以实现复杂的查询。 下面的段落详细解释了ddlog中不同的可能操作。

1.4 常量文字:

数字,文本字符串,布尔值,空值表示如下:

  • 数字文字,例如:123-456.78

  • 字符串文字用双引号(")括起来,例如:"Hello, World!"

    前面的反斜杠(\)用作包括双引号本身以及反斜杠的转义序列:

    "For example, \"There're backslashes (\\) before the surrounding double quotes.\""

    下面的文字是如何写成字符串的:

    For example, "There're backslashes (\) before the surrounding double quotes."
  • 布尔文字:TRUEFALSE

  • 空文字:NULL

1.5 操作符:

op是二元运算符,并且uop是下列元素中的一元运算符:expr op expr uop expr

二进制运算符

  • 数值运算+-*/
  • 字符串连接 ||

一元运营商

  • 负号 -
  • 否定布尔值 !

表达式可以任意嵌套,圆括号可以包围它们以使操作员关联清晰。(expr)

比较

  • 平等 =
  • 分别 !=
  • 不平等<<=>>=
  • *expr* IS NULL*expr* IS NOT NULL
  • 字符串模式 *exprText* LIKE *exprPattern*

有条件的值

可以使用语法表达由条件案例确定的值。例如,当变量为正数时,以下表达式的值为1 ,否则为-1 。

if x > 0 then 1
else if x < 0 then -1
else NULL
end

1.6 功能的应用:

更复杂的数值可表示为施加预定义的函数,以使用以下语法表达式的元组:。目前,DDlog直接将函数名称映射到SQL,因此可以使用底层数据库定义的任何函数,例如PostgreSQL的函数。例如,下面用函数和函数的绝对值来平均值。*name*(*expr*, *expr*, ...)**abs``power

power(abs(x - y), 2)

类型转换

当一个值需要被转换成一个不同的类型时,例如,把整数转换成一个浮点,反之亦然,那么类型转换语法可以遵循这个表达式,即。例如,下面的代码将分母中的变量转换为一个浮点数,所以可以正确计算比率:*expr* :: *type*

num_occurs / total :: FLOAT

占位符

一个占位符_可以用在body原子的列中,表示没有变量与该列相关。如果派生需要只有一个列的子集,这是很有用的。例如,以下规则只使用两列R进行定义Q,而其余列不绑定到任何变量:

Q(x, y, x + y) :- R(x, _, _, y, _, _, _).

条件

条件放在与原子体相同的水平上,并与体原子共同限定了头部使用的变量。连接条件由逗号(,)分隔,而分离条件由分号(;)分隔。感叹号(!)可以先于否定它的条件。条件可以任意嵌套在方括号()内。例如,下面的规则将第一列关系中满足一定条件的变量的值与第四列进行比较。[*cond*, *cond*, ...; *cond*; ...]``x``b``b

Q(x) :- b(x,_,_,w), [x + w = 100; [!x > 50, w < 10]].

析取

析取的情况可以表示为定义相同头的多个规则,或者作为具有由分号(;)分隔的多个体的一个规则。以下面两条规则为例。

Q(x, y) :- R(x, y), S(y).
Q(x, y) :- T(x, y).

他们可以写成一个单一的规则:

Q(x, y) :- R(x, y), S(y); T(x, y).

聚合

对于满足body的每个变量组合,我们不用为每个变量组合导出一个头元组,而是通过对某些列取总值来将一组元组简化为一个元组。通过用集合函数围绕头部的一些列,从由不在聚合下的其他列的值确定的每个列值计算聚合。DDlog识别下列集合函数:

  • SUM
  • MAX
  • MIN
  • ARRAY_AGG
  • COUNT

例如,以下规则R将第一列和第二列的第三列的所有值分组,然后取最大值来派生元组Q

Q(a,b,MAX(c)) :- R(a,b,c).

Select distinct

为了仅从其他关系中选择不同的元素,*:-可以使用操作员。例如,我们考虑以下规则:

Q(x,y) *:- R(x, y).

在这个规则中,只有(x,y)这个关系变量的两个变量R才会被插入到头部Q

量词

Existential/Universal

另一种派生头数量减少的方法是使用量化的身体。可以将体原子和条件置于量词之下,用以下语法表示对某些变量的existential(EXISTS)或universal(ALL)约束:

body, ..., EXISTS[body, body, ...], body, ...
body, ...,    ALL[body, body, ...], body, ...

对于量化内部和外部使用的变量,量词内部的关系表示对已经被量词之外的一些关系约束的变量的约束。 EXISTS表示对这些变量的约束必须存在满足量化主体的值的组合,而ALL对于变量的每个值的组合,都必须满足对量化主体内的其他变量的所有可能的约束。这使得使用关系中的派生值来表达复杂的条件成为可能。以下是使用量词的两个示例规则:

P(a) :- R(a, _), EXISTS[S(a, _)].
Q(a) :- R(a, b),    ALL[S(a, c), c > b].

第一条规则意味着P包含在关系的第一列中R至少出现一次的关系的所有第一列S。第二条规则意味着Q包含所有关系的第一列,R如果第一列上S具有相同值的关系的元组总是有第二列大于第二列的值R

可选的

OPTIONAL当特定的原子体是可选的时,可以使用量词。这意味着即使不存在某些身体关系中的元组,也应该派生出一个元首关系的元组。只有在可选体中出现的变量NULL不能被满足时才会被绑定。这个量词大致对应于SQL中的外连接

以下是使用可选量词的示例规则:

Q(a, c) :- R(a, b), OPTIONAL[S(a, c), c > b].

它意味着Q包含第一列关系的第一列R与第二列关系S元组的所有值成对的每一个值,这些关系元组在第一列上具有相同的值,并且第二列大于第二列R,或者NULL如果不存在这样的值。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章