DDlog语言特征

原文地址:这里写链接内容

DDlog是一种语法为datalog式,用来编写DeepDive应用的语言。一个ddlog程序会被编译成deepdive格式下的配置文件,我们通常用这个文件来运行我们的应用。

一个ddlog程序由一组声明组成,这些声明由dots分割,而状态的顺序是无关紧要的。一个声明可以是一个模式声明,一个datalog函数声明,一个函数调用规则,一个监管规则,或者一条推理规则。

1. Schema Declaration 模式声明

每个模式声明(schema declaration)在一个关系(relation)中声明了关系的每一列的类型以及列的顺序。其语法类似于SQL里的schema:

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

relation_name 是数据库中一个指明关系的名字的标识符。类似的, column_names 和 column_types 是数据库中与列名称和列类型相匹配的字符串。ddlog使用与SQL相同的类型集合。

​例如:

sentences(
  doc_id  text,
  sent_id int,
  text    text,
  words   text[]).

​它定义了一个包含了4列的关系articles:doc_id, sent_id, text, 和 words, 他们的类型分别是text, int, text, text[],其中text[] 代表了 text数组.

​一个在关系名后的问号指出了这是一个包含了随机变量(random variable)的变量关系(variable relation),这些随机变量被包含在因子图(factor graph)中。例如,

has_spouse?(relation_id text).

​定义了一个变量关系has_spouse,并且每个不同的 relation_id 代表了一个不同的变量。

2. Normal datalog Rules 规则

​典型的datalog规则可以被用来定义一个关系是如何被其他关系驱动的。一个规则的head被定义的规则,body则是一个合取查询体的合取式(conjunction),由逗号进行分割。析取的情况则被多个由分号分割body表达。

​例如,下列程序表示了 元组Q是由R和S派生的,其中R的第二列和S的第一列是统一的,也就是说,这个body是一个等值连接。

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

​在这里,Q(x, y) 是头部head, 而 R(x, y)S(y) 是body原子. xy 是规则的变量。

Expressions 表达式

​表达式可以在原子column中被使用。head atom中的表达式会被输出到头部关系。而在body atom中的表达式则会成为一个条件。注意datalog的语义是基于变量和表达式的统一:有相同名字的变量是统一的,body atom中则是根据相应的column统一的。下面是一个便于理解的例子:

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").

​这里的输出是一个字符串“text”逐字形成的元组,一个函数f在根据输入的参数123完成操作,而id则由body产生,在body中,条件被编译为:

a.k = b.k -- unifying variable id in a(id) and b(id, ...)
AND c.n = 10  -- unifying literal 10 with the column in c(...,10,...)
AND c.t = 'foo' -- unifying literal "foo" with the column in c(...,"foo")
AND b.p || b.q = c.s  -- unifying expression x||y with the column in c(x||y,...)

​值得一提的是,表达式可以被随意嵌套。

Conditions 条件

​条件(conditions)出现在在body atoms的同一层,和body atoms一起定义了对head的输出。合取(conjunction)条件由逗号分隔,析取(Disjunction)条件则由分号分隔。条件可以通过放置内部方括号(”[]”)来任意嵌套。例如,

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

​这个条件是 (x + w = 100) OR ((NOT x > 50) AND w < 10)

Placeholder占位符

​占位符”_”可以用在body atoms的各个列中,表明输出和这个列是不相关的。

3. Aggregation 聚合

​在head atom columns中使用聚合函数表示在其他列上做了一个group by的分组操作,以及一个聚合操作。现在DDlog支持的函数有 SUM, MAX, MIN, ARRAY_AGG, COUNT. 例如,

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

​会根据R的第一列和第二列进行分组,然后在第三列上选择最大值。

4. Supervision Rule 监督规则

​监督规则被用来考量和监督随机变量,也就是定义变量集合和训练数据。它的语法和normal datalog rule是一样的,但是多了一个注解 @label(column_variable)。例如,

@label(is_true)
has_spouse(rid) :- has_spouse_candidates(_, _, _, _, rid, is_true).

​这个规则使用has_spouse_candidates里的 is_true这一列来监督has_spouse里的随机变量。

5. Inference Rule 推理规则

​推理规则是用来表达如何推理随机规则的。一个推理规则的head式定义了因子图里的一个因子。head里的的atom必须是变量关系。权重绑定(weight tying)表示在规则前,使用了@weight(expression)的语法,其中expression可以是任意的表达式。例如,

@weight(3)
smoke(x) => cancer(x) :- person(x).
@weight(feature)
smoke(x)  =  smoke(y) :- friend(x, y, feature).

​第一个规则表示了一个人抽烟影响了他/她患上癌症的概率。第二个规则表示了如果x和y是朋友,他们要么都抽烟和要么都不抽烟,权重被捆绑在friend关系中的feature列。权重也可以是一个字符串常量,意味着规则的因子都有相同的权重。被支持的deepdive因子函数和相应的head语法如下:

Imply  : A1, A2, ... => An
Equal  : A1 = A2 = ... = An
And    : A1 ^ A2 ^ ... ^ An
Or     : A1 v A2 v ... v An
IsTrue : A
Multinomial: Multinomial(A1, A2, ..., An)

​其中 As 是atoms。

6. Compiling 编译

​给定ddlog编译器 ddlog.jar, 一个ddlog程序 app.ddlog 可以这样编译:

java -jar ddlog.jar compile app.ddlog > deepdive.conf

7. Extensions 扩展

​这一节描述了更多ddlog合取查询表达。

Quantified Body 量化体

​量化的body指出了一个量化的条件,语法是

quantifier(atom_or_condition, ...)

​支持的量词有 EXISTS, ALL, OPTIONAL。前两个类似于相应的SQL中的量词,第三个对应于SQL里一个outer join(外接)中的outer relation。例如,

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

8. Function Declaration 函数声明

​每个函数声明给出了用户定义函数(UDF)的input和output每个列的类型,以及它如何被实现和执行。语法:

function function_name function_input_type function_return_type implemetation

function 是关键字, function_typefunction_return_type 可以是

over relation_type_declaration

​或者是

returns relation_type_declaration

relation_type_declaration 也可以是一个类型名和类型的列表,或者让 像 relation_name 这样的行使用同样的关系. implementation 是这样的,

implementation "path_to_udf" handles tsv lines

​它用来指出一个tsv函数,或者说 handles tsv lines 被替换为 runs as plpy 来表示一个 plpy 提取器函数。例如,

Q(x int).

function ext_people over (a int, b int) returns like Q
  implementation "udf/ext_people.py" handles tsv lines.

9. Function Call Rule 函数调用规则

​如上述声明的函数只能在函数调用规则中使用。用户自定义规则可以从合取查询中派生出关系。语法是:

output_relation += user_defined_function(x, y) :- relation1(x, y), relation2(y, z).

​body关系中的元组(x, y)会被输入到 user_defined_function, 而输出会被送到output_relation。例如,

has_spouse_candidates += ext_has_spouse(s, p1_id, p1_text, p2_id, p2_text) :-
  people_mentions(s, _, _, p1_text, p1_id),
  people_mentions(s, _, _, p2_text, p2_id).

你可能感兴趣的:(机器学习)