|
| 1 | +\chapter{От CFPQ к вычислению Datalog-запросов}\label{Subsection Datalog} |
| 2 | +Рассмотрим грамматику $S \rightarrow aSb \mid SS \mid \varepsilon$, заданную через набор предикатов: |
| 3 | +\begin{itemize} |
| 4 | + \item $a(i, w)$ --- Предикат, соответствующий терминалу. Обращается в True, если на $i$-том месте в строке $w$ стоит символ $a$ |
| 5 | + \item $S(i, j, w)$ --- Предикат, соответствующий нетерминалу. Обращается в True, если выполняется одно из условий: |
| 6 | + \begin{enumerate} |
| 7 | + \item $i == j \quad(\varepsilon)$ |
| 8 | + \item $\exists k: i \leq k \leq j \And S(i, k - 1, w) \And S(k, j, w) \quad (SS)$ |
| 9 | + \item ${a(i, w) \And S(i+1, j-1, w) \And b(j-1, w)} \quad (aSb)$ |
| 10 | + \end{enumerate} |
| 11 | +\end{itemize} |
| 12 | + |
| 13 | +Таким образом $S(0,|w|,w)$ покажет, выводится ли строка $w$ из данной грамматики, |
| 14 | +а $S(\_,\_,w)$ даст нам список всех цепочек внутри $w$, выводящихся из $S$. |
| 15 | + |
| 16 | +\subsection{Datalog} |
| 17 | +Datalog~\cite{Datalog}\footnote{\url{https://www.computer.org/csdl/journal/tk/1989/01/k0146/13rRUx0xPIQ}} --- декларативный логический язык программирования. Используется для написания запросов к дедуктивным базам данных\footnote{\url{https://en.wikipedia.org/wiki/Deductive_database}}. |
| 18 | + |
| 19 | +\begin{example} |
| 20 | + Пример программы на даталоге. |
| 21 | + \begin{enumerate} |
| 22 | + \item Набор фактов (часто факты находятся в базе данных): |
| 23 | + \begin{itemize} |
| 24 | + \item $a(0).$ |
| 25 | + \item $b(1).$ |
| 26 | + \item $a(2).$ |
| 27 | + \item $b(3).$ |
| 28 | + \item $s(I, I).$ |
| 29 | + \end{itemize} |
| 30 | + \item Набор правил: |
| 31 | + \begin{itemize} |
| 32 | + \item $s(I, J) \coloneq s(I, K-1), s(K,J), (I \leq K \leq J)$ |
| 33 | + \item $s(I,J)\coloneq a(I), s(I+1, J-1),b(J)$ |
| 34 | + \end{itemize} |
| 35 | + \item Запросы: |
| 36 | + \begin{itemize} |
| 37 | + \item $?- s(I, J)$ |
| 38 | + \end{itemize} |
| 39 | + \end{enumerate} |
| 40 | +\end{example} |
| 41 | + |
| 42 | +Таким образом мы описали на даталоге строку через набор фактов, грамматику, указанную выше, через набор фактов и правил и сделали запрос на все цепочки, выводящиеся из $S$. |
| 43 | + |
| 44 | +\textbf{NB!} Обратите внимание~\cite{Datalog}, что строки, начинающиеся с большой буквы, в даталоге считаются переменными. Также важно, что все переменные неявно квантифицированны. |
| 45 | + |
| 46 | + |
| 47 | +\subsection{Datalog для работы с графами} |
| 48 | +На даталоге также можно задавать графы и писать к ним запросы. |
| 49 | +\begin{example} |
| 50 | + Пример описания графа на даталоге. |
| 51 | + \begin{center} |
| 52 | + \begin{tikzpicture}[shorten >=1pt,on grid,auto] |
| 53 | + \node[state] (q_0) {$0$}; |
| 54 | + \node[state] (q_1) [above right=of q_0] {$1$}; |
| 55 | + \node[state] (q_2) [right=of q_0] {$2$}; |
| 56 | + \node[state] (q_3) [right=of q_2] {$3$}; |
| 57 | + \path[->] |
| 58 | + (q_0) edge node {$a$} (q_1) |
| 59 | + (q_1) edge node {$a$} (q_2) |
| 60 | + (q_2) edge node {$a$} (q_0) |
| 61 | + (q_2) edge[bend left, above] node {$b$} (q_3) |
| 62 | + (q_3) edge[bend left, below] node {$b$} (q_2); |
| 63 | + \end{tikzpicture} |
| 64 | + \end{center} |
| 65 | +\begin{itemize} |
| 66 | + \item[] $a(0, 1).$ |
| 67 | + \item[] $a(1, 2).$ |
| 68 | + \item[] $a(2, 0).$ |
| 69 | + \item[] $b(2, 3).$ |
| 70 | + \item[] $b(3, 2).$ |
| 71 | +\end{itemize} |
| 72 | + |
| 73 | +\end{example} |
| 74 | + |
| 75 | +Теперь зададим рассмотренную выше грамматику для работы с графом. |
| 76 | +\begin{itemize} |
| 77 | + \item[] $s(I, I).$ |
| 78 | + \item[] $s(I,J) \coloneq s(I, K-1),s(K, J).$ |
| 79 | + \item[] $s(I, J) \coloneq a(I, L),S(L,M),b(M,J).$ |
| 80 | +\end{itemize} |
| 81 | + |
| 82 | +Тогда запрос $?-s(I, J)$ выдаст нам все такие пути в графе, что последовательность составляющих их вершин в порядке прохождения выводится их грамматики. |
| 83 | + |
| 84 | +\subsection{Алгоритм Эрли} |
| 85 | +Для распознавания контекстно-свободных грамматик может использоваться алгоритм Эрли~\cite{Earley} \footnote{\url{https://en.wikipedia.org/wiki/Earley}}. |
| 86 | +Рассмотрим грамматику $G=(N,T,P,S)$, слово $a_1...a_n$, |
| 87 | +и правило $A \rightarrow \alpha\beta$. Будем считать, что утверждение |
| 88 | +$[A\rightarrow \alpha \bullet \beta](i,j), j \in [1..n]$ является истиной, если верно, что: |
| 89 | +\begin{itemize} |
| 90 | + \item $\alpha \xrightarrow{\smash{*}} a_{i+1}...a_j$ (Последовательность выводится из $\alpha$) |
| 91 | + \item $S \xrightarrow{\smash{*}} a_1...a_jA_\gamma$ |
| 92 | +\end{itemize} |
| 93 | + |
| 94 | + |
| 95 | +Рассмотрим правила вывода для подобных утверждений: |
| 96 | + |
| 97 | +\begin{enumerate} |
| 98 | + \item $\frac{S \rightarrow \alpha \in P}{[S \rightarrow \bullet \alpha](0,0)}$ Инициализация (Init) |
| 99 | + |
| 100 | + \item $\frac{\left[A \rightarrow \alpha \bullet a_{j+1} \beta\right](i, j)}{\left[A \rightarrow \alpha a_{j+1} \bullet \beta\right](i, j+1)}$ Сканирование (Scan) |
| 101 | + |
| 102 | + \item $\frac{[A \rightarrow \alpha \cdot B \beta](i, j) \quad B \rightarrow \gamma \in P}{[B \rightarrow \bullet \gamma](j, j)}$ Предсказание (Predict) |
| 103 | + |
| 104 | + \item $\frac{[A \rightarrow \alpha \cdot B](i, j) \quad[B \rightarrow \gamma \bullet](j, k)}{[A \rightarrow \alpha B \bullet \beta](i, k)}$ Завершение (Complete) |
| 105 | + |
| 106 | +\end{enumerate} |
| 107 | + |
| 108 | +Идея алгоритма Эрли заключается в том, чтобы, начиная с инициализации, используя правила, вывести утверждение, содержащие данную строку слева от точки, и ничего справа, или попробовать все возможные выводы и признать, что строка не выводима. |
| 109 | + |
| 110 | +Сложность алгоритма Эрли составляет $O(|P|^2n^3)$ |
| 111 | + |
| 112 | +\begin{example} Пример начала одной из веток дерева вывода для алгоритма Эрли для рассматриваемой грамматики |
| 113 | + |
| 114 | + $$\underline{S \rightarrow SS} \quad Init$$ |
| 115 | + $$\underline{[S \rightarrow \bullet SS](0,0), \space S \rightarrow aSb} \quad Predict$$ |
| 116 | + $$\underline{[S \rightarrow \bullet aSb](0,0)} \quad Scan$$ |
| 117 | + $$\underline{[S \rightarrow a \bullet Sb](0,1), S \rightarrow \varepsilon} \quad Predict$$ |
| 118 | + $$\underline{[S \rightarrow \bullet](0, 1), [S \rightarrow aS \bullet b](0,1)} \quad Complete$$ |
| 119 | + $$\underline{[S \rightarrow aS \bullet b](0,1)} \quad Scan$$ |
| 120 | + $$\underline{[S \rightarrow \bullet SS](0,0),[S \rightarrow aSb \bullet](0,2)} \quad Complete$$ |
| 121 | + $$[\underline{S \rightarrow S \bullet S](0,2)}$$ |
| 122 | + $$\cdot\cdot\cdot$$ |
| 123 | + |
| 124 | +\end{example} |
| 125 | + |
| 126 | +Сложность можно понизить, изменив правила ``Предсказание'' и ``Завершение'' таким образом: |
| 127 | +\begin{itemize} |
| 128 | + \item $\frac{[A \rightarrow \alpha \cdot B \beta](i, j) \quad B \rightarrow \gamma \in P}{[B \rightarrow \bullet \gamma](j, j)} \Rightarrow$ $ |
| 129 | + \frac{[A \rightarrow \alpha \cdot B \beta](i, j)}{? B(j)}; \quad \frac{? B(j) \quad B \rightarrow \gamma \in P}{[B \rightarrow \cdot \gamma](j, j)}$ |
| 130 | + \item $\frac{[A \rightarrow \alpha \cdot B](i, j) \quad[B \rightarrow \gamma \bullet](j, k)}{[A \rightarrow \alpha B \bullet \beta](i, k)} \Rightarrow$ $\frac{[B \rightarrow \gamma \bullet](j, k)}{B(j, k)}; \quad \frac{[A \rightarrow \alpha \cdot B \beta](i, j) \quad B(j, k)}{[A \rightarrow \alpha B \cdot \beta](i, k)}$ |
| 131 | +\end{itemize} |
| 132 | +Так, разложив каждое правило на два, мы избавляемся от необходимости перевычислять дерево разбора каждого нетерминала после того, как однократно вычислим, что он выводим (мемоизируем его). Получаем сложность $O(|P|)$. |
| 133 | + |
| 134 | +Описанный подход мемоизации~\cite{Magic} части используется для оптимизации программ на даталоге. Можно либо видоизменять правила, задающие грамматику в тексте программы, либо модифицировать компилятор, чтобы он пытался сделать это автоматически. |
| 135 | +\section{Вопросы и задачи} |
| 136 | +\begin{enumerate} |
| 137 | + \item Написать синтаксический анализатор раз. |
| 138 | + \item Написать синтаксический анализатор два. |
| 139 | + \item Побаловаться с неоднозначными грамматиками |
| 140 | + \item Побаловаться с конъюнктивными грамматиками. |
| 141 | + \item Графы? |
| 142 | +\end{enumerate} |
0 commit comments