<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=5.18.184.8&amp;*</id>
		<title>Викиконспекты - Вклад участника [ru]</title>
		<link rel="self" type="application/atom+xml" href="http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=5.18.184.8&amp;*"/>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/5.18.184.8"/>
		<updated>2026-05-19T17:15:16Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D1%81%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B4%D0%BE%D0%BC%D0%B5%D0%BD%D0%BE%D0%B2_%D0%B8_%D0%B5%D0%B3%D0%BE_%D1%80%D0%B5%D0%BB%D1%8F%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D1%82%D0%B0&amp;diff=81940</id>
		<title>Исчисление доменов и его реляционная полнота</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D1%81%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B4%D0%BE%D0%BC%D0%B5%D0%BD%D0%BE%D0%B2_%D0%B8_%D0%B5%D0%B3%D0%BE_%D1%80%D0%B5%D0%BB%D1%8F%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D1%82%D0%B0&amp;diff=81940"/>
				<updated>2021-12-26T19:55:56Z</updated>
		
		<summary type="html">&lt;p&gt;5.18.184.8: /* Реляционная полнота исчисления доменов */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Исчисление доменов==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Исчисление доменов''' {{---}} вид реляционного исчисления, в котором значения переменных принадлежат заранее определённым ''доменам''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Домен следует понимать как какое-то именованное множество допустимых значений для переменных. На современном языке, это понятие достаточно близко к понятию типа.&lt;br /&gt;
&lt;br /&gt;
Введём синтаксис для указания типов переменных. Также введём предикат, будем называть его ''условием принадлежности'', который для заданного отношения и значений атрибутов проверяет, есть ли совпадающий кортеж в отношении.&lt;br /&gt;
&lt;br /&gt;
===Синтаксис===&lt;br /&gt;
 &amp;lt;font color=red&amp;gt;Переменная&amp;lt;/font&amp;gt; :: &amp;lt;font color=red&amp;gt;Тип&amp;lt;/font&amp;gt; &amp;lt;font color=green&amp;gt;-- Переменная может принимать значения из какого-то типа. Тип == набор значений&lt;br /&gt;
 &amp;lt;/font&amp;gt;&lt;br /&gt;
  &amp;lt;font color=green&amp;gt;-- Условие принадлежности отношению&amp;lt;/font&amp;gt;&lt;br /&gt;
 &amp;lt;font color=red&amp;gt;Отношение {&amp;lt;/font&amp;gt;&lt;br /&gt;
   &amp;lt;font color=red&amp;gt;Атрибут1&amp;lt;/font&amp;gt; = &amp;lt;font color=red&amp;gt;Значение1&amp;lt;/font&amp;gt;,&lt;br /&gt;
   &amp;lt;font color=red&amp;gt;Атрибут2&amp;lt;/font&amp;gt; = &amp;lt;font color=red&amp;gt;Значение2&amp;lt;/font&amp;gt;,&lt;br /&gt;
   ...&lt;br /&gt;
 &amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Примеры использования условия принадлежности===&lt;br /&gt;
Следующий предикат будет истинным, если в отношении S найдётся кортеж &amp;lt;code&amp;gt;(FirstName = 'Иван', LastName = 'Иванов')&amp;lt;/code&amp;gt; или, например (при наличии ещё одного атрибута), &amp;lt;code&amp;gt;(FirstName = 'Иван', LastName = 'Иванов', Email = 'ivan@example.com')&amp;lt;/code&amp;gt; и ложным, если ни в одном кортеже не совпали все значения атрибутов с перечисленными&lt;br /&gt;
&lt;br /&gt;
 S&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;FirstName = &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;, LastName = &amp;lt;font color=green&amp;gt;'Иванов'&amp;lt;/font&amp;gt;&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Имя атрибута может совпадать с именем переменной, это может поначалу немного запутывать. Слева от знака равенства стоит имя атрибута, справа - значение, с которым атрибут сравниваем&lt;br /&gt;
&lt;br /&gt;
 S&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;FirstName = FirstName, LastName = LastName&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Примеры запросов===&lt;br /&gt;
=====Идентификаторы всех студентов=====&lt;br /&gt;
Запишем запрос для получения идентификаторов всех студентов. Можно представлять это так: единственная свободная переменная SId пробегает все возможные значения из домена (все возможные идентификаторы студентов), а в результирующее отношение попадают только те её значения, для которых реально существовал такой студент.&lt;br /&gt;
&lt;br /&gt;
 SId &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; S&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;SId = SId&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Идентификаторы студентов, не сдавших курс с CId=10=====&lt;br /&gt;
Также как и в исчислении кортежей, в исчислении доменов можно использовать кванторы. Студент не сдал курс, если у него нет положительных оценок за этот курс.&lt;br /&gt;
&lt;br /&gt;
 SId &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; ¬∃Points (Points ≥ 60 ∧ Points&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;SId = SId, Points = Points, CId = 10&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
==Реляционная полнота исчисления доменов==&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Исчисление доменов реляционно полно&lt;br /&gt;
|proof=&lt;br /&gt;
Выразим базис реляционной алгебры в терминах исчисления доменов:&lt;br /&gt;
&lt;br /&gt;
'''Проекция $\pi_{A_1, ..., A_n}(R)$''' Выбираем только такие наборы значений $A_1$...$A_n$, для которых в исходном отношении есть кортеж, в котором атрибуты $A_1$...$A_n$ принимают значения $A_1$...$A_n$.&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_1$ = $A_1$, ..., $A_n$ = $A_n$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Фильтр $σ_θ(R)$'''&lt;br /&gt;
Выбираем только такие наборы значений $A_1$...$A_n$, которые есть в исходном отношении R и удовлетворяют условию θ&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_1$ = $A_1$, ..., $A_n$ = $A_n$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $θ$&lt;br /&gt;
&lt;br /&gt;
'''Переименовывание $ε_{A=expr}(R_1)$''' &lt;br /&gt;
Просто используем специальный синтаксис&lt;br /&gt;
 ..., $expr$ as $A$, ... &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R${$A_1$ = $A_1$, ..., $A_n$ = $A_n$}&lt;br /&gt;
&lt;br /&gt;
'''Объединение $R_1 ∪ R_2$'''&lt;br /&gt;
Выбираем только такие наборы значений $A_1$...$A_n$, что хотя бы в одном из отношений есть соответствующий кортеж&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∨ $R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Разность $R_1 ∖ R_2$'''&lt;br /&gt;
Выбираем только такие наборы значений $A_1$...$A_n$, что соответствующий кортеж есть в $R_1$, но нет в $R_2$&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $¬R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Декартово произведение $R_1 × R_2$'''&lt;br /&gt;
Выбираем наборы значений  $A_1$, ..., $A_n$, $B_1$, ..., $B_m$ такие, что ($A_1$...$A_n$) есть в $R_1$, а ($B_1$...$B_n$) есть в $R_2$&lt;br /&gt;
 $A_1$, ..., $A_n$, $B_1$, ..., $B_m$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$B_j$ = $B_j$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Естественное соединение $R_1 ⋈ R_2$''' &lt;br /&gt;
Выбираем такие наборы значений $A_1$, ..., $A_n$, $B_1$, ..., $B_m$, $C_1$, ..., $C_l$, что $B_1$, ..., $B_m$ что ($A_1$, ..., $A_n$, $B_1$, ..., $B_m$) входит в $R_1$, а ($B_1$, ..., $B_m$, $C_1$, ..., $C_l$) в $R_2$. Автоматически получаем соединение по $B_1$, ..., $B_m$. Это можно было бы записать иначе - явной проверкой равенства этих атрибутов (тогда придётся использовать ещё m переменных), но проще сделать так.&lt;br /&gt;
 $A_1$, ..., $A_n$, $B_1$, ..., $B_m$, $C_1$, ..., $C_l$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$, $B_j$ = $B_j$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$C_k$ = $C_k$, $B_j$ = $B_j$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>5.18.184.8</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D1%81%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B4%D0%BE%D0%BC%D0%B5%D0%BD%D0%BE%D0%B2_%D0%B8_%D0%B5%D0%B3%D0%BE_%D1%80%D0%B5%D0%BB%D1%8F%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D1%82%D0%B0&amp;diff=81939</id>
		<title>Исчисление доменов и его реляционная полнота</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D1%81%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B4%D0%BE%D0%BC%D0%B5%D0%BD%D0%BE%D0%B2_%D0%B8_%D0%B5%D0%B3%D0%BE_%D1%80%D0%B5%D0%BB%D1%8F%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D1%82%D0%B0&amp;diff=81939"/>
				<updated>2021-12-26T19:55:29Z</updated>
		
		<summary type="html">&lt;p&gt;5.18.184.8: /* Реляционная полнота исчисления доменов */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Исчисление доменов==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Исчисление доменов''' {{---}} вид реляционного исчисления, в котором значения переменных принадлежат заранее определённым ''доменам''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Домен следует понимать как какое-то именованное множество допустимых значений для переменных. На современном языке, это понятие достаточно близко к понятию типа.&lt;br /&gt;
&lt;br /&gt;
Введём синтаксис для указания типов переменных. Также введём предикат, будем называть его ''условием принадлежности'', который для заданного отношения и значений атрибутов проверяет, есть ли совпадающий кортеж в отношении.&lt;br /&gt;
&lt;br /&gt;
===Синтаксис===&lt;br /&gt;
 &amp;lt;font color=red&amp;gt;Переменная&amp;lt;/font&amp;gt; :: &amp;lt;font color=red&amp;gt;Тип&amp;lt;/font&amp;gt; &amp;lt;font color=green&amp;gt;-- Переменная может принимать значения из какого-то типа. Тип == набор значений&lt;br /&gt;
 &amp;lt;/font&amp;gt;&lt;br /&gt;
  &amp;lt;font color=green&amp;gt;-- Условие принадлежности отношению&amp;lt;/font&amp;gt;&lt;br /&gt;
 &amp;lt;font color=red&amp;gt;Отношение {&amp;lt;/font&amp;gt;&lt;br /&gt;
   &amp;lt;font color=red&amp;gt;Атрибут1&amp;lt;/font&amp;gt; = &amp;lt;font color=red&amp;gt;Значение1&amp;lt;/font&amp;gt;,&lt;br /&gt;
   &amp;lt;font color=red&amp;gt;Атрибут2&amp;lt;/font&amp;gt; = &amp;lt;font color=red&amp;gt;Значение2&amp;lt;/font&amp;gt;,&lt;br /&gt;
   ...&lt;br /&gt;
 &amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Примеры использования условия принадлежности===&lt;br /&gt;
Следующий предикат будет истинным, если в отношении S найдётся кортеж &amp;lt;code&amp;gt;(FirstName = 'Иван', LastName = 'Иванов')&amp;lt;/code&amp;gt; или, например (при наличии ещё одного атрибута), &amp;lt;code&amp;gt;(FirstName = 'Иван', LastName = 'Иванов', Email = 'ivan@example.com')&amp;lt;/code&amp;gt; и ложным, если ни в одном кортеже не совпали все значения атрибутов с перечисленными&lt;br /&gt;
&lt;br /&gt;
 S&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;FirstName = &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;, LastName = &amp;lt;font color=green&amp;gt;'Иванов'&amp;lt;/font&amp;gt;&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Имя атрибута может совпадать с именем переменной, это может поначалу немного запутывать. Слева от знака равенства стоит имя атрибута, справа - значение, с которым атрибут сравниваем&lt;br /&gt;
&lt;br /&gt;
 S&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;FirstName = FirstName, LastName = LastName&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Примеры запросов===&lt;br /&gt;
=====Идентификаторы всех студентов=====&lt;br /&gt;
Запишем запрос для получения идентификаторов всех студентов. Можно представлять это так: единственная свободная переменная SId пробегает все возможные значения из домена (все возможные идентификаторы студентов), а в результирующее отношение попадают только те её значения, для которых реально существовал такой студент.&lt;br /&gt;
&lt;br /&gt;
 SId &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; S&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;SId = SId&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Идентификаторы студентов, не сдавших курс с CId=10=====&lt;br /&gt;
Также как и в исчислении кортежей, в исчислении доменов можно использовать кванторы. Студент не сдал курс, если у него нет положительных оценок за этот курс.&lt;br /&gt;
&lt;br /&gt;
 SId &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; ¬∃Points (Points ≥ 60 ∧ Points&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;SId = SId, Points = Points, CId = 10&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
==Реляционная полнота исчисления доменов==&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Исчисление доменов реляционно полно&lt;br /&gt;
|proof=&lt;br /&gt;
Выразим базис реляционной алгебры в терминах исчисления доменов:&lt;br /&gt;
&lt;br /&gt;
'''Проекция $\pi_{A_1, ..., A_n}(R)$''' Выбираем только такие наборы значений $A_1$...$A_n$, для которых в исходном отношении есть кортеж, в котором атрибуты $A_1$...$A_n$ принимают значения $A_1$...$A_n$.&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_1$ = $A_1$, ..., $A_n$ = $A_n$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Фильтр $σ_θ(R)$'''&lt;br /&gt;
Выбираем только такие наборы значений $A_1$...$A_n$, которые есть в исходном отношении R и удовлетворяют условию θ&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_1$ = $A_1$, ..., $A_n$ = $A_n$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $θ$&lt;br /&gt;
&lt;br /&gt;
'''Переименовывание $ε_{A=expr}(R_1)$''' &lt;br /&gt;
Просто используем специальный синтаксис&lt;br /&gt;
 ..., $expr$ as $A$, ... &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R${$A_1$ = $A_1$, ..., $A_n$ = $A_n$}&lt;br /&gt;
&lt;br /&gt;
'''Объединение $R_1 ∪ R_2$'''&lt;br /&gt;
Выбираем только такие наборы значений $A_1$...$A_n$, что хотя бы в одном из отношений есть соответствующий кортеж&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∨ $R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Разность $R_1 ∖ R_2$'''&lt;br /&gt;
Выбираем только такие наборы значений $A_1$...$A_n$, что соответствующий кортеж есть в $R_1$, но нет в $R_2$&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $¬R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Декартово произведение $R_1 × R_2$'''&lt;br /&gt;
Выбираем наборы значений  $A_1$, ..., $A_n$, $B_1$, ..., $B_m$ такие, что $A_1$...$A_n$ есть в $R_1$, а $B_1$...$B_n$ есть в $R_2$&lt;br /&gt;
 $A_1$, ..., $A_n$, $B_1$, ..., $B_m$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$B_j$ = $B_j$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Естественное соединение $R_1 ⋈ R_2$''' &lt;br /&gt;
Выбираем такие наборы значений $A_1$, ..., $A_n$, $B_1$, ..., $B_m$, $C_1$, ..., $C_l$, что $B_1$, ..., $B_m$ что ($A_1$, ..., $A_n$, $B_1$, ..., $B_m$) входит в $R_1$, а ($B_1$, ..., $B_m$, $C_1$, ..., $C_l$) в $R_2$. Автоматически получаем соединение по $B_1$, ..., $B_m$. Это можно было бы записать иначе - явной проверкой равенства этих атрибутов (тогда придётся использовать ещё m переменных), но проще сделать так.&lt;br /&gt;
 $A_1$, ..., $A_n$, $B_1$, ..., $B_m$, $C_1$, ..., $C_l$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$, $B_j$ = $B_j$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$C_k$ = $C_k$, $B_j$ = $B_j$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>5.18.184.8</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Datalog_%D0%B8_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F&amp;diff=81938</id>
		<title>Datalog и рекурсия</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Datalog_%D0%B8_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F&amp;diff=81938"/>
				<updated>2021-12-26T19:51:04Z</updated>
		
		<summary type="html">&lt;p&gt;5.18.184.8: /* Реляционная полнота */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Язык Datalog==&lt;br /&gt;
Декларативный язык для запросов к базам данных на основе исчисления доменов. Разработан в 1978 году, синтаксически - подмножество языка Prolog. Широкого применения в реальных базах данных не получил, но повлиял на формирование более поздних языков для запросов, таких как SQL.&lt;br /&gt;
&lt;br /&gt;
==Синтаксис==&lt;br /&gt;
===Отношение===&lt;br /&gt;
Программа на Datalog - набор '''отношений'''. Отношение на языке Datalog определяется так: &lt;br /&gt;
 Отношение(x1,x2...xn) :- Цель.&lt;br /&gt;
Определение одного и того же отношения может повторяться несколько раз, тогда в это отношение будут входить кортежи, которые удовлетворяют хотя бы одной цели.&lt;br /&gt;
===Цель===&lt;br /&gt;
'''Цель''' в свою очередь - это набор '''атомов''', перечисленных через запятую. Кортеж удовлетворяет цели, если он удовлетворяет всем атомам цели.&lt;br /&gt;
===Атом===&lt;br /&gt;
Атомы бывают двух типов: реляционные и арифметические&lt;br /&gt;
====Реляционный====&lt;br /&gt;
Аналог конструкции условия принадлежности из исчисления доменов.&lt;br /&gt;
Есть два вида:&lt;br /&gt;
* Кортеж удовлетворяет атому &amp;lt;code&amp;gt;R(x1, x2, ..., xn)&amp;lt;/code&amp;gt; тогда и только тогда, когда принадлежит отношению R.&lt;br /&gt;
* Кортеж удовлетворяет атому &amp;lt;code&amp;gt;¬R(x1, x2, ..., xn)&amp;lt;/code&amp;gt; тогда и только тогда, когда такого кортежа нет в отношении R.&lt;br /&gt;
Заметим, что в Datalog нет имён атрибутов, атрибуты различаются только по своей позиции.&lt;br /&gt;
&lt;br /&gt;
====Арифметический====&lt;br /&gt;
Сюда входят сравнения арифмитических выражений на равенство и неравенство.&lt;br /&gt;
&lt;br /&gt;
==Примеры запросов==&lt;br /&gt;
===Идентификаторы и фамилии всех Иванов===&lt;br /&gt;
Рассмотрим такой запрос на языке исчисления доменов&lt;br /&gt;
 Id, LastName &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; Students&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;Id = Id, FirstName = &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;, LastName = LastName&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Его можно переписать на Datalog так:&lt;br /&gt;
 Ivans(Id, LastName) :-&lt;br /&gt;
     Students(Id, &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;, LastName).&lt;br /&gt;
&lt;br /&gt;
===Имена родителей===&lt;br /&gt;
Пусть есть таблица &amp;lt;code&amp;gt;Person(Id, Name, MotherId, FatherId)&amp;lt;/code&amp;gt;&lt;br /&gt;
====Получить имена обоих родителей каждого человека (Name, Father, Mother)====&lt;br /&gt;
Запишем конъюнкцию атомов: &amp;quot;FatherId - отец Name&amp;quot;, &amp;quot;MotherId - мать Name&amp;quot;, &amp;quot;Имя FatherId - FatherName&amp;quot;, &amp;quot;Имя MotherId - MotherName&amp;quot;:&lt;br /&gt;
 Parents(Name, FatherName, MotherName) :- Person(_, Name, FatherId, MotherId),&lt;br /&gt;
     Person(FatherId, FatherName, _, _), Person(MotherId, MotherName, _, _).&lt;br /&gt;
&lt;br /&gt;
====Получить для каждого человека всех его родителей (Name, Parent)====&lt;br /&gt;
Воспользуемся тем, что в Datalog при определении отношений дважды, они объёдиняются:&lt;br /&gt;
 Parents(Name, FatherName) :- Person(_, Name, FatherId, _),&lt;br /&gt;
     Person(FatherId, FatherName, _, _).&lt;br /&gt;
 Parents(Name, MotherName) :- Person(_, Name, _, MotherId),&lt;br /&gt;
     Person(MotherId, MotherName, _, _).&lt;br /&gt;
====Идентификаторы студентов не сдавших курс с CId=10====&lt;br /&gt;
На языке исчисления доменов этот запрос можно записать так:&lt;br /&gt;
 SId &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; ¬∃Points (Points ≥ 60 ∧ Points&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;SId = SId, Points = Points, CId = 10&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Перепишем его на язык Datalog. Так как в Datalog нет явных кванторов, то мы вынуждены пользоваться неявным квантором существования, который в Datalog связывает все свободные переменные цели. Над ним невозможно поставить отрицание, поэтому запишем вспомогательное отношение, в котором есть те и только те студенты, которые '''сдали курс''', затем построим отрицание.&lt;br /&gt;
 Graded(SId) :- Points(SId, Points, 10), Points &amp;gt;= 60.&lt;br /&gt;
 Failed(SId) :- Points(SId, _, _), ¬Graded(SId).&lt;br /&gt;
&lt;br /&gt;
==Ограничение отношений==&lt;br /&gt;
Как и на любую другую программу, на синтаксически корректную программу на языке Datalog нужно наложить дополнительные ограничения, чтобы она имела смысл.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим отношения&lt;br /&gt;
 Less(x,y) :- x &amp;lt; y.&lt;br /&gt;
 NotStudent(Id, Name) :- ¬Students(Id, Name, _).&lt;br /&gt;
&lt;br /&gt;
Здесь есть проблема - во-первых, мы даже не знаем тип &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Id&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;Name&amp;lt;/code&amp;gt;, это значит, что мы не знаем области их значения.&lt;br /&gt;
Во-вторых, даже если бы мы знали их тип, пусть это будут, например, целые числа, то получили бы бесконечное отношение, с такими мы работать не умеем.&lt;br /&gt;
&lt;br /&gt;
Поэтому, нужно запретить такую ситуацию, для этого добавим требование:&lt;br /&gt;
&lt;br /&gt;
'''Каждая переменная должна входить в неотрицательный реляционный атом'''&lt;br /&gt;
&lt;br /&gt;
==Реляционная полнота==&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Язык Datalog реляционно полон&lt;br /&gt;
|proof=&lt;br /&gt;
Выразим базис реляционной алгебры на языке Datalog:&lt;br /&gt;
&lt;br /&gt;
'''Проекция $\pi_{A_1, ..., A_n}(R)$''' Цели удовлетворяют те и только те кортежи, для которых в исходном отношении есть кортеж, совпадающий с ними по первым n атрибутам&lt;br /&gt;
 Q(A1, ..., An) :- R(A1, ..., An, _, ..., _).&lt;br /&gt;
'''Фильтр $σ_θ(R)$''' Цели удовлетворяют те и только те кортежи, которые есть в исходном отношении и удовлетворяют условию θ&lt;br /&gt;
 Q(A1, ..., An) :- R(A1, ..., An), θ.&lt;br /&gt;
'''Объединение $R_1 ∪ R_2$''' Отношение содержит кортежи, которые удовлетворяют хотя бы одной из целей, а значит принадлежит хотя бы одному из исходных отношений. &lt;br /&gt;
 Q(A1, ..., An) :- R1(A1, ..., An).&lt;br /&gt;
 Q(A1, ..., An) :- R2(A1, ..., An).&lt;br /&gt;
'''Разность $R_1 ∖ R_2$''' Цели удовлетворяют только такие кортежи, которые есть в $R_1$, но не в $R_2$.&lt;br /&gt;
 Q(A1, ..., An) :- R1(A1, ..., An), ¬R2(A1, ..., An).&lt;br /&gt;
'''Декартово произведение $R_1 × R_2$''' Цели удовлетворяют такие кортежи, что первые $n$ значений атрибутов взяты из первого отношения, а следующие $m$ - из второго&lt;br /&gt;
 Q(A1, ..., An, B1, ..., Bm) :- &lt;br /&gt;
     R1(A1, ..., An), R2(B1, ..., Bm).&lt;br /&gt;
&lt;br /&gt;
'''Естественное соединение $R_1 ⋈ R_2$''' Почти как декартово произведение, но теперь переменные $B_1 \ldots B_m$ - атрибуты, по которым идёт соединение - используются сразу в двух атомах.&lt;br /&gt;
 Q(A1, ..., An, B1, ..., Bm, C1, ..., Cl) :-&lt;br /&gt;
     R1(A1, ..., An, B1, ..., Bm), R2(B1, ..., Bm, C1, ..., Cl).&lt;br /&gt;
'''Переименовывание''' Заметим что в Datalog нет имён атрибутов, роль имён здесь играют позиции. Поэтому переименовывание не нужно, вместо этого можно сделать перестановку атрибутов.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Рекурсивные запросы==&lt;br /&gt;
Синтаксис Datalog позволяет написать рекурсивный запрос, но может быть не очевидно, какой смысл придавать такой конструкции.&lt;br /&gt;
Далее будет рассмотрен пример и приведены некоторые рассуждения о семантике рекурсивных запросов.&lt;br /&gt;
===Смысл===&lt;br /&gt;
Пусть есть некоторое отношение &amp;quot;потомок-родитель&amp;quot;&lt;br /&gt;
 Parent(Id, ParentId)&lt;br /&gt;
&lt;br /&gt;
Хотим найти его транзитивное замыкание, по определению:&lt;br /&gt;
 Ancestor(Id, PId) :- Parent(Id, PId).&lt;br /&gt;
 Ancestor(Id, GId) :- Parent(Id, GId), Ancestor(PId, GId).&lt;br /&gt;
&lt;br /&gt;
Пусть $P$ - множество всех людей, у которых есть хотя бы один родитель.&lt;br /&gt;
Очевидно, что $P \times P$ есть неподвижная точка, то есть правая часть отношения совпадает с левой, но найденное отношение не является транзитивным замыканием исходного.&lt;br /&gt;
&lt;br /&gt;
Поэтому, следует уточнить, что мы ищем '''минимальную по включению неподвижную точку''', начиная с пустого множества, тогда наш запрос отработает корректно.&lt;br /&gt;
&lt;br /&gt;
===Алгоритм поиска минимальной неподвижной точки===&lt;br /&gt;
&lt;br /&gt;
 Проинициализируем отношения из нерекурсивных определений&lt;br /&gt;
 Пока не достигли неподвижной точки&lt;br /&gt;
   Пополняем отношения из рекурсивных определений&lt;br /&gt;
&lt;br /&gt;
===Циклы и отрицание===&lt;br /&gt;
&lt;br /&gt;
Представим ситуацию, когда принадлежность кортежа к отношению зависит от отрицания его принадлежности к отношению. Это в чистом виде парадокс брадобрея и мы знаем, что такая конструкция не имеет смысла.&lt;br /&gt;
&lt;br /&gt;
Поэтому, введём '''стратифицированное отрицание''', то есть запрет на отрицание в циклах.&lt;/div&gt;</summary>
		<author><name>5.18.184.8</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Datalog_%D0%B8_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F&amp;diff=81937</id>
		<title>Datalog и рекурсия</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Datalog_%D0%B8_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F&amp;diff=81937"/>
				<updated>2021-12-26T19:42:50Z</updated>
		
		<summary type="html">&lt;p&gt;5.18.184.8: /* Реляционная полнота */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Язык Datalog==&lt;br /&gt;
Декларативный язык для запросов к базам данных на основе исчисления доменов. Разработан в 1978 году, синтаксически - подмножество языка Prolog. Широкого применения в реальных базах данных не получил, но повлиял на формирование более поздних языков для запросов, таких как SQL.&lt;br /&gt;
&lt;br /&gt;
==Синтаксис==&lt;br /&gt;
===Отношение===&lt;br /&gt;
Программа на Datalog - набор '''отношений'''. Отношение на языке Datalog определяется так: &lt;br /&gt;
 Отношение(x1,x2...xn) :- Цель.&lt;br /&gt;
Определение одного и того же отношения может повторяться несколько раз, тогда в это отношение будут входить кортежи, которые удовлетворяют хотя бы одной цели.&lt;br /&gt;
===Цель===&lt;br /&gt;
'''Цель''' в свою очередь - это набор '''атомов''', перечисленных через запятую. Кортеж удовлетворяет цели, если он удовлетворяет всем атомам цели.&lt;br /&gt;
===Атом===&lt;br /&gt;
Атомы бывают двух типов: реляционные и арифметические&lt;br /&gt;
====Реляционный====&lt;br /&gt;
Аналог конструкции условия принадлежности из исчисления доменов.&lt;br /&gt;
Есть два вида:&lt;br /&gt;
* Кортеж удовлетворяет атому &amp;lt;code&amp;gt;R(x1, x2, ..., xn)&amp;lt;/code&amp;gt; тогда и только тогда, когда принадлежит отношению R.&lt;br /&gt;
* Кортеж удовлетворяет атому &amp;lt;code&amp;gt;¬R(x1, x2, ..., xn)&amp;lt;/code&amp;gt; тогда и только тогда, когда такого кортежа нет в отношении R.&lt;br /&gt;
Заметим, что в Datalog нет имён атрибутов, атрибуты различаются только по своей позиции.&lt;br /&gt;
&lt;br /&gt;
====Арифметический====&lt;br /&gt;
Сюда входят сравнения арифмитических выражений на равенство и неравенство.&lt;br /&gt;
&lt;br /&gt;
==Примеры запросов==&lt;br /&gt;
===Идентификаторы и фамилии всех Иванов===&lt;br /&gt;
Рассмотрим такой запрос на языке исчисления доменов&lt;br /&gt;
 Id, LastName &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; Students&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;Id = Id, FirstName = &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;, LastName = LastName&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Его можно переписать на Datalog так:&lt;br /&gt;
 Ivans(Id, LastName) :-&lt;br /&gt;
     Students(Id, &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;, LastName).&lt;br /&gt;
&lt;br /&gt;
===Имена родителей===&lt;br /&gt;
Пусть есть таблица &amp;lt;code&amp;gt;Person(Id, Name, MotherId, FatherId)&amp;lt;/code&amp;gt;&lt;br /&gt;
====Получить имена обоих родителей каждого человека (Name, Father, Mother)====&lt;br /&gt;
Запишем конъюнкцию атомов: &amp;quot;FatherId - отец Name&amp;quot;, &amp;quot;MotherId - мать Name&amp;quot;, &amp;quot;Имя FatherId - FatherName&amp;quot;, &amp;quot;Имя MotherId - MotherName&amp;quot;:&lt;br /&gt;
 Parents(Name, FatherName, MotherName) :- Person(_, Name, FatherId, MotherId),&lt;br /&gt;
     Person(FatherId, FatherName, _, _), Person(MotherId, MotherName, _, _).&lt;br /&gt;
&lt;br /&gt;
====Получить для каждого человека всех его родителей (Name, Parent)====&lt;br /&gt;
Воспользуемся тем, что в Datalog при определении отношений дважды, они объёдиняются:&lt;br /&gt;
 Parents(Name, FatherName) :- Person(_, Name, FatherId, _),&lt;br /&gt;
     Person(FatherId, FatherName, _, _).&lt;br /&gt;
 Parents(Name, MotherName) :- Person(_, Name, _, MotherId),&lt;br /&gt;
     Person(MotherId, MotherName, _, _).&lt;br /&gt;
====Идентификаторы студентов не сдавших курс с CId=10====&lt;br /&gt;
На языке исчисления доменов этот запрос можно записать так:&lt;br /&gt;
 SId &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; ¬∃Points (Points ≥ 60 ∧ Points&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;SId = SId, Points = Points, CId = 10&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Перепишем его на язык Datalog. Так как в Datalog нет явных кванторов, то мы вынуждены пользоваться неявным квантором существования, который в Datalog связывает все свободные переменные цели. Над ним невозможно поставить отрицание, поэтому запишем вспомогательное отношение, в котором есть те и только те студенты, которые '''сдали курс''', затем построим отрицание.&lt;br /&gt;
 Graded(SId) :- Points(SId, Points, 10), Points &amp;gt;= 60.&lt;br /&gt;
 Failed(SId) :- Points(SId, _, _), ¬Graded(SId).&lt;br /&gt;
&lt;br /&gt;
==Ограничение отношений==&lt;br /&gt;
Как и на любую другую программу, на синтаксически корректную программу на языке Datalog нужно наложить дополнительные ограничения, чтобы она имела смысл.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим отношения&lt;br /&gt;
 Less(x,y) :- x &amp;lt; y.&lt;br /&gt;
 NotStudent(Id, Name) :- ¬Students(Id, Name, _).&lt;br /&gt;
&lt;br /&gt;
Здесь есть проблема - во-первых, мы даже не знаем тип &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Id&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;Name&amp;lt;/code&amp;gt;, это значит, что мы не знаем области их значения.&lt;br /&gt;
Во-вторых, даже если бы мы знали их тип, пусть это будут, например, целые числа, то получили бы бесконечное отношение, с такими мы работать не умеем.&lt;br /&gt;
&lt;br /&gt;
Поэтому, нужно запретить такую ситуацию, для этого добавим требование:&lt;br /&gt;
&lt;br /&gt;
'''Каждая переменная должна входить в неотрицательный реляционный атом'''&lt;br /&gt;
&lt;br /&gt;
==Реляционная полнота==&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Язык Datalog реляционно полон&lt;br /&gt;
|proof=&lt;br /&gt;
Выразим базис реляционной алгебры на языке Datalog:&lt;br /&gt;
&lt;br /&gt;
'''Проекция $\pi_{A_1, ..., A_n}(R)$''' Цели удовлетворяют те и только те кортежи, для которых в исходном отношении есть кортеж, совпадающий с ними по первым n атрибутам&lt;br /&gt;
 Q(A1, ..., An) :- R(A1, ..., An, _, ..., _).&lt;br /&gt;
'''Фильтр $σ_θ(R)$''' Цели удовлетворяют те и только те кортежи, которые есть в исходном отношении и удовлетворяют условию θ&lt;br /&gt;
 Q(A1, ..., An) :- R(A1, ..., An), θ.&lt;br /&gt;
'''Объединение $R_1 ∪ R_2$''' Отношение содержит кортежи, которые удовлетворяют хотя бы одной из целей, а значит принадлежит хотя бы одному из исходных отношений. &lt;br /&gt;
 Q(A1, ..., An) :- R1(A1, ..., An).&lt;br /&gt;
 Q(A1, ..., An) :- R2(A1, ..., An).&lt;br /&gt;
'''Разность $R_1 ∖ R_2$''' Цели удовлетворяют только такие кортежи, которые есть в $R_1$, но не в $R_2$.&lt;br /&gt;
 Q(A1, ..., An) :- R1(A1, ..., An), ¬R2(A1, ..., An).&lt;br /&gt;
'''Декартово произведение $R_1 × R_2$''' Цели удовлетворяют такие кортежи, что первые $n$ значений атрибутов взяты из первого отношения, а следующие $m$ - из второго&lt;br /&gt;
 Q(A1, ..., An, B1, ..., Bm) :- &lt;br /&gt;
     R1(A1, ..., An), R2(B1, ..., Bm).&lt;br /&gt;
&lt;br /&gt;
'''Естественное соединение $R_1 ⋈ R_2$''' Почти как декартово произведение, но теперь переменные $B_1 \ldots B_m$ - атрибуты, по которым идёт соединение - используются сразу в двух атомах.&lt;br /&gt;
 Q(A1, ..., An, B1, ..., Bm, C1, ..., Cl) :-&lt;br /&gt;
     R1(A1, ..., An, B1, ..., Bm), R2(B1, ..., Bm, C1, ..., Cl).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Рекурсивные запросы==&lt;br /&gt;
Синтаксис Datalog позволяет написать рекурсивный запрос, но может быть не очевидно, какой смысл придавать такой конструкции.&lt;br /&gt;
Далее будет рассмотрен пример и приведены некоторые рассуждения о семантике рекурсивных запросов.&lt;br /&gt;
===Смысл===&lt;br /&gt;
Пусть есть некоторое отношение &amp;quot;потомок-родитель&amp;quot;&lt;br /&gt;
 Parent(Id, ParentId)&lt;br /&gt;
&lt;br /&gt;
Хотим найти его транзитивное замыкание, по определению:&lt;br /&gt;
 Ancestor(Id, PId) :- Parent(Id, PId).&lt;br /&gt;
 Ancestor(Id, GId) :- Parent(Id, GId), Ancestor(PId, GId).&lt;br /&gt;
&lt;br /&gt;
Пусть $P$ - множество всех людей, у которых есть хотя бы один родитель.&lt;br /&gt;
Очевидно, что $P \times P$ есть неподвижная точка, то есть правая часть отношения совпадает с левой, но найденное отношение не является транзитивным замыканием исходного.&lt;br /&gt;
&lt;br /&gt;
Поэтому, следует уточнить, что мы ищем '''минимальную по включению неподвижную точку''', начиная с пустого множества, тогда наш запрос отработает корректно.&lt;br /&gt;
&lt;br /&gt;
===Алгоритм поиска минимальной неподвижной точки===&lt;br /&gt;
&lt;br /&gt;
 Проинициализируем отношения из нерекурсивных определений&lt;br /&gt;
 Пока не достигли неподвижной точки&lt;br /&gt;
   Пополняем отношения из рекурсивных определений&lt;br /&gt;
&lt;br /&gt;
===Циклы и отрицание===&lt;br /&gt;
&lt;br /&gt;
Представим ситуацию, когда принадлежность кортежа к отношению зависит от отрицания его принадлежности к отношению. Это в чистом виде парадокс брадобрея и мы знаем, что такая конструкция не имеет смысла.&lt;br /&gt;
&lt;br /&gt;
Поэтому, введём '''стратифицированное отрицание''', то есть запрет на отрицание в циклах.&lt;/div&gt;</summary>
		<author><name>5.18.184.8</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D1%81%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B4%D0%BE%D0%BC%D0%B5%D0%BD%D0%BE%D0%B2_%D0%B8_%D0%B5%D0%B3%D0%BE_%D1%80%D0%B5%D0%BB%D1%8F%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D1%82%D0%B0&amp;diff=81918</id>
		<title>Исчисление доменов и его реляционная полнота</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D1%81%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B4%D0%BE%D0%BC%D0%B5%D0%BD%D0%BE%D0%B2_%D0%B8_%D0%B5%D0%B3%D0%BE_%D1%80%D0%B5%D0%BB%D1%8F%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D1%82%D0%B0&amp;diff=81918"/>
				<updated>2021-12-26T18:32:00Z</updated>
		
		<summary type="html">&lt;p&gt;5.18.184.8: /* Реляционная полнота исчисления доменов */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Исчисление доменов==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Исчисление доменов''' {{---}} вид реляционного исчисления, в котором значения переменных принадлежат заранее определённым ''доменам''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Домен следует понимать как какое-то именованное множество допустимых значений для переменных. На современном языке, это понятие достаточно близко к понятию типа.&lt;br /&gt;
&lt;br /&gt;
Введём синтаксис для указания типов переменных. Также введём предикат, будем называть его ''условием принадлежности'', который для заданного отношения и значений атрибутов проверяет, есть ли совпадающий кортеж в отношении.&lt;br /&gt;
&lt;br /&gt;
===Синтаксис===&lt;br /&gt;
 &amp;lt;font color=red&amp;gt;Переменная&amp;lt;/font&amp;gt; :: &amp;lt;font color=red&amp;gt;Тип&amp;lt;/font&amp;gt; &amp;lt;font color=green&amp;gt;-- Переменная может принимать значения из какого-то типа. Тип == набор значений&lt;br /&gt;
 &amp;lt;/font&amp;gt;&lt;br /&gt;
  &amp;lt;font color=green&amp;gt;-- Условие принадлежности отношению&amp;lt;/font&amp;gt;&lt;br /&gt;
 &amp;lt;font color=red&amp;gt;Отношение {&amp;lt;/font&amp;gt;&lt;br /&gt;
   &amp;lt;font color=red&amp;gt;Атрибут1&amp;lt;/font&amp;gt; = &amp;lt;font color=red&amp;gt;Значение1&amp;lt;/font&amp;gt;,&lt;br /&gt;
   &amp;lt;font color=red&amp;gt;Атрибут2&amp;lt;/font&amp;gt; = &amp;lt;font color=red&amp;gt;Значение2&amp;lt;/font&amp;gt;,&lt;br /&gt;
   ...&lt;br /&gt;
 &amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Примеры использования условия принадлежности===&lt;br /&gt;
Следующий предикат будет истинным, если в отношении S найдётся кортеж &amp;lt;code&amp;gt;(FirstName = 'Иван', LastName = 'Иванов')&amp;lt;/code&amp;gt; или, например (при наличии ещё одного атрибута), &amp;lt;code&amp;gt;(FirstName = 'Иван', LastName = 'Иванов', Email = 'ivan@example.com')&amp;lt;/code&amp;gt; и ложным, если ни в одном кортеже не совпали все значения атрибутов с перечисленными&lt;br /&gt;
&lt;br /&gt;
 S&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;FirstName = &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;, LastName = &amp;lt;font color=green&amp;gt;'Иванов'&amp;lt;/font&amp;gt;&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Имя атрибута может совпадать с именем переменной, это может поначалу немного запутывать. Слева от знака равенства стоит имя атрибута, справа - значение, с которым атрибут сравниваем&lt;br /&gt;
&lt;br /&gt;
 S&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;FirstName = FirstName, LastName = LastName&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Примеры запросов===&lt;br /&gt;
=====Идентификаторы всех студентов=====&lt;br /&gt;
Запишем запрос для получения идентификаторов всех студентов. Можно представлять это так: единственная свободная переменная SId пробегает все возможные значения из домена (все возможные идентификаторы студентов), а в результирующее отношение попадают только те её значения, для которых реально существовал такой студент.&lt;br /&gt;
&lt;br /&gt;
 SId &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; S&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;SId = SId&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Идентификаторы студентов, не сдавших курс с CId=10=====&lt;br /&gt;
Также как и в исчислении кортежей, в исчислении доменов можно использовать кванторы. Студент не сдал курс, если у него нет положительных оценок за этот курс.&lt;br /&gt;
&lt;br /&gt;
 SId &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; ¬∃Points (Points ≥ 60 ∧ Points&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;SId = SId, Points = Points, CId = 10&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
==Реляционная полнота исчисления доменов==&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Исчисление доменов реляционно полно&lt;br /&gt;
|proof=&lt;br /&gt;
Выразим базис реляционной алгебры в терминах исчисления доменов:&lt;br /&gt;
&lt;br /&gt;
'''Проекция $\pi_{A_1, ..., A_n}(R)$''' Выбираем только такие наборы значений $A_1$...$A_n$, для которых в исходном отношении есть кортеж, в котором атрибуты $A_1$...$A_n$ принимают значения $A_1$...$A_n$.&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_1$ = $A_1$, ..., $A_n$ = $A_n$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Фильтр $σ_θ(R)$'''&lt;br /&gt;
Выбираем только такие наборы значений $A_1$...$A_n$, которые есть в исходном отношении R и удовлетворяют условию θ&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_1$ = $A_1$, ..., $A_n$ = $A_n$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $θ$&lt;br /&gt;
&lt;br /&gt;
'''Переименовывание $ε_{A=expr}(R_1)$''' &lt;br /&gt;
Просто используем специальный синтаксис&lt;br /&gt;
 ..., $expr$ as $A$, ... &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R${$A_1$ = $A_1$, ..., $A_n$ = $A_n$}&lt;br /&gt;
&lt;br /&gt;
'''Объединение $R_1 ∪ R_2$'''&lt;br /&gt;
Выбираем только такие наборы значений $A_1$...$A_n$, что хотя бы в одном из отношений есть соответствующий кортеж&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∨ $R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Разность $R_1 ∖ R_2$'''&lt;br /&gt;
Выбираем только такие наборы значений $A_1$...$A_n$, что соответствующий кортеж есть в $R_1$, но нет в $R_2$&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $¬R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Декартово произведение $R_1 × R_2$'''&lt;br /&gt;
Выбираем наборы значений  $A_1$, ..., $A_n$, $B_1$, ..., $B_m$ такие, что $A_1$...$A_n$ есть в $R_1$, а $B_1$...$B_n$ есть в $R_2$&lt;br /&gt;
 $A_1$, ..., $A_n$, $B_1$, ..., $B_m$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$B_j$ = $B_j$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Естественное соединение $R_1 ⋈ R_2$''' &lt;br /&gt;
Выбираем такие наборы значений $A_1$, ..., $A_n$, $B_1$, ..., $B_m$, $C_1$, ..., $C_l$, что $B_1$, ..., $B_m$ совпадает с соответствующими атрибутами и $R_1$ и $R_2$. Это можно записать как с явной проверкой равенства этих атрибутов (тогда придётся использовать ещё m переменных), так и с неявной, как это сделано здесь.&lt;br /&gt;
 $A_1$, ..., $A_n$, $B_1$, ..., $B_m$, $C_1$, ..., $C_l$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$, $B_j$ = $B_j$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$C_k$ = $C_k$, $B_j$ = $B_j$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>5.18.184.8</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Datalog_%D0%B8_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F&amp;diff=81753</id>
		<title>Datalog и рекурсия</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Datalog_%D0%B8_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F&amp;diff=81753"/>
				<updated>2021-12-20T09:49:12Z</updated>
		
		<summary type="html">&lt;p&gt;5.18.184.8: /* Примеры запросов */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Язык Datalog==&lt;br /&gt;
Декларативный язык для запросов к базам данных на основе исчисления доменов. Разработан в 1978 году, синтаксически - подмножество языка Prolog. Широкого применения в реальных базах данных не получил, но повлиял на формирование более поздних языков для запросов, таких как SQL.&lt;br /&gt;
&lt;br /&gt;
==Синтаксис==&lt;br /&gt;
===Отношение===&lt;br /&gt;
Программа на Datalog - набор '''отношений'''. Отношение на языке Datalog определяется так: &lt;br /&gt;
 Отношение(x1,x2...xn) :- Цель.&lt;br /&gt;
Определение одного и того же отношения может повторяться несколько раз, тогда в это отношение будут входить кортежи, которые удовлетворяют хотя бы одной цели.&lt;br /&gt;
===Цель===&lt;br /&gt;
'''Цель''' в свою очередь - это набор '''атомов''', перечисленных через запятую. Кортеж удовлетворяет цели, если он удовлетворяет всем атомам цели.&lt;br /&gt;
===Атом===&lt;br /&gt;
Атомы бывают двух типов: реляционные и арифметические&lt;br /&gt;
====Реляционный====&lt;br /&gt;
Аналог конструкции условия принадлежности из исчисления доменов.&lt;br /&gt;
Есть два вида:&lt;br /&gt;
* Кортеж удовлетворяет атому &amp;lt;code&amp;gt;R(x1, x2, ..., xn)&amp;lt;/code&amp;gt; тогда и только тогда, когда принадлежит отношению R.&lt;br /&gt;
* Кортеж удовлетворяет атому &amp;lt;code&amp;gt;¬R(x1, x2, ..., xn)&amp;lt;/code&amp;gt; тогда и только тогда, когда такого кортежа нет в отношении R.&lt;br /&gt;
Заметим, что в Datalog нет имён атрибутов, атрибуты различаются только по своей позиции.&lt;br /&gt;
&lt;br /&gt;
====Арифметический====&lt;br /&gt;
Сюда входят сравнения арифмитических выражений на равенство и неравенство.&lt;br /&gt;
&lt;br /&gt;
==Примеры запросов==&lt;br /&gt;
===Идентификаторы и фамилии всех Иванов===&lt;br /&gt;
Рассмотрим такой запрос на языке исчисления доменов&lt;br /&gt;
 Id, LastName &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; Students&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;Id = Id, FirstName = &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;, LastName = LastName&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Его можно переписать на Datalog так:&lt;br /&gt;
 Ivans(Id, LastName) :-&lt;br /&gt;
     Students(Id, &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;, LastName).&lt;br /&gt;
&lt;br /&gt;
===Имена родителей===&lt;br /&gt;
Пусть есть таблица &amp;lt;code&amp;gt;Person(Id, Name, MotherId, FatherId)&amp;lt;/code&amp;gt;&lt;br /&gt;
====Получить имена обоих родителей каждого человека (Name, Father, Mother)====&lt;br /&gt;
Запишем конъюнкцию атомов: &amp;quot;FatherId - отец Name&amp;quot;, &amp;quot;MotherId - мать Name&amp;quot;, &amp;quot;Имя FatherId - FatherName&amp;quot;, &amp;quot;Имя MotherId - MotherName&amp;quot;:&lt;br /&gt;
 Parents(Name, FatherName, MotherName) :- Person(_, Name, FatherId, MotherId),&lt;br /&gt;
     Person(FatherId, FatherName, _, _), Person(MotherId, MotherName, _, _).&lt;br /&gt;
&lt;br /&gt;
====Получить для каждого человека всех его родителей (Name, Parent)====&lt;br /&gt;
Воспользуемся тем, что в Datalog при определении отношений дважды, они объёдиняются:&lt;br /&gt;
 Parents(Name, FatherName) :- Person(_, Name, FatherId, _),&lt;br /&gt;
     Person(FatherId, FatherName, _, _).&lt;br /&gt;
 Parents(Name, MotherName) :- Person(_, Name, _, MotherId),&lt;br /&gt;
     Person(MotherId, MotherName, _, _).&lt;br /&gt;
====Идентификаторы студентов не сдавших курс с CId=10====&lt;br /&gt;
На языке исчисления доменов этот запрос можно записать так:&lt;br /&gt;
 SId &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; ¬∃Points (Points ≥ 60 ∧ Points&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;SId = SId, Points = Points, CId = 10&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Перепишем его на язык Datalog. Так как в Datalog нет явных кванторов, то мы вынуждены пользоваться неявным квантором существования, который в Datalog связывает все свободные переменные цели. Над ним невозможно поставить отрицание, поэтому запишем вспомогательное отношение, в котором есть те и только те студенты, которые '''сдали курс''', затем построим отрицание.&lt;br /&gt;
 Graded(SId) :- Points(SId, Points, 10), Points &amp;gt;= 60.&lt;br /&gt;
 Failed(SId) :- Points(SId, _, _), ¬Graded(SId).&lt;br /&gt;
&lt;br /&gt;
==Ограничение отношений==&lt;br /&gt;
Как и на любую другую программу, на синтаксически корректную программу на языке Datalog нужно наложить дополнительные ограничения, чтобы она имела смысл.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим отношения&lt;br /&gt;
 Less(x,y) :- x &amp;lt; y.&lt;br /&gt;
 NotStudent(Id, Name) :- ¬Students(Id, Name, _).&lt;br /&gt;
&lt;br /&gt;
Здесь есть проблема - во-первых, мы даже не знаем тип &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Id&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;Name&amp;lt;/code&amp;gt;, это значит, что мы не знаем области их значения.&lt;br /&gt;
Во-вторых, даже если бы мы знали их тип, пусть это будут, например, целые числа, то получили бы бесконечное отношение, с такими мы работать не умеем.&lt;br /&gt;
&lt;br /&gt;
Поэтому, нужно запретить такую ситуацию, для этого добавим требование:&lt;br /&gt;
&lt;br /&gt;
'''Каждая переменная должна входить в неотрицательный реляционный атом'''&lt;br /&gt;
&lt;br /&gt;
==Реляционная полнота==&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Язык Datalog реляционно полон&lt;br /&gt;
|proof=&lt;br /&gt;
Выразим базис реляционной алгебры на языке Datalog:&lt;br /&gt;
&lt;br /&gt;
'''Проекция $\pi_{A_1, ..., A_n}(R)$''' &lt;br /&gt;
 Q(A1, ..., An) :- R(A1, ..., An, _, ..., _).&lt;br /&gt;
'''Фильтр $σ_θ(R)$'''&lt;br /&gt;
 Q(A1, ..., An) :- R(A1, ..., An), θ.&lt;br /&gt;
'''Объединение $R_1 ∪ R_2$'''&lt;br /&gt;
 Q(A1, ..., An) :- R1(A1, ..., An).&lt;br /&gt;
 Q(A1, ..., An) :- R2(A1, ..., An).&lt;br /&gt;
'''Разность $R_1 ∖ R_2$'''&lt;br /&gt;
 Q(A1, ..., An) :- R1(A1, ..., An), ¬R2(A1, ..., An).&lt;br /&gt;
'''Декартово произведение $R_1 × R_2$'''&lt;br /&gt;
 Q(A1, ..., An, B1, ..., Bm) :- &lt;br /&gt;
     R1(A1, ..., An), R2(B1, ..., Bm).&lt;br /&gt;
&lt;br /&gt;
'''Естественное соединение $R_1 ⋈ R_2$''' &lt;br /&gt;
 Q(A1, ..., An, B1, ..., Bm, C1, ..., Cl) :-&lt;br /&gt;
     R1(A1, ..., An, B1, ..., Bm), R2(B1, ..., Bm, C1, ..., Cl).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Рекурсивные запросы==&lt;br /&gt;
Синтаксис Datalog позволяет написать рекурсивный запрос, но может быть не очевидно, какой смысл придавать такой конструкции.&lt;br /&gt;
Далее будет рассмотрен пример и приведены некоторые рассуждения о семантике рекурсивных запросов.&lt;br /&gt;
===Смысл===&lt;br /&gt;
Пусть есть некоторое отношение &amp;quot;потомок-родитель&amp;quot;&lt;br /&gt;
 Parent(Id, ParentId)&lt;br /&gt;
&lt;br /&gt;
Хотим найти его транзитивное замыкание, по определению:&lt;br /&gt;
 Ancestor(Id, PId) :- Parent(Id, PId).&lt;br /&gt;
 Ancestor(Id, GId) :- Parent(Id, GId), Ancestor(PId, GId).&lt;br /&gt;
&lt;br /&gt;
Пусть $P$ - множество всех людей, у которых есть хотя бы один родитель.&lt;br /&gt;
Очевидно, что $P \times P$ есть неподвижная точка, то есть правая часть отношения совпадает с левой, но найденное отношение не является транзитивным замыканием исходного.&lt;br /&gt;
&lt;br /&gt;
Поэтому, следует уточнить, что мы ищем '''минимальную по включению неподвижную точку''', начиная с пустого множества, тогда наш запрос отработает корректно.&lt;br /&gt;
&lt;br /&gt;
===Алгоритм поиска минимальной неподвижной точки===&lt;br /&gt;
&lt;br /&gt;
 Проинициализируем отношения из нерекурсивных определений&lt;br /&gt;
 Пока не достигли неподвижной точки&lt;br /&gt;
   Пополняем отношения из рекурсивных определений&lt;br /&gt;
&lt;br /&gt;
===Циклы и отрицание===&lt;br /&gt;
&lt;br /&gt;
Представим ситуацию, когда принадлежность кортежа к отношению зависит от отрицания его принадлежности к отношению. Это в чистом виде парадокс брадобрея и мы знаем, что такая конструкция не имеет смысла.&lt;br /&gt;
&lt;br /&gt;
Поэтому, введём '''стратифицированное отрицание''', то есть запрет на отрицание в циклах.&lt;/div&gt;</summary>
		<author><name>5.18.184.8</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Datalog_%D0%B8_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F&amp;diff=81730</id>
		<title>Datalog и рекурсия</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Datalog_%D0%B8_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F&amp;diff=81730"/>
				<updated>2021-12-20T09:32:09Z</updated>
		
		<summary type="html">&lt;p&gt;5.18.184.8: /* Идентификаторы и фамилии всех Иванов */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Язык Datalog==&lt;br /&gt;
Декларативный язык для запросов к базам данных на основе исчисления доменов. Разработан в 1978 году, синтаксически - подмножество языка Prolog. Широкого применения в реальных базах данных не получил, но повлиял на формирование более поздних языков для запросов, таких как SQL.&lt;br /&gt;
&lt;br /&gt;
==Синтаксис==&lt;br /&gt;
===Отношение===&lt;br /&gt;
Программа на Datalog - набор '''отношений'''. Отношение на языке Datalog определяется так: &lt;br /&gt;
 Отношение(x1,x2...xn) :- Цель.&lt;br /&gt;
Определение одного и того же отношения может повторяться несколько раз, тогда в это отношение будут входить кортежи, которые удовлетворяют хотя бы одной цели.&lt;br /&gt;
===Цель===&lt;br /&gt;
'''Цель''' в свою очередь - это набор '''атомов''', перечисленных через запятую. Кортеж удовлетворяет цели, если он удовлетворяет всем атомам цели.&lt;br /&gt;
===Атом===&lt;br /&gt;
Атомы бывают двух типов: реляционные и арифметические&lt;br /&gt;
====Реляционный====&lt;br /&gt;
Аналог конструкции условия принадлежности из исчисления доменов.&lt;br /&gt;
Есть два вида:&lt;br /&gt;
* Кортеж удовлетворяет атому &amp;lt;code&amp;gt;R(x1, x2, ..., xn)&amp;lt;/code&amp;gt; тогда и только тогда, когда принадлежит отношению R.&lt;br /&gt;
* Кортеж удовлетворяет атому &amp;lt;code&amp;gt;¬R(x1, x2, ..., xn)&amp;lt;/code&amp;gt; тогда и только тогда, когда такого кортежа нет в отношении R.&lt;br /&gt;
Заметим, что в Datalog нет имён атрибутов, атрибуты различаются только по своей позиции.&lt;br /&gt;
&lt;br /&gt;
====Арифметический====&lt;br /&gt;
Сюда входят сравнения арифмитических выражений на равенство и неравенство.&lt;br /&gt;
&lt;br /&gt;
==Примеры запросов==&lt;br /&gt;
===Идентификаторы и фамилии всех Иванов===&lt;br /&gt;
Рассмотрим такой запрос на языке исчисления доменов&lt;br /&gt;
 Id, LastName &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; Students&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;Id = Id, FirstName = &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;, LastName = LastName&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Его можно переписать на Datalog так:&lt;br /&gt;
 Ivans(Id, LastName) :-&lt;br /&gt;
     Students(Id, &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;, LastName).&lt;br /&gt;
&lt;br /&gt;
===Имена родителей===&lt;br /&gt;
Пусть есть таблица &amp;lt;code&amp;gt;Person(Id, Name, MotherId, FatherId)&amp;lt;/code&amp;gt;&lt;br /&gt;
====Получить имена обоих родителей каждого человека (Name, Father, Mother)====&lt;br /&gt;
Запишем конъюнкцию атомов: &amp;quot;FatherId - отец Name&amp;quot;, &amp;quot;MotherId - мать Name&amp;quot;, &amp;quot;Имя FatherId - FatherName&amp;quot;, &amp;quot;Имя MotherId - MotherName&amp;quot;:&lt;br /&gt;
 Parents(Name, FatherName, MotherName) :- Person(_, Name, FatherId, MotherId),&lt;br /&gt;
     Person(FatherId, FatherName, _, _), Person(MotherId, MotherName, _, _).&lt;br /&gt;
&lt;br /&gt;
====Получить для каждого человека всех его родителей (Name, Parent)====&lt;br /&gt;
Воспользуемся тем, что в Datalog при определении отношений дважды, они объёдиняются:&lt;br /&gt;
 Parents(Name, FatherName) :- Person(_, Name, FatherId, _),&lt;br /&gt;
     Person(FatherId, FatherName, _, _).&lt;br /&gt;
 Parents(Name, MotherName) :- Person(_, Name, _, MotherId),&lt;br /&gt;
     Person(MotherId, MotherName, _, _).&lt;br /&gt;
&lt;br /&gt;
==Ограничение отношений==&lt;br /&gt;
Как и на любую другую программу, на синтаксически корректную программу на языке Datalog нужно наложить дополнительные ограничения, чтобы она имела смысл.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим отношения&lt;br /&gt;
 Less(x,y) :- x &amp;lt; y.&lt;br /&gt;
 NotStudent(Id, Name) :- ¬Students(Id, Name, _).&lt;br /&gt;
&lt;br /&gt;
Здесь есть проблема - во-первых, мы даже не знаем тип &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Id&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;Name&amp;lt;/code&amp;gt;, это значит, что мы не знаем области их значения.&lt;br /&gt;
Во-вторых, даже если бы мы знали их тип, пусть это будут, например, целые числа, то получили бы бесконечное отношение, с такими мы работать не умеем.&lt;br /&gt;
&lt;br /&gt;
Поэтому, нужно запретить такую ситуацию, для этого добавим требование:&lt;br /&gt;
&lt;br /&gt;
'''Каждая переменная должна входить в неотрицательный реляционный атом'''&lt;br /&gt;
&lt;br /&gt;
==Реляционная полнота==&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Язык Datalog реляционно полон&lt;br /&gt;
|proof=&lt;br /&gt;
Выразим базис реляционной алгебры на языке Datalog:&lt;br /&gt;
&lt;br /&gt;
'''Проекция $\pi_{A_1, ..., A_n}(R)$''' &lt;br /&gt;
 Q(A1, ..., An) :- R(A1, ..., An, _, ..., _).&lt;br /&gt;
'''Фильтр $σ_θ(R)$'''&lt;br /&gt;
 Q(A1, ..., An) :- R(A1, ..., An), θ.&lt;br /&gt;
'''Объединение $R_1 ∪ R_2$'''&lt;br /&gt;
 Q(A1, ..., An) :- R1(A1, ..., An).&lt;br /&gt;
 Q(A1, ..., An) :- R2(A1, ..., An).&lt;br /&gt;
'''Разность $R_1 ∖ R_2$'''&lt;br /&gt;
 Q(A1, ..., An) :- R1(A1, ..., An), ¬R2(A1, ..., An).&lt;br /&gt;
'''Декартово произведение $R_1 × R_2$'''&lt;br /&gt;
 Q(A1, ..., An, B1, ..., Bm) :- &lt;br /&gt;
     R1(A1, ..., An), R2(B1, ..., Bm).&lt;br /&gt;
&lt;br /&gt;
'''Естественное соединение $R_1 ⋈ R_2$''' &lt;br /&gt;
 Q(A1, ..., An, B1, ..., Bm, C1, ..., Cl) :-&lt;br /&gt;
     R1(A1, ..., An, B1, ..., Bm), R2(B1, ..., Bm, C1, ..., Cl).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Рекурсивные запросы==&lt;br /&gt;
Синтаксис Datalog позволяет написать рекурсивный запрос, но может быть не очевидно, какой смысл придавать такой конструкции.&lt;br /&gt;
Далее будет рассмотрен пример и приведены некоторые рассуждения о семантике рекурсивных запросов.&lt;br /&gt;
===Смысл===&lt;br /&gt;
Пусть есть некоторое отношение &amp;quot;потомок-родитель&amp;quot;&lt;br /&gt;
 Parent(Id, ParentId)&lt;br /&gt;
&lt;br /&gt;
Хотим найти его транзитивное замыкание, по определению:&lt;br /&gt;
 Ancestor(Id, PId) :- Parent(Id, PId).&lt;br /&gt;
 Ancestor(Id, GId) :- Parent(Id, GId), Ancestor(PId, GId).&lt;br /&gt;
&lt;br /&gt;
Пусть $P$ - множество всех людей, у которых есть хотя бы один родитель.&lt;br /&gt;
Очевидно, что $P \times P$ есть неподвижная точка, то есть правая часть отношения совпадает с левой, но найденное отношение не является транзитивным замыканием исходного.&lt;br /&gt;
&lt;br /&gt;
Поэтому, следует уточнить, что мы ищем '''минимальную по включению неподвижную точку''', начиная с пустого множества, тогда наш запрос отработает корректно.&lt;br /&gt;
&lt;br /&gt;
===Алгоритм поиска минимальной неподвижной точки===&lt;br /&gt;
&lt;br /&gt;
 Проинициализируем отношения из нерекурсивных определений&lt;br /&gt;
 Пока не достигли неподвижной точки&lt;br /&gt;
   Пополняем отношения из рекурсивных определений&lt;br /&gt;
&lt;br /&gt;
===Циклы и отрицание===&lt;br /&gt;
&lt;br /&gt;
Представим ситуацию, когда принадлежность кортежа к отношению зависит от отрицания его принадлежности к отношению. Это в чистом виде парадокс брадобрея и мы знаем, что такая конструкция не имеет смысла.&lt;br /&gt;
&lt;br /&gt;
Поэтому, введём '''стратифицированное отрицание''', то есть запрет на отрицание в циклах.&lt;/div&gt;</summary>
		<author><name>5.18.184.8</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Datalog_%D0%B8_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F&amp;diff=81717</id>
		<title>Datalog и рекурсия</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Datalog_%D0%B8_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F&amp;diff=81717"/>
				<updated>2021-12-20T09:15:22Z</updated>
		
		<summary type="html">&lt;p&gt;5.18.184.8: /* Реляционный */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Язык Datalog==&lt;br /&gt;
Декларативный язык для запросов к базам данных на основе исчисления доменов. Разработан в 1978 году, синтаксически - подмножество языка Prolog. Широкого применения в реальных базах данных не получил, но повлиял на формирование более поздних языков для запросов, таких как SQL.&lt;br /&gt;
&lt;br /&gt;
==Синтаксис==&lt;br /&gt;
===Отношение===&lt;br /&gt;
Программа на Datalog - набор '''отношений'''. Отношение на языке Datalog определяется так: &lt;br /&gt;
 Отношение(x1,x2...xn) :- Цель.&lt;br /&gt;
Определение одного и того же отношения может повторяться несколько раз, тогда в это отношение будут входить кортежи, которые удовлетворяют хотя бы одной цели.&lt;br /&gt;
===Цель===&lt;br /&gt;
'''Цель''' в свою очередь - это набор '''атомов''', перечисленных через запятую. Кортеж удовлетворяет цели, если он удовлетворяет всем атомам цели.&lt;br /&gt;
===Атом===&lt;br /&gt;
Атомы бывают двух типов: реляционные и арифметические&lt;br /&gt;
====Реляционный====&lt;br /&gt;
Аналог конструкции условия принадлежности из исчисления доменов.&lt;br /&gt;
Есть два вида:&lt;br /&gt;
* Кортеж удовлетворяет атому &amp;lt;code&amp;gt;R(x1, x2, ..., xn)&amp;lt;/code&amp;gt; тогда и только тогда, когда принадлежит отношению R.&lt;br /&gt;
* Кортеж удовлетворяет атому &amp;lt;code&amp;gt;¬R(x1, x2, ..., xn)&amp;lt;/code&amp;gt; тогда и только тогда, когда такого кортежа нет в отношении R.&lt;br /&gt;
Заметим, что в Datalog нет имён атрибутов, атрибуты различаются только по своей позиции.&lt;br /&gt;
&lt;br /&gt;
====Арифметический====&lt;br /&gt;
Сюда входят сравнения арифмитических выражений на равенство и неравенство.&lt;br /&gt;
&lt;br /&gt;
==Примеры запросов==&lt;br /&gt;
===Идентификаторы и фамилии всех Иванов===&lt;br /&gt;
Рассмотрим такой запрос на языке исчисления доменов&lt;br /&gt;
 Id, LastName &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; Students&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;Id = Id, FirstName = FirstName, LastName = LastName&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; $\wedge$ FirstName = &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Его можно переписать на Datalog так:&lt;br /&gt;
 Ivans(Id, LastName) :-&lt;br /&gt;
     Students(Id, FirstName, LastName),&lt;br /&gt;
     FirstName = &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Или ещё проще:&lt;br /&gt;
 Ivans(Id, LastName) :-&lt;br /&gt;
     Students(Id, &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;, LastName).&lt;br /&gt;
===Имена родителей===&lt;br /&gt;
Пусть есть таблица &amp;lt;code&amp;gt;Person(Id, Name, MotherId, FatherId)&amp;lt;/code&amp;gt;&lt;br /&gt;
====Получить имена обоих родителей каждого человека (Name, Father, Mother)====&lt;br /&gt;
Запишем конъюнкцию атомов: &amp;quot;FatherId - отец Name&amp;quot;, &amp;quot;MotherId - мать Name&amp;quot;, &amp;quot;Имя FatherId - FatherName&amp;quot;, &amp;quot;Имя MotherId - MotherName&amp;quot;:&lt;br /&gt;
 Parents(Name, FatherName, MotherName) :- Person(_, Name, FatherId, MotherId),&lt;br /&gt;
     Person(FatherId, FatherName, _, _), Person(MotherId, MotherName, _, _).&lt;br /&gt;
&lt;br /&gt;
====Получить для каждого человека всех его родителей (Name, Parent)====&lt;br /&gt;
Воспользуемся тем, что в Datalog при определении отношений дважды, они объёдиняются:&lt;br /&gt;
 Parents(Name, FatherName) :- Person(_, Name, FatherId, _),&lt;br /&gt;
     Person(FatherId, FatherName, _, _).&lt;br /&gt;
 Parents(Name, MotherName) :- Person(_, Name, _, MotherId),&lt;br /&gt;
     Person(MotherId, MotherName, _, _).&lt;br /&gt;
&lt;br /&gt;
==Ограничение отношений==&lt;br /&gt;
Как и на любую другую программу, на синтаксически корректную программу на языке Datalog нужно наложить дополнительные ограничения, чтобы она имела смысл.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим отношения&lt;br /&gt;
 Less(x,y) :- x &amp;lt; y.&lt;br /&gt;
 NotStudent(Id, Name) :- ¬Students(Id, Name, _).&lt;br /&gt;
&lt;br /&gt;
Здесь есть проблема - во-первых, мы даже не знаем тип &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Id&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;Name&amp;lt;/code&amp;gt;, это значит, что мы не знаем области их значения.&lt;br /&gt;
Во-вторых, даже если бы мы знали их тип, пусть это будут, например, целые числа, то получили бы бесконечное отношение, с такими мы работать не умеем.&lt;br /&gt;
&lt;br /&gt;
Поэтому, нужно запретить такую ситуацию, для этого добавим требование:&lt;br /&gt;
&lt;br /&gt;
'''Каждая переменная должна входить в неотрицательный реляционный атом'''&lt;br /&gt;
&lt;br /&gt;
==Реляционная полнота==&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Язык Datalog реляционно полон&lt;br /&gt;
|proof=&lt;br /&gt;
Выразим базис реляционной алгебры на языке Datalog:&lt;br /&gt;
&lt;br /&gt;
'''Проекция $\pi_{A_1, ..., A_n}(R)$''' &lt;br /&gt;
 Q(A1, ..., An) :- R(A1, ..., An, _, ..., _).&lt;br /&gt;
'''Фильтр $σ_θ(R)$'''&lt;br /&gt;
 Q(A1, ..., An) :- R(A1, ..., An), θ.&lt;br /&gt;
'''Объединение $R_1 ∪ R_2$'''&lt;br /&gt;
 Q(A1, ..., An) :- R1(A1, ..., An).&lt;br /&gt;
 Q(A1, ..., An) :- R2(A1, ..., An).&lt;br /&gt;
'''Разность $R_1 ∖ R_2$'''&lt;br /&gt;
 Q(A1, ..., An) :- R1(A1, ..., An), ¬R2(A1, ..., An).&lt;br /&gt;
'''Декартово произведение $R_1 × R_2$'''&lt;br /&gt;
 Q(A1, ..., An, B1, ..., Bm) :- &lt;br /&gt;
     R1(A1, ..., An), R2(B1, ..., Bm).&lt;br /&gt;
&lt;br /&gt;
'''Естественное соединение $R_1 ⋈ R_2$''' &lt;br /&gt;
 Q(A1, ..., An, B1, ..., Bm, C1, ..., Cl) :-&lt;br /&gt;
     R1(A1, ..., An, B1, ..., Bm), R2(B1, ..., Bm, C1, ..., Cl).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Рекурсивные запросы==&lt;br /&gt;
Синтаксис Datalog позволяет написать рекурсивный запрос, но может быть не очевидно, какой смысл придавать такой конструкции.&lt;br /&gt;
Далее будет рассмотрен пример и приведены некоторые рассуждения о семантике рекурсивных запросов.&lt;br /&gt;
===Смысл===&lt;br /&gt;
Пусть есть некоторое отношение &amp;quot;потомок-родитель&amp;quot;&lt;br /&gt;
 Parent(Id, ParentId)&lt;br /&gt;
&lt;br /&gt;
Хотим найти его транзитивное замыкание, по определению:&lt;br /&gt;
 Ancestor(Id, PId) :- Parent(Id, PId).&lt;br /&gt;
 Ancestor(Id, GId) :- Parent(Id, GId), Ancestor(PId, GId).&lt;br /&gt;
&lt;br /&gt;
Пусть $P$ - множество всех людей, у которых есть хотя бы один родитель.&lt;br /&gt;
Очевидно, что $P \times P$ есть неподвижная точка, то есть правая часть отношения совпадает с левой, но найденное отношение не является транзитивным замыканием исходного.&lt;br /&gt;
&lt;br /&gt;
Поэтому, следует уточнить, что мы ищем '''минимальную по включению неподвижную точку''', начиная с пустого множества, тогда наш запрос отработает корректно.&lt;br /&gt;
&lt;br /&gt;
===Алгоритм поиска минимальной неподвижной точки===&lt;br /&gt;
&lt;br /&gt;
 Проинициализируем отношения из нерекурсивных определений&lt;br /&gt;
 Пока не достигли неподвижной точки&lt;br /&gt;
   Пополняем отношения из рекурсивных определений&lt;br /&gt;
&lt;br /&gt;
===Циклы и отрицание===&lt;br /&gt;
&lt;br /&gt;
Представим ситуацию, когда принадлежность кортежа к отношению зависит от отрицания его принадлежности к отношению. Это в чистом виде парадокс брадобрея и мы знаем, что такая конструкция не имеет смысла.&lt;br /&gt;
&lt;br /&gt;
Поэтому, введём '''стратифицированное отрицание''', то есть запрет на отрицание в циклах.&lt;/div&gt;</summary>
		<author><name>5.18.184.8</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Datalog_%D0%B8_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F&amp;diff=81716</id>
		<title>Datalog и рекурсия</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Datalog_%D0%B8_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F&amp;diff=81716"/>
				<updated>2021-12-20T09:15:09Z</updated>
		
		<summary type="html">&lt;p&gt;5.18.184.8: /* Реляционный */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Язык Datalog==&lt;br /&gt;
Декларативный язык для запросов к базам данных на основе исчисления доменов. Разработан в 1978 году, синтаксически - подмножество языка Prolog. Широкого применения в реальных базах данных не получил, но повлиял на формирование более поздних языков для запросов, таких как SQL.&lt;br /&gt;
&lt;br /&gt;
==Синтаксис==&lt;br /&gt;
===Отношение===&lt;br /&gt;
Программа на Datalog - набор '''отношений'''. Отношение на языке Datalog определяется так: &lt;br /&gt;
 Отношение(x1,x2...xn) :- Цель.&lt;br /&gt;
Определение одного и того же отношения может повторяться несколько раз, тогда в это отношение будут входить кортежи, которые удовлетворяют хотя бы одной цели.&lt;br /&gt;
===Цель===&lt;br /&gt;
'''Цель''' в свою очередь - это набор '''атомов''', перечисленных через запятую. Кортеж удовлетворяет цели, если он удовлетворяет всем атомам цели.&lt;br /&gt;
===Атом===&lt;br /&gt;
Атомы бывают двух типов: реляционные и арифметические&lt;br /&gt;
====Реляционный====&lt;br /&gt;
Аналог конструкции условия принадлежности из исчисления доменов.&lt;br /&gt;
Есть два вида:&lt;br /&gt;
* Кортеж удовлетворяет атому &amp;lt;code&amp;gt;R(x1, x2, ..., xn)&amp;lt;/code&amp;gt; тогда и только тогда, когда принадлежит отношению R.&lt;br /&gt;
* Кортеж удовлетворяет атому code&amp;gt;¬R(x1, x2, ..., xn)&amp;lt;/code&amp;gt; тогда и только тогда, когда такого кортежа нет в отношении R.&lt;br /&gt;
Заметим, что в Datalog нет имён атрибутов, атрибуты различаются только по своей позиции.&lt;br /&gt;
&lt;br /&gt;
====Арифметический====&lt;br /&gt;
Сюда входят сравнения арифмитических выражений на равенство и неравенство.&lt;br /&gt;
&lt;br /&gt;
==Примеры запросов==&lt;br /&gt;
===Идентификаторы и фамилии всех Иванов===&lt;br /&gt;
Рассмотрим такой запрос на языке исчисления доменов&lt;br /&gt;
 Id, LastName &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; Students&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;Id = Id, FirstName = FirstName, LastName = LastName&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; $\wedge$ FirstName = &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Его можно переписать на Datalog так:&lt;br /&gt;
 Ivans(Id, LastName) :-&lt;br /&gt;
     Students(Id, FirstName, LastName),&lt;br /&gt;
     FirstName = &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Или ещё проще:&lt;br /&gt;
 Ivans(Id, LastName) :-&lt;br /&gt;
     Students(Id, &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;, LastName).&lt;br /&gt;
===Имена родителей===&lt;br /&gt;
Пусть есть таблица &amp;lt;code&amp;gt;Person(Id, Name, MotherId, FatherId)&amp;lt;/code&amp;gt;&lt;br /&gt;
====Получить имена обоих родителей каждого человека (Name, Father, Mother)====&lt;br /&gt;
Запишем конъюнкцию атомов: &amp;quot;FatherId - отец Name&amp;quot;, &amp;quot;MotherId - мать Name&amp;quot;, &amp;quot;Имя FatherId - FatherName&amp;quot;, &amp;quot;Имя MotherId - MotherName&amp;quot;:&lt;br /&gt;
 Parents(Name, FatherName, MotherName) :- Person(_, Name, FatherId, MotherId),&lt;br /&gt;
     Person(FatherId, FatherName, _, _), Person(MotherId, MotherName, _, _).&lt;br /&gt;
&lt;br /&gt;
====Получить для каждого человека всех его родителей (Name, Parent)====&lt;br /&gt;
Воспользуемся тем, что в Datalog при определении отношений дважды, они объёдиняются:&lt;br /&gt;
 Parents(Name, FatherName) :- Person(_, Name, FatherId, _),&lt;br /&gt;
     Person(FatherId, FatherName, _, _).&lt;br /&gt;
 Parents(Name, MotherName) :- Person(_, Name, _, MotherId),&lt;br /&gt;
     Person(MotherId, MotherName, _, _).&lt;br /&gt;
&lt;br /&gt;
==Ограничение отношений==&lt;br /&gt;
Как и на любую другую программу, на синтаксически корректную программу на языке Datalog нужно наложить дополнительные ограничения, чтобы она имела смысл.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим отношения&lt;br /&gt;
 Less(x,y) :- x &amp;lt; y.&lt;br /&gt;
 NotStudent(Id, Name) :- ¬Students(Id, Name, _).&lt;br /&gt;
&lt;br /&gt;
Здесь есть проблема - во-первых, мы даже не знаем тип &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Id&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;Name&amp;lt;/code&amp;gt;, это значит, что мы не знаем области их значения.&lt;br /&gt;
Во-вторых, даже если бы мы знали их тип, пусть это будут, например, целые числа, то получили бы бесконечное отношение, с такими мы работать не умеем.&lt;br /&gt;
&lt;br /&gt;
Поэтому, нужно запретить такую ситуацию, для этого добавим требование:&lt;br /&gt;
&lt;br /&gt;
'''Каждая переменная должна входить в неотрицательный реляционный атом'''&lt;br /&gt;
&lt;br /&gt;
==Реляционная полнота==&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Язык Datalog реляционно полон&lt;br /&gt;
|proof=&lt;br /&gt;
Выразим базис реляционной алгебры на языке Datalog:&lt;br /&gt;
&lt;br /&gt;
'''Проекция $\pi_{A_1, ..., A_n}(R)$''' &lt;br /&gt;
 Q(A1, ..., An) :- R(A1, ..., An, _, ..., _).&lt;br /&gt;
'''Фильтр $σ_θ(R)$'''&lt;br /&gt;
 Q(A1, ..., An) :- R(A1, ..., An), θ.&lt;br /&gt;
'''Объединение $R_1 ∪ R_2$'''&lt;br /&gt;
 Q(A1, ..., An) :- R1(A1, ..., An).&lt;br /&gt;
 Q(A1, ..., An) :- R2(A1, ..., An).&lt;br /&gt;
'''Разность $R_1 ∖ R_2$'''&lt;br /&gt;
 Q(A1, ..., An) :- R1(A1, ..., An), ¬R2(A1, ..., An).&lt;br /&gt;
'''Декартово произведение $R_1 × R_2$'''&lt;br /&gt;
 Q(A1, ..., An, B1, ..., Bm) :- &lt;br /&gt;
     R1(A1, ..., An), R2(B1, ..., Bm).&lt;br /&gt;
&lt;br /&gt;
'''Естественное соединение $R_1 ⋈ R_2$''' &lt;br /&gt;
 Q(A1, ..., An, B1, ..., Bm, C1, ..., Cl) :-&lt;br /&gt;
     R1(A1, ..., An, B1, ..., Bm), R2(B1, ..., Bm, C1, ..., Cl).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Рекурсивные запросы==&lt;br /&gt;
Синтаксис Datalog позволяет написать рекурсивный запрос, но может быть не очевидно, какой смысл придавать такой конструкции.&lt;br /&gt;
Далее будет рассмотрен пример и приведены некоторые рассуждения о семантике рекурсивных запросов.&lt;br /&gt;
===Смысл===&lt;br /&gt;
Пусть есть некоторое отношение &amp;quot;потомок-родитель&amp;quot;&lt;br /&gt;
 Parent(Id, ParentId)&lt;br /&gt;
&lt;br /&gt;
Хотим найти его транзитивное замыкание, по определению:&lt;br /&gt;
 Ancestor(Id, PId) :- Parent(Id, PId).&lt;br /&gt;
 Ancestor(Id, GId) :- Parent(Id, GId), Ancestor(PId, GId).&lt;br /&gt;
&lt;br /&gt;
Пусть $P$ - множество всех людей, у которых есть хотя бы один родитель.&lt;br /&gt;
Очевидно, что $P \times P$ есть неподвижная точка, то есть правая часть отношения совпадает с левой, но найденное отношение не является транзитивным замыканием исходного.&lt;br /&gt;
&lt;br /&gt;
Поэтому, следует уточнить, что мы ищем '''минимальную по включению неподвижную точку''', начиная с пустого множества, тогда наш запрос отработает корректно.&lt;br /&gt;
&lt;br /&gt;
===Алгоритм поиска минимальной неподвижной точки===&lt;br /&gt;
&lt;br /&gt;
 Проинициализируем отношения из нерекурсивных определений&lt;br /&gt;
 Пока не достигли неподвижной точки&lt;br /&gt;
   Пополняем отношения из рекурсивных определений&lt;br /&gt;
&lt;br /&gt;
===Циклы и отрицание===&lt;br /&gt;
&lt;br /&gt;
Представим ситуацию, когда принадлежность кортежа к отношению зависит от отрицания его принадлежности к отношению. Это в чистом виде парадокс брадобрея и мы знаем, что такая конструкция не имеет смысла.&lt;br /&gt;
&lt;br /&gt;
Поэтому, введём '''стратифицированное отрицание''', то есть запрет на отрицание в циклах.&lt;/div&gt;</summary>
		<author><name>5.18.184.8</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Datalog_%D0%B8_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F&amp;diff=81715</id>
		<title>Datalog и рекурсия</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Datalog_%D0%B8_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F&amp;diff=81715"/>
				<updated>2021-12-20T09:08:09Z</updated>
		
		<summary type="html">&lt;p&gt;5.18.184.8: /* Получить для каждого человека всех его родителей (Name, Parent) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Язык Datalog==&lt;br /&gt;
Декларативный язык для запросов к базам данных на основе исчисления доменов. Разработан в 1978 году, синтаксически - подмножество языка Prolog. Широкого применения в реальных базах данных не получил, но повлиял на формирование более поздних языков для запросов, таких как SQL.&lt;br /&gt;
&lt;br /&gt;
==Синтаксис==&lt;br /&gt;
===Отношение===&lt;br /&gt;
Программа на Datalog - набор '''отношений'''. Отношение на языке Datalog определяется так: &lt;br /&gt;
 Отношение(x1,x2...xn) :- Цель.&lt;br /&gt;
Определение одного и того же отношения может повторяться несколько раз, тогда в это отношение будут входить кортежи, которые удовлетворяют хотя бы одной цели.&lt;br /&gt;
===Цель===&lt;br /&gt;
'''Цель''' в свою очередь - это набор '''атомов''', перечисленных через запятую. Кортеж удовлетворяет цели, если он удовлетворяет всем атомам цели.&lt;br /&gt;
===Атом===&lt;br /&gt;
Атомы бывают двух типов: реляционные и арифметические&lt;br /&gt;
====Реляционный====&lt;br /&gt;
Аналог конструкции условия принадлежности из исчисления доменов.&lt;br /&gt;
Есть два вида:&lt;br /&gt;
* Кортеж принадлежит отношению &amp;lt;code&amp;gt;R(x1, x2, ..., xn)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Кортеж не принадлежит отношению &amp;lt;code&amp;gt;¬R(x1, x2, ..., xn)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что в Datalog нет имён атрибутов, атрибуты различаются только по своей позиции.&lt;br /&gt;
&lt;br /&gt;
====Арифметический====&lt;br /&gt;
Сюда входят сравнения арифмитических выражений на равенство и неравенство.&lt;br /&gt;
&lt;br /&gt;
==Примеры запросов==&lt;br /&gt;
===Идентификаторы и фамилии всех Иванов===&lt;br /&gt;
Рассмотрим такой запрос на языке исчисления доменов&lt;br /&gt;
 Id, LastName &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; Students&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;Id = Id, FirstName = FirstName, LastName = LastName&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; $\wedge$ FirstName = &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Его можно переписать на Datalog так:&lt;br /&gt;
 Ivans(Id, LastName) :-&lt;br /&gt;
     Students(Id, FirstName, LastName),&lt;br /&gt;
     FirstName = &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Или ещё проще:&lt;br /&gt;
 Ivans(Id, LastName) :-&lt;br /&gt;
     Students(Id, &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;, LastName).&lt;br /&gt;
===Имена родителей===&lt;br /&gt;
Пусть есть таблица &amp;lt;code&amp;gt;Person(Id, Name, MotherId, FatherId)&amp;lt;/code&amp;gt;&lt;br /&gt;
====Получить имена обоих родителей каждого человека (Name, Father, Mother)====&lt;br /&gt;
Запишем конъюнкцию атомов: &amp;quot;FatherId - отец Name&amp;quot;, &amp;quot;MotherId - мать Name&amp;quot;, &amp;quot;Имя FatherId - FatherName&amp;quot;, &amp;quot;Имя MotherId - MotherName&amp;quot;:&lt;br /&gt;
 Parents(Name, FatherName, MotherName) :- Person(_, Name, FatherId, MotherId),&lt;br /&gt;
     Person(FatherId, FatherName, _, _), Person(MotherId, MotherName, _, _).&lt;br /&gt;
&lt;br /&gt;
====Получить для каждого человека всех его родителей (Name, Parent)====&lt;br /&gt;
Воспользуемся тем, что в Datalog при определении отношений дважды, они объёдиняются:&lt;br /&gt;
 Parents(Name, FatherName) :- Person(_, Name, FatherId, _),&lt;br /&gt;
     Person(FatherId, FatherName, _, _).&lt;br /&gt;
 Parents(Name, MotherName) :- Person(_, Name, _, MotherId),&lt;br /&gt;
     Person(MotherId, MotherName, _, _).&lt;br /&gt;
&lt;br /&gt;
==Ограничение отношений==&lt;br /&gt;
Как и на любую другую программу, на синтаксически корректную программу на языке Datalog нужно наложить дополнительные ограничения, чтобы она имела смысл.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим отношения&lt;br /&gt;
 Less(x,y) :- x &amp;lt; y.&lt;br /&gt;
 NotStudent(Id, Name) :- ¬Students(Id, Name, _).&lt;br /&gt;
&lt;br /&gt;
Здесь есть проблема - во-первых, мы даже не знаем тип &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Id&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;Name&amp;lt;/code&amp;gt;, это значит, что мы не знаем области их значения.&lt;br /&gt;
Во-вторых, даже если бы мы знали их тип, пусть это будут, например, целые числа, то получили бы бесконечное отношение, с такими мы работать не умеем.&lt;br /&gt;
&lt;br /&gt;
Поэтому, нужно запретить такую ситуацию, для этого добавим требование:&lt;br /&gt;
&lt;br /&gt;
'''Каждая переменная должна входить в неотрицательный реляционный атом'''&lt;br /&gt;
&lt;br /&gt;
==Реляционная полнота==&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Язык Datalog реляционно полон&lt;br /&gt;
|proof=&lt;br /&gt;
Выразим базис реляционной алгебры на языке Datalog:&lt;br /&gt;
&lt;br /&gt;
'''Проекция $\pi_{A_1, ..., A_n}(R)$''' &lt;br /&gt;
 Q(A1, ..., An) :- R(A1, ..., An, _, ..., _).&lt;br /&gt;
'''Фильтр $σ_θ(R)$'''&lt;br /&gt;
 Q(A1, ..., An) :- R(A1, ..., An), θ.&lt;br /&gt;
'''Объединение $R_1 ∪ R_2$'''&lt;br /&gt;
 Q(A1, ..., An) :- R1(A1, ..., An).&lt;br /&gt;
 Q(A1, ..., An) :- R2(A1, ..., An).&lt;br /&gt;
'''Разность $R_1 ∖ R_2$'''&lt;br /&gt;
 Q(A1, ..., An) :- R1(A1, ..., An), ¬R2(A1, ..., An).&lt;br /&gt;
'''Декартово произведение $R_1 × R_2$'''&lt;br /&gt;
 Q(A1, ..., An, B1, ..., Bm) :- &lt;br /&gt;
     R1(A1, ..., An), R2(B1, ..., Bm).&lt;br /&gt;
&lt;br /&gt;
'''Естественное соединение $R_1 ⋈ R_2$''' &lt;br /&gt;
 Q(A1, ..., An, B1, ..., Bm, C1, ..., Cl) :-&lt;br /&gt;
     R1(A1, ..., An, B1, ..., Bm), R2(B1, ..., Bm, C1, ..., Cl).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Рекурсивные запросы==&lt;br /&gt;
Синтаксис Datalog позволяет написать рекурсивный запрос, но может быть не очевидно, какой смысл придавать такой конструкции.&lt;br /&gt;
Далее будет рассмотрен пример и приведены некоторые рассуждения о семантике рекурсивных запросов.&lt;br /&gt;
===Смысл===&lt;br /&gt;
Пусть есть некоторое отношение &amp;quot;потомок-родитель&amp;quot;&lt;br /&gt;
 Parent(Id, ParentId)&lt;br /&gt;
&lt;br /&gt;
Хотим найти его транзитивное замыкание, по определению:&lt;br /&gt;
 Ancestor(Id, PId) :- Parent(Id, PId).&lt;br /&gt;
 Ancestor(Id, GId) :- Parent(Id, GId), Ancestor(PId, GId).&lt;br /&gt;
&lt;br /&gt;
Пусть $P$ - множество всех людей, у которых есть хотя бы один родитель.&lt;br /&gt;
Очевидно, что $P \times P$ есть неподвижная точка, то есть правая часть отношения совпадает с левой, но найденное отношение не является транзитивным замыканием исходного.&lt;br /&gt;
&lt;br /&gt;
Поэтому, следует уточнить, что мы ищем '''минимальную по включению неподвижную точку''', начиная с пустого множества, тогда наш запрос отработает корректно.&lt;br /&gt;
&lt;br /&gt;
===Алгоритм поиска минимальной неподвижной точки===&lt;br /&gt;
&lt;br /&gt;
 Проинициализируем отношения из нерекурсивных определений&lt;br /&gt;
 Пока не достигли неподвижной точки&lt;br /&gt;
   Пополняем отношения из рекурсивных определений&lt;br /&gt;
&lt;br /&gt;
===Циклы и отрицание===&lt;br /&gt;
&lt;br /&gt;
Представим ситуацию, когда принадлежность кортежа к отношению зависит от отрицания его принадлежности к отношению. Это в чистом виде парадокс брадобрея и мы знаем, что такая конструкция не имеет смысла.&lt;br /&gt;
&lt;br /&gt;
Поэтому, введём '''стратифицированное отрицание''', то есть запрет на отрицание в циклах.&lt;/div&gt;</summary>
		<author><name>5.18.184.8</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Datalog_%D0%B8_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F&amp;diff=81713</id>
		<title>Datalog и рекурсия</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Datalog_%D0%B8_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F&amp;diff=81713"/>
				<updated>2021-12-20T09:07:08Z</updated>
		
		<summary type="html">&lt;p&gt;5.18.184.8: /* Получить имена обоих родителей каждого человека (Name, Father, Mother) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Язык Datalog==&lt;br /&gt;
Декларативный язык для запросов к базам данных на основе исчисления доменов. Разработан в 1978 году, синтаксически - подмножество языка Prolog. Широкого применения в реальных базах данных не получил, но повлиял на формирование более поздних языков для запросов, таких как SQL.&lt;br /&gt;
&lt;br /&gt;
==Синтаксис==&lt;br /&gt;
===Отношение===&lt;br /&gt;
Программа на Datalog - набор '''отношений'''. Отношение на языке Datalog определяется так: &lt;br /&gt;
 Отношение(x1,x2...xn) :- Цель.&lt;br /&gt;
Определение одного и того же отношения может повторяться несколько раз, тогда в это отношение будут входить кортежи, которые удовлетворяют хотя бы одной цели.&lt;br /&gt;
===Цель===&lt;br /&gt;
'''Цель''' в свою очередь - это набор '''атомов''', перечисленных через запятую. Кортеж удовлетворяет цели, если он удовлетворяет всем атомам цели.&lt;br /&gt;
===Атом===&lt;br /&gt;
Атомы бывают двух типов: реляционные и арифметические&lt;br /&gt;
====Реляционный====&lt;br /&gt;
Аналог конструкции условия принадлежности из исчисления доменов.&lt;br /&gt;
Есть два вида:&lt;br /&gt;
* Кортеж принадлежит отношению &amp;lt;code&amp;gt;R(x1, x2, ..., xn)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Кортеж не принадлежит отношению &amp;lt;code&amp;gt;¬R(x1, x2, ..., xn)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что в Datalog нет имён атрибутов, атрибуты различаются только по своей позиции.&lt;br /&gt;
&lt;br /&gt;
====Арифметический====&lt;br /&gt;
Сюда входят сравнения арифмитических выражений на равенство и неравенство.&lt;br /&gt;
&lt;br /&gt;
==Примеры запросов==&lt;br /&gt;
===Идентификаторы и фамилии всех Иванов===&lt;br /&gt;
Рассмотрим такой запрос на языке исчисления доменов&lt;br /&gt;
 Id, LastName &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; Students&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;Id = Id, FirstName = FirstName, LastName = LastName&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; $\wedge$ FirstName = &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Его можно переписать на Datalog так:&lt;br /&gt;
 Ivans(Id, LastName) :-&lt;br /&gt;
     Students(Id, FirstName, LastName),&lt;br /&gt;
     FirstName = &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Или ещё проще:&lt;br /&gt;
 Ivans(Id, LastName) :-&lt;br /&gt;
     Students(Id, &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;, LastName).&lt;br /&gt;
===Имена родителей===&lt;br /&gt;
Пусть есть таблица &amp;lt;code&amp;gt;Person(Id, Name, MotherId, FatherId)&amp;lt;/code&amp;gt;&lt;br /&gt;
====Получить имена обоих родителей каждого человека (Name, Father, Mother)====&lt;br /&gt;
Запишем конъюнкцию атомов: &amp;quot;FatherId - отец Name&amp;quot;, &amp;quot;MotherId - мать Name&amp;quot;, &amp;quot;Имя FatherId - FatherName&amp;quot;, &amp;quot;Имя MotherId - MotherName&amp;quot;:&lt;br /&gt;
 Parents(Name, FatherName, MotherName) :- Person(_, Name, FatherId, MotherId),&lt;br /&gt;
     Person(FatherId, FatherName, _, _), Person(MotherId, MotherName, _, _).&lt;br /&gt;
&lt;br /&gt;
====Получить для каждого человека всех его родителей (Name, Parent)====&lt;br /&gt;
Воспользуемся тем, что в Datalog при определении отношений дважды, они объёдиняются:&lt;br /&gt;
 Parents(N, FN) :- Person(_, N, FId, _),&lt;br /&gt;
     Person(FId, FN, _, _).&lt;br /&gt;
 Parents(N, MN) :- Person(_, N, _, MId),&lt;br /&gt;
     Person(MId, MN, _, _).&lt;br /&gt;
&lt;br /&gt;
==Ограничение отношений==&lt;br /&gt;
Как и на любую другую программу, на синтаксически корректную программу на языке Datalog нужно наложить дополнительные ограничения, чтобы она имела смысл.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим отношения&lt;br /&gt;
 Less(x,y) :- x &amp;lt; y.&lt;br /&gt;
 NotStudent(Id, Name) :- ¬Students(Id, Name, _).&lt;br /&gt;
&lt;br /&gt;
Здесь есть проблема - во-первых, мы даже не знаем тип &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Id&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;Name&amp;lt;/code&amp;gt;, это значит, что мы не знаем области их значения.&lt;br /&gt;
Во-вторых, даже если бы мы знали их тип, пусть это будут, например, целые числа, то получили бы бесконечное отношение, с такими мы работать не умеем.&lt;br /&gt;
&lt;br /&gt;
Поэтому, нужно запретить такую ситуацию, для этого добавим требование:&lt;br /&gt;
&lt;br /&gt;
'''Каждая переменная должна входить в неотрицательный реляционный атом'''&lt;br /&gt;
&lt;br /&gt;
==Реляционная полнота==&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Язык Datalog реляционно полон&lt;br /&gt;
|proof=&lt;br /&gt;
Выразим базис реляционной алгебры на языке Datalog:&lt;br /&gt;
&lt;br /&gt;
'''Проекция $\pi_{A_1, ..., A_n}(R)$''' &lt;br /&gt;
 Q(A1, ..., An) :- R(A1, ..., An, _, ..., _).&lt;br /&gt;
'''Фильтр $σ_θ(R)$'''&lt;br /&gt;
 Q(A1, ..., An) :- R(A1, ..., An), θ.&lt;br /&gt;
'''Объединение $R_1 ∪ R_2$'''&lt;br /&gt;
 Q(A1, ..., An) :- R1(A1, ..., An).&lt;br /&gt;
 Q(A1, ..., An) :- R2(A1, ..., An).&lt;br /&gt;
'''Разность $R_1 ∖ R_2$'''&lt;br /&gt;
 Q(A1, ..., An) :- R1(A1, ..., An), ¬R2(A1, ..., An).&lt;br /&gt;
'''Декартово произведение $R_1 × R_2$'''&lt;br /&gt;
 Q(A1, ..., An, B1, ..., Bm) :- &lt;br /&gt;
     R1(A1, ..., An), R2(B1, ..., Bm).&lt;br /&gt;
&lt;br /&gt;
'''Естественное соединение $R_1 ⋈ R_2$''' &lt;br /&gt;
 Q(A1, ..., An, B1, ..., Bm, C1, ..., Cl) :-&lt;br /&gt;
     R1(A1, ..., An, B1, ..., Bm), R2(B1, ..., Bm, C1, ..., Cl).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Рекурсивные запросы==&lt;br /&gt;
Синтаксис Datalog позволяет написать рекурсивный запрос, но может быть не очевидно, какой смысл придавать такой конструкции.&lt;br /&gt;
Далее будет рассмотрен пример и приведены некоторые рассуждения о семантике рекурсивных запросов.&lt;br /&gt;
===Смысл===&lt;br /&gt;
Пусть есть некоторое отношение &amp;quot;потомок-родитель&amp;quot;&lt;br /&gt;
 Parent(Id, ParentId)&lt;br /&gt;
&lt;br /&gt;
Хотим найти его транзитивное замыкание, по определению:&lt;br /&gt;
 Ancestor(Id, PId) :- Parent(Id, PId).&lt;br /&gt;
 Ancestor(Id, GId) :- Parent(Id, GId), Ancestor(PId, GId).&lt;br /&gt;
&lt;br /&gt;
Пусть $P$ - множество всех людей, у которых есть хотя бы один родитель.&lt;br /&gt;
Очевидно, что $P \times P$ есть неподвижная точка, то есть правая часть отношения совпадает с левой, но найденное отношение не является транзитивным замыканием исходного.&lt;br /&gt;
&lt;br /&gt;
Поэтому, следует уточнить, что мы ищем '''минимальную по включению неподвижную точку''', начиная с пустого множества, тогда наш запрос отработает корректно.&lt;br /&gt;
&lt;br /&gt;
===Алгоритм поиска минимальной неподвижной точки===&lt;br /&gt;
&lt;br /&gt;
 Проинициализируем отношения из нерекурсивных определений&lt;br /&gt;
 Пока не достигли неподвижной точки&lt;br /&gt;
   Пополняем отношения из рекурсивных определений&lt;br /&gt;
&lt;br /&gt;
===Циклы и отрицание===&lt;br /&gt;
&lt;br /&gt;
Представим ситуацию, когда принадлежность кортежа к отношению зависит от отрицания его принадлежности к отношению. Это в чистом виде парадокс брадобрея и мы знаем, что такая конструкция не имеет смысла.&lt;br /&gt;
&lt;br /&gt;
Поэтому, введём '''стратифицированное отрицание''', то есть запрет на отрицание в циклах.&lt;/div&gt;</summary>
		<author><name>5.18.184.8</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Datalog_%D0%B8_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F&amp;diff=81562</id>
		<title>Datalog и рекурсия</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Datalog_%D0%B8_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F&amp;diff=81562"/>
				<updated>2021-12-19T22:23:24Z</updated>
		
		<summary type="html">&lt;p&gt;5.18.184.8: /* Ограничение отношений */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Язык Datalog==&lt;br /&gt;
Декларативный язык для запросов к базам данных на основе исчисления доменов. Разработан в 1978 году, синтаксически - подмножество языка Prolog. Широкого применения в реальных базах данных не получил, но повлиял на формирование более поздних языков для запросов, таких как SQL.&lt;br /&gt;
&lt;br /&gt;
==Синтаксис==&lt;br /&gt;
===Отношение===&lt;br /&gt;
Программа на Datalog - набор '''отношений'''. Отношение на языке Datalog определяется так: &lt;br /&gt;
 Отношение(x1,x2...xn) :- Цель.&lt;br /&gt;
Определение одного и того же отношения может повторяться несколько раз, тогда в это отношение будут входить кортежи, которые удовлетворяют хотя бы одной цели.&lt;br /&gt;
===Цель===&lt;br /&gt;
'''Цель''' в свою очередь - это набор '''атомов''', перечисленных через запятую. Кортеж удовлетворяет цели, если он удовлетворяет всем атомам цели.&lt;br /&gt;
===Атом===&lt;br /&gt;
Атомы бывают двух типов: реляционные и арифметические&lt;br /&gt;
====Реляционный====&lt;br /&gt;
Аналог конструкции условия принадлежности из исчисления доменов.&lt;br /&gt;
Есть два вида:&lt;br /&gt;
* Кортеж принадлежит отношению &amp;lt;code&amp;gt;R(x1, x2, ..., xn)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Кортеж не принадлежит отношению &amp;lt;code&amp;gt;¬R(x1, x2, ..., xn)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что в Datalog нет имён атрибутов, атрибуты различаются только по своей позиции.&lt;br /&gt;
&lt;br /&gt;
====Арифметический====&lt;br /&gt;
Сюда входят сравнения арифмитических выражений на равенство и неравенство.&lt;br /&gt;
&lt;br /&gt;
==Примеры запросов==&lt;br /&gt;
===Идентификаторы и фамилии всех Иванов===&lt;br /&gt;
Рассмотрим такой запрос на языке исчисления доменов&lt;br /&gt;
 Id, LastName &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; Students&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;Id = Id, FirstName = FirstName, LastName = LastName&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; $\wedge$ FirstName = &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Его можно переписать на Datalog так:&lt;br /&gt;
 Ivans(Id, LastName) :-&lt;br /&gt;
     Students(Id, FirstName, LastName),&lt;br /&gt;
     FirstName = &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Или ещё проще:&lt;br /&gt;
 Ivans(Id, LastName) :-&lt;br /&gt;
     Students(Id, &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;, LastName).&lt;br /&gt;
===Имена родителей===&lt;br /&gt;
Пусть есть таблица &amp;lt;code&amp;gt;Person(Id, Name, MotherId, FatherId)&amp;lt;/code&amp;gt;&lt;br /&gt;
====Получить имена обоих родителей каждого человека (Name, Father, Mother)====&lt;br /&gt;
Атомы в Datalog находятся в неявной конъюнкции, поэтому чтобы записать утверждение &amp;quot;FId - отец N, а MId - мать N&amp;quot;, запишем их через запятую:&lt;br /&gt;
 Parents(N, FN, MN) :- Person(_, N, FId, MId),&lt;br /&gt;
     Person(FId, _, FN, _), Person(MId, MN, _, _).&lt;br /&gt;
====Получить для каждого человека всех его родителей (Name, Parent)====&lt;br /&gt;
Воспользуемся тем, что в Datalog при определении отношений дважды, они объёдиняются:&lt;br /&gt;
 Parents(N, FN) :- Person(_, N, FId, _),&lt;br /&gt;
     Person(FId, FN, _, _).&lt;br /&gt;
 Parents(N, MN) :- Person(_, N, _, MId),&lt;br /&gt;
     Person(MId, MN, _, _).&lt;br /&gt;
&lt;br /&gt;
==Ограничение отношений==&lt;br /&gt;
Как и на любую другую программу, на синтаксически корректную программу на языке Datalog нужно наложить дополнительные ограничения, чтобы она имела смысл.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим отношения&lt;br /&gt;
 Less(x,y) :- x &amp;lt; y.&lt;br /&gt;
 NotStudent(Id, Name) :- ¬Students(Id, Name, _).&lt;br /&gt;
&lt;br /&gt;
Здесь есть проблема - во-первых, мы даже не знаем тип &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Id&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;Name&amp;lt;/code&amp;gt;, это значит, что мы не знаем области их значения.&lt;br /&gt;
Во-вторых, даже если бы мы знали их тип, пусть это будут, например, целые числа, то получили бы бесконечное отношение, с такими мы работать не умеем.&lt;br /&gt;
&lt;br /&gt;
Поэтому, нужно запретить такую ситуацию, для этого добавим требование:&lt;br /&gt;
&lt;br /&gt;
'''Каждая переменная должна входить в неотрицательный реляционный атом'''&lt;br /&gt;
&lt;br /&gt;
==Реляционная полнота==&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Язык Datalog реляционно полон&lt;br /&gt;
|proof=&lt;br /&gt;
Выразим базис реляционной алгебры на языке Datalog:&lt;br /&gt;
&lt;br /&gt;
'''Проекция $\pi_{A_1, ..., A_n}(R)$''' &lt;br /&gt;
 Q(A1, ..., An) :- R(A1, ..., An, _, ..., _).&lt;br /&gt;
'''Фильтр $σ_θ(R)$'''&lt;br /&gt;
 Q(A1, ..., An) :- R(A1, ..., An), θ.&lt;br /&gt;
'''Объединение $R_1 ∪ R_2$'''&lt;br /&gt;
 Q(A1, ..., An) :- R1(A1, ..., An).&lt;br /&gt;
 Q(A1, ..., An) :- R2(A1, ..., An).&lt;br /&gt;
'''Разность $R_1 ∖ R_2$'''&lt;br /&gt;
 Q(A1, ..., An) :- R1(A1, ..., An), ¬R2(A1, ..., An).&lt;br /&gt;
'''Декартово произведение $R_1 × R_2$'''&lt;br /&gt;
 Q(A1, ..., An, B1, ..., Bm) :- &lt;br /&gt;
     R1(A1, ..., An), R2(B1, ..., Bm).&lt;br /&gt;
&lt;br /&gt;
'''Естественное соединение $R_1 ⋈ R_2$''' &lt;br /&gt;
 Q(A1, ..., An, B1, ..., Bm, C1, ..., Cl) :-&lt;br /&gt;
     R1(A1, ..., An, B1, ..., Bm), R2(B1, ..., Bm, C1, ..., Cl).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Рекурсивные запросы==&lt;br /&gt;
Синтаксис Datalog позволяет написать рекурсивный запрос, но может быть не очевидно, какой смысл придавать такой конструкции.&lt;br /&gt;
Далее будет рассмотрен пример и приведены некоторые рассуждения о семантике рекурсивных запросов.&lt;br /&gt;
===Смысл===&lt;br /&gt;
Пусть есть некоторое отношение &amp;quot;потомок-родитель&amp;quot;&lt;br /&gt;
 Parent(Id, ParentId)&lt;br /&gt;
&lt;br /&gt;
Хотим найти его транзитивное замыкание, по определению:&lt;br /&gt;
 Ancestor(Id, PId) :- Parent(Id, PId).&lt;br /&gt;
 Ancestor(Id, GId) :- Parent(Id, GId), Ancestor(PId, GId).&lt;br /&gt;
&lt;br /&gt;
Пусть $P$ - множество всех людей, у которых есть хотя бы один родитель.&lt;br /&gt;
Очевидно, что $P \times P$ есть неподвижная точка, то есть правая часть отношения совпадает с левой, но найденное отношение не является транзитивным замыканием исходного.&lt;br /&gt;
&lt;br /&gt;
Поэтому, следует уточнить, что мы ищем '''минимальную по включению неподвижную точку''', начиная с пустого множества, тогда наш запрос отработает корректно.&lt;br /&gt;
&lt;br /&gt;
===Алгоритм поиска минимальной неподвижной точки===&lt;br /&gt;
&lt;br /&gt;
 Проинициализируем отношения из нерекурсивных определений&lt;br /&gt;
 Пока не достигли неподвижной точки&lt;br /&gt;
   Пополняем отношения из рекурсивных определений&lt;br /&gt;
&lt;br /&gt;
===Циклы и отрицание===&lt;br /&gt;
&lt;br /&gt;
Представим ситуацию, когда принадлежность кортежа к отношению зависит от отрицания его принадлежности к отношению. Это в чистом виде парадокс брадобрея и мы знаем, что такая конструкция не имеет смысла.&lt;br /&gt;
&lt;br /&gt;
Поэтому, введём '''стратифицированное отрицание''', то есть запрет на отрицание в циклах.&lt;/div&gt;</summary>
		<author><name>5.18.184.8</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Datalog_%D0%B8_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F&amp;diff=81558</id>
		<title>Datalog и рекурсия</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Datalog_%D0%B8_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F&amp;diff=81558"/>
				<updated>2021-12-19T21:54:18Z</updated>
		
		<summary type="html">&lt;p&gt;5.18.184.8: /* Получить для каждого человека всех его родителей (Name, Parent) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Язык Datalog==&lt;br /&gt;
Декларативный язык для запросов к базам данных на основе исчисления доменов. Разработан в 1978 году, синтаксически - подмножество языка Prolog. Широкого применения в реальных базах данных не получил, но повлиял на формирование более поздних языков для запросов, таких как SQL.&lt;br /&gt;
&lt;br /&gt;
==Синтаксис==&lt;br /&gt;
===Отношение===&lt;br /&gt;
Программа на Datalog - набор '''отношений'''. Отношение на языке Datalog определяется так: &lt;br /&gt;
 Отношение(x1,x2...xn) :- Цель.&lt;br /&gt;
Определение одного и того же отношения может повторяться несколько раз, тогда в это отношение будут входить кортежи, которые удовлетворяют хотя бы одной цели.&lt;br /&gt;
===Цель===&lt;br /&gt;
'''Цель''' в свою очередь - это набор '''атомов''', перечисленных через запятую. Кортеж удовлетворяет цели, если он удовлетворяет всем атомам цели.&lt;br /&gt;
===Атом===&lt;br /&gt;
Атомы бывают двух типов: реляционные и арифметические&lt;br /&gt;
====Реляционный====&lt;br /&gt;
Аналог конструкции условия принадлежности из исчисления доменов.&lt;br /&gt;
Есть два вида:&lt;br /&gt;
* Кортеж принадлежит отношению &amp;lt;code&amp;gt;R(x1, x2, ..., xn)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Кортеж не принадлежит отношению &amp;lt;code&amp;gt;¬R(x1, x2, ..., xn)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что в Datalog нет имён атрибутов, атрибуты различаются только по своей позиции.&lt;br /&gt;
&lt;br /&gt;
====Арифметический====&lt;br /&gt;
Сюда входят сравнения арифмитических выражений на равенство и неравенство.&lt;br /&gt;
&lt;br /&gt;
==Примеры запросов==&lt;br /&gt;
===Идентификаторы и фамилии всех Иванов===&lt;br /&gt;
Рассмотрим такой запрос на языке исчисления доменов&lt;br /&gt;
 Id, LastName &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; Students&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;Id = Id, FirstName = FirstName, LastName = LastName&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; $\wedge$ FirstName = &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Его можно переписать на Datalog так:&lt;br /&gt;
 Ivans(Id, LastName) :-&lt;br /&gt;
     Students(Id, FirstName, LastName),&lt;br /&gt;
     FirstName = &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Или ещё проще:&lt;br /&gt;
 Ivans(Id, LastName) :-&lt;br /&gt;
     Students(Id, &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;, LastName).&lt;br /&gt;
===Имена родителей===&lt;br /&gt;
Пусть есть таблица &amp;lt;code&amp;gt;Person(Id, Name, MotherId, FatherId)&amp;lt;/code&amp;gt;&lt;br /&gt;
====Получить имена обоих родителей каждого человека (Name, Father, Mother)====&lt;br /&gt;
Атомы в Datalog находятся в неявной конъюнкции, поэтому чтобы записать утверждение &amp;quot;FId - отец N, а MId - мать N&amp;quot;, запишем их через запятую:&lt;br /&gt;
 Parents(N, FN, MN) :- Person(_, N, FId, MId),&lt;br /&gt;
     Person(FId, _, FN, _), Person(MId, MN, _, _).&lt;br /&gt;
====Получить для каждого человека всех его родителей (Name, Parent)====&lt;br /&gt;
Воспользуемся тем, что в Datalog при определении отношений дважды, они объёдиняются:&lt;br /&gt;
 Parents(N, FN) :- Person(_, N, FId, _),&lt;br /&gt;
     Person(FId, FN, _, _).&lt;br /&gt;
 Parents(N, MN) :- Person(_, N, _, MId),&lt;br /&gt;
     Person(MId, MN, _, _).&lt;br /&gt;
&lt;br /&gt;
==Ограничение отношений==&lt;br /&gt;
Как и на любую другую программу, на синтаксически корректную программу на языке Datalog нужно наложить дополнительные ограничения, чтобы она имела смысл.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим отношения&lt;br /&gt;
 Less(x,y) :- x &amp;lt; y.&lt;br /&gt;
 NotStudent(Id, Name) :- ¬Students(Id, Name, _).&lt;br /&gt;
&lt;br /&gt;
Здесь есть проблема - во-первых, мы даже не знаем тип &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Id&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;Name&amp;lt;/code&amp;gt;, это значит, что мы не знаем области их значения.&lt;br /&gt;
Во-вторых, даже если бы мы знали их тип, пусть это будут, например, целые числа, то получили бы бесконечное отношение, с такими мы работать не умеем.&lt;br /&gt;
&lt;br /&gt;
Поэтому, нужно запретить такую ситуацию, для этого добавим требование:&lt;br /&gt;
&lt;br /&gt;
'''Каждая переменная должна входить в неотрицательный реляционный атом'''&lt;br /&gt;
&lt;br /&gt;
==Рекурсивные запросы==&lt;br /&gt;
Синтаксис Datalog позволяет написать рекурсивный запрос, но может быть не очевидно, какой смысл придавать такой конструкции.&lt;br /&gt;
Далее будет рассмотрен пример и приведены некоторые рассуждения о семантике рекурсивных запросов.&lt;br /&gt;
===Смысл===&lt;br /&gt;
Пусть есть некоторое отношение &amp;quot;потомок-родитель&amp;quot;&lt;br /&gt;
 Parent(Id, ParentId)&lt;br /&gt;
&lt;br /&gt;
Хотим найти его транзитивное замыкание, по определению:&lt;br /&gt;
 Ancestor(Id, PId) :- Parent(Id, PId).&lt;br /&gt;
 Ancestor(Id, GId) :- Parent(Id, GId), Ancestor(PId, GId).&lt;br /&gt;
&lt;br /&gt;
Пусть $P$ - множество всех людей, у которых есть хотя бы один родитель.&lt;br /&gt;
Очевидно, что $P \times P$ есть неподвижная точка, то есть правая часть отношения совпадает с левой, но найденное отношение не является транзитивным замыканием исходного.&lt;br /&gt;
&lt;br /&gt;
Поэтому, следует уточнить, что мы ищем '''минимальную по включению неподвижную точку''', начиная с пустого множества, тогда наш запрос отработает корректно.&lt;br /&gt;
&lt;br /&gt;
===Алгоритм поиска минимальной неподвижной точки===&lt;br /&gt;
&lt;br /&gt;
 Проинициализируем отношения из нерекурсивных определений&lt;br /&gt;
 Пока не достигли неподвижной точки&lt;br /&gt;
   Пополняем отношения из рекурсивных определений&lt;br /&gt;
&lt;br /&gt;
===Циклы и отрицание===&lt;br /&gt;
&lt;br /&gt;
Представим ситуацию, когда принадлежность кортежа к отношению зависит от отрицания его принадлежности к отношению. Это в чистом виде парадокс брадобрея и мы знаем, что такая конструкция не имеет смысла.&lt;br /&gt;
&lt;br /&gt;
Поэтому, введём '''стратифицированное отрицание''', то есть запрет на отрицание в циклах.&lt;/div&gt;</summary>
		<author><name>5.18.184.8</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Datalog_%D0%B8_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F&amp;diff=81556</id>
		<title>Datalog и рекурсия</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Datalog_%D0%B8_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F&amp;diff=81556"/>
				<updated>2021-12-19T21:53:44Z</updated>
		
		<summary type="html">&lt;p&gt;5.18.184.8: /* Примеры запросов */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Язык Datalog==&lt;br /&gt;
Декларативный язык для запросов к базам данных на основе исчисления доменов. Разработан в 1978 году, синтаксически - подмножество языка Prolog. Широкого применения в реальных базах данных не получил, но повлиял на формирование более поздних языков для запросов, таких как SQL.&lt;br /&gt;
&lt;br /&gt;
==Синтаксис==&lt;br /&gt;
===Отношение===&lt;br /&gt;
Программа на Datalog - набор '''отношений'''. Отношение на языке Datalog определяется так: &lt;br /&gt;
 Отношение(x1,x2...xn) :- Цель.&lt;br /&gt;
Определение одного и того же отношения может повторяться несколько раз, тогда в это отношение будут входить кортежи, которые удовлетворяют хотя бы одной цели.&lt;br /&gt;
===Цель===&lt;br /&gt;
'''Цель''' в свою очередь - это набор '''атомов''', перечисленных через запятую. Кортеж удовлетворяет цели, если он удовлетворяет всем атомам цели.&lt;br /&gt;
===Атом===&lt;br /&gt;
Атомы бывают двух типов: реляционные и арифметические&lt;br /&gt;
====Реляционный====&lt;br /&gt;
Аналог конструкции условия принадлежности из исчисления доменов.&lt;br /&gt;
Есть два вида:&lt;br /&gt;
* Кортеж принадлежит отношению &amp;lt;code&amp;gt;R(x1, x2, ..., xn)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Кортеж не принадлежит отношению &amp;lt;code&amp;gt;¬R(x1, x2, ..., xn)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что в Datalog нет имён атрибутов, атрибуты различаются только по своей позиции.&lt;br /&gt;
&lt;br /&gt;
====Арифметический====&lt;br /&gt;
Сюда входят сравнения арифмитических выражений на равенство и неравенство.&lt;br /&gt;
&lt;br /&gt;
==Примеры запросов==&lt;br /&gt;
===Идентификаторы и фамилии всех Иванов===&lt;br /&gt;
Рассмотрим такой запрос на языке исчисления доменов&lt;br /&gt;
 Id, LastName &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; Students&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;Id = Id, FirstName = FirstName, LastName = LastName&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; $\wedge$ FirstName = &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Его можно переписать на Datalog так:&lt;br /&gt;
 Ivans(Id, LastName) :-&lt;br /&gt;
     Students(Id, FirstName, LastName),&lt;br /&gt;
     FirstName = &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Или ещё проще:&lt;br /&gt;
 Ivans(Id, LastName) :-&lt;br /&gt;
     Students(Id, &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;, LastName).&lt;br /&gt;
===Имена родителей===&lt;br /&gt;
Пусть есть таблица &amp;lt;code&amp;gt;Person(Id, Name, MotherId, FatherId)&amp;lt;/code&amp;gt;&lt;br /&gt;
====Получить имена обоих родителей каждого человека (Name, Father, Mother)====&lt;br /&gt;
Атомы в Datalog находятся в неявной конъюнкции, поэтому чтобы записать утверждение &amp;quot;FId - отец N, а MId - мать N&amp;quot;, запишем их через запятую:&lt;br /&gt;
 Parents(N, FN, MN) :- Person(_, N, FId, MId),&lt;br /&gt;
     Person(FId, _, FN, _), Person(MId, MN, _, _).&lt;br /&gt;
====Получить для каждого человека всех его родителей (Name, Parent)====&lt;br /&gt;
Воспользуемся тем, что в Datalog при определении отношений дважды, они объёдиняются:&lt;br /&gt;
Parents(N, FN) :- Person(_, N, FId, _),&lt;br /&gt;
    Person(FId, FN, _, _).&lt;br /&gt;
Parents(N, MN) :- Person(_, N, _, MId),&lt;br /&gt;
    Person(MId, MN, _, _).&lt;br /&gt;
&lt;br /&gt;
==Ограничение отношений==&lt;br /&gt;
Как и на любую другую программу, на синтаксически корректную программу на языке Datalog нужно наложить дополнительные ограничения, чтобы она имела смысл.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим отношения&lt;br /&gt;
 Less(x,y) :- x &amp;lt; y.&lt;br /&gt;
 NotStudent(Id, Name) :- ¬Students(Id, Name, _).&lt;br /&gt;
&lt;br /&gt;
Здесь есть проблема - во-первых, мы даже не знаем тип &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Id&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;Name&amp;lt;/code&amp;gt;, это значит, что мы не знаем области их значения.&lt;br /&gt;
Во-вторых, даже если бы мы знали их тип, пусть это будут, например, целые числа, то получили бы бесконечное отношение, с такими мы работать не умеем.&lt;br /&gt;
&lt;br /&gt;
Поэтому, нужно запретить такую ситуацию, для этого добавим требование:&lt;br /&gt;
&lt;br /&gt;
'''Каждая переменная должна входить в неотрицательный реляционный атом'''&lt;br /&gt;
&lt;br /&gt;
==Рекурсивные запросы==&lt;br /&gt;
Синтаксис Datalog позволяет написать рекурсивный запрос, но может быть не очевидно, какой смысл придавать такой конструкции.&lt;br /&gt;
Далее будет рассмотрен пример и приведены некоторые рассуждения о семантике рекурсивных запросов.&lt;br /&gt;
===Смысл===&lt;br /&gt;
Пусть есть некоторое отношение &amp;quot;потомок-родитель&amp;quot;&lt;br /&gt;
 Parent(Id, ParentId)&lt;br /&gt;
&lt;br /&gt;
Хотим найти его транзитивное замыкание, по определению:&lt;br /&gt;
 Ancestor(Id, PId) :- Parent(Id, PId).&lt;br /&gt;
 Ancestor(Id, GId) :- Parent(Id, GId), Ancestor(PId, GId).&lt;br /&gt;
&lt;br /&gt;
Пусть $P$ - множество всех людей, у которых есть хотя бы один родитель.&lt;br /&gt;
Очевидно, что $P \times P$ есть неподвижная точка, то есть правая часть отношения совпадает с левой, но найденное отношение не является транзитивным замыканием исходного.&lt;br /&gt;
&lt;br /&gt;
Поэтому, следует уточнить, что мы ищем '''минимальную по включению неподвижную точку''', начиная с пустого множества, тогда наш запрос отработает корректно.&lt;br /&gt;
&lt;br /&gt;
===Алгоритм поиска минимальной неподвижной точки===&lt;br /&gt;
&lt;br /&gt;
 Проинициализируем отношения из нерекурсивных определений&lt;br /&gt;
 Пока не достигли неподвижной точки&lt;br /&gt;
   Пополняем отношения из рекурсивных определений&lt;br /&gt;
&lt;br /&gt;
===Циклы и отрицание===&lt;br /&gt;
&lt;br /&gt;
Представим ситуацию, когда принадлежность кортежа к отношению зависит от отрицания его принадлежности к отношению. Это в чистом виде парадокс брадобрея и мы знаем, что такая конструкция не имеет смысла.&lt;br /&gt;
&lt;br /&gt;
Поэтому, введём '''стратифицированное отрицание''', то есть запрет на отрицание в циклах.&lt;/div&gt;</summary>
		<author><name>5.18.184.8</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Datalog_%D0%B8_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F&amp;diff=81550</id>
		<title>Datalog и рекурсия</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Datalog_%D0%B8_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F&amp;diff=81550"/>
				<updated>2021-12-19T21:43:28Z</updated>
		
		<summary type="html">&lt;p&gt;5.18.184.8: /* Идентификаторы и фамилии всех Иванов. */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Язык Datalog==&lt;br /&gt;
Декларативный язык для запросов к базам данных на основе исчисления доменов. Разработан в 1978 году, синтаксически - подмножество языка Prolog. Широкого применения в реальных базах данных не получил, но повлиял на формирование более поздних языков для запросов, таких как SQL.&lt;br /&gt;
&lt;br /&gt;
==Синтаксис==&lt;br /&gt;
===Отношение===&lt;br /&gt;
Программа на Datalog - набор '''отношений'''. Отношение на языке Datalog определяется так: &lt;br /&gt;
 Отношение(x1,x2...xn) :- Цель.&lt;br /&gt;
Определение одного и того же отношения может повторяться несколько раз, тогда в это отношение будут входить кортежи, которые удовлетворяют хотя бы одной цели.&lt;br /&gt;
===Цель===&lt;br /&gt;
'''Цель''' в свою очередь - это набор '''атомов''', перечисленных через запятую. Кортеж удовлетворяет цели, если он удовлетворяет всем атомам цели.&lt;br /&gt;
===Атом===&lt;br /&gt;
Атомы бывают двух типов: реляционные и арифметические&lt;br /&gt;
====Реляционный====&lt;br /&gt;
Аналог конструкции условия принадлежности из исчисления доменов.&lt;br /&gt;
Есть два вида:&lt;br /&gt;
* Кортеж принадлежит отношению &amp;lt;code&amp;gt;R(x1, x2, ..., xn)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Кортеж не принадлежит отношению &amp;lt;code&amp;gt;¬R(x1, x2, ..., xn)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что в Datalog нет имён атрибутов, атрибуты различаются только по своей позиции.&lt;br /&gt;
&lt;br /&gt;
====Арифметический====&lt;br /&gt;
Сюда входят сравнения арифмитических выражений на равенство и неравенство.&lt;br /&gt;
&lt;br /&gt;
==Примеры запросов==&lt;br /&gt;
===Идентификаторы и фамилии всех Иванов===&lt;br /&gt;
Рассмотрим такой запрос на языке исчисления доменов&lt;br /&gt;
 Id, LastName &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; Students&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;Id = Id, FirstName = FirstName, LastName = LastName&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; $\wedge$ FirstName = &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Его можно переписать на Datalog так:&lt;br /&gt;
 Ivans(Id, LastName) :-&lt;br /&gt;
     Students(Id, FirstName, LastName),&lt;br /&gt;
     FirstName = &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Или ещё проще:&lt;br /&gt;
 Ivans(Id, LastName) :-&lt;br /&gt;
     Students(Id, &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;, LastName).&lt;br /&gt;
&lt;br /&gt;
==Ограничение отношений==&lt;br /&gt;
Как и на любую другую программу, на синтаксически корректную программу на языке Datalog нужно наложить дополнительные ограничения, чтобы она имела смысл.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим отношения&lt;br /&gt;
 Less(x,y) :- x &amp;lt; y.&lt;br /&gt;
 NotStudent(Id, Name) :- ¬Students(Id, Name, _).&lt;br /&gt;
&lt;br /&gt;
Здесь есть проблема - во-первых, мы даже не знаем тип &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Id&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;Name&amp;lt;/code&amp;gt;, это значит, что мы не знаем области их значения.&lt;br /&gt;
Во-вторых, даже если бы мы знали их тип, пусть это будут, например, целые числа, то получили бы бесконечное отношение, с такими мы работать не умеем.&lt;br /&gt;
&lt;br /&gt;
Поэтому, нужно запретить такую ситуацию, для этого добавим требование:&lt;br /&gt;
&lt;br /&gt;
'''Каждая переменная должна входить в неотрицательный реляционный атом'''&lt;br /&gt;
&lt;br /&gt;
==Рекурсивные запросы==&lt;br /&gt;
Синтаксис Datalog позволяет написать рекурсивный запрос, но может быть не очевидно, какой смысл придавать такой конструкции.&lt;br /&gt;
Далее будет рассмотрен пример и приведены некоторые рассуждения о семантике рекурсивных запросов.&lt;br /&gt;
===Смысл===&lt;br /&gt;
Пусть есть некоторое отношение &amp;quot;потомок-родитель&amp;quot;&lt;br /&gt;
 Parent(Id, ParentId)&lt;br /&gt;
&lt;br /&gt;
Хотим найти его транзитивное замыкание, по определению:&lt;br /&gt;
 Ancestor(Id, PId) :- Parent(Id, PId).&lt;br /&gt;
 Ancestor(Id, GId) :- Parent(Id, GId), Ancestor(PId, GId).&lt;br /&gt;
&lt;br /&gt;
Пусть $P$ - множество всех людей, у которых есть хотя бы один родитель.&lt;br /&gt;
Очевидно, что $P \times P$ есть неподвижная точка, то есть правая часть отношения совпадает с левой, но найденное отношение не является транзитивным замыканием исходного.&lt;br /&gt;
&lt;br /&gt;
Поэтому, следует уточнить, что мы ищем '''минимальную по включению неподвижную точку''', начиная с пустого множества, тогда наш запрос отработает корректно.&lt;br /&gt;
&lt;br /&gt;
===Алгоритм поиска минимальной неподвижной точки===&lt;br /&gt;
&lt;br /&gt;
 Проинициализируем отношения из нерекурсивных определений&lt;br /&gt;
 Пока не достигли неподвижной точки&lt;br /&gt;
   Пополняем отношения из рекурсивных определений&lt;br /&gt;
&lt;br /&gt;
===Циклы и отрицание===&lt;br /&gt;
&lt;br /&gt;
Представим ситуацию, когда принадлежность кортежа к отношению зависит от отрицания его принадлежности к отношению. Это в чистом виде парадокс брадобрея и мы знаем, что такая конструкция не имеет смысла.&lt;br /&gt;
&lt;br /&gt;
Поэтому, введём '''стратифицированное отрицание''', то есть запрет на отрицание в циклах.&lt;/div&gt;</summary>
		<author><name>5.18.184.8</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Datalog_%D0%B8_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F&amp;diff=81549</id>
		<title>Datalog и рекурсия</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Datalog_%D0%B8_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F&amp;diff=81549"/>
				<updated>2021-12-19T21:43:15Z</updated>
		
		<summary type="html">&lt;p&gt;5.18.184.8: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Язык Datalog==&lt;br /&gt;
Декларативный язык для запросов к базам данных на основе исчисления доменов. Разработан в 1978 году, синтаксически - подмножество языка Prolog. Широкого применения в реальных базах данных не получил, но повлиял на формирование более поздних языков для запросов, таких как SQL.&lt;br /&gt;
&lt;br /&gt;
==Синтаксис==&lt;br /&gt;
===Отношение===&lt;br /&gt;
Программа на Datalog - набор '''отношений'''. Отношение на языке Datalog определяется так: &lt;br /&gt;
 Отношение(x1,x2...xn) :- Цель.&lt;br /&gt;
Определение одного и того же отношения может повторяться несколько раз, тогда в это отношение будут входить кортежи, которые удовлетворяют хотя бы одной цели.&lt;br /&gt;
===Цель===&lt;br /&gt;
'''Цель''' в свою очередь - это набор '''атомов''', перечисленных через запятую. Кортеж удовлетворяет цели, если он удовлетворяет всем атомам цели.&lt;br /&gt;
===Атом===&lt;br /&gt;
Атомы бывают двух типов: реляционные и арифметические&lt;br /&gt;
====Реляционный====&lt;br /&gt;
Аналог конструкции условия принадлежности из исчисления доменов.&lt;br /&gt;
Есть два вида:&lt;br /&gt;
* Кортеж принадлежит отношению &amp;lt;code&amp;gt;R(x1, x2, ..., xn)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Кортеж не принадлежит отношению &amp;lt;code&amp;gt;¬R(x1, x2, ..., xn)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что в Datalog нет имён атрибутов, атрибуты различаются только по своей позиции.&lt;br /&gt;
&lt;br /&gt;
====Арифметический====&lt;br /&gt;
Сюда входят сравнения арифмитических выражений на равенство и неравенство.&lt;br /&gt;
&lt;br /&gt;
==Примеры запросов==&lt;br /&gt;
===Идентификаторы и фамилии всех Иванов.===&lt;br /&gt;
Рассмотрим такой запрос на языке исчисления доменов&lt;br /&gt;
 Id, LastName &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; Students&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;Id = Id, FirstName = FirstName, LastName = LastName&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; $\wedge$ FirstName = &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Его можно переписать на Datalog так:&lt;br /&gt;
 Ivans(Id, LastName) :-&lt;br /&gt;
     Students(Id, FirstName, LastName),&lt;br /&gt;
     FirstName = &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Или ещё проще:&lt;br /&gt;
 Ivans(Id, LastName) :-&lt;br /&gt;
     Students(Id, &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;, LastName).&lt;br /&gt;
&lt;br /&gt;
==Ограничение отношений==&lt;br /&gt;
Как и на любую другую программу, на синтаксически корректную программу на языке Datalog нужно наложить дополнительные ограничения, чтобы она имела смысл.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим отношения&lt;br /&gt;
 Less(x,y) :- x &amp;lt; y.&lt;br /&gt;
 NotStudent(Id, Name) :- ¬Students(Id, Name, _).&lt;br /&gt;
&lt;br /&gt;
Здесь есть проблема - во-первых, мы даже не знаем тип &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Id&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;Name&amp;lt;/code&amp;gt;, это значит, что мы не знаем области их значения.&lt;br /&gt;
Во-вторых, даже если бы мы знали их тип, пусть это будут, например, целые числа, то получили бы бесконечное отношение, с такими мы работать не умеем.&lt;br /&gt;
&lt;br /&gt;
Поэтому, нужно запретить такую ситуацию, для этого добавим требование:&lt;br /&gt;
&lt;br /&gt;
'''Каждая переменная должна входить в неотрицательный реляционный атом'''&lt;br /&gt;
&lt;br /&gt;
==Рекурсивные запросы==&lt;br /&gt;
Синтаксис Datalog позволяет написать рекурсивный запрос, но может быть не очевидно, какой смысл придавать такой конструкции.&lt;br /&gt;
Далее будет рассмотрен пример и приведены некоторые рассуждения о семантике рекурсивных запросов.&lt;br /&gt;
===Смысл===&lt;br /&gt;
Пусть есть некоторое отношение &amp;quot;потомок-родитель&amp;quot;&lt;br /&gt;
 Parent(Id, ParentId)&lt;br /&gt;
&lt;br /&gt;
Хотим найти его транзитивное замыкание, по определению:&lt;br /&gt;
 Ancestor(Id, PId) :- Parent(Id, PId).&lt;br /&gt;
 Ancestor(Id, GId) :- Parent(Id, GId), Ancestor(PId, GId).&lt;br /&gt;
&lt;br /&gt;
Пусть $P$ - множество всех людей, у которых есть хотя бы один родитель.&lt;br /&gt;
Очевидно, что $P \times P$ есть неподвижная точка, то есть правая часть отношения совпадает с левой, но найденное отношение не является транзитивным замыканием исходного.&lt;br /&gt;
&lt;br /&gt;
Поэтому, следует уточнить, что мы ищем '''минимальную по включению неподвижную точку''', начиная с пустого множества, тогда наш запрос отработает корректно.&lt;br /&gt;
&lt;br /&gt;
===Алгоритм поиска минимальной неподвижной точки===&lt;br /&gt;
&lt;br /&gt;
 Проинициализируем отношения из нерекурсивных определений&lt;br /&gt;
 Пока не достигли неподвижной точки&lt;br /&gt;
   Пополняем отношения из рекурсивных определений&lt;br /&gt;
&lt;br /&gt;
===Циклы и отрицание===&lt;br /&gt;
&lt;br /&gt;
Представим ситуацию, когда принадлежность кортежа к отношению зависит от отрицания его принадлежности к отношению. Это в чистом виде парадокс брадобрея и мы знаем, что такая конструкция не имеет смысла.&lt;br /&gt;
&lt;br /&gt;
Поэтому, введём '''стратифицированное отрицание''', то есть запрет на отрицание в циклах.&lt;/div&gt;</summary>
		<author><name>5.18.184.8</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Datalog_%D0%B8_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F&amp;diff=81539</id>
		<title>Datalog и рекурсия</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Datalog_%D0%B8_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F&amp;diff=81539"/>
				<updated>2021-12-19T21:25:24Z</updated>
		
		<summary type="html">&lt;p&gt;5.18.184.8: /* Синтаксис */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Язык Datalog==&lt;br /&gt;
Декларативный язык для запросов к базам данных на основе исчисления доменов. Разработан в 1978 году, синтаксически - подмножество языка Prolog. Широкого применения в реальных базах данных не получил, но повлиял на формирование более поздних языков для запросов, таких как SQL.&lt;br /&gt;
&lt;br /&gt;
==Синтаксис==&lt;br /&gt;
===Отношение===&lt;br /&gt;
Программа на Datalog - набор '''отношений'''. Отношение на языке Datalog определяется так: &lt;br /&gt;
 Отношение(x1,x2...xn) :- Цель.&lt;br /&gt;
Определение одного и того же отношения может повторяться несколько раз, тогда в это отношение будут входить кортежи, которые удовлетворяют хотя бы одной цели.&lt;br /&gt;
===Цель===&lt;br /&gt;
'''Цель''' в свою очередь - это набор '''атомов''', перечисленных через запятую. Кортеж удовлетворяет цели, если он удовлетворяет всем атомам цели.&lt;br /&gt;
===Атом===&lt;br /&gt;
Атомы бывают двух типов: реляционные и арифметические&lt;br /&gt;
====Реляционный====&lt;br /&gt;
Аналог конструкции условия принадлежности из исчисления доменов.&lt;br /&gt;
Есть два вида:&lt;br /&gt;
* Кортеж принадлежит отношению &amp;lt;code&amp;gt;R(x1, x2, ..., xn)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Кортеж не принадлежит отношению &amp;lt;code&amp;gt;¬R(x1, x2, ..., xn)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что в Datalog нет имён атрибутов, атрибуты различаются только по своей позиции.&lt;br /&gt;
&lt;br /&gt;
====Арифметический====&lt;br /&gt;
Сюда входят сравнения арифмитических выражений на равенство и неравенство.&lt;br /&gt;
&lt;br /&gt;
==Ограничение отношений==&lt;br /&gt;
Как и на любую другую программу, на синтаксически корректную программу на языке Datalog нужно наложить дополнительные ограничения, чтобы она имела смысл.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим отношения&lt;br /&gt;
 Less(x,y) :- x &amp;lt; y.&lt;br /&gt;
 NotStudent(Id, Name) :- ¬Students(Id, Name, _).&lt;br /&gt;
&lt;br /&gt;
Здесь есть проблема - во-первых, мы даже не знаем тип &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Id&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;Name&amp;lt;/code&amp;gt;, это значит, что мы не знаем области их значения.&lt;br /&gt;
Во-вторых, даже если бы мы знали их тип, пусть это будут, например, целые числа, то получили бы бесконечное отношение, с такими мы работать не умеем.&lt;br /&gt;
&lt;br /&gt;
Поэтому, нужно запретить такую ситуацию, для этого добавим требование:&lt;br /&gt;
&lt;br /&gt;
'''Каждая переменная должна входить в неотрицательный реляционный атом'''&lt;br /&gt;
&lt;br /&gt;
==Рекурсивные запросы==&lt;br /&gt;
Синтаксис Datalog позволяет написать рекурсивный запрос, но может быть не очевидно, какой смысл придавать такой конструкции.&lt;br /&gt;
Далее будет рассмотрен пример и приведены некоторые рассуждения о семантике рекурсивных запросов.&lt;br /&gt;
===Смысл===&lt;br /&gt;
Пусть есть некоторое отношение &amp;quot;потомок-родитель&amp;quot;&lt;br /&gt;
 Parent(Id, ParentId)&lt;br /&gt;
&lt;br /&gt;
Хотим найти его транзитивное замыкание, по определению:&lt;br /&gt;
 Ancestor(Id, PId) :- Parent(Id, PId).&lt;br /&gt;
 Ancestor(Id, GId) :- Parent(Id, GId), Ancestor(PId, GId).&lt;br /&gt;
&lt;br /&gt;
Пусть $P$ - множество всех людей, у которых есть хотя бы один родитель.&lt;br /&gt;
Очевидно, что $P \times P$ есть неподвижная точка, то есть правая часть отношения совпадает с левой, но найденное отношение не является транзитивным замыканием исходного.&lt;br /&gt;
&lt;br /&gt;
Поэтому, следует уточнить, что мы ищем '''минимальную по включению неподвижную точку''', начиная с пустого множества, тогда наш запрос отработает корректно.&lt;br /&gt;
&lt;br /&gt;
===Алгоритм поиска минимальной неподвижной точки===&lt;br /&gt;
&lt;br /&gt;
 Проинициализируем отношения из нерекурсивных определений&lt;br /&gt;
 Пока не достигли неподвижной точки&lt;br /&gt;
   Пополняем отношения из рекурсивных определений&lt;br /&gt;
&lt;br /&gt;
===Циклы и отрицание===&lt;br /&gt;
&lt;br /&gt;
Представим ситуацию, когда принадлежность кортежа к отношению зависит от отрицания его принадлежности к отношению. Это в чистом виде парадокс брадобрея и мы знаем, что такая конструкция не имеет смысла.&lt;br /&gt;
&lt;br /&gt;
Поэтому, введём '''стратифицированное отрицание''', то есть запрет на отрицание в циклах.&lt;/div&gt;</summary>
		<author><name>5.18.184.8</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Datalog_%D0%B8_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F&amp;diff=81538</id>
		<title>Datalog и рекурсия</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Datalog_%D0%B8_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F&amp;diff=81538"/>
				<updated>2021-12-19T21:17:23Z</updated>
		
		<summary type="html">&lt;p&gt;5.18.184.8: /* Смысл */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Язык Datalog==&lt;br /&gt;
Декларативный язык для запросов к базам данных на основе исчисления доменов. Разработан в 1978 году, синтаксически - подмножество языка Prolog. Широкого применения в реальных базах данных не получил, но повлиял на формирование более поздних языков для запросов, таких как SQL.&lt;br /&gt;
&lt;br /&gt;
==Синтаксис==&lt;br /&gt;
Программа на Datalog - набор '''отношений''': Отношение на языке Datalog определяется так: &amp;lt;code&amp;gt;Отношение(x1,x2...xn) :- Цель.&amp;lt;/code&amp;gt;. Определение одного и того же отношения может повторяться несколько раз, тогда в это отношение будут входить кортежи, которые удовлетворяют хотя бы одной цели.&lt;br /&gt;
&lt;br /&gt;
'''Цель''' в свою очередь - это набор '''атомов''', перечисленных через запятую. Кортеж удовлетворяет цели, если он удовлетворяет всем атомам цели.&lt;br /&gt;
===Атом===&lt;br /&gt;
Атомы бывают двух типов: реляционные и арифметические&lt;br /&gt;
====Реляционный====&lt;br /&gt;
Аналог конструкции условия принадлежности из исчисления доменов.&lt;br /&gt;
Есть два вида:&lt;br /&gt;
* Кортеж принадлежит отношению &amp;lt;code&amp;gt;R(x1, x2, ..., xn)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Кортеж не принадлежит отношению &amp;lt;code&amp;gt;¬R(x1, x2, ..., xn)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что в Datalog нет имён атрибутов, атрибуты различаются только по своей позиции.&lt;br /&gt;
&lt;br /&gt;
====Арифметический====&lt;br /&gt;
всевозможные сравнения на равенство/неравенство&lt;br /&gt;
&lt;br /&gt;
==Ограничение отношений==&lt;br /&gt;
Как и на любую другую программу, на синтаксически корректную программу на языке Datalog нужно наложить дополнительные ограничения, чтобы она имела смысл.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим отношения&lt;br /&gt;
 Less(x,y) :- x &amp;lt; y.&lt;br /&gt;
 NotStudent(Id, Name) :- ¬Students(Id, Name, _).&lt;br /&gt;
&lt;br /&gt;
Здесь есть проблема - во-первых, мы даже не знаем тип &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Id&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;Name&amp;lt;/code&amp;gt;, это значит, что мы не знаем области их значения.&lt;br /&gt;
Во-вторых, даже если бы мы знали их тип, пусть это будут, например, целые числа, то получили бы бесконечное отношение, с такими мы работать не умеем.&lt;br /&gt;
&lt;br /&gt;
Поэтому, нужно запретить такую ситуацию, для этого добавим требование:&lt;br /&gt;
&lt;br /&gt;
'''Каждая переменная должна входить в неотрицательный реляционный атом'''&lt;br /&gt;
&lt;br /&gt;
==Рекурсивные запросы==&lt;br /&gt;
Синтаксис Datalog позволяет написать рекурсивный запрос, но может быть не очевидно, какой смысл придавать такой конструкции.&lt;br /&gt;
Далее будет рассмотрен пример и приведены некоторые рассуждения о семантике рекурсивных запросов.&lt;br /&gt;
===Смысл===&lt;br /&gt;
Пусть есть некоторое отношение &amp;quot;потомок-родитель&amp;quot;&lt;br /&gt;
 Parent(Id, ParentId)&lt;br /&gt;
&lt;br /&gt;
Хотим найти его транзитивное замыкание, по определению:&lt;br /&gt;
 Ancestor(Id, PId) :- Parent(Id, PId).&lt;br /&gt;
 Ancestor(Id, GId) :- Parent(Id, GId), Ancestor(PId, GId).&lt;br /&gt;
&lt;br /&gt;
Пусть $P$ - множество всех людей, у которых есть хотя бы один родитель.&lt;br /&gt;
Очевидно, что $P \times P$ есть неподвижная точка, то есть правая часть отношения совпадает с левой, но найденное отношение не является транзитивным замыканием исходного.&lt;br /&gt;
&lt;br /&gt;
Поэтому, следует уточнить, что мы ищем '''минимальную по включению неподвижную точку''', начиная с пустого множества, тогда наш запрос отработает корректно.&lt;br /&gt;
&lt;br /&gt;
===Алгоритм поиска минимальной неподвижной точки===&lt;br /&gt;
&lt;br /&gt;
 Проинициализируем отношения из нерекурсивных определений&lt;br /&gt;
 Пока не достигли неподвижной точки&lt;br /&gt;
   Пополняем отношения из рекурсивных определений&lt;br /&gt;
&lt;br /&gt;
===Циклы и отрицание===&lt;br /&gt;
&lt;br /&gt;
Представим ситуацию, когда принадлежность кортежа к отношению зависит от отрицания его принадлежности к отношению. Это в чистом виде парадокс брадобрея и мы знаем, что такая конструкция не имеет смысла.&lt;br /&gt;
&lt;br /&gt;
Поэтому, введём '''стратифицированное отрицание''', то есть запрет на отрицание в циклах.&lt;/div&gt;</summary>
		<author><name>5.18.184.8</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Datalog_%D0%B8_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F&amp;diff=81523</id>
		<title>Datalog и рекурсия</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Datalog_%D0%B8_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F&amp;diff=81523"/>
				<updated>2021-12-19T21:01:05Z</updated>
		
		<summary type="html">&lt;p&gt;5.18.184.8: /* Рекурсивные запросы */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Язык Datalog==&lt;br /&gt;
Декларативный язык для запросов к базам данных на основе исчисления доменов. Разработан в 1978 году, синтаксически - подмножество языка Prolog. Широкого применения в реальных базах данных не получил, но повлиял на формирование более поздних языков для запросов, таких как SQL.&lt;br /&gt;
&lt;br /&gt;
==Синтаксис==&lt;br /&gt;
Программа на Datalog - набор '''отношений''': Отношение на языке Datalog определяется так: &amp;lt;code&amp;gt;Отношение(x1,x2...xn) :- Цель.&amp;lt;/code&amp;gt;. Определение одного и того же отношения может повторяться несколько раз, тогда в это отношение будут входить кортежи, которые удовлетворяют хотя бы одной цели.&lt;br /&gt;
&lt;br /&gt;
'''Цель''' в свою очередь - это набор '''атомов''', перечисленных через запятую. Кортеж удовлетворяет цели, если он удовлетворяет всем атомам цели.&lt;br /&gt;
===Атом===&lt;br /&gt;
Атомы бывают двух типов: реляционные и арифметические&lt;br /&gt;
====Реляционный====&lt;br /&gt;
Аналог конструкции условия принадлежности из исчисления доменов.&lt;br /&gt;
Есть два вида:&lt;br /&gt;
* Кортеж принадлежит отношению &amp;lt;code&amp;gt;R(x1, x2, ..., xn)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Кортеж не принадлежит отношению &amp;lt;code&amp;gt;¬R(x1, x2, ..., xn)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что в Datalog нет имён атрибутов, атрибуты различаются только по своей позиции.&lt;br /&gt;
&lt;br /&gt;
====Арифметический====&lt;br /&gt;
всевозможные сравнения на равенство/неравенство&lt;br /&gt;
&lt;br /&gt;
==Ограничение отношений==&lt;br /&gt;
Как и на любую другую программу, на синтаксически корректную программу на языке Datalog нужно наложить дополнительные ограничения, чтобы она имела смысл.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим отношения&lt;br /&gt;
 Less(x,y) :- x &amp;lt; y.&lt;br /&gt;
 NotStudent(Id, Name) :- ¬Students(Id, Name, _).&lt;br /&gt;
&lt;br /&gt;
Здесь есть проблема - во-первых, мы даже не знаем тип &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Id&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;Name&amp;lt;/code&amp;gt;, это значит, что мы не знаем области их значения.&lt;br /&gt;
Во-вторых, даже если бы мы знали их тип, пусть это будут, например, целые числа, то получили бы бесконечное отношение, с такими мы работать не умеем.&lt;br /&gt;
&lt;br /&gt;
Поэтому, нужно запретить такую ситуацию, для этого добавим требование:&lt;br /&gt;
&lt;br /&gt;
'''Каждая переменная должна входить в неотрицательный реляционный атом'''&lt;br /&gt;
&lt;br /&gt;
==Рекурсивные запросы==&lt;br /&gt;
Синтаксис Datalog позволяет написать рекурсивный запрос, но может быть не очевидно, какой смысл придавать такой конструкции.&lt;br /&gt;
Далее будет рассмотрен пример и приведены некоторые рассуждения о семантике рекурсивных запросов.&lt;br /&gt;
===Смысл===&lt;br /&gt;
Пусть есть некоторое отношение &amp;quot;потомок-родитель&amp;quot;&lt;br /&gt;
 Parent(Id, ParentId)&lt;br /&gt;
&lt;br /&gt;
Хотим найти его транзитивное замыкание, по определению:&lt;br /&gt;
 Ancestor(Id, PId) :- Parent(Id, PId).&lt;br /&gt;
 Ancestor(Id, GId) :- Parent(Id, GId), Ancestor(PId, GId).&lt;br /&gt;
&lt;br /&gt;
Пусть $P$ - множество всех людей, у которых есть хотя бы один родитель.&lt;br /&gt;
Очевидно, что $P \times P$ есть неподвижная точка, то есть правая часть отношения совпадает с левой, но найденное отношение не является транзитивным замыканием исходного.&lt;br /&gt;
&lt;br /&gt;
Поэтому, следует уточнить, что мы ищем '''минимальную по включению неподвижную точку''', начиная с пустого множества.&lt;br /&gt;
&lt;br /&gt;
===Алгоритм поиска минимальной неподвижной точки===&lt;br /&gt;
&lt;br /&gt;
 Проинициализируем отношения из нерекурсивных определений&lt;br /&gt;
 Пока не достигли неподвижной точки&lt;br /&gt;
   Пополняем отношения из рекурсивных определений&lt;br /&gt;
&lt;br /&gt;
===Циклы и отрицание===&lt;br /&gt;
&lt;br /&gt;
Представим ситуацию, когда принадлежность кортежа к отношению зависит от отрицания его принадлежности к отношению. Это в чистом виде парадокс брадобрея и мы знаем, что такая конструкция не имеет смысла.&lt;br /&gt;
&lt;br /&gt;
Поэтому, введём '''стратифицированное отрицание''', то есть запрет на отрицание в циклах.&lt;/div&gt;</summary>
		<author><name>5.18.184.8</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Datalog_%D0%B8_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F&amp;diff=81508</id>
		<title>Datalog и рекурсия</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Datalog_%D0%B8_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F&amp;diff=81508"/>
				<updated>2021-12-19T20:42:56Z</updated>
		
		<summary type="html">&lt;p&gt;5.18.184.8: /* Синтаксис */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Язык Datalog==&lt;br /&gt;
Декларативный язык для запросов к базам данных на основе исчисления доменов. Разработан в 1978 году, синтаксически - подмножество языка Prolog. Широкого применения в реальных базах данных не получил, но повлиял на формирование более поздних языков для запросов, таких как SQL.&lt;br /&gt;
&lt;br /&gt;
==Синтаксис==&lt;br /&gt;
Программа на Datalog - набор '''отношений''': Отношение на языке Datalog определяется так: &amp;lt;code&amp;gt;Отношение(x1,x2...xn) :- Цель.&amp;lt;/code&amp;gt;. Определение одного и того же отношения может повторяться несколько раз, тогда в это отношение будут входить кортежи, которые удовлетворяют хотя бы одной цели.&lt;br /&gt;
&lt;br /&gt;
'''Цель''' в свою очередь - это набор '''атомов''', перечисленных через запятую. Кортеж удовлетворяет цели, если он удовлетворяет всем атомам цели.&lt;br /&gt;
===Атом===&lt;br /&gt;
Атомы бывают двух типов: реляционные и арифметические&lt;br /&gt;
====Реляционный====&lt;br /&gt;
Аналог конструкции условия принадлежности из исчисления доменов.&lt;br /&gt;
Есть два вида:&lt;br /&gt;
* Кортеж принадлежит отношению &amp;lt;code&amp;gt;R(x1, x2, ..., xn)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Кортеж не принадлежит отношению &amp;lt;code&amp;gt;¬R(x1, x2, ..., xn)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что в Datalog нет имён атрибутов, атрибуты различаются только по своей позиции.&lt;br /&gt;
&lt;br /&gt;
====Арифметический====&lt;br /&gt;
всевозможные сравнения на равенство/неравенство&lt;br /&gt;
&lt;br /&gt;
==Ограничение отношений==&lt;br /&gt;
Как и на любую другую программу, на синтаксически корректную программу на языке Datalog нужно наложить дополнительные ограничения, чтобы она имела смысл.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим отношения&lt;br /&gt;
 Less(x,y) :- x &amp;lt; y.&lt;br /&gt;
 NotStudent(Id, Name) :- ¬Students(Id, Name, _).&lt;br /&gt;
&lt;br /&gt;
Здесь есть проблема - во-первых, мы даже не знаем тип &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Id&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;Name&amp;lt;/code&amp;gt;, это значит, что мы не знаем области их значения.&lt;br /&gt;
Во-вторых, даже если бы мы знали их тип, пусть это будут, например, целые числа, то получили бы бесконечное отношение, с такими мы работать не умеем.&lt;br /&gt;
&lt;br /&gt;
Поэтому, нужно запретить такую ситуацию, для этого добавим требование:&lt;br /&gt;
&lt;br /&gt;
'''Каждая переменная должна входить в неотрицательный реляционный атом'''&lt;br /&gt;
&lt;br /&gt;
==Рекурсивные запросы==&lt;br /&gt;
===Смысл===&lt;br /&gt;
Пусть есть некоторое отношение &amp;quot;потомок-родитель&amp;quot;&lt;br /&gt;
 Parent(Id, ParentId)&lt;br /&gt;
&lt;br /&gt;
Хотим найти его транзитивное замыкание, по определению:&lt;br /&gt;
 Ancestor(Id, PId) :- Parent(Id, PId).&lt;br /&gt;
 Ancestor(Id, GId) :- Parent(Id, GId), Ancestor(PId, GId).&lt;br /&gt;
&lt;br /&gt;
Пусть $P$ - множество всех людей, у которых есть хотя бы один родитель.&lt;br /&gt;
Очевидно, что $P \times P$ есть неподвижная точка, но найденное отношение не является транзитивным замыканием.&lt;br /&gt;
&lt;br /&gt;
Поэтому, следует уточнить, что мы ищем '''минимальную по включению неподвижную точку'''.&lt;br /&gt;
&lt;br /&gt;
===Алгоритм поиска минимальной неподвижной точки===&lt;br /&gt;
&lt;br /&gt;
 Проинициализируем отношения из нерекурсивных определений&lt;br /&gt;
 Пока не достигли неподвижной точки&lt;br /&gt;
   Пополняем отношения из рекурсивных определений&lt;br /&gt;
&lt;br /&gt;
===Циклы и отрицание===&lt;br /&gt;
&lt;br /&gt;
Представим ситуацию, когда принадлежность кортежа к отношению зависит от отрицания его принадлежности к отношению. Это в чистом виде парадокс брадобрея и мы знаем, что такая конструкция не имеет смысла.&lt;br /&gt;
&lt;br /&gt;
Поэтому, введём '''стратифицированное отрицание''', то есть запрет на отрицание в циклах.&lt;/div&gt;</summary>
		<author><name>5.18.184.8</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Datalog_%D0%B8_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F&amp;diff=81503</id>
		<title>Datalog и рекурсия</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Datalog_%D0%B8_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F&amp;diff=81503"/>
				<updated>2021-12-19T20:35:45Z</updated>
		
		<summary type="html">&lt;p&gt;5.18.184.8: /* Язык Datalog */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Язык Datalog==&lt;br /&gt;
Декларативный язык для запросов к базам данных на основе исчисления доменов. Разработан в 1978 году, синтаксически - подмножество языка Prolog. Широкого применения в реальных базах данных не получил, но повлиял на формирование более поздних языков для запросов, таких как SQL.&lt;br /&gt;
&lt;br /&gt;
==Синтаксис==&lt;br /&gt;
Программа на Datalog - набор '''отношений''': Отношение на языке Datalog определяется так: &amp;lt;code&amp;gt;Отношение(x1,x2...xn) :- Цель.&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Цель''' в свою очередь - это набор '''атомов''', перечисленных через запятую&lt;br /&gt;
===Атом===&lt;br /&gt;
Атомы бывают двух типов: реляционные и арифметические&lt;br /&gt;
====Реляционный====&lt;br /&gt;
Аналог конструкции условия принадлежности из исчисления доменов.&lt;br /&gt;
Есть два вида:&lt;br /&gt;
* Кортеж принадлежит отношению &amp;lt;code&amp;gt;R(x1, x2, ..., xn)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Кортеж не принадлежит отношению &amp;lt;code&amp;gt;¬R(x1, x2, ..., xn)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что в Datalog нет имён атрибутов, атрибуты различаются только по своей позиции.&lt;br /&gt;
&lt;br /&gt;
====Арифметический====&lt;br /&gt;
всевозможные сравнения на равенство/неравенство&lt;br /&gt;
&lt;br /&gt;
==Ограничение отношений==&lt;br /&gt;
Как и на любую другую программу, на синтаксически корректную программу на языке Datalog нужно наложить дополнительные ограничения, чтобы она имела смысл.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим отношения&lt;br /&gt;
 Less(x,y) :- x &amp;lt; y.&lt;br /&gt;
 NotStudent(Id, Name) :- ¬Students(Id, Name, _).&lt;br /&gt;
&lt;br /&gt;
Здесь есть проблема - во-первых, мы даже не знаем тип &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Id&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;Name&amp;lt;/code&amp;gt;, это значит, что мы не знаем области их значения.&lt;br /&gt;
Во-вторых, даже если бы мы знали их тип, пусть это будут, например, целые числа, то получили бы бесконечное отношение, с такими мы работать не умеем.&lt;br /&gt;
&lt;br /&gt;
Поэтому, нужно запретить такую ситуацию, для этого добавим требование:&lt;br /&gt;
&lt;br /&gt;
'''Каждая переменная должна входить в неотрицательный реляционный атом'''&lt;br /&gt;
&lt;br /&gt;
==Рекурсивные запросы==&lt;br /&gt;
===Смысл===&lt;br /&gt;
Пусть есть некоторое отношение &amp;quot;потомок-родитель&amp;quot;&lt;br /&gt;
 Parent(Id, ParentId)&lt;br /&gt;
&lt;br /&gt;
Хотим найти его транзитивное замыкание, по определению:&lt;br /&gt;
 Ancestor(Id, PId) :- Parent(Id, PId).&lt;br /&gt;
 Ancestor(Id, GId) :- Parent(Id, GId), Ancestor(PId, GId).&lt;br /&gt;
&lt;br /&gt;
Пусть $P$ - множество всех людей, у которых есть хотя бы один родитель.&lt;br /&gt;
Очевидно, что $P \times P$ есть неподвижная точка, но найденное отношение не является транзитивным замыканием.&lt;br /&gt;
&lt;br /&gt;
Поэтому, следует уточнить, что мы ищем '''минимальную по включению неподвижную точку'''.&lt;br /&gt;
&lt;br /&gt;
===Алгоритм поиска минимальной неподвижной точки===&lt;br /&gt;
&lt;br /&gt;
 Проинициализируем отношения из нерекурсивных определений&lt;br /&gt;
 Пока не достигли неподвижной точки&lt;br /&gt;
   Пополняем отношения из рекурсивных определений&lt;br /&gt;
&lt;br /&gt;
===Циклы и отрицание===&lt;br /&gt;
&lt;br /&gt;
Представим ситуацию, когда принадлежность кортежа к отношению зависит от отрицания его принадлежности к отношению. Это в чистом виде парадокс брадобрея и мы знаем, что такая конструкция не имеет смысла.&lt;br /&gt;
&lt;br /&gt;
Поэтому, введём '''стратифицированное отрицание''', то есть запрет на отрицание в циклах.&lt;/div&gt;</summary>
		<author><name>5.18.184.8</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Datalog_%D0%B8_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F&amp;diff=81502</id>
		<title>Datalog и рекурсия</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Datalog_%D0%B8_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F&amp;diff=81502"/>
				<updated>2021-12-19T20:35:17Z</updated>
		
		<summary type="html">&lt;p&gt;5.18.184.8: /* Язык Datalog */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Язык Datalog==&lt;br /&gt;
Декларативный язык для запросов к базам данных на основе исчисления доменов. Разработан в 1978 году, синтаксически - подмножество языка Prolog. Широкого применения в реальных базах данных не получил, но повлиял на формирование более поздних языков для запросов, таких как SQL. &lt;br /&gt;
&lt;br /&gt;
Программа на языке Datalog представляет из себя набор определений отношений, результат выполнения - тело одного из отношений.&lt;br /&gt;
&lt;br /&gt;
==Синтаксис==&lt;br /&gt;
Программа на Datalog - набор '''отношений''': Отношение на языке Datalog определяется так: &amp;lt;code&amp;gt;Отношение(x1,x2...xn) :- Цель.&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Цель''' в свою очередь - это набор '''атомов''', перечисленных через запятую&lt;br /&gt;
===Атом===&lt;br /&gt;
Атомы бывают двух типов: реляционные и арифметические&lt;br /&gt;
====Реляционный====&lt;br /&gt;
Аналог конструкции условия принадлежности из исчисления доменов.&lt;br /&gt;
Есть два вида:&lt;br /&gt;
* Кортеж принадлежит отношению &amp;lt;code&amp;gt;R(x1, x2, ..., xn)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Кортеж не принадлежит отношению &amp;lt;code&amp;gt;¬R(x1, x2, ..., xn)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что в Datalog нет имён атрибутов, атрибуты различаются только по своей позиции.&lt;br /&gt;
&lt;br /&gt;
====Арифметический====&lt;br /&gt;
всевозможные сравнения на равенство/неравенство&lt;br /&gt;
&lt;br /&gt;
==Ограничение отношений==&lt;br /&gt;
Как и на любую другую программу, на синтаксически корректную программу на языке Datalog нужно наложить дополнительные ограничения, чтобы она имела смысл.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим отношения&lt;br /&gt;
 Less(x,y) :- x &amp;lt; y.&lt;br /&gt;
 NotStudent(Id, Name) :- ¬Students(Id, Name, _).&lt;br /&gt;
&lt;br /&gt;
Здесь есть проблема - во-первых, мы даже не знаем тип &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Id&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;Name&amp;lt;/code&amp;gt;, это значит, что мы не знаем области их значения.&lt;br /&gt;
Во-вторых, даже если бы мы знали их тип, пусть это будут, например, целые числа, то получили бы бесконечное отношение, с такими мы работать не умеем.&lt;br /&gt;
&lt;br /&gt;
Поэтому, нужно запретить такую ситуацию, для этого добавим требование:&lt;br /&gt;
&lt;br /&gt;
'''Каждая переменная должна входить в неотрицательный реляционный атом'''&lt;br /&gt;
&lt;br /&gt;
==Рекурсивные запросы==&lt;br /&gt;
===Смысл===&lt;br /&gt;
Пусть есть некоторое отношение &amp;quot;потомок-родитель&amp;quot;&lt;br /&gt;
 Parent(Id, ParentId)&lt;br /&gt;
&lt;br /&gt;
Хотим найти его транзитивное замыкание, по определению:&lt;br /&gt;
 Ancestor(Id, PId) :- Parent(Id, PId).&lt;br /&gt;
 Ancestor(Id, GId) :- Parent(Id, GId), Ancestor(PId, GId).&lt;br /&gt;
&lt;br /&gt;
Пусть $P$ - множество всех людей, у которых есть хотя бы один родитель.&lt;br /&gt;
Очевидно, что $P \times P$ есть неподвижная точка, но найденное отношение не является транзитивным замыканием.&lt;br /&gt;
&lt;br /&gt;
Поэтому, следует уточнить, что мы ищем '''минимальную по включению неподвижную точку'''.&lt;br /&gt;
&lt;br /&gt;
===Алгоритм поиска минимальной неподвижной точки===&lt;br /&gt;
&lt;br /&gt;
 Проинициализируем отношения из нерекурсивных определений&lt;br /&gt;
 Пока не достигли неподвижной точки&lt;br /&gt;
   Пополняем отношения из рекурсивных определений&lt;br /&gt;
&lt;br /&gt;
===Циклы и отрицание===&lt;br /&gt;
&lt;br /&gt;
Представим ситуацию, когда принадлежность кортежа к отношению зависит от отрицания его принадлежности к отношению. Это в чистом виде парадокс брадобрея и мы знаем, что такая конструкция не имеет смысла.&lt;br /&gt;
&lt;br /&gt;
Поэтому, введём '''стратифицированное отрицание''', то есть запрет на отрицание в циклах.&lt;/div&gt;</summary>
		<author><name>5.18.184.8</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D1%81%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B4%D0%BE%D0%BC%D0%B5%D0%BD%D0%BE%D0%B2_%D0%B8_%D0%B5%D0%B3%D0%BE_%D1%80%D0%B5%D0%BB%D1%8F%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D1%82%D0%B0&amp;diff=81501</id>
		<title>Исчисление доменов и его реляционная полнота</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D1%81%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B4%D0%BE%D0%BC%D0%B5%D0%BD%D0%BE%D0%B2_%D0%B8_%D0%B5%D0%B3%D0%BE_%D1%80%D0%B5%D0%BB%D1%8F%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D1%82%D0%B0&amp;diff=81501"/>
				<updated>2021-12-19T20:24:18Z</updated>
		
		<summary type="html">&lt;p&gt;5.18.184.8: /* Реляционная полнота исчисления доменов */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Исчисление доменов==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Исчисление доменов''' {{---}} вид реляционного исчисления, в котором значения переменных принадлежат заранее определённым ''доменам''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Домен следует понимать как какое-то именованное множество допустимых значений для переменных. На современном языке, это понятие достаточно близко к понятию типа.&lt;br /&gt;
&lt;br /&gt;
Введём синтаксис для указания типов переменных. Также введём предикат, будем называть его ''условием принадлежности'', который для заданного отношения и значений атрибутов проверяет, есть ли совпадающий кортеж в отношении.&lt;br /&gt;
&lt;br /&gt;
===Синтаксис===&lt;br /&gt;
 &amp;lt;font color=red&amp;gt;Переменная&amp;lt;/font&amp;gt; :: &amp;lt;font color=red&amp;gt;Тип&amp;lt;/font&amp;gt; &amp;lt;font color=green&amp;gt;-- Переменная может принимать значения из какого-то типа. Тип == набор значений&lt;br /&gt;
 &amp;lt;/font&amp;gt;&lt;br /&gt;
  &amp;lt;font color=green&amp;gt;-- Условие принадлежности отношению&amp;lt;/font&amp;gt;&lt;br /&gt;
 &amp;lt;font color=red&amp;gt;Отношение {&amp;lt;/font&amp;gt;&lt;br /&gt;
   &amp;lt;font color=red&amp;gt;Атрибут1&amp;lt;/font&amp;gt; = &amp;lt;font color=red&amp;gt;Значение1&amp;lt;/font&amp;gt;,&lt;br /&gt;
   &amp;lt;font color=red&amp;gt;Атрибут2&amp;lt;/font&amp;gt; = &amp;lt;font color=red&amp;gt;Значение2&amp;lt;/font&amp;gt;,&lt;br /&gt;
   ...&lt;br /&gt;
 &amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Примеры использования условия принадлежности===&lt;br /&gt;
Следующий предикат будет истинным, если в отношении S найдётся кортеж &amp;lt;code&amp;gt;(FirstName = 'Иван', LastName = 'Иванов')&amp;lt;/code&amp;gt; или, например (при наличии ещё одного атрибута), &amp;lt;code&amp;gt;(FirstName = 'Иван', LastName = 'Иванов', Email = 'ivan@example.com')&amp;lt;/code&amp;gt; и ложным, если ни в одном кортеже не совпали все значения атрибутов с перечисленными&lt;br /&gt;
&lt;br /&gt;
 S&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;FirstName = &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;, LastName = &amp;lt;font color=green&amp;gt;'Иванов'&amp;lt;/font&amp;gt;&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Имя атрибута может совпадать с именем переменной, это может поначалу немного запутывать. Слева от знака равенства стоит имя атрибута, справа - значение, с которым атрибут сравниваем&lt;br /&gt;
&lt;br /&gt;
 S&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;FirstName = FirstName, LastName = LastName&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Примеры запросов===&lt;br /&gt;
=====Идентификаторы всех студентов=====&lt;br /&gt;
Запишем запрос для получения идентификаторов всех студентов. Можно представлять это так: единственная свободная переменная SId пробегает все возможные значения из домена (все возможные идентификаторы студентов), а в результирующее отношение попадают только те её значения, для которых реально существовал такой студент.&lt;br /&gt;
&lt;br /&gt;
 SId &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; S&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;SId = SId&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Идентификаторы студентов, не сдавших курс с CId=10=====&lt;br /&gt;
Также как и в исчислении кортежей, в исчислении доменов можно использовать кванторы. Студент не сдал курс, если у него нет положительных оценок за этот курс.&lt;br /&gt;
&lt;br /&gt;
 SId &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; ¬∃Points (Points ≥ 60 ∧ Points&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;SId = SId, Points = Points, CId = 10&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
==Реляционная полнота исчисления доменов==&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Исчисление доменов реляционно полно&lt;br /&gt;
|proof=&lt;br /&gt;
Выразим базис реляционной алгебры в терминах исчисления доменов:&lt;br /&gt;
&lt;br /&gt;
'''Проекция $\pi_{A_1, ..., A_n}(R)$''' Выбираем только такие наборы значений $A_1$...$A_n$, которые есть в исходном отношении R. Это важно, тк если опустить &amp;lt;code&amp;gt;where&amp;lt;/code&amp;gt;, то получим декартово произведение доменов&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;from&amp;lt;/font&amp;gt; $R$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_1$ = $A_1$, ..., $A_n$ = $A_n$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Фильтр $σ_θ(R)$'''&lt;br /&gt;
Выбираем только такие наборы значений $A_1$...$A_n$, которые есть в исходном отношении R и удовлетворяют условию θ&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;from&amp;lt;/font&amp;gt; $R$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_1$ = $A_1$, ..., $A_n$ = $A_n$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $θ$&lt;br /&gt;
&lt;br /&gt;
'''Переименовывание $ε_{A=expr}(R_1)$''' &lt;br /&gt;
Просто используем специальный синтаксис&lt;br /&gt;
 ..., $expr$ as $A$, ... &amp;lt;font color=blue&amp;gt;from&amp;lt;/font&amp;gt; $R$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R${$A_1$ = $A_1$, ..., $A_n$ = $A_n$}&lt;br /&gt;
&lt;br /&gt;
'''Объединение $R_1 ∪ R_2$'''&lt;br /&gt;
Выбираем только такие наборы значений $A_1$...$A_n$, что хотя бы в одном из отношений есть соответствующий кортеж&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∨ $R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Разность $R_1 ∖ R_2$'''&lt;br /&gt;
Выбираем только такие наборы значений $A_1$...$A_n$, что соответствующий кортеж есть в $R_1$, но нет в $R_2$&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $¬R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Декартово произведение $R_1 × R_2$'''&lt;br /&gt;
Выбираем наборы значений  $A_1$, ..., $A_n$, $B_1$, ..., $B_m$ такие, что $A_1$...$A_n$ есть в $R_1$, а $B_1$...$B_n$ есть в $R_2$&lt;br /&gt;
 $A_1$, ..., $A_n$, $B_1$, ..., $B_m$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$B_j$ = $B_j$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Естественное соединение $R_1 ⋈ R_2$''' &lt;br /&gt;
Выбираем такие наборы значений $A_1$, ..., $A_n$, $B_1$, ..., $B_m$, $C_1$, ..., $C_l$, что $B_1$, ..., $B_m$ совпадает с соответствующими атрибутами и $R_1$ и $R_2$. Это можно записать как с явной проверкой равенства этих атрибутов (тогда придётся использовать ещё m переменных), так и с неявной, как это сделано здесь.&lt;br /&gt;
 $A_1$, ..., $A_n$, $B_1$, ..., $B_m$, $C_1$, ..., $C_l$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$, $B_j$ = $B_j$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$C_k$ = $C_k$, $B_j$ = $B_j$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>5.18.184.8</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D1%81%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B4%D0%BE%D0%BC%D0%B5%D0%BD%D0%BE%D0%B2_%D0%B8_%D0%B5%D0%B3%D0%BE_%D1%80%D0%B5%D0%BB%D1%8F%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D1%82%D0%B0&amp;diff=81498</id>
		<title>Исчисление доменов и его реляционная полнота</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D1%81%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B4%D0%BE%D0%BC%D0%B5%D0%BD%D0%BE%D0%B2_%D0%B8_%D0%B5%D0%B3%D0%BE_%D1%80%D0%B5%D0%BB%D1%8F%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D1%82%D0%B0&amp;diff=81498"/>
				<updated>2021-12-19T20:04:20Z</updated>
		
		<summary type="html">&lt;p&gt;5.18.184.8: /* Реляционная полнота исчисления доменов */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Исчисление доменов==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Исчисление доменов''' {{---}} вид реляционного исчисления, в котором значения переменных принадлежат заранее определённым ''доменам''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Домен следует понимать как какое-то именованное множество допустимых значений для переменных. На современном языке, это понятие достаточно близко к понятию типа.&lt;br /&gt;
&lt;br /&gt;
Введём синтаксис для указания типов переменных. Также введём предикат, будем называть его ''условием принадлежности'', который для заданного отношения и значений атрибутов проверяет, есть ли совпадающий кортеж в отношении.&lt;br /&gt;
&lt;br /&gt;
===Синтаксис===&lt;br /&gt;
 &amp;lt;font color=red&amp;gt;Переменная&amp;lt;/font&amp;gt; :: &amp;lt;font color=red&amp;gt;Тип&amp;lt;/font&amp;gt; &amp;lt;font color=green&amp;gt;-- Переменная может принимать значения из какого-то типа. Тип == набор значений&lt;br /&gt;
 &amp;lt;/font&amp;gt;&lt;br /&gt;
  &amp;lt;font color=green&amp;gt;-- Условие принадлежности отношению&amp;lt;/font&amp;gt;&lt;br /&gt;
 &amp;lt;font color=red&amp;gt;Отношение {&amp;lt;/font&amp;gt;&lt;br /&gt;
   &amp;lt;font color=red&amp;gt;Атрибут1&amp;lt;/font&amp;gt; = &amp;lt;font color=red&amp;gt;Значение1&amp;lt;/font&amp;gt;,&lt;br /&gt;
   &amp;lt;font color=red&amp;gt;Атрибут2&amp;lt;/font&amp;gt; = &amp;lt;font color=red&amp;gt;Значение2&amp;lt;/font&amp;gt;,&lt;br /&gt;
   ...&lt;br /&gt;
 &amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Примеры использования условия принадлежности===&lt;br /&gt;
Следующий предикат будет истинным, если в отношении S найдётся кортеж &amp;lt;code&amp;gt;(FirstName = 'Иван', LastName = 'Иванов')&amp;lt;/code&amp;gt; или, например (при наличии ещё одного атрибута), &amp;lt;code&amp;gt;(FirstName = 'Иван', LastName = 'Иванов', Email = 'ivan@example.com')&amp;lt;/code&amp;gt; и ложным, если ни в одном кортеже не совпали все значения атрибутов с перечисленными&lt;br /&gt;
&lt;br /&gt;
 S&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;FirstName = &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;, LastName = &amp;lt;font color=green&amp;gt;'Иванов'&amp;lt;/font&amp;gt;&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Имя атрибута может совпадать с именем переменной, это может поначалу немного запутывать. Слева от знака равенства стоит имя атрибута, справа - значение, с которым атрибут сравниваем&lt;br /&gt;
&lt;br /&gt;
 S&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;FirstName = FirstName, LastName = LastName&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Примеры запросов===&lt;br /&gt;
=====Идентификаторы всех студентов=====&lt;br /&gt;
Запишем запрос для получения идентификаторов всех студентов. Можно представлять это так: единственная свободная переменная SId пробегает все возможные значения из домена (все возможные идентификаторы студентов), а в результирующее отношение попадают только те её значения, для которых реально существовал такой студент.&lt;br /&gt;
&lt;br /&gt;
 SId &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; S&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;SId = SId&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Идентификаторы студентов, не сдавших курс с CId=10=====&lt;br /&gt;
Также как и в исчислении кортежей, в исчислении доменов можно использовать кванторы. Студент не сдал курс, если у него нет положительных оценок за этот курс.&lt;br /&gt;
&lt;br /&gt;
 SId &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; ¬∃Points (Points ≥ 60 ∧ Points&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;SId = SId, Points = Points, CId = 10&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
==Реляционная полнота исчисления доменов==&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Исчисление доменов реляционно полно&lt;br /&gt;
|proof=&lt;br /&gt;
Выразим базис реляционной алгебры в терминах исчисления доменов:&lt;br /&gt;
&lt;br /&gt;
'''Проекция $\pi_{A_1, ..., A_n}(R)$'''&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;from&amp;lt;/font&amp;gt; $R$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_1$ = $A_1$, ..., $A_n$ = $A_n$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Фильтр $σ_θ(R)$'''&lt;br /&gt;
Выбираем только такие наборы значений $A_1$...$A_n$, которые есть в исходном отношении R и удовлетворяют условию θ&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;from&amp;lt;/font&amp;gt; $R$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_1$ = $A_1$, ..., $A_n$ = $A_n$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $θ$&lt;br /&gt;
&lt;br /&gt;
'''Переименовывание $ε_{A=expr}(R_1)$'''&lt;br /&gt;
 expr as A &amp;lt;font color=blue&amp;gt;from&amp;lt;/font&amp;gt; $R$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R${$A_1$ = $A_1$, ..., $A_n$ = $A_n$}&lt;br /&gt;
&lt;br /&gt;
'''Объединение $R_1 ∪ R_2$'''&lt;br /&gt;
Выбираем только такие наборы значений $A_1$...$A_n$, что хотя бы в одном из отношений есть соответствующий кортеж&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∨ $R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Разность $R_1 ∖ R_2$'''&lt;br /&gt;
Выбираем только такие наборы значений $A_1$...$A_n$, что соответствующий кортеж есть в $R_1$, но нет в $R_2$&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $¬R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Декартово произведение $R_1 × R_2$'''&lt;br /&gt;
Выбираем наборы значений  $A_1$, ..., $A_n$, $B_1$, ..., $B_m$ такие, что $A_1$...$A_n$ есть в $R_1$, а $B_1$...$B_n$ есть в $R_2$&lt;br /&gt;
 $A_1$, ..., $A_n$, $B_1$, ..., $B_m$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$B_j$ = $B_j$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Естественное соединение $R_1 ⋈ R_2$'''&lt;br /&gt;
 $A_1$, ..., $A_n$, $B_1$, ..., $B_m$, $C_1$, ..., $C_l$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$, $B_j$ = $B_j$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$C_k$ = $C_k$, $B_j$ = $B_j$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>5.18.184.8</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D1%81%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B4%D0%BE%D0%BC%D0%B5%D0%BD%D0%BE%D0%B2_%D0%B8_%D0%B5%D0%B3%D0%BE_%D1%80%D0%B5%D0%BB%D1%8F%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D1%82%D0%B0&amp;diff=81497</id>
		<title>Исчисление доменов и его реляционная полнота</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D1%81%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B4%D0%BE%D0%BC%D0%B5%D0%BD%D0%BE%D0%B2_%D0%B8_%D0%B5%D0%B3%D0%BE_%D1%80%D0%B5%D0%BB%D1%8F%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D1%82%D0%B0&amp;diff=81497"/>
				<updated>2021-12-19T19:53:02Z</updated>
		
		<summary type="html">&lt;p&gt;5.18.184.8: /* Реляционная полнота исчисления доменов */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Исчисление доменов==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Исчисление доменов''' {{---}} вид реляционного исчисления, в котором значения переменных принадлежат заранее определённым ''доменам''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Домен следует понимать как какое-то именованное множество допустимых значений для переменных. На современном языке, это понятие достаточно близко к понятию типа.&lt;br /&gt;
&lt;br /&gt;
Введём синтаксис для указания типов переменных. Также введём предикат, будем называть его ''условием принадлежности'', который для заданного отношения и значений атрибутов проверяет, есть ли совпадающий кортеж в отношении.&lt;br /&gt;
&lt;br /&gt;
===Синтаксис===&lt;br /&gt;
 &amp;lt;font color=red&amp;gt;Переменная&amp;lt;/font&amp;gt; :: &amp;lt;font color=red&amp;gt;Тип&amp;lt;/font&amp;gt; &amp;lt;font color=green&amp;gt;-- Переменная может принимать значения из какого-то типа. Тип == набор значений&lt;br /&gt;
 &amp;lt;/font&amp;gt;&lt;br /&gt;
  &amp;lt;font color=green&amp;gt;-- Условие принадлежности отношению&amp;lt;/font&amp;gt;&lt;br /&gt;
 &amp;lt;font color=red&amp;gt;Отношение {&amp;lt;/font&amp;gt;&lt;br /&gt;
   &amp;lt;font color=red&amp;gt;Атрибут1&amp;lt;/font&amp;gt; = &amp;lt;font color=red&amp;gt;Значение1&amp;lt;/font&amp;gt;,&lt;br /&gt;
   &amp;lt;font color=red&amp;gt;Атрибут2&amp;lt;/font&amp;gt; = &amp;lt;font color=red&amp;gt;Значение2&amp;lt;/font&amp;gt;,&lt;br /&gt;
   ...&lt;br /&gt;
 &amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Примеры использования условия принадлежности===&lt;br /&gt;
Следующий предикат будет истинным, если в отношении S найдётся кортеж &amp;lt;code&amp;gt;(FirstName = 'Иван', LastName = 'Иванов')&amp;lt;/code&amp;gt; или, например (при наличии ещё одного атрибута), &amp;lt;code&amp;gt;(FirstName = 'Иван', LastName = 'Иванов', Email = 'ivan@example.com')&amp;lt;/code&amp;gt; и ложным, если ни в одном кортеже не совпали все значения атрибутов с перечисленными&lt;br /&gt;
&lt;br /&gt;
 S&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;FirstName = &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;, LastName = &amp;lt;font color=green&amp;gt;'Иванов'&amp;lt;/font&amp;gt;&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Имя атрибута может совпадать с именем переменной, это может поначалу немного запутывать. Слева от знака равенства стоит имя атрибута, справа - значение, с которым атрибут сравниваем&lt;br /&gt;
&lt;br /&gt;
 S&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;FirstName = FirstName, LastName = LastName&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Примеры запросов===&lt;br /&gt;
=====Идентификаторы всех студентов=====&lt;br /&gt;
Запишем запрос для получения идентификаторов всех студентов. Можно представлять это так: единственная свободная переменная SId пробегает все возможные значения из домена (все возможные идентификаторы студентов), а в результирующее отношение попадают только те её значения, для которых реально существовал такой студент.&lt;br /&gt;
&lt;br /&gt;
 SId &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; S&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;SId = SId&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Идентификаторы студентов, не сдавших курс с CId=10=====&lt;br /&gt;
Также как и в исчислении кортежей, в исчислении доменов можно использовать кванторы. Студент не сдал курс, если у него нет положительных оценок за этот курс.&lt;br /&gt;
&lt;br /&gt;
 SId &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; ¬∃Points (Points ≥ 60 ∧ Points&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;SId = SId, Points = Points, CId = 10&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
==Реляционная полнота исчисления доменов==&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Исчисление доменов реляционно полно&lt;br /&gt;
|proof=&lt;br /&gt;
Выразим базис реляционной алгебры в терминах исчисления доменов:&lt;br /&gt;
&lt;br /&gt;
====Проекция $\pi_{A_1, ..., A_n}(R)$====&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;from&amp;lt;/font&amp;gt; $R$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_1$ = $A_1$, ..., $A_n$ = $A_n$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Фильтр $σ_θ(R)$====&lt;br /&gt;
Выбираем только такие наборы значений $A_1$...$A_n$, которые есть в исходном отношении R и удовлетворяют условию θ&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;from&amp;lt;/font&amp;gt; $R$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_1$ = $A_1$, ..., $A_n$ = $A_n$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $θ$&lt;br /&gt;
&lt;br /&gt;
====Переименовывание $ε_{A=expr}(R_1)$====&lt;br /&gt;
 expr as A &amp;lt;font color=blue&amp;gt;from&amp;lt;/font&amp;gt; $R$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R${$A_1$ = $A_1$, ..., $A_n$ = $A_n$}&lt;br /&gt;
&lt;br /&gt;
====Объединение $R_1 ∪ R_2$====&lt;br /&gt;
Выбираем только такие наборы значений $A_1$...$A_n$, что хотя бы в одном из отношений есть соответствующий кортеж&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∨ $R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Разность $R_1 ∖ R_2$====&lt;br /&gt;
Выбираем только такие наборы значений $A_1$...$A_n$, что соответствующий кортеж есть в $R_1$, но нет в $R_2$&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $¬R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Декартово произведение $R_1 × R_2$====&lt;br /&gt;
Выбирает наборы значений  $A_1$, ..., $A_n$, $B_1$, ..., $B_m$ такие, что $A_1$...$A_n$ есть в $R_1$, а $B_1$...$B_n$ есть в $R_2$&lt;br /&gt;
 $A_1$, ..., $A_n$, $B_1$, ..., $B_m$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$B_j$ = $B_j$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Естественное соединение $R_1 ⋈ R_2$====&lt;br /&gt;
 $A_1$, ..., $A_n$, $B_1$, ..., $B_m$, $C_1$, ..., $C_l$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$, $B_j$ = $B_j$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$C_k$ = $C_k$, $B_j$ = $B_j$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>5.18.184.8</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D1%81%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B4%D0%BE%D0%BC%D0%B5%D0%BD%D0%BE%D0%B2_%D0%B8_%D0%B5%D0%B3%D0%BE_%D1%80%D0%B5%D0%BB%D1%8F%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D1%82%D0%B0&amp;diff=81496</id>
		<title>Исчисление доменов и его реляционная полнота</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D1%81%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B4%D0%BE%D0%BC%D0%B5%D0%BD%D0%BE%D0%B2_%D0%B8_%D0%B5%D0%B3%D0%BE_%D1%80%D0%B5%D0%BB%D1%8F%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D1%82%D0%B0&amp;diff=81496"/>
				<updated>2021-12-19T19:47:22Z</updated>
		
		<summary type="html">&lt;p&gt;5.18.184.8: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Исчисление доменов==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Исчисление доменов''' {{---}} вид реляционного исчисления, в котором значения переменных принадлежат заранее определённым ''доменам''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Домен следует понимать как какое-то именованное множество допустимых значений для переменных. На современном языке, это понятие достаточно близко к понятию типа.&lt;br /&gt;
&lt;br /&gt;
Введём синтаксис для указания типов переменных. Также введём предикат, будем называть его ''условием принадлежности'', который для заданного отношения и значений атрибутов проверяет, есть ли совпадающий кортеж в отношении.&lt;br /&gt;
&lt;br /&gt;
===Синтаксис===&lt;br /&gt;
 &amp;lt;font color=red&amp;gt;Переменная&amp;lt;/font&amp;gt; :: &amp;lt;font color=red&amp;gt;Тип&amp;lt;/font&amp;gt; &amp;lt;font color=green&amp;gt;-- Переменная может принимать значения из какого-то типа. Тип == набор значений&lt;br /&gt;
 &amp;lt;/font&amp;gt;&lt;br /&gt;
  &amp;lt;font color=green&amp;gt;-- Условие принадлежности отношению&amp;lt;/font&amp;gt;&lt;br /&gt;
 &amp;lt;font color=red&amp;gt;Отношение {&amp;lt;/font&amp;gt;&lt;br /&gt;
   &amp;lt;font color=red&amp;gt;Атрибут1&amp;lt;/font&amp;gt; = &amp;lt;font color=red&amp;gt;Значение1&amp;lt;/font&amp;gt;,&lt;br /&gt;
   &amp;lt;font color=red&amp;gt;Атрибут2&amp;lt;/font&amp;gt; = &amp;lt;font color=red&amp;gt;Значение2&amp;lt;/font&amp;gt;,&lt;br /&gt;
   ...&lt;br /&gt;
 &amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Примеры использования условия принадлежности===&lt;br /&gt;
Следующий предикат будет истинным, если в отношении S найдётся кортеж &amp;lt;code&amp;gt;(FirstName = 'Иван', LastName = 'Иванов')&amp;lt;/code&amp;gt; или, например (при наличии ещё одного атрибута), &amp;lt;code&amp;gt;(FirstName = 'Иван', LastName = 'Иванов', Email = 'ivan@example.com')&amp;lt;/code&amp;gt; и ложным, если ни в одном кортеже не совпали все значения атрибутов с перечисленными&lt;br /&gt;
&lt;br /&gt;
 S&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;FirstName = &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;, LastName = &amp;lt;font color=green&amp;gt;'Иванов'&amp;lt;/font&amp;gt;&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Имя атрибута может совпадать с именем переменной, это может поначалу немного запутывать. Слева от знака равенства стоит имя атрибута, справа - значение, с которым атрибут сравниваем&lt;br /&gt;
&lt;br /&gt;
 S&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;FirstName = FirstName, LastName = LastName&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Примеры запросов===&lt;br /&gt;
=====Идентификаторы всех студентов=====&lt;br /&gt;
Запишем запрос для получения идентификаторов всех студентов. Можно представлять это так: единственная свободная переменная SId пробегает все возможные значения из домена (все возможные идентификаторы студентов), а в результирующее отношение попадают только те её значения, для которых реально существовал такой студент.&lt;br /&gt;
&lt;br /&gt;
 SId &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; S&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;SId = SId&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Идентификаторы студентов, не сдавших курс с CId=10=====&lt;br /&gt;
Также как и в исчислении кортежей, в исчислении доменов можно использовать кванторы. Студент не сдал курс, если у него нет положительных оценок за этот курс.&lt;br /&gt;
&lt;br /&gt;
 SId &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; ¬∃Points (Points ≥ 60 ∧ Points&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;SId = SId, Points = Points, CId = 10&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
==Реляционная полнота исчисления доменов==&lt;br /&gt;
Выразим базис реляционной алгебры в исчислении доменов, тем самым докажем реляционную полноту исчисления доменов:&lt;br /&gt;
&lt;br /&gt;
====Проекция $\pi_{A_1, ..., A_n}(R)$====&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;from&amp;lt;/font&amp;gt; $R$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_1$ = $A_1$, ..., $A_n$ = $A_n$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Фильтр $σ_θ(R)$====&lt;br /&gt;
Выбираем только такие наборы значений $A_1$...$A_n$, которые есть в исходном отношении R и удовлетворяют условию θ&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;from&amp;lt;/font&amp;gt; $R$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_1$ = $A_1$, ..., $A_n$ = $A_n$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $θ$&lt;br /&gt;
&lt;br /&gt;
====Переименовывание $ε_{A=expr}(R_1)$====&lt;br /&gt;
 expr as A &amp;lt;font color=blue&amp;gt;from&amp;lt;/font&amp;gt; $R$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R${$A_1$ = $A_1$, ..., $A_n$ = $A_n$}&lt;br /&gt;
&lt;br /&gt;
====Объединение $R_1 ∪ R_2$====&lt;br /&gt;
Выбираем только такие наборы значений $A_1$...$A_n$, что хотя бы в одном из отношений есть соответствующий кортеж&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∨ $R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Разность $R_1 ∖ R_2$====&lt;br /&gt;
Выбираем только такие наборы значений $A_1$...$A_n$, что соответствующий кортеж есть в $R_1$, но нет в $R_2$&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $¬R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Декартово произведение $R_1 × R_2$====&lt;br /&gt;
Выбирает наборы значений  $A_1$, ..., $A_n$, $B_1$, ..., $B_m$ такие, что $A_1$...$A_n$ есть в $R_1$, а $B_1$...$B_n$ есть в $R_2$&lt;br /&gt;
 $A_1$, ..., $A_n$, $B_1$, ..., $B_m$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$B_j$ = $B_j$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Естественное соединение $R_1 ⋈ R_2$====&lt;br /&gt;
 $A_1$, ..., $A_n$, $B_1$, ..., $B_m$, $C_1$, ..., $C_l$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$, $B_j$ = $B_j$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$C_k$ = $C_k$, $B_j$ = $B_j$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;/div&gt;</summary>
		<author><name>5.18.184.8</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D1%81%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B4%D0%BE%D0%BC%D0%B5%D0%BD%D0%BE%D0%B2_%D0%B8_%D0%B5%D0%B3%D0%BE_%D1%80%D0%B5%D0%BB%D1%8F%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D1%82%D0%B0&amp;diff=81494</id>
		<title>Исчисление доменов и его реляционная полнота</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D1%81%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B4%D0%BE%D0%BC%D0%B5%D0%BD%D0%BE%D0%B2_%D0%B8_%D0%B5%D0%B3%D0%BE_%D1%80%D0%B5%D0%BB%D1%8F%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D1%82%D0%B0&amp;diff=81494"/>
				<updated>2021-12-19T19:29:15Z</updated>
		
		<summary type="html">&lt;p&gt;5.18.184.8: /* Реляционная полнота исчисления доменов */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Исчисление доменов==&lt;br /&gt;
В отличие от исчисления кортежей, где областью значения переменных были отношения, в исчислении доменов, значения переменных лежат в заренее заданых доменах (мы будем называть их также типами). Введём синтаксис для указания типов переменных. Также введём предикат, будем называть его ''условием принадлежности'', который для заданного отношения и значений атрибутов проверяет, есть ли совпадающий кортеж в отношении.&lt;br /&gt;
===Синтаксис===&lt;br /&gt;
 &amp;lt;font color=red&amp;gt;Переменная&amp;lt;/font&amp;gt; :: &amp;lt;font color=red&amp;gt;Тип&amp;lt;/font&amp;gt; &amp;lt;font color=green&amp;gt;-- Переменная может принимать значения из какого-то типа. Тип == набор значений&lt;br /&gt;
 &amp;lt;/font&amp;gt;&lt;br /&gt;
  &amp;lt;font color=green&amp;gt;-- Условие принадлежности отношению&amp;lt;/font&amp;gt;&lt;br /&gt;
 &amp;lt;font color=red&amp;gt;Отношение {&amp;lt;/font&amp;gt;&lt;br /&gt;
   &amp;lt;font color=red&amp;gt;Атрибут1&amp;lt;/font&amp;gt; = &amp;lt;font color=red&amp;gt;Значение1&amp;lt;/font&amp;gt;,&lt;br /&gt;
   &amp;lt;font color=red&amp;gt;Атрибут2&amp;lt;/font&amp;gt; = &amp;lt;font color=red&amp;gt;Значение2&amp;lt;/font&amp;gt;,&lt;br /&gt;
   ...&lt;br /&gt;
 &amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Примеры использования условия принадлежности===&lt;br /&gt;
Следующий предикат будет истинным, если в отношении S найдётся кортеж &amp;lt;code&amp;gt;(FirstName = 'Иван', LastName = 'Иванов')&amp;lt;/code&amp;gt; или, например (при наличии ещё одного атрибута), &amp;lt;code&amp;gt;(FirstName = 'Иван', LastName = 'Иванов', Email = 'ivan@example.com')&amp;lt;/code&amp;gt; и ложным, если ни в одном кортеже не совпали все значения атрибутов с перечисленными&lt;br /&gt;
&lt;br /&gt;
 S&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;FirstName = &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;, LastName = &amp;lt;font color=green&amp;gt;'Иванов'&amp;lt;/font&amp;gt;&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Имя атрибута может совпадать с именем переменной, это может поначалу немного запутывать. Слева от знака равенства стоит имя атрибута, справа - значение, с которым атрибут сравниваем&lt;br /&gt;
&lt;br /&gt;
 S&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;FirstName = FirstName, LastName = LastName&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Примеры запросов===&lt;br /&gt;
=====Идентификаторы всех студентов=====&lt;br /&gt;
Запишем запрос для получения идентификаторов всех студентов. Можно представлять это так: единственная свободная переменная SId пробегает все возможные значения из домена (все возможные идентификаторы студентов), а в результирующее отношение попадают только те её значения, для которых реально существовал такой студент.&lt;br /&gt;
&lt;br /&gt;
 SId &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; S&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;SId = SId&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Идентификаторы студентов, не сдавших курс с CId=10=====&lt;br /&gt;
Также как и в исчислении кортежей, в исчислении доменов можно использовать кванторы. Студент не сдал курс, если у него нет положительных оценок за этот курс.&lt;br /&gt;
&lt;br /&gt;
 SId &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; ¬∃Points (Points ≥ 60 ∧ Points&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;SId = SId, Points = Points, CId = 10&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
==Реляционная полнота исчисления доменов==&lt;br /&gt;
Выразим базис реляционной алгебры в исчислении доменов, тем самым докажем реляционную полноту исчисления доменов:&lt;br /&gt;
&lt;br /&gt;
====Проекция $\pi_{A_1, ..., A_n}(R)$====&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;from&amp;lt;/font&amp;gt; $R$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_1$ = $A_1$, ..., $A_n$ = $A_n$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Фильтр $σ_θ(R)$====&lt;br /&gt;
Выбираем только такие наборы значений $A_1$...$A_n$, которые есть в исходном отношении R и удовлетворяют условию θ&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;from&amp;lt;/font&amp;gt; $R$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_1$ = $A_1$, ..., $A_n$ = $A_n$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $θ$&lt;br /&gt;
&lt;br /&gt;
====Переименовывание $ε_{A=expr}(R_1)$====&lt;br /&gt;
 expr as A &amp;lt;font color=blue&amp;gt;from&amp;lt;/font&amp;gt; $R$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R${$A_1$ = $A_1$, ..., $A_n$ = $A_n$}&lt;br /&gt;
&lt;br /&gt;
====Объединение $R_1 ∪ R_2$====&lt;br /&gt;
Выбираем только такие наборы значений $A_1$...$A_n$, что хотя бы в одном из отношений есть соответствующий кортеж&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∨ $R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Разность $R_1 ∖ R_2$====&lt;br /&gt;
Выбираем только такие наборы значений $A_1$...$A_n$, что соответствующий кортеж есть в $R_1$, но нет в $R_2$&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $¬R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Декартово произведение $R_1 × R_2$====&lt;br /&gt;
Выбирает наборы значений  $A_1$, ..., $A_n$, $B_1$, ..., $B_m$ такие, что $A_1$...$A_n$ есть в $R_1$, а $B_1$...$B_n$ есть в $R_2$&lt;br /&gt;
 $A_1$, ..., $A_n$, $B_1$, ..., $B_m$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$B_j$ = $B_j$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Естественное соединение $R_1 ⋈ R_2$====&lt;br /&gt;
 $A_1$, ..., $A_n$, $B_1$, ..., $B_m$, $C_1$, ..., $C_l$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$, $B_j$ = $B_j$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$C_k$ = $C_k$, $B_j$ = $B_j$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;/div&gt;</summary>
		<author><name>5.18.184.8</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D1%81%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B4%D0%BE%D0%BC%D0%B5%D0%BD%D0%BE%D0%B2_%D0%B8_%D0%B5%D0%B3%D0%BE_%D1%80%D0%B5%D0%BB%D1%8F%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D1%82%D0%B0&amp;diff=81478</id>
		<title>Исчисление доменов и его реляционная полнота</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D1%81%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B4%D0%BE%D0%BC%D0%B5%D0%BD%D0%BE%D0%B2_%D0%B8_%D0%B5%D0%B3%D0%BE_%D1%80%D0%B5%D0%BB%D1%8F%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D1%82%D0%B0&amp;diff=81478"/>
				<updated>2021-12-19T17:53:47Z</updated>
		
		<summary type="html">&lt;p&gt;5.18.184.8: /* Примеры использования условия принадлежности */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Исчисление доменов==&lt;br /&gt;
В отличие от исчисления кортежей, где областью значения переменных были отношения, в исчислении доменов, значения переменных лежат в заренее заданых доменах (мы будем называть их также типами). Введём синтаксис для указания типов переменных. Также введём предикат, будем называть его ''условием принадлежности'', который для заданного отношения и значений атрибутов проверяет, есть ли совпадающий кортеж в отношении.&lt;br /&gt;
===Синтаксис===&lt;br /&gt;
 &amp;lt;font color=red&amp;gt;Переменная&amp;lt;/font&amp;gt; :: &amp;lt;font color=red&amp;gt;Тип&amp;lt;/font&amp;gt; &amp;lt;font color=green&amp;gt;-- Переменная может принимать значения из какого-то типа. Тип == набор значений&lt;br /&gt;
 &amp;lt;/font&amp;gt;&lt;br /&gt;
  &amp;lt;font color=green&amp;gt;-- Условие принадлежности отношению&amp;lt;/font&amp;gt;&lt;br /&gt;
 &amp;lt;font color=red&amp;gt;Отношение {&amp;lt;/font&amp;gt;&lt;br /&gt;
   &amp;lt;font color=red&amp;gt;Атрибут1&amp;lt;/font&amp;gt; = &amp;lt;font color=red&amp;gt;Значение1&amp;lt;/font&amp;gt;,&lt;br /&gt;
   &amp;lt;font color=red&amp;gt;Атрибут2&amp;lt;/font&amp;gt; = &amp;lt;font color=red&amp;gt;Значение2&amp;lt;/font&amp;gt;,&lt;br /&gt;
   ...&lt;br /&gt;
 &amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Примеры использования условия принадлежности===&lt;br /&gt;
Следующий предикат будет истинным, если в отношении S найдётся кортеж &amp;lt;code&amp;gt;(FirstName = 'Иван', LastName = 'Иванов')&amp;lt;/code&amp;gt; или, например (при наличии ещё одного атрибута), &amp;lt;code&amp;gt;(FirstName = 'Иван', LastName = 'Иванов', Email = 'ivan@example.com')&amp;lt;/code&amp;gt; и ложным, если ни в одном кортеже не совпали все значения атрибутов с перечисленными&lt;br /&gt;
&lt;br /&gt;
 S&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;FirstName = &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;, LastName = &amp;lt;font color=green&amp;gt;'Иванов'&amp;lt;/font&amp;gt;&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Имя атрибута может совпадать с именем переменной, это может поначалу немного запутывать. Слева от знака равенства стоит имя атрибута, справа - значение, с которым атрибут сравниваем&lt;br /&gt;
&lt;br /&gt;
 S&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;FirstName = FirstName, LastName = LastName&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Примеры запросов===&lt;br /&gt;
=====Идентификаторы всех студентов=====&lt;br /&gt;
Запишем запрос для получения идентификаторов всех студентов. Можно представлять это так: единственная свободная переменная SId пробегает все возможные значения из домена (все возможные идентификаторы студентов), а в результирующее отношение попадают только те её значения, для которых реально существовал такой студент.&lt;br /&gt;
&lt;br /&gt;
 SId &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; S&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;SId = SId&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Идентификаторы студентов, не сдавших курс с CId=10=====&lt;br /&gt;
Также как и в исчислении кортежей, в исчислении доменов можно использовать кванторы. Студент не сдал курс, если у него нет положительных оценок за этот курс.&lt;br /&gt;
&lt;br /&gt;
 SId &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; ¬∃Points (Points ≥ 60 ∧ Points&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;SId = SId, Points = Points, CId = 10&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
==Реляционная полнота исчисления доменов==&lt;br /&gt;
&lt;br /&gt;
====Проекция $\pi_{A_1, ..., A_n}(R)$====&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;from&amp;lt;/font&amp;gt; $R$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_1$ = $A_1$, ..., $A_n$ = $A_n$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Фильтр $σ_θ(R)$====&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;from&amp;lt;/font&amp;gt; $R$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_1$ = $A_1$, ..., $A_n$ = $A_n$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $θ$&lt;br /&gt;
&lt;br /&gt;
====Переименовывание $ε_{A=expr}(R_1)$====&lt;br /&gt;
 expr as A &amp;lt;font color=blue&amp;gt;from&amp;lt;/font&amp;gt; $R$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R${$A_1$ = $A_1$, ..., $A_n$ = $A_n$}&lt;br /&gt;
&lt;br /&gt;
====Объединение $R_1 ∪ R_2$====&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∨ $R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Разность $R_1 ∖ R_2$====&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $¬R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Декартово произведение $R_1 × R_2$====&lt;br /&gt;
 $A_1$, ..., $A_n$, $B_1$, ..., $B_m$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$B_j$ = $B_j$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Естественное соединение $R_1 ⋈ R_2$====&lt;br /&gt;
 $A_1$, ..., $A_n$, $B_1$, ..., $B_m$, $C_1$, ..., $C_l$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$, $B_j$ = $B_j$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$C_k$ = $C_k$, $B_j$ = $B_j$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;/div&gt;</summary>
		<author><name>5.18.184.8</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D1%81%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B4%D0%BE%D0%BC%D0%B5%D0%BD%D0%BE%D0%B2_%D0%B8_%D0%B5%D0%B3%D0%BE_%D1%80%D0%B5%D0%BB%D1%8F%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D1%82%D0%B0&amp;diff=81477</id>
		<title>Исчисление доменов и его реляционная полнота</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D1%81%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B4%D0%BE%D0%BC%D0%B5%D0%BD%D0%BE%D0%B2_%D0%B8_%D0%B5%D0%B3%D0%BE_%D1%80%D0%B5%D0%BB%D1%8F%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D1%82%D0%B0&amp;diff=81477"/>
				<updated>2021-12-19T17:52:52Z</updated>
		
		<summary type="html">&lt;p&gt;5.18.184.8: /* Исчисление доменов */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Исчисление доменов==&lt;br /&gt;
В отличие от исчисления кортежей, где областью значения переменных были отношения, в исчислении доменов, значения переменных лежат в заренее заданых доменах (мы будем называть их также типами). Введём синтаксис для указания типов переменных. Также введём предикат, будем называть его ''условием принадлежности'', который для заданного отношения и значений атрибутов проверяет, есть ли совпадающий кортеж в отношении.&lt;br /&gt;
===Синтаксис===&lt;br /&gt;
 &amp;lt;font color=red&amp;gt;Переменная&amp;lt;/font&amp;gt; :: &amp;lt;font color=red&amp;gt;Тип&amp;lt;/font&amp;gt; &amp;lt;font color=green&amp;gt;-- Переменная может принимать значения из какого-то типа. Тип == набор значений&lt;br /&gt;
 &amp;lt;/font&amp;gt;&lt;br /&gt;
  &amp;lt;font color=green&amp;gt;-- Условие принадлежности отношению&amp;lt;/font&amp;gt;&lt;br /&gt;
 &amp;lt;font color=red&amp;gt;Отношение {&amp;lt;/font&amp;gt;&lt;br /&gt;
   &amp;lt;font color=red&amp;gt;Атрибут1&amp;lt;/font&amp;gt; = &amp;lt;font color=red&amp;gt;Значение1&amp;lt;/font&amp;gt;,&lt;br /&gt;
   &amp;lt;font color=red&amp;gt;Атрибут2&amp;lt;/font&amp;gt; = &amp;lt;font color=red&amp;gt;Значение2&amp;lt;/font&amp;gt;,&lt;br /&gt;
   ...&lt;br /&gt;
 &amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Примеры использования условия принадлежности===&lt;br /&gt;
Предикат будет истинным, если в отношении S найдётся кортеж &amp;lt;code&amp;gt;(FirstName = 'Иван', LastName = 'Иванов')&amp;lt;/code&amp;gt; или, например (при наличии ещё одного атрибута), &amp;lt;code&amp;gt;(FirstName = 'Иван', LastName = 'Иванов', Email = 'ivan@example.com')&amp;lt;/code&amp;gt; и ложным, если ни в одном кортеже не совпали все значения атрибутов с перечисленными&lt;br /&gt;
&lt;br /&gt;
 S&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;FirstName = &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;, LastName = &amp;lt;font color=green&amp;gt;'Иванов'&amp;lt;/font&amp;gt;&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Имя атрибута может совпадать с именем переменной, это может поначалу немного запутывать. Слева от знака равенства стоит имя атрибута, справа - значение, с которым атрибут сравниваем&lt;br /&gt;
&lt;br /&gt;
 S&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;FirstName = FirstName, LastName = LastName&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Примеры запросов===&lt;br /&gt;
=====Идентификаторы всех студентов=====&lt;br /&gt;
Запишем запрос для получения идентификаторов всех студентов. Можно представлять это так: единственная свободная переменная SId пробегает все возможные значения из домена (все возможные идентификаторы студентов), а в результирующее отношение попадают только те её значения, для которых реально существовал такой студент.&lt;br /&gt;
&lt;br /&gt;
 SId &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; S&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;SId = SId&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Идентификаторы студентов, не сдавших курс с CId=10=====&lt;br /&gt;
Также как и в исчислении кортежей, в исчислении доменов можно использовать кванторы. Студент не сдал курс, если у него нет положительных оценок за этот курс.&lt;br /&gt;
&lt;br /&gt;
 SId &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; ¬∃Points (Points ≥ 60 ∧ Points&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;SId = SId, Points = Points, CId = 10&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
==Реляционная полнота исчисления доменов==&lt;br /&gt;
&lt;br /&gt;
====Проекция $\pi_{A_1, ..., A_n}(R)$====&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;from&amp;lt;/font&amp;gt; $R$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_1$ = $A_1$, ..., $A_n$ = $A_n$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Фильтр $σ_θ(R)$====&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;from&amp;lt;/font&amp;gt; $R$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_1$ = $A_1$, ..., $A_n$ = $A_n$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $θ$&lt;br /&gt;
&lt;br /&gt;
====Переименовывание $ε_{A=expr}(R_1)$====&lt;br /&gt;
 expr as A &amp;lt;font color=blue&amp;gt;from&amp;lt;/font&amp;gt; $R$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R${$A_1$ = $A_1$, ..., $A_n$ = $A_n$}&lt;br /&gt;
&lt;br /&gt;
====Объединение $R_1 ∪ R_2$====&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∨ $R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Разность $R_1 ∖ R_2$====&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $¬R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Декартово произведение $R_1 × R_2$====&lt;br /&gt;
 $A_1$, ..., $A_n$, $B_1$, ..., $B_m$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$B_j$ = $B_j$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Естественное соединение $R_1 ⋈ R_2$====&lt;br /&gt;
 $A_1$, ..., $A_n$, $B_1$, ..., $B_m$, $C_1$, ..., $C_l$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$, $B_j$ = $B_j$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$C_k$ = $C_k$, $B_j$ = $B_j$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;/div&gt;</summary>
		<author><name>5.18.184.8</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D1%81%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B4%D0%BE%D0%BC%D0%B5%D0%BD%D0%BE%D0%B2_%D0%B8_%D0%B5%D0%B3%D0%BE_%D1%80%D0%B5%D0%BB%D1%8F%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D1%82%D0%B0&amp;diff=81476</id>
		<title>Исчисление доменов и его реляционная полнота</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D1%81%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B4%D0%BE%D0%BC%D0%B5%D0%BD%D0%BE%D0%B2_%D0%B8_%D0%B5%D0%B3%D0%BE_%D1%80%D0%B5%D0%BB%D1%8F%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D1%82%D0%B0&amp;diff=81476"/>
				<updated>2021-12-19T17:51:16Z</updated>
		
		<summary type="html">&lt;p&gt;5.18.184.8: /* Идентификаторы студентов, не сдавших курс с CId=10 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Исчисление доменов==&lt;br /&gt;
В отличие от исчисления кортежей, где областью значения переменных были отношения, в исчислении доменов, значения переменных лежат в заренее заданых доменах (мы будем называть их также типами). Введём синтаксис для указания типов переменных. Также введём предикат, который для заданного отношения и значений атрибутов проверяет, есть ли совпадающий кортеж в отношении.&lt;br /&gt;
===Синтаксис===&lt;br /&gt;
 &amp;lt;font color=red&amp;gt;Переменная&amp;lt;/font&amp;gt; :: &amp;lt;font color=red&amp;gt;Тип&amp;lt;/font&amp;gt; &amp;lt;font color=green&amp;gt;-- Переменная может принимать значения из какого-то типа. Тип == набор значений&lt;br /&gt;
 &amp;lt;/font&amp;gt;&lt;br /&gt;
  &amp;lt;font color=green&amp;gt;-- Условие принадлежности отношению&amp;lt;/font&amp;gt;&lt;br /&gt;
 &amp;lt;font color=red&amp;gt;Отношение {&amp;lt;/font&amp;gt;&lt;br /&gt;
   &amp;lt;font color=red&amp;gt;Атрибут1&amp;lt;/font&amp;gt; = &amp;lt;font color=red&amp;gt;Значение1&amp;lt;/font&amp;gt;,&lt;br /&gt;
   &amp;lt;font color=red&amp;gt;Атрибут2&amp;lt;/font&amp;gt; = &amp;lt;font color=red&amp;gt;Значение2&amp;lt;/font&amp;gt;,&lt;br /&gt;
   ...&lt;br /&gt;
 &amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Примеры использования условия принадлежности===&lt;br /&gt;
Предикат будет истинным, если в отношении S найдётся кортеж &amp;lt;code&amp;gt;(FirstName = 'Иван', LastName = 'Иванов')&amp;lt;/code&amp;gt; или, например (при наличии ещё одного атрибута), &amp;lt;code&amp;gt;(FirstName = 'Иван', LastName = 'Иванов', Email = 'ivan@example.com')&amp;lt;/code&amp;gt; и ложным, если ни в одном кортеже не совпали все значения атрибутов с перечисленными&lt;br /&gt;
&lt;br /&gt;
 S&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;FirstName = &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;, LastName = &amp;lt;font color=green&amp;gt;'Иванов'&amp;lt;/font&amp;gt;&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Имя атрибута может совпадать с именем переменной, это может поначалу немного запутывать. Слева от знака равенства стоит имя атрибута, справа - значение, с которым атрибут сравниваем&lt;br /&gt;
&lt;br /&gt;
 S&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;FirstName = FirstName, LastName = LastName&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Примеры запросов===&lt;br /&gt;
=====Идентификаторы всех студентов=====&lt;br /&gt;
Запишем запрос для получения идентификаторов всех студентов. Можно представлять это так: единственная свободная переменная SId пробегает все возможные значения из домена (все возможные идентификаторы студентов), а в результирующее отношение попадают только те её значения, для которых реально существовал такой студент.&lt;br /&gt;
&lt;br /&gt;
 SId &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; S&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;SId = SId&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Идентификаторы студентов, не сдавших курс с CId=10=====&lt;br /&gt;
Также как и в исчислении кортежей, в исчислении доменов можно использовать кванторы. Студент не сдал курс, если у него нет положительных оценок за этот курс.&lt;br /&gt;
&lt;br /&gt;
 SId &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; ¬∃Points (Points ≥ 60 ∧ Points&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;SId = SId, Points = Points, CId = 10&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
==Реляционная полнота исчисления доменов==&lt;br /&gt;
&lt;br /&gt;
====Проекция $\pi_{A_1, ..., A_n}(R)$====&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;from&amp;lt;/font&amp;gt; $R$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_1$ = $A_1$, ..., $A_n$ = $A_n$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Фильтр $σ_θ(R)$====&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;from&amp;lt;/font&amp;gt; $R$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_1$ = $A_1$, ..., $A_n$ = $A_n$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $θ$&lt;br /&gt;
&lt;br /&gt;
====Переименовывание $ε_{A=expr}(R_1)$====&lt;br /&gt;
 expr as A &amp;lt;font color=blue&amp;gt;from&amp;lt;/font&amp;gt; $R$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R${$A_1$ = $A_1$, ..., $A_n$ = $A_n$}&lt;br /&gt;
&lt;br /&gt;
====Объединение $R_1 ∪ R_2$====&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∨ $R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Разность $R_1 ∖ R_2$====&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $¬R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Декартово произведение $R_1 × R_2$====&lt;br /&gt;
 $A_1$, ..., $A_n$, $B_1$, ..., $B_m$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$B_j$ = $B_j$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Естественное соединение $R_1 ⋈ R_2$====&lt;br /&gt;
 $A_1$, ..., $A_n$, $B_1$, ..., $B_m$, $C_1$, ..., $C_l$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$, $B_j$ = $B_j$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$C_k$ = $C_k$, $B_j$ = $B_j$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;/div&gt;</summary>
		<author><name>5.18.184.8</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D1%81%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B4%D0%BE%D0%BC%D0%B5%D0%BD%D0%BE%D0%B2_%D0%B8_%D0%B5%D0%B3%D0%BE_%D1%80%D0%B5%D0%BB%D1%8F%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D1%82%D0%B0&amp;diff=81474</id>
		<title>Исчисление доменов и его реляционная полнота</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D1%81%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B4%D0%BE%D0%BC%D0%B5%D0%BD%D0%BE%D0%B2_%D0%B8_%D0%B5%D0%B3%D0%BE_%D1%80%D0%B5%D0%BB%D1%8F%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D1%82%D0%B0&amp;diff=81474"/>
				<updated>2021-12-19T17:32:17Z</updated>
		
		<summary type="html">&lt;p&gt;5.18.184.8: /* Идентификаторы всех студентов */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Исчисление доменов==&lt;br /&gt;
В отличие от исчисления кортежей, где областью значения переменных были отношения, в исчислении доменов, значения переменных лежат в заренее заданых доменах (мы будем называть их также типами). Введём синтаксис для указания типов переменных. Также введём предикат, который для заданного отношения и значений атрибутов проверяет, есть ли совпадающий кортеж в отношении.&lt;br /&gt;
===Синтаксис===&lt;br /&gt;
 &amp;lt;font color=red&amp;gt;Переменная&amp;lt;/font&amp;gt; :: &amp;lt;font color=red&amp;gt;Тип&amp;lt;/font&amp;gt; &amp;lt;font color=green&amp;gt;-- Переменная может принимать значения из какого-то типа. Тип == набор значений&lt;br /&gt;
 &amp;lt;/font&amp;gt;&lt;br /&gt;
  &amp;lt;font color=green&amp;gt;-- Условие принадлежности отношению&amp;lt;/font&amp;gt;&lt;br /&gt;
 &amp;lt;font color=red&amp;gt;Отношение {&amp;lt;/font&amp;gt;&lt;br /&gt;
   &amp;lt;font color=red&amp;gt;Атрибут1&amp;lt;/font&amp;gt; = &amp;lt;font color=red&amp;gt;Значение1&amp;lt;/font&amp;gt;,&lt;br /&gt;
   &amp;lt;font color=red&amp;gt;Атрибут2&amp;lt;/font&amp;gt; = &amp;lt;font color=red&amp;gt;Значение2&amp;lt;/font&amp;gt;,&lt;br /&gt;
   ...&lt;br /&gt;
 &amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Примеры использования условия принадлежности===&lt;br /&gt;
Предикат будет истинным, если в отношении S найдётся кортеж &amp;lt;code&amp;gt;(FirstName = 'Иван', LastName = 'Иванов')&amp;lt;/code&amp;gt; или, например (при наличии ещё одного атрибута), &amp;lt;code&amp;gt;(FirstName = 'Иван', LastName = 'Иванов', Email = 'ivan@example.com')&amp;lt;/code&amp;gt; и ложным, если ни в одном кортеже не совпали все значения атрибутов с перечисленными&lt;br /&gt;
&lt;br /&gt;
 S&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;FirstName = &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;, LastName = &amp;lt;font color=green&amp;gt;'Иванов'&amp;lt;/font&amp;gt;&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Имя атрибута может совпадать с именем переменной, это может поначалу немного запутывать. Слева от знака равенства стоит имя атрибута, справа - значение, с которым атрибут сравниваем&lt;br /&gt;
&lt;br /&gt;
 S&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;FirstName = FirstName, LastName = LastName&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Примеры запросов===&lt;br /&gt;
=====Идентификаторы всех студентов=====&lt;br /&gt;
Запишем запрос для получения идентификаторов всех студентов. Можно представлять это так: единственная свободная переменная SId пробегает все возможные значения из домена (все возможные идентификаторы студентов), а в результирующее отношение попадают только те её значения, для которых реально существовал такой студент.&lt;br /&gt;
&lt;br /&gt;
 SId &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; S&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;SId = SId&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Идентификаторы студентов, не сдавших курс с CId=10=====&lt;br /&gt;
 SId &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; ¬∃Points (Points ≥ 60 ∧ Points&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;SId = SId, Points = Points, CId = 10&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
==Реляционная полнота исчисления доменов==&lt;br /&gt;
&lt;br /&gt;
====Проекция $\pi_{A_1, ..., A_n}(R)$====&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;from&amp;lt;/font&amp;gt; $R$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_1$ = $A_1$, ..., $A_n$ = $A_n$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Фильтр $σ_θ(R)$====&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;from&amp;lt;/font&amp;gt; $R$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_1$ = $A_1$, ..., $A_n$ = $A_n$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $θ$&lt;br /&gt;
&lt;br /&gt;
====Переименовывание $ε_{A=expr}(R_1)$====&lt;br /&gt;
 expr as A &amp;lt;font color=blue&amp;gt;from&amp;lt;/font&amp;gt; $R$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R${$A_1$ = $A_1$, ..., $A_n$ = $A_n$}&lt;br /&gt;
&lt;br /&gt;
====Объединение $R_1 ∪ R_2$====&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∨ $R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Разность $R_1 ∖ R_2$====&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $¬R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Декартово произведение $R_1 × R_2$====&lt;br /&gt;
 $A_1$, ..., $A_n$, $B_1$, ..., $B_m$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$B_j$ = $B_j$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Естественное соединение $R_1 ⋈ R_2$====&lt;br /&gt;
 $A_1$, ..., $A_n$, $B_1$, ..., $B_m$, $C_1$, ..., $C_l$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$, $B_j$ = $B_j$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$C_k$ = $C_k$, $B_j$ = $B_j$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;/div&gt;</summary>
		<author><name>5.18.184.8</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D1%81%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B4%D0%BE%D0%BC%D0%B5%D0%BD%D0%BE%D0%B2_%D0%B8_%D0%B5%D0%B3%D0%BE_%D1%80%D0%B5%D0%BB%D1%8F%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D1%82%D0%B0&amp;diff=81473</id>
		<title>Исчисление доменов и его реляционная полнота</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D1%81%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B4%D0%BE%D0%BC%D0%B5%D0%BD%D0%BE%D0%B2_%D0%B8_%D0%B5%D0%B3%D0%BE_%D1%80%D0%B5%D0%BB%D1%8F%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D1%82%D0%B0&amp;diff=81473"/>
				<updated>2021-12-19T17:18:58Z</updated>
		
		<summary type="html">&lt;p&gt;5.18.184.8: /* Условие принадлежности */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Исчисление доменов==&lt;br /&gt;
В отличие от исчисления кортежей, где областью значения переменных были отношения, в исчислении доменов, значения переменных лежат в заренее заданых доменах (мы будем называть их также типами). Введём синтаксис для указания типов переменных. Также введём предикат, который для заданного отношения и значений атрибутов проверяет, есть ли совпадающий кортеж в отношении.&lt;br /&gt;
===Синтаксис===&lt;br /&gt;
 &amp;lt;font color=red&amp;gt;Переменная&amp;lt;/font&amp;gt; :: &amp;lt;font color=red&amp;gt;Тип&amp;lt;/font&amp;gt; &amp;lt;font color=green&amp;gt;-- Переменная может принимать значения из какого-то типа. Тип == набор значений&lt;br /&gt;
 &amp;lt;/font&amp;gt;&lt;br /&gt;
  &amp;lt;font color=green&amp;gt;-- Условие принадлежности отношению&amp;lt;/font&amp;gt;&lt;br /&gt;
 &amp;lt;font color=red&amp;gt;Отношение {&amp;lt;/font&amp;gt;&lt;br /&gt;
   &amp;lt;font color=red&amp;gt;Атрибут1&amp;lt;/font&amp;gt; = &amp;lt;font color=red&amp;gt;Значение1&amp;lt;/font&amp;gt;,&lt;br /&gt;
   &amp;lt;font color=red&amp;gt;Атрибут2&amp;lt;/font&amp;gt; = &amp;lt;font color=red&amp;gt;Значение2&amp;lt;/font&amp;gt;,&lt;br /&gt;
   ...&lt;br /&gt;
 &amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Примеры использования условия принадлежности===&lt;br /&gt;
Предикат будет истинным, если в отношении S найдётся кортеж &amp;lt;code&amp;gt;(FirstName = 'Иван', LastName = 'Иванов')&amp;lt;/code&amp;gt; или, например (при наличии ещё одного атрибута), &amp;lt;code&amp;gt;(FirstName = 'Иван', LastName = 'Иванов', Email = 'ivan@example.com')&amp;lt;/code&amp;gt; и ложным, если ни в одном кортеже не совпали все значения атрибутов с перечисленными&lt;br /&gt;
&lt;br /&gt;
 S&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;FirstName = &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;, LastName = &amp;lt;font color=green&amp;gt;'Иванов'&amp;lt;/font&amp;gt;&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Имя атрибута может совпадать с именем переменной, это может поначалу немного запутывать. Слева от знака равенства стоит имя атрибута, справа - значение, с которым атрибут сравниваем&lt;br /&gt;
&lt;br /&gt;
 S&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;FirstName = FirstName, LastName = LastName&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Примеры запросов===&lt;br /&gt;
=====Идентификаторы всех студентов=====&lt;br /&gt;
 SId &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; S&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;SId = SId&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
=====Идентификаторы студентов, не сдавших курс с CId=10=====&lt;br /&gt;
 SId &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; ¬∃Points (Points ≥ 60 ∧ Points&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;SId = SId, Points = Points, CId = 10&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
==Реляционная полнота исчисления доменов==&lt;br /&gt;
&lt;br /&gt;
====Проекция $\pi_{A_1, ..., A_n}(R)$====&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;from&amp;lt;/font&amp;gt; $R$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_1$ = $A_1$, ..., $A_n$ = $A_n$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Фильтр $σ_θ(R)$====&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;from&amp;lt;/font&amp;gt; $R$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_1$ = $A_1$, ..., $A_n$ = $A_n$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $θ$&lt;br /&gt;
&lt;br /&gt;
====Переименовывание $ε_{A=expr}(R_1)$====&lt;br /&gt;
 expr as A &amp;lt;font color=blue&amp;gt;from&amp;lt;/font&amp;gt; $R$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R${$A_1$ = $A_1$, ..., $A_n$ = $A_n$}&lt;br /&gt;
&lt;br /&gt;
====Объединение $R_1 ∪ R_2$====&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∨ $R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Разность $R_1 ∖ R_2$====&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $¬R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Декартово произведение $R_1 × R_2$====&lt;br /&gt;
 $A_1$, ..., $A_n$, $B_1$, ..., $B_m$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$B_j$ = $B_j$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Естественное соединение $R_1 ⋈ R_2$====&lt;br /&gt;
 $A_1$, ..., $A_n$, $B_1$, ..., $B_m$, $C_1$, ..., $C_l$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$, $B_j$ = $B_j$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$C_k$ = $C_k$, $B_j$ = $B_j$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;/div&gt;</summary>
		<author><name>5.18.184.8</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Datalog_%D0%B8_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F&amp;diff=81447</id>
		<title>Datalog и рекурсия</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Datalog_%D0%B8_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F&amp;diff=81447"/>
				<updated>2021-12-19T13:38:40Z</updated>
		
		<summary type="html">&lt;p&gt;5.18.184.8: /* Атом */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Язык Datalog==&lt;br /&gt;
Декларативный язык на основе исчисления доменов. Разработан в 1978 году, синтаксически - подмножество языка Prolog&lt;br /&gt;
&lt;br /&gt;
Программа на языке Datalog представляет из себя набор определений отношений, результат выполнения - тело одного из отношений.&lt;br /&gt;
&lt;br /&gt;
==Синтаксис==&lt;br /&gt;
Программа на Datalog - набор '''отношений''': Отношение на языке Datalog определяется так: &amp;lt;code&amp;gt;Отношение(x1,x2...xn) :- Цель.&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Цель''' в свою очередь - это набор '''атомов''', перечисленных через запятую&lt;br /&gt;
===Атом===&lt;br /&gt;
Атомы бывают двух типов: реляционные и арифметические&lt;br /&gt;
====Реляционный====&lt;br /&gt;
Аналог конструкции условия принадлежности из исчисления доменов.&lt;br /&gt;
Есть два вида:&lt;br /&gt;
* Кортеж принадлежит отношению &amp;lt;code&amp;gt;R(x1, x2, ..., xn)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Кортеж не принадлежит отношению &amp;lt;code&amp;gt;¬R(x1, x2, ..., xn)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что в Datalog нет имён атрибутов, атрибуты различаются только по своей позиции.&lt;br /&gt;
&lt;br /&gt;
====Арифметический====&lt;br /&gt;
всевозможные сравнения на равенство/неравенство&lt;br /&gt;
&lt;br /&gt;
==Ограничение отношений==&lt;br /&gt;
Как и на любую другую программу, на синтаксически корректную программу на языке Datalog нужно наложить дополнительные ограничения, чтобы она имела смысл.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим отношения&lt;br /&gt;
 Less(x,y) :- x &amp;lt; y.&lt;br /&gt;
 NotStudent(Id, Name) :- ¬Students(Id, Name, _).&lt;br /&gt;
&lt;br /&gt;
Здесь есть проблема - во-первых, мы даже не знаем тип &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Id&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;Name&amp;lt;/code&amp;gt;, это значит, что мы не знаем области их значения.&lt;br /&gt;
Во-вторых, даже если бы мы знали их тип, пусть это будут, например, целые числа, то получили бы бесконечное отношение, с такими мы работать не умеем.&lt;br /&gt;
&lt;br /&gt;
Поэтому, нужно запретить такую ситуацию, для этого добавим требование:&lt;br /&gt;
&lt;br /&gt;
'''Каждая переменная должна входить в неотрицательный реляционный атом'''&lt;br /&gt;
&lt;br /&gt;
==Рекурсивные запросы==&lt;br /&gt;
===Смысл===&lt;br /&gt;
Пусть есть некоторое отношение &amp;quot;потомок-родитель&amp;quot;&lt;br /&gt;
 Parent(Id, ParentId)&lt;br /&gt;
&lt;br /&gt;
Хотим найти его транзитивное замыкание, по определению:&lt;br /&gt;
 Ancestor(Id, PId) :- Parent(Id, PId).&lt;br /&gt;
 Ancestor(Id, GId) :- Parent(Id, GId), Ancestor(PId, GId).&lt;br /&gt;
&lt;br /&gt;
Пусть $P$ - множество всех людей, у которых есть хотя бы один родитель.&lt;br /&gt;
Очевидно, что $P \times P$ есть неподвижная точка, но найденное отношение не является транзитивным замыканием.&lt;br /&gt;
&lt;br /&gt;
Поэтому, следует уточнить, что мы ищем '''минимальную по включению неподвижную точку'''.&lt;br /&gt;
&lt;br /&gt;
===Алгоритм поиска минимальной неподвижной точки===&lt;br /&gt;
&lt;br /&gt;
 Проинициализируем отношения из нерекурсивных определений&lt;br /&gt;
 Пока не достигли неподвижной точки&lt;br /&gt;
   Пополняем отношения из рекурсивных определений&lt;br /&gt;
&lt;br /&gt;
===Циклы и отрицание===&lt;br /&gt;
&lt;br /&gt;
Представим ситуацию, когда принадлежность кортежа к отношению зависит от отрицания его принадлежности к отношению. Это в чистом виде парадокс брадобрея и мы знаем, что такая конструкция не имеет смысла.&lt;br /&gt;
&lt;br /&gt;
Поэтому, введём '''стратифицированное отрицание''', то есть запрет на отрицание в циклах.&lt;/div&gt;</summary>
		<author><name>5.18.184.8</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Datalog_%D0%B8_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F&amp;diff=81446</id>
		<title>Datalog и рекурсия</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Datalog_%D0%B8_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F&amp;diff=81446"/>
				<updated>2021-12-19T13:25:46Z</updated>
		
		<summary type="html">&lt;p&gt;5.18.184.8: /* Синтаксис */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Язык Datalog==&lt;br /&gt;
Декларативный язык на основе исчисления доменов. Разработан в 1978 году, синтаксически - подмножество языка Prolog&lt;br /&gt;
&lt;br /&gt;
Программа на языке Datalog представляет из себя набор определений отношений, результат выполнения - тело одного из отношений.&lt;br /&gt;
&lt;br /&gt;
==Синтаксис==&lt;br /&gt;
Программа на Datalog - набор '''отношений''': Отношение на языке Datalog определяется так: &amp;lt;code&amp;gt;Отношение(x1,x2...xn) :- Цель.&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Цель''' в свою очередь - это набор '''атомов''', перечисленных через запятую&lt;br /&gt;
===Атом===&lt;br /&gt;
Атомы бывают двух типов&lt;br /&gt;
====Реляционный====&lt;br /&gt;
Аналог конструкции условия принадлежности из исчисления доменов.&lt;br /&gt;
Есть два вида:&lt;br /&gt;
* Кортеж принадлежит отношению &amp;lt;code&amp;gt;R(x1, x2, ..., xn)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Кортеж не принадлежит отношению &amp;lt;code&amp;gt;¬R(x1, x2, ..., xn)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что в Datalog нет имён атрибутов, атрибуты различаются только по своей позиции.&lt;br /&gt;
&lt;br /&gt;
====Арифметический====&lt;br /&gt;
всевозможные сравнения на равенство/неравенство&lt;br /&gt;
&lt;br /&gt;
==Ограничение отношений==&lt;br /&gt;
Как и на любую другую программу, на синтаксически корректную программу на языке Datalog нужно наложить дополнительные ограничения, чтобы она имела смысл.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим отношения&lt;br /&gt;
 Less(x,y) :- x &amp;lt; y.&lt;br /&gt;
 NotStudent(Id, Name) :- ¬Students(Id, Name, _).&lt;br /&gt;
&lt;br /&gt;
Здесь есть проблема - во-первых, мы даже не знаем тип &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Id&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;Name&amp;lt;/code&amp;gt;, это значит, что мы не знаем области их значения.&lt;br /&gt;
Во-вторых, даже если бы мы знали их тип, пусть это будут, например, целые числа, то получили бы бесконечное отношение, с такими мы работать не умеем.&lt;br /&gt;
&lt;br /&gt;
Поэтому, нужно запретить такую ситуацию, для этого добавим требование:&lt;br /&gt;
&lt;br /&gt;
'''Каждая переменная должна входить в неотрицательный реляционный атом'''&lt;br /&gt;
&lt;br /&gt;
==Рекурсивные запросы==&lt;br /&gt;
===Смысл===&lt;br /&gt;
Пусть есть некоторое отношение &amp;quot;потомок-родитель&amp;quot;&lt;br /&gt;
 Parent(Id, ParentId)&lt;br /&gt;
&lt;br /&gt;
Хотим найти его транзитивное замыкание, по определению:&lt;br /&gt;
 Ancestor(Id, PId) :- Parent(Id, PId).&lt;br /&gt;
 Ancestor(Id, GId) :- Parent(Id, GId), Ancestor(PId, GId).&lt;br /&gt;
&lt;br /&gt;
Пусть $P$ - множество всех людей, у которых есть хотя бы один родитель.&lt;br /&gt;
Очевидно, что $P \times P$ есть неподвижная точка, но найденное отношение не является транзитивным замыканием.&lt;br /&gt;
&lt;br /&gt;
Поэтому, следует уточнить, что мы ищем '''минимальную по включению неподвижную точку'''.&lt;br /&gt;
&lt;br /&gt;
===Алгоритм поиска минимальной неподвижной точки===&lt;br /&gt;
&lt;br /&gt;
 Проинициализируем отношения из нерекурсивных определений&lt;br /&gt;
 Пока не достигли неподвижной точки&lt;br /&gt;
   Пополняем отношения из рекурсивных определений&lt;br /&gt;
&lt;br /&gt;
===Циклы и отрицание===&lt;br /&gt;
&lt;br /&gt;
Представим ситуацию, когда принадлежность кортежа к отношению зависит от отрицания его принадлежности к отношению. Это в чистом виде парадокс брадобрея и мы знаем, что такая конструкция не имеет смысла.&lt;br /&gt;
&lt;br /&gt;
Поэтому, введём '''стратифицированное отрицание''', то есть запрет на отрицание в циклах.&lt;/div&gt;</summary>
		<author><name>5.18.184.8</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Datalog_%D0%B8_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F&amp;diff=81445</id>
		<title>Datalog и рекурсия</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Datalog_%D0%B8_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F&amp;diff=81445"/>
				<updated>2021-12-19T13:23:25Z</updated>
		
		<summary type="html">&lt;p&gt;5.18.184.8: /* Язык Datalog */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Язык Datalog==&lt;br /&gt;
Декларативный язык на основе исчисления доменов. Разработан в 1978 году, синтаксически - подмножество языка Prolog&lt;br /&gt;
&lt;br /&gt;
Программа на языке Datalog представляет из себя набор определений отношений, результат выполнения - тело одного из отношений.&lt;br /&gt;
&lt;br /&gt;
==Синтаксис==&lt;br /&gt;
Программа на Datalog - набор '''отношений''': &amp;lt;code&amp;gt;Отношение(x1,x2...xn) :- Цель.&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Цель''' - Набор '''атомов''', перечисленных через запятую&lt;br /&gt;
===Атом===&lt;br /&gt;
====Реляционный====&lt;br /&gt;
Аналог конструкции условия принадлежности из исчисления доменов.&lt;br /&gt;
Есть два вида:&lt;br /&gt;
* Кортеж принадлежит отношению &amp;lt;code&amp;gt;R(x1, x2, ..., xn)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Кортеж не принадлежит отношению &amp;lt;code&amp;gt;¬R(x1, x2, ..., xn)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что в Datalog нет имён атрибутов, атрибуты различаются только по своей позиции.&lt;br /&gt;
&lt;br /&gt;
====Арифметический====&lt;br /&gt;
всевозможные сравнения на равенство/неравенство&lt;br /&gt;
&lt;br /&gt;
==Ограничение отношений==&lt;br /&gt;
Как и на любую другую программу, на синтаксически корректную программу на языке Datalog нужно наложить дополнительные ограничения, чтобы она имела смысл.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим отношения&lt;br /&gt;
 Less(x,y) :- x &amp;lt; y.&lt;br /&gt;
 NotStudent(Id, Name) :- ¬Students(Id, Name, _).&lt;br /&gt;
&lt;br /&gt;
Здесь есть проблема - во-первых, мы даже не знаем тип &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Id&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;Name&amp;lt;/code&amp;gt;, это значит, что мы не знаем области их значения.&lt;br /&gt;
Во-вторых, даже если бы мы знали их тип, пусть это будут, например, целые числа, то получили бы бесконечное отношение, с такими мы работать не умеем.&lt;br /&gt;
&lt;br /&gt;
Поэтому, нужно запретить такую ситуацию, для этого добавим требование:&lt;br /&gt;
&lt;br /&gt;
'''Каждая переменная должна входить в неотрицательный реляционный атом'''&lt;br /&gt;
&lt;br /&gt;
==Рекурсивные запросы==&lt;br /&gt;
===Смысл===&lt;br /&gt;
Пусть есть некоторое отношение &amp;quot;потомок-родитель&amp;quot;&lt;br /&gt;
 Parent(Id, ParentId)&lt;br /&gt;
&lt;br /&gt;
Хотим найти его транзитивное замыкание, по определению:&lt;br /&gt;
 Ancestor(Id, PId) :- Parent(Id, PId).&lt;br /&gt;
 Ancestor(Id, GId) :- Parent(Id, GId), Ancestor(PId, GId).&lt;br /&gt;
&lt;br /&gt;
Пусть $P$ - множество всех людей, у которых есть хотя бы один родитель.&lt;br /&gt;
Очевидно, что $P \times P$ есть неподвижная точка, но найденное отношение не является транзитивным замыканием.&lt;br /&gt;
&lt;br /&gt;
Поэтому, следует уточнить, что мы ищем '''минимальную по включению неподвижную точку'''.&lt;br /&gt;
&lt;br /&gt;
===Алгоритм поиска минимальной неподвижной точки===&lt;br /&gt;
&lt;br /&gt;
 Проинициализируем отношения из нерекурсивных определений&lt;br /&gt;
 Пока не достигли неподвижной точки&lt;br /&gt;
   Пополняем отношения из рекурсивных определений&lt;br /&gt;
&lt;br /&gt;
===Циклы и отрицание===&lt;br /&gt;
&lt;br /&gt;
Представим ситуацию, когда принадлежность кортежа к отношению зависит от отрицания его принадлежности к отношению. Это в чистом виде парадокс брадобрея и мы знаем, что такая конструкция не имеет смысла.&lt;br /&gt;
&lt;br /&gt;
Поэтому, введём '''стратифицированное отрицание''', то есть запрет на отрицание в циклах.&lt;/div&gt;</summary>
		<author><name>5.18.184.8</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D1%81%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B4%D0%BE%D0%BC%D0%B5%D0%BD%D0%BE%D0%B2_%D0%B8_%D0%B5%D0%B3%D0%BE_%D1%80%D0%B5%D0%BB%D1%8F%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D1%82%D0%B0&amp;diff=81440</id>
		<title>Исчисление доменов и его реляционная полнота</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D1%81%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B4%D0%BE%D0%BC%D0%B5%D0%BD%D0%BE%D0%B2_%D0%B8_%D0%B5%D0%B3%D0%BE_%D1%80%D0%B5%D0%BB%D1%8F%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D1%82%D0%B0&amp;diff=81440"/>
				<updated>2021-12-19T13:05:30Z</updated>
		
		<summary type="html">&lt;p&gt;5.18.184.8: /* Исчисление доменов */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Исчисление доменов==&lt;br /&gt;
В отличие от исчисления кортежей, где областью значения переменных были отношения, в исчислении доменов, значения переменных лежат в заренее заданых доменах (мы будем называть их также типами). Введём синтаксис для указания типов переменных. Также введём предикат, который для заданного отношения и значений атрибутов проверяет, есть ли совпадающий кортеж в отношении.&lt;br /&gt;
===Синтаксис===&lt;br /&gt;
 &amp;lt;font color=red&amp;gt;Переменная&amp;lt;/font&amp;gt; :: &amp;lt;font color=red&amp;gt;Тип&amp;lt;/font&amp;gt; &amp;lt;font color=green&amp;gt;-- Переменная может принимать значения из какого-то типа. Тип == набор значений&lt;br /&gt;
 &amp;lt;/font&amp;gt;&lt;br /&gt;
  &amp;lt;font color=green&amp;gt;-- Условие принадлежности отношению&amp;lt;/font&amp;gt;&lt;br /&gt;
 &amp;lt;font color=red&amp;gt;Отношение {&amp;lt;/font&amp;gt;&lt;br /&gt;
   &amp;lt;font color=red&amp;gt;Атрибут1&amp;lt;/font&amp;gt; = &amp;lt;font color=red&amp;gt;Значение1&amp;lt;/font&amp;gt;,&lt;br /&gt;
   &amp;lt;font color=red&amp;gt;Атрибут2&amp;lt;/font&amp;gt; = &amp;lt;font color=red&amp;gt;Значение2&amp;lt;/font&amp;gt;,&lt;br /&gt;
   ...&lt;br /&gt;
 &amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Условие принадлежности===&lt;br /&gt;
Предикат, значение которого истина тогда и только тогда, когда в отношении есть кортеж с совпадающими значениями атрибутов.&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&lt;br /&gt;
 S&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;FirstName = &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;, LastName = &amp;lt;font color=green&amp;gt;'Иванов'&amp;lt;/font&amp;gt;&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Будет истинным, если в отношении будет кортеж &amp;lt;code&amp;gt;(FirstName = 'Иван', LastName = 'Иванов')&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;(FirstName = 'Иван', LastName = 'Иванов', Email = 'ivan@example.com')&amp;lt;/code&amp;gt; и ложным, если хотя бы какой-нибудь атрибут не совпадёт.&lt;br /&gt;
&lt;br /&gt;
===Примеры запросов===&lt;br /&gt;
=====Идентификаторы всех студентов=====&lt;br /&gt;
 SId &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; S&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;SId = SId&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
=====Идентификаторы студентов, не сдавших курс с CId=10=====&lt;br /&gt;
 SId &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; ¬∃Points (Points ≥ 60 ∧ Points&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;SId = SId, Points = Points, CId = 10&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
==Реляционная полнота исчисления доменов==&lt;br /&gt;
&lt;br /&gt;
====Проекция $\pi_{A_1, ..., A_n}(R)$====&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;from&amp;lt;/font&amp;gt; $R$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_1$ = $A_1$, ..., $A_n$ = $A_n$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Фильтр $σ_θ(R)$====&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;from&amp;lt;/font&amp;gt; $R$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_1$ = $A_1$, ..., $A_n$ = $A_n$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $θ$&lt;br /&gt;
&lt;br /&gt;
====Переименовывание $ε_{A=expr}(R_1)$====&lt;br /&gt;
 expr as A &amp;lt;font color=blue&amp;gt;from&amp;lt;/font&amp;gt; $R$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R${$A_1$ = $A_1$, ..., $A_n$ = $A_n$}&lt;br /&gt;
&lt;br /&gt;
====Объединение $R_1 ∪ R_2$====&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∨ $R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Разность $R_1 ∖ R_2$====&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $¬R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Декартово произведение $R_1 × R_2$====&lt;br /&gt;
 $A_1$, ..., $A_n$, $B_1$, ..., $B_m$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$B_j$ = $B_j$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Естественное соединение $R_1 ⋈ R_2$====&lt;br /&gt;
 $A_1$, ..., $A_n$, $B_1$, ..., $B_m$, $C_1$, ..., $C_l$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$, $B_j$ = $B_j$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$C_k$ = $C_k$, $B_j$ = $B_j$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;/div&gt;</summary>
		<author><name>5.18.184.8</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D1%81%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B4%D0%BE%D0%BC%D0%B5%D0%BD%D0%BE%D0%B2_%D0%B8_%D0%B5%D0%B3%D0%BE_%D1%80%D0%B5%D0%BB%D1%8F%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D1%82%D0%B0&amp;diff=81439</id>
		<title>Исчисление доменов и его реляционная полнота</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D1%81%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B4%D0%BE%D0%BC%D0%B5%D0%BD%D0%BE%D0%B2_%D0%B8_%D0%B5%D0%B3%D0%BE_%D1%80%D0%B5%D0%BB%D1%8F%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D1%82%D0%B0&amp;diff=81439"/>
				<updated>2021-12-19T12:47:12Z</updated>
		
		<summary type="html">&lt;p&gt;5.18.184.8: /* Исчисление доменов */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Исчисление доменов==&lt;br /&gt;
В отличие от исчисления кортежей, где областью знацения переменных были отношения, в исчислении доменов, значения переменных лежат в заренее заданых доменах (мы будем называть их также типами). Введём синтаксис для указания типов переменных. Также введём предикат, который для заданного отношения и значений атрибутов проверяет, есть ли совпадающий кортеж в отношении.&lt;br /&gt;
===Синтаксис===&lt;br /&gt;
 &amp;lt;font color=red&amp;gt;Переменная&amp;lt;/font&amp;gt; :: &amp;lt;font color=red&amp;gt;Тип&amp;lt;/font&amp;gt; &amp;lt;font color=green&amp;gt;-- Переменная может принимать значения из какого-то типа. Тип == набор значений&lt;br /&gt;
 &amp;lt;/font&amp;gt;&lt;br /&gt;
  &amp;lt;font color=green&amp;gt;-- Условие принадлежности отношению&amp;lt;/font&amp;gt;&lt;br /&gt;
 &amp;lt;font color=red&amp;gt;Отношение {&amp;lt;/font&amp;gt;&lt;br /&gt;
   &amp;lt;font color=red&amp;gt;Атрибут1&amp;lt;/font&amp;gt; = &amp;lt;font color=red&amp;gt;Значение1&amp;lt;/font&amp;gt;,&lt;br /&gt;
   &amp;lt;font color=red&amp;gt;Атрибут2&amp;lt;/font&amp;gt; = &amp;lt;font color=red&amp;gt;Значение2&amp;lt;/font&amp;gt;,&lt;br /&gt;
   ...&lt;br /&gt;
 &amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Условие принадлежности===&lt;br /&gt;
Предикат, значение которого истина тогда, когда в отношении есть кортеж с совпадающими значениями атрибутов.&lt;br /&gt;
&lt;br /&gt;
 S&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;FirstName = &amp;lt;font color=green&amp;gt;'Иван'&amp;lt;/font&amp;gt;, LastName = &amp;lt;font color=green&amp;gt;'Иванов'&amp;lt;/font&amp;gt;&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Примеры запросов===&lt;br /&gt;
=====Идентификаторы всех студентов=====&lt;br /&gt;
 SId &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; S&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;SId = SId&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
=====Идентификаторы студентов, не сдавших курс с CId=10=====&lt;br /&gt;
 SId &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; ¬∃Points (Points ≥ 60 ∧ Points&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;SId = SId, Points = Points, CId = 10&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
==Реляционная полнота исчисления доменов==&lt;br /&gt;
&lt;br /&gt;
====Проекция $\pi_{A_1, ..., A_n}(R)$====&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;from&amp;lt;/font&amp;gt; $R$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_1$ = $A_1$, ..., $A_n$ = $A_n$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Фильтр $σ_θ(R)$====&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;from&amp;lt;/font&amp;gt; $R$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_1$ = $A_1$, ..., $A_n$ = $A_n$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $θ$&lt;br /&gt;
&lt;br /&gt;
====Переименовывание $ε_{A=expr}(R_1)$====&lt;br /&gt;
 expr as A &amp;lt;font color=blue&amp;gt;from&amp;lt;/font&amp;gt; $R$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R${$A_1$ = $A_1$, ..., $A_n$ = $A_n$}&lt;br /&gt;
&lt;br /&gt;
====Объединение $R_1 ∪ R_2$====&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∨ $R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Разность $R_1 ∖ R_2$====&lt;br /&gt;
 $A_1$, ..., $A_n$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $¬R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Декартово произведение $R_1 × R_2$====&lt;br /&gt;
 $A_1$, ..., $A_n$, $B_1$, ..., $B_m$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$B_j$ = $B_j$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Естественное соединение $R_1 ⋈ R_2$====&lt;br /&gt;
 $A_1$, ..., $A_n$, $B_1$, ..., $B_m$, $C_1$, ..., $C_l$ &amp;lt;font color=blue&amp;gt;where&amp;lt;/font&amp;gt; $R_1$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$A_i$ = $A_i$, $B_j$ = $B_j$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt; ∧ $R_2$&amp;lt;font color=red&amp;gt;{&amp;lt;/font&amp;gt;$C_k$ = $C_k$, $B_j$ = $B_j$&amp;lt;font color=red&amp;gt;}&amp;lt;/font&amp;gt;&lt;/div&gt;</summary>
		<author><name>5.18.184.8</name></author>	</entry>

	</feed>