1.0在DDlog中定義數據流:
DDlog是用簡潔,類似於Datalog的語法編寫DeepDive應用程序的高級語言。這裏我們重點介紹在DeepDive應用程序中定義數據流的一般語言特性。
DDlog程序是聲明和規則的集合。每個聲明和規則都以句點(.
)結尾。DDlog中的註釋以hash(#
)字符開頭。規則的順序沒有意義。DDlog程序由以下部分組成:
- 模式關係的聲明
- 正常推導規則
- 關係派生(頭部原子)
- 使用的關係(身體原子)
- 條件
- 用戶定義的函數(UDFS)
- 函數聲明
- 函數調用規則
- 推理規則
所有的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”。每列都有它自己的類型,在這裏使用int
,text
和text[]
。
1.2 正常推導規則:
典型的類似於數據記錄的規則用於定義如何從其他關係派生關係。例如,下面的規則指出關係的元組Q
是從關係R
和S
中獲取的。
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."
布爾文字:
TRUE
,FALSE
。空文字:
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
如果不存在這樣的值。