<?xml version="1.0" encoding="UTF-8"?>
<TEI xml:space="preserve" xmlns="http://www.tei-c.org/ns/1.0" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://www.tei-c.org/ns/1.0 https://raw.githubusercontent.com/kermitt2/grobid/master/grobid-home/schemas/xsd/Grobid.xsd"
 xmlns:xlink="http://www.w3.org/1999/xlink">
	<teiHeader xml:lang="en">
		<fileDesc>
			<titleStmt>
				<title level="a" type="main">Experiencing Hypothetical Datalog in SQL Puzzles</title>
			</titleStmt>
			<publicationStmt>
				<publisher/>
				<availability status="unknown"><licence/></availability>
			</publicationStmt>
			<sourceDesc>
				<biblStruct>
					<analytic>
						<author>
							<persName><forename type="first">Fernando</forename><surname>Sáenz-Pérez</surname></persName>
							<affiliation key="aff0">
								<orgName type="department">Faculty of Computer Science</orgName>
								<orgName type="institution">Complutense University of Madrid</orgName>
								<address>
									<postCode>28040</postCode>
									<settlement>Madrid</settlement>
									<country key="ES">Spain</country>
								</address>
							</affiliation>
							<affiliation key="aff0">
								<orgName type="department">Faculty of Computer Science</orgName>
								<orgName type="institution">Complutense University of Madrid</orgName>
								<address>
									<postCode>28040</postCode>
									<settlement>Madrid</settlement>
									<country key="ES">Spain</country>
								</address>
							</affiliation>
						</author>
						<author>
							<persName><forename type="first">Workshop</forename><surname>Ceur</surname></persName>
							<affiliation key="aff0">
								<orgName type="department">Faculty of Computer Science</orgName>
								<orgName type="institution">Complutense University of Madrid</orgName>
								<address>
									<postCode>28040</postCode>
									<settlement>Madrid</settlement>
									<country key="ES">Spain</country>
								</address>
							</affiliation>
						</author>
						<author>
							<persName><surname>Proceedings</surname></persName>
							<affiliation key="aff0">
								<orgName type="department">Faculty of Computer Science</orgName>
								<orgName type="institution">Complutense University of Madrid</orgName>
								<address>
									<postCode>28040</postCode>
									<settlement>Madrid</settlement>
									<country key="ES">Spain</country>
								</address>
							</affiliation>
						</author>
						<title level="a" type="main">Experiencing Hypothetical Datalog in SQL Puzzles</title>
					</analytic>
					<monogr>
						<idno type="ISSN">1613-0073</idno>
					</monogr>
					<idno type="MD5">D2D4D3EA30161B80B038A15DFD56E488</idno>
				</biblStruct>
			</sourceDesc>
		</fileDesc>
		<encodingDesc>
			<appInfo>
				<application version="0.7.2" ident="GROBID" when="2025-04-23T19:11+0000">
					<desc>GROBID - A machine learning software for extracting information from scholarly documents</desc>
					<ref target="https://github.com/kermitt2/grobid"/>
				</application>
			</appInfo>
		</encodingDesc>
		<profileDesc>
			<textClass>
				<keywords>
					<term>Hypothetical Datalog</term>
					<term>Recursive SQL</term>
					<term>Teaching</term>
					<term>Puzzles</term>
				</keywords>
			</textClass>
			<abstract>
<div xmlns="http://www.tei-c.org/ns/1.0"><p>This work presents some SQL puzzles making use of the application of Hypothetical Datalog (HD) to implement an SQL system. HD provides a way of declaring SQL Common Table Expressions as used to specify local view definitions and recursive queries. We present the concepts of HD that will be employed to translate SQL queries to HD, providing its syntax, an inference system and translation rules. Finally, several SQL puzzles used during teaching SQL in a database subject are proposed.</p></div>
			</abstract>
		</profileDesc>
	</teiHeader>
	<text xml:lang="en">
		<body>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="1.">Introduction</head><p>SQL is usually understood as a specific-purpose, declarative programming language, intended to insert and extract data from relational databases. However, since the addition of recursive common table expressions (CTE, included for the first time in the ISO/IEC Standard SQL:1999, also known as SQL3) its nature has evolved to become a Turing-complete language. To acknowledge this, a specific class of tag systems, CTS's (Cyclic Tag Systems) were proposed in <ref type="bibr" target="#b0">[1]</ref>, and a corollary of its work was that a CTS can emulate a Turing-complete class of tag systems. Since a CTS can be implemented in standard SQL, 1  this proves that SQL is Turing complete.</p><p>This result can be used to pose more advanced problems as puzzles to students with the aim of sharpening their programming skills and promoting open-mindedness. Using puzzles to this end is a well-known technique <ref type="bibr" target="#b1">[2]</ref>, and in fact they are used all around the world as in the Hour of Code, 2  Programming Praxis, 3 CodeKata, 4 ¡Acepta el reto! 5 and also specific for SQL <ref type="bibr" target="#b2">[3]</ref>. 6 Our experience and student feedback when teaching database concepts to advanced students (typically in the double degree of Computer Science and Mathematics) during last years confirms the usefulness of puzzles as an intellectual challenge posed to students (proposed as extra-curricular activities). This paper collects some of those SQL puzzles, ranging from the easier ones to the more complex and appealing ones. Though SQL can not be considered as an esoteric language <ref type="bibr" target="#b3">[4]</ref>, expressing these puzzles with this language can be viewed as an esoteric usage.</p><p>While these puzzles can be solved in most SQL systems, when teaching we use instead the Datalog Educational System (DES) 7  <ref type="bibr" target="#b4">[5]</ref>. This system, which is capable of solving standard SQL queries, is in our view more adequate for students than others because, in particular, it provides better syntax error explanations and even semantic error warnings <ref type="bibr" target="#b5">[6]</ref>. Moreover, students can use its SQL declarative debugger <ref type="bibr" target="#b6">[7]</ref> for fixing semantically incorrect views. These last two features are absent in commercial SQL systems. Apart from this, DES extends the SQL language beyond the standard, including the </p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="1.1.">Motivation</head><p>SQL data-retrieval queries usually start with a SELECT keyword, which builds the outcome in terms of its expression list. An exception to this is the WITH clause, which permits local view declarations which can be used in its outcome SQL statement. These declarations are known as Common Table Expressions (CTE's), and its syntax in recursive WITH queries can be simplified as:</p><formula xml:id="formula_0">WITH RECURSIVE R 1 AS SQL 1 , --CTE 1 ..., R 𝑛 AS SQL 𝑛 --CTE 𝑛 SQL --Outcome SQL</formula><p>where each R 𝑖 is a local, temporary view name defined by the SQL query SQL 𝑖 , and can be referenced only in the context of each SQL 𝑖 and SQL , which is the query that builds the outcome. Each declaration R 𝑖 AS SQL 𝑖 is a CTE. Whilst a local view declaration is similar to a CREATE VIEW declaration, its scope is restricted as already noted, and its lifetime is the same as for SQL . Though CTE's are used for a number of reasons (divide-and-conquer, readability, creating views for which the user has no rights, . . . ), we are interested in the use that enables SQL as a Turing complete language: by specifying recursive queries. As an example, the following defines natural numbers:</p><formula xml:id="formula_1">WITH RECURSIVE nat(n) AS (SELECT 0 UNION ALL SELECT n+1 FROM nat) SELECT n FROM nat;</formula><p>where the keyword RECURSIVE is required by the standard to specify a (potentially) recursive CTE, the first SELECT is the base case (simply returning the tuple (0) as a FROM-less statement), which is unionised with the inductive case (second SELECT). This single CTE is used in the outcome SQL (third SELECT) to deliver all the naturals. Query semantics can be understood as finding its fixpoint for the application of the unionised queries on an enlarging relation nat, which is increased with a new number in each fixpoint-search iteration. In this case, the fixpoint would be infinite, though top-𝑁 queries can limit the number of retrieved tuples.</p><p>Current SQL systems include limitations on recursive queries: mutual and non-linear recursion are not allowed, only one recursive case can be set, and duplicate elimination is not allowed in the union of the base and inductive cases. These limitations can be overcome with other database languages such as Datalog operating over the same relational data, a language capable of expressing mutual and non-linear recursion, and duplicates <ref type="bibr" target="#b9">[10,</ref><ref type="bibr" target="#b10">11]</ref>. However, local (temporary) view definitions as needed to represent the behavior of a WITH clause are not part of a Datalog language, which only allows for non-volatile predicates.</p><p>Here is where intuitionistic logic programming (ILP) can be of help because it adds embedded implications in the body of clauses. Intuitively, in an embedded implication 𝐴 ⇒ 𝐵, the atom 𝐴 is assumed during proving 𝐵 <ref type="bibr" target="#b11">[12]</ref>, limiting its scope to this proof. A database language based on ILP is Hypothetical Datalog <ref type="bibr" target="#b7">[8]</ref>, which is extended in <ref type="bibr" target="#b8">[9,</ref><ref type="bibr" target="#b12">13,</ref><ref type="bibr" target="#b13">14]</ref> with rules (not only atoms) in such assumptions, a feature that can be leveraged to represent those SQL local view definitions. Next section recalls this feature implemented in the DES system, which also includes essential SQL functionalities such as handling duplicates and aggregates.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="2.">Intuitionistic Logic Programming for SQL</head><p>The Hypothetical Datalog language in <ref type="bibr" target="#b8">[9]</ref> implements a system based on intuitionistic logic programming. Here, its syntax and semantics are extended with conditions in expressions and meta-predicates for supporting common SQL needs: top-𝑁 queries (i.e., at most, 𝑁 solutions to its goal are allowed), aggregates, and expressions in comparison predicates. Next, 𝑣𝑎𝑟𝑠(𝑇 ) is the set of variables in 𝑇 .</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>Definition 2.1 (Syntax). 𝜌</head><formula xml:id="formula_2">:= 𝐴 | 𝐴 ← 𝜑 1 ∧ . . . ∧ 𝜑 𝑛 𝜑 := 𝐴 | ¬𝐴 | 𝐸 1 ◇ 𝐸 2 | 𝛿(𝐴) | 𝜏 (𝑁, 𝐴) | 𝒢(𝐴, 𝑋𝑠, 𝜑) | 𝜌 1 ∧ . . . ∧ 𝜌 𝑛 ⇒ 𝜑</formula><p>where 𝜌 stands for rule, 𝜑 for goal, 𝐴 for atom (possibly containing variables and constants, but no compound terms), 𝑁 is a natural number, 𝑋𝑠 is a list of variables, 𝐸 𝑖 are expressions, ◇ is a comparison operator (=, &lt;, ≤. . . ), symbols ¬, 𝛿, 𝜏 and 𝒢 are meta-predicates, and 𝑣𝑎𝑟𝑠(𝜌 𝑖 ) do not occur out of 𝜌 𝑖 .</p><p>Here, the symbol ⇒ denotes the embedded implication (it builds a goal that can occur in the body of a rule), and 𝛿 is a duplicate elimination meta-predicate. The first condition (on compound terms) is needed for ensuring a finite fixpoint in absence of infinite relations, and the second one (on variables of rules 𝜌 𝑖 ) ensures that 𝜌 𝑖 is not specialized by any substitution out of it along inferencing, so 𝜌 𝑖 can be assumed "as is" for any inference step, which is an adequate requirement for modelling local definitions in SQL WITH statements (however, it represents a limitation with respect to <ref type="bibr" target="#b11">[12]</ref>).</p><p>Symbols ¬, 𝛿, 𝜏 and 𝒢 are meta-predicates, standing respectively for negation, duplicate elimination, top-𝑁 queries, and group-by (for solving aggregations as counts and summations, which can occur in expressions as other scalar functions). A group-by goal 𝒢(𝐴, 𝑋𝑠, 𝜑) means that ground instances of 𝐴 are grouped by the list of variables 𝑋𝑠 (grouping criteria) and, for each group, there is at most one instantation such that it fulfils 𝜑.</p><p>Next, we extend the inference system in <ref type="bibr" target="#b8">[9]</ref> with inference rules for comparison operators, top-𝑁 and group-by goals. The well-known concepts of predicate dependency graph (PDG) and stratifiable database Δ <ref type="bibr" target="#b14">[15]</ref> are used here (see also page 298 in <ref type="bibr" target="#b8">[9]</ref>). Here, the PDG includes a negative arc 𝑝 ¬ ← 𝑞 between the head predicate 𝑝 of a rule and a predicate 𝑞 in its body, such that 𝑞 occurs in an argument of a meta-predicate ¬, 𝜏 or 𝒢; otherwise, it includes a positive arc 𝑝 ← 𝑞. A negative arc 𝑝 ¬ ← 𝑞 imposes that 𝑞 must be solved before 𝑝 for avoiding non-monotonicity <ref type="bibr" target="#b14">[15]</ref>. 𝑠𝑡𝑟(Δ, 𝑃 ) is the stratum corresponding to predicate 𝑃 in Δ <ref type="bibr" target="#b8">[9]</ref> such that for a positive arc p←q, 𝑠𝑡𝑟(Δ, p) ≥ 𝑠𝑡𝑟(Δ, q), and for a negative arc p ¬ ←q, 𝑠𝑡𝑟(Δ, p) &gt; 𝑠𝑡𝑟(Δ, q). Δ ⊢ 𝜓 is an inference expression, where 𝜓 is an identified ground atom 𝑖𝑑 : 𝐴. Such an 𝑖𝑑 is of the form</p><formula xml:id="formula_3">𝑖𝑑 1 • • • • • 𝑖𝑑 𝑛 (𝑛 ≥ 1)</formula><p>and helps data provenance for supporting duplicates. 𝑝𝑟𝑒𝑑(𝐴) is the predicate of atom 𝐴. A negative inference expression is of the form Δ ⊢ 𝑖𝑑 : −𝐴. Negative inference expressions play a key role in the SQL extension for negative assumptions, but are out of the scope of this paper. Next definition specifies an inference system where each rule is read as: If the formulas above the line can be inferred, then the ones below the line can be inferred as well. The application of an inference rule is an inference step.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>Definition 2.2 (Inference system).</head><p>Given a database Δ and a set of input inference expressions ℰ, the inference system associated to the 𝑠-th stratum is defined as follows, where 𝑑 𝑠 (ℰ) is a closure operator that denotes the set of inference expressions derivable in this system: Axioms:</p><p>• Δ ⊢ 𝑖𝑑 : 𝐴 is an axiom for each (ground) atomic formula 𝑖𝑑 : 𝐴 in Δ, where 𝑠𝑡𝑟(Δ, 𝑝𝑟𝑒𝑑(𝐴)) = 𝑠.</p><p>• Δ ⊢ 𝑐 1 ◇ 𝑐 2 is an axiom, where ◇ ∈ {=, &lt;, &gt;, ≤, ≥}, 𝑐 𝑖 are constants, and 𝑐 1 ◇ 𝑐 2 holds.</p><p>• Each expression in ℰ is an axiom.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>Inference Rules:</head><p>• For any rule 𝐴 ← 𝜑 1 ∧ . . . ∧ 𝜑 𝑛 with identifier 𝑖𝑑 in Δ, where 𝑠𝑡𝑟(Δ, 𝑝𝑟𝑒𝑑(𝐴)) = 𝑠 and for any ground substitution 𝜃:</p><formula xml:id="formula_4">Δ ⊢ 𝑖𝑑 𝑖 : 𝜑 𝑖 𝜃 for each 𝑖 Δ ⊢ 𝑖𝑑 ′ : 𝐴𝜃 (Clause) where 𝑖𝑑 ′ is the composition of identifiers 𝑖𝑑 • 𝑖𝑑 1 • • • 𝑖𝑑 𝑛 .</formula><p>• For any constants 𝑐 𝑖 and expressions 𝑒 𝑖 :</p><formula xml:id="formula_5">Δ ⊢ 𝑐 1 ◇ 𝑐 2 Δ ⊢ 𝑒 1 𝜃 ◇ 𝑒 2 𝜃</formula><p>(Expression) where ◇ ∈ {=, &lt;, &gt;, ≤, ≥}, and 𝑒 𝑖 𝜃 evaluates to 𝑐 𝑖 .</p><p>• For any atoms 𝐴, 𝐴 ′ :</p><formula xml:id="formula_6">Δ ⊢ 𝑖𝑑 : 𝐴 Δ ⊢ 𝛼 : 𝛿(𝐴 ′ 𝜃)</formula><p>(Duplicates) where 𝐴 = 𝐴 ′ 𝜃, 𝛼 is a single, unique identifier.</p><p>• For any atoms 𝐴 𝑖 , 𝐴, natural number 𝑁 , and ground substitutions 𝜃 𝑖 :</p><formula xml:id="formula_7">Δ ⊢ 𝑖𝑑 𝑖 : 𝐴 𝑖 Δ ⊢ 𝛼 𝑖 : 𝜏 (𝑁, 𝐴𝜃 𝑖 )</formula><p>(Top) where 𝐴 𝑖 = 𝐴𝜃 𝑖 , 𝛼 𝑖 are at most 𝑁 single, unique identifiers.</p><p>• For any atoms 𝐴 𝑖 , 𝐴, 𝐵 𝑗 , 𝐵 and ground substitutions 𝜃 𝑖 , 𝜃:</p><formula xml:id="formula_8">Δ ⊢ 𝑖𝑑 𝑖 : 𝐴 𝑖 Δ ⊢ 𝑖𝑑 𝑗 : 𝐵 𝑗 Δ ⊢ 𝛼 𝑖 : 𝒢(𝐴𝜃 𝑖 , 𝑋𝑠𝜃 𝑖 , 𝐵𝜃 𝑖 )</formula><p>(Group-By) where each 𝛼 𝑖 is a unique identifier for each group 𝑋𝑠𝜃 𝑖 , and 𝐴 = 𝐴 𝑖 𝜃, 𝐵 = 𝐵 𝑗 𝜃.</p><p>• For any goal 𝜑:</p><formula xml:id="formula_9">Δ ∪ {𝜌 1 , . . . , 𝜌 𝑛 } ⊢ 𝜑 Δ ⊢ 𝜌 1 ∧ . . . ∧ 𝜌 𝑛 ⇒ 𝜑 (Assumption)</formula><p>Example 1. Natural numbers can be specified in this language as follows:</p><formula xml:id="formula_10">𝜑 1 ≡ (𝑛𝑎𝑡(0) ∧ (𝑛𝑎𝑡(𝑋) ← 𝑛𝑎𝑡(𝑌 ) ∧ 𝑋 = 𝑌 + 1)) ⇒ 𝑛𝑎𝑡(𝑋)</formula><p>Starting with Δ = ∅, and applying the Assumption rule:</p><formula xml:id="formula_11">{(𝑛𝑎𝑡(0)), (𝑛𝑎𝑡(𝑋) ← 𝑛𝑎𝑡(𝑌 ) ∧ 𝑋 = 𝑌 + 1)} ⊢ 𝑛𝑎𝑡(𝑋) ∅ ⊢ (𝑛𝑎𝑡(0) ∧ (𝑛𝑎𝑡(𝑋) ← 𝑛𝑎𝑡(𝑌 ) ∧ 𝑋 = 𝑌 + 1)) ⇒ 𝑛𝑎𝑡(𝑋)</formula><p>Δ, originally empty, has been enlarged with the two rules in the assumption (let us call it Δ ′ ), and each one receives a unique identifier (as any other possible rule in the program). For this example, let 𝑟 1 and 𝑟 2 be the respective identifiers for 𝑛𝑎𝑡(0) and 𝑛𝑎𝑡(𝑋) ← 𝑛𝑎𝑡(𝑌 ) ∧ 𝑋 = 𝑌 + 1. In a second inference step, we can apply the Clause inference rule, giving:</p><formula xml:id="formula_12">Δ ′ ⊢ 𝑟 1 : 𝑛𝑎𝑡(𝑋){𝑋 ↦ → 0} ≡ Δ ′ ⊢ 𝑟 1 : 𝑛𝑎𝑡(0),</formula><p>where 𝜃 = {𝑋 ↦ → 0}, and Δ ′ ⊢ 𝑟 1 : 𝑛𝑎𝑡(0) represents a first solution of the query. This can be read as: the atom 𝑛𝑎𝑡(0) identified by 𝑟 1 has been inferred for the context Δ ′ . Next, using 𝑟 2 in Clause for some 𝑖𝑑 after Assumption yields:</p><formula xml:id="formula_13">Δ ′ ⊢ 𝑖𝑑 : 𝑛𝑎𝑡(𝑌 )𝜃 1 Δ ′ ⊢ (𝑋 = 𝑌 + 1)𝜃 1 Δ ′ ⊢ 𝑟 2 • 𝑖𝑑 : 𝑛𝑎𝑡(𝑋)𝜃 1</formula><p>where axioms above the line can be inferred: First, the axiom Δ ′ ⊢ 𝑟 1 : 𝑛𝑎𝑡(0) (with 𝜃 = {𝑌 ↦ → 0}) as before, and the second one because it becomes a trivial axiom Δ ′ ⊢ 1 = 1 after applying Expression (i.e., the evaluated 𝑋 = 0 + 1 for {𝑋 ↦ → 1}). So 𝜃 1 = {𝑌 ↦ → 0, 𝑋 ↦ → 1}, and the axiom Δ ′ ⊢ 𝑟 2 • 𝑟 1 : 𝑛𝑎𝑡(1) can be inferred. Proceeding in the same way, the following axioms are inferred with 𝑘 &gt; 0:</p><formula xml:id="formula_14">Δ ′ ⊢ 𝑟 2 • • • 𝑟 2 ⏟ ⏞ 𝑘 •𝑟 1 : 𝑛𝑎𝑡(𝑘)</formula></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>□</head><p>Negative information is deduced by applying the closed-world assumption to a set of inference expressions ℰ (written as 𝑐𝑤𝑎(ℰ)) as the union of ℰ and the negative inference expression for Δ ⊢ 𝜑 such that Δ ⊢ 𝜑 / ∈ ℰ. Thus, a stratified bottom-up construction of the unified stratified semantics can be specified by:</p><formula xml:id="formula_15">• ℰ 0 = ∅ • ℰ 𝑠+1 = 𝑐𝑤𝑎(𝑑 𝑠+1 (ℰ 𝑠 )) for 𝑠 ≥ 0.</formula><p>which builds a set of axioms ℰ that provides a way to assign a meaning to a goal 𝜑 with:</p><formula xml:id="formula_16">𝑠𝑜𝑙𝑣𝑒(𝜑, ℰ) = {Δ ⊢ 𝑖𝑑 : 𝜓 ∈ ℰ | 𝜑𝜃 = 𝜓}</formula><p>where 𝜃 is a substitution and each axiom in ℰ is mapped to the database Δ it was deduced for, and the inferred fact 𝜓 is labelled with its data source 𝑖𝑑 (for supporting duplicates). We use Δ(ℰ) to denote the multiset of facts 𝜓 so that Δ ⊢ 𝑖𝑑 : 𝜓 ∈ ℰ for any 𝑖𝑑. In Example 1, there is only one stratum, so:</p><formula xml:id="formula_17">𝑠𝑜𝑙𝑣𝑒(𝜑 1 , ℰ) = {Δ ′ ⊢ 𝑟 2 • • • 𝑟 2 ⏟ ⏞ 𝑘 •𝑟 1 : 𝑛𝑎𝑡(𝑘) | 𝑘 ≥ 0} = ℰ 𝜑 1</formula><p>and the outcome would be the multiset</p><formula xml:id="formula_18">Δ(ℰ 𝜑 1 ) = {𝑛𝑎𝑡(𝑘) | 𝑘 ≥ 0}.</formula><p>A top-10 goal for this example would restrict the number of solutions as: Δ(ℰ 𝜏 (10,𝜑 1 ) ) = {𝑛𝑎𝑡(𝑘) | 0 ≤ 𝑘 ≤ 9}, which corresponds to modifying the outcome SQL query in the WITH statement by SELECT TOP 10 n FROM nat.</p><p>The stratified construction of inference expressions captures the requirements of SQL clauses such as EXCEPT, NOT IN, and GROUP BY, which are sources of negative arcs in the construction of a predicate dependency graph (PDG) <ref type="bibr" target="#b15">[16]</ref>.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="3.">Translating SQL to Hypothetical Datalog</head><p>Here, the function SQL_to_DL is defined by extending Definition 6 in <ref type="bibr" target="#b8">[9]</ref> with top-𝑁 queries, aggregates and expressions. This function takes a relation name and an SQL statement as input and returns a multiset of Hypothetical Datalog rules providing the same meaning as the SQL relation for a corresponding predicate with the same name as the relation. From here on: Without loss of expressivity, we assume that a group-by statement includes a relation name in its FROM clause; set-related operators and symbols refer to multisets because SQL relations can contain duplicates; each attribute is qualified by the relation name it corresponds to so that they can be uniquely identified; an empty conjunctive goal is 𝑡𝑟𝑢𝑒; where convenient, variables of goals are made explicit; and for the sake of conciseness, Hypothetical Datalog is simply referred to as Datalog. Here, each E 𝑖 in the list 𝐸𝑥𝑝𝑠 is either an expression or an argument name present in the relation 𝑅𝑒𝑙 with corresponding logic variable 𝑋 𝑖 ∈ 𝑋. 𝑅𝑒𝑙 is either a single defined relation (table or view), or a join of relations, or an SQL statement. Function SQLREL_to_DL (respectively, SQLCOND_to_DL ) takes an SQL relation (respectively, condition) and returns a goal with as many variables 𝑌 as arguments of 𝑅𝑒𝑙 and, possibly, additional rules which result from the translation (and similarly for SQLEXPS_to_DL (𝐸𝑥𝑝𝑠)).</p><p>Variables 𝑍 ⊆ 𝑌 come as a result of the translation of the condition 𝐷𝐿𝐶𝑜𝑛𝑑 to a goal.</p><formula xml:id="formula_19">% GROUP BY statement SQL_to_DL (𝑟, SELECT 𝐸𝑥𝑝𝑠 FROM 𝑅𝑒𝑙 GROUP BY 𝐶𝑜𝑙𝑠) = { 𝑟(𝑋) ← 𝐷𝐿𝐸𝑥𝑝𝑠 ∧ 𝒢(𝐷𝐿𝑅𝑒𝑙(𝑌 ), 𝑉 , 𝐷𝐿𝐴𝑔𝑔) } ⋃︀ 𝐸𝑥𝑝𝑠𝑅𝑢𝑙𝑒𝑠 ⋃︀ 𝑅𝑒𝑙𝑅𝑢𝑙𝑒𝑠,</formula><p>where SQLEXPS_to_DL (𝐸𝑥𝑝𝑠) = (𝐷𝐿𝐸𝑥𝑝𝑠, 𝐷𝐿𝐴𝑔𝑔, 𝐸𝑥𝑝𝑠𝑅𝑢𝑙𝑒𝑠), SQLREL_to_DL (𝑅𝑒𝑙) = (𝐷𝐿𝑅𝑒𝑙(𝑌 ), 𝑅𝑒𝑙𝑅𝑢𝑙𝑒𝑠). Here, 𝑉 ⊆ 𝑌 are the variables of the predicate 𝐷𝐿𝑅𝑒𝑙 corresponding to the attributes 𝐶𝑜𝑙𝑠 of the relation 𝑅𝑒𝑙. </p><formula xml:id="formula_20">% Top-𝑁 SQL_to_DL (𝑟, SELECT TOP N 𝐸𝑥𝑝𝑠 FROM 𝑅𝑒𝑙 WHERE 𝐶𝑜𝑛𝑑) = { 𝑟(𝑋) ← 𝜏 (𝑁, 𝑟 ′ (𝑋)) } ⋃︀ 𝑅𝑢𝑙𝑒𝑠, where SQL_to_DL (𝑟 ′ , SELECT 𝐸𝑥𝑝𝑠 FROM 𝑅𝑒𝑙 WHERE 𝐶𝑜𝑛𝑑) = 𝑅𝑢𝑙𝑒𝑠 % Union SQL_to_DL (𝑟, SQL 1 UNION ALL SQL 2 ) = SQL_to_DL (𝑟, SQL 1 ) ⋃︀ SQL_to_DL (𝑟, SQL 2 ) % Difference SQL_to_DL (𝑟, SQL 1 EXCEPT SQL 2 ) = { 𝑟(𝑋) ← 𝑠(𝑋) ∧ ¬𝑡(𝑋) } ⋃︀ SQL_to_DL (𝑠, SQL 1 ) ⋃︀ SQL_to_DL (𝑡, SQL 2 ) % Intersection SQL_to_DL (𝑟, SQL 1 INTERSECT SQL 2 ) = { 𝑟(𝑋) ← 𝑠(𝑋) ∧ 𝑡(𝑋) } ⋃︀ SQL_to_DL (𝑠,</formula><formula xml:id="formula_21">)) = (𝐷𝐿𝑅𝑒𝑙(𝑋 1 )∧• • •∧𝐷𝐿𝑅𝑒𝑙(𝑋 𝑛 ), 𝑅𝑒𝑙𝑅𝑢𝑙𝑒𝑠 1 ∪• • •∪𝑅𝑒𝑙𝑅𝑢𝑙𝑒𝑠 𝑛 )</formula><p>where SQLREL_to_DL (𝑅𝑒𝑙 𝑖 ) = (𝐷𝐿𝑅𝑒𝑙(𝑋 𝑖 ), 𝑅𝑒𝑙𝑅𝑢𝑙𝑒𝑠 𝑖 ).</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>% SQL statement</head><p>SQLREL_to_DL (𝑆𝑄𝐿) = (𝑅𝑒𝑙𝑁 𝑎𝑚𝑒(𝑋), SQL_to_DL (𝑅𝑒𝑙𝑁 𝑎𝑚𝑒, 𝑆𝑄𝐿)) where 𝑋 are the 𝑛 variables corresponding to the 𝑛-ary statement 𝑆𝑄𝐿, and 𝑅𝑒𝑙𝑁 𝑎𝑚𝑒 is a fresh relation name.</p><p>Definition 3.3. The function SQLEXPS_to_DL takes a sequence of SQL expressions as input and returns a Datalog conjunctive goal for expressions, another for aggregates, and a program, as defined by cases as follows:</p><formula xml:id="formula_22">% Sequence of expressions SQLEXPS_to_DL ((𝐸𝑥𝑝 1 , . . . , 𝐸𝑥𝑝 𝑛 )) = ( ⋀︀ {𝐷𝐿𝐸𝑥𝑝 𝑖 | 1 ≤ 𝑖 ≤ 𝑛}, ⋀︀ {𝐷𝐿𝐴𝑔𝑔 𝑖 | 1 ≤ 𝑖 ≤ 𝑛}, 𝐸𝑥𝑝𝑅𝑢𝑙𝑒𝑠 1 ∪ • • • ∪ 𝐸𝑥𝑝𝑅𝑢𝑙𝑒𝑠 𝑛 ),</formula><p>where SQLEXPS_to_DL (𝐸𝑥𝑝 𝑖 ) = (𝐷𝐿𝐸𝑥𝑝 𝑖 , 𝐷𝐿𝐴𝑔𝑔 𝑖 , 𝐸𝑥𝑝𝑅𝑢𝑙𝑒𝑠 𝑖 ).</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>% Expression</head><p>SQLEXPS_to_DL (𝐸𝑥𝑝) = ((𝑋 = 𝐷𝐿𝐸𝑥𝑝) ∧ 𝐷𝐿𝑄𝑠, 𝐷𝐿𝐴𝑔𝑔, 𝐸𝑥𝑝𝑅𝑢𝑙𝑒𝑠), where 𝑋 is the variable corresponding to the expression 𝐸𝑥𝑝 at position 𝑝 in the list of SQL expressions (𝐸𝑥𝑝 1 , . . . , 𝐸𝑥𝑝 𝑛 ), and 𝐷𝐿𝐸𝑥𝑝 is the result of: 1) replacing each attribute 𝑎 𝑖 of a relation 𝑟 in 𝐸𝑥𝑝 by the respective variable 𝑋 𝑖 of the predicate 𝑟; 2) replacing each aggregate function 𝑓 over an attribute 𝑏 𝑗 of the relation 𝑠 by a fresh variable 𝑌 𝑗 . For each 𝑓 out of 𝑛, 𝐷𝐿𝐴𝑔𝑔 includes a conjunctive goal 𝑌 𝑗 = 𝑓 (𝑍 𝑗 ), where 𝑍 𝑗 is the variable of 𝑠(𝑍) which corresponds to the attribute 𝑏 𝑗 ; and 3) replacing each query 𝑄 with alias 𝑎 by a fresh variable 𝑈 such that SQL_to_DL (𝑎, 𝑄) = (𝑄𝑅𝑢𝑙𝑒𝑠), 𝐸𝑥𝑝𝑅𝑢𝑙𝑒𝑠 contains 𝑄𝑅𝑢𝑙𝑒𝑠, and 𝐷𝐿𝑄𝑠 includes a conjunctive goal 𝑎(𝑈 ). Definition 3.4. The function SQLCOND_to_DL takes an SQL condition as input and returns a Datalog conjunctive goal and a program, as defined by cases as follows:</p><formula xml:id="formula_23">% Basic condition SQLCOND_to_DL (𝐸𝑥𝑝 1 𝑐𝑜𝑝 𝐸𝑥𝑝 2 ) = ((𝑋 1 𝑐𝑜𝑝 ′ 𝑋 2 ) ⋀︀ {(𝑋 𝑖 = 𝐷𝐿𝐸𝑥𝑝 𝑖 ) ∧ 𝐷𝐿𝑄𝑠 𝑖 | 1 ≤ 𝑖 ≤ 2}, 𝐸𝑥𝑝𝑅𝑢𝑙𝑒𝑠 1 ∪ 𝐸𝑥𝑝𝑅𝑢𝑙𝑒𝑠 2 ),</formula><p>where SQLEXPS_to_DL (𝐸𝑥𝑝 𝑖 ) = ((𝑋 𝑖 = 𝐷𝐿𝐸𝑥𝑝 𝑖 ) ∧ 𝐷𝐿𝑄𝑠 𝑖 , 𝑡𝑟𝑢𝑒, 𝐸𝑥𝑝𝑅𝑢𝑙𝑒𝑠 𝑖 ), 1 ≤ 𝑖 ≤ 2, and 𝑐𝑜𝑝 ′ is the Datalog corresponding comparison operator to 𝑐𝑜𝑝.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>% Conjunction</head><formula xml:id="formula_24">SQLCOND_to_DL (𝐶 1 AND 𝐶 2 ) = (𝐶 ′ 1 ∧ 𝐶 ′ 2 , 𝐶𝑅𝑢𝑙𝑒𝑠 1 ∪ 𝐶𝑅𝑢𝑙𝑒𝑠 2 ) where 𝐶 𝑖 (1 ≤ 𝑖 ≤ 2) are conditions and SQLCOND_to_DL (𝐶 𝑖 )=(𝐶 ′ 𝑖 , 𝐶𝑅𝑢𝑙𝑒𝑠 𝑖 ). % Disjunction SQLCOND_to_DL (𝐶 1 OR 𝐶 2 ) = (𝛿(𝑑), {𝑑 ← 𝐶 ′ 1 , 𝑑 ← 𝐶 ′ 2 } ∪ 𝐶𝑅𝑢𝑙𝑒𝑠 1 ∪ 𝐶𝑅𝑢𝑙𝑒𝑠 2 ) where 𝐶 𝑖 (1 ≤ 𝑖 ≤ 2) are conditions, SQLCOND_to_DL (𝐶 𝑖 )=(𝐶 ′</formula><p>𝑖 , 𝐶𝑅𝑢𝑙𝑒𝑠 𝑖 ), and 𝑑 is a fresh atom. % Negated condition SQLCOND_to_DL (NOT 𝐶) = (𝐶 ′ , 𝐶𝑅𝑢𝑙𝑒𝑠) where 𝐶 ′ =SQLCOND_to_DL (𝐶)=(𝐶 ′ , 𝐶𝑅𝑢𝑙𝑒𝑠), and 𝐶 represents the logical complement of 𝐶 (𝑋 &lt; 𝑌 = 𝑋 ≥ 𝑌 , 𝐶 1 ∧ 𝐶 2 = 𝐶 1 ∨ 𝐶 2 , and so on).</p><p>Note that disjunction requires duplicate elimination because, otherwise, there can be more tuples in the result because a disjunction in a rule is rewritten as two rules, as the next example illustrates: </p><formula xml:id="formula_25">(𝑟(𝑋), ℰ) = {Δ ⊢ 𝑟 1 • 𝑟 2 : 𝑟(1.4142), Δ ⊢ 𝑟 1 • 𝑟 3 :</formula><p>𝑟(1.4142)}, which is not the expected outcome for the SQL query.</p><p>The actual system applies other techniques to simplify the translated program, such as partial evaluation and folding/unfolding <ref type="bibr" target="#b16">[17]</ref>, which are not presented here. In this case, the resulting translation is simply {𝑟(1.4142)}, as it can be checked in the system by displaying compilations with the command /show_compilations on. Observe also that the system emits the warning for this example: [Sem] Tautological condition: (true OR true), which is one of the results of its semantic analysis <ref type="bibr" target="#b5">[6]</ref> </p><formula xml:id="formula_26">SQL_to_DL (𝑟, WITH RECURSIVE nat(n) AS (SELECT 0 UNION ALL SELECT n+1 FROM nat) SELECT n FROM nat ) = { 𝑟(𝑋) ← ⋀︀ ({SQL_to_DL (𝑟 𝑖 , SQL 𝑖 ) | 1 ≤ 𝑖 ≤ 𝑛}) ⇒ 𝑠(𝑋) } ⋃︀ SQL_to_DL (𝑠, SQL ) = {(𝑟(𝑋) ← ((𝑛𝑎𝑡(𝑋 1 ) ← 𝑑𝑢𝑎𝑙 ∧ 𝑋 1 = 0 ∧ 𝑡𝑟𝑢𝑒) ∧ (𝑛𝑎𝑡(𝑋 2 ) ← 𝑛𝑎𝑡(𝑌 ) ∧ 𝑋 2 = 𝑌 + 1 ∧ 𝑡𝑟𝑢𝑒) ⇒ 𝑠(𝑋))), (𝑠(𝑋 3 ) ← 𝑛𝑎𝑡(𝑍) ∧ 𝑋 3 = 𝑍 ∧ 𝑡𝑟𝑢𝑒)} because, by Definition 3.1-Union: SQL_to_DL (𝑛𝑎𝑡, SELECT 0 UNION ALL SELECT n+1 FROM nat) = SQL_to_DL (𝑛𝑎𝑡, SELECT 0) ∪ SQL_to_DL (𝑛𝑎𝑡, SELECT n+1 FROM nat)</formula><p>and, by Definition 3.1-Basic SQL statement, where SELECT 0 is an abbreviation for SELECT 0 FROM dual WHERE TRUE, the following is get by performing similar steps to Example 2: SQL_to_DL (𝑛𝑎𝑡, SELECT 0) = { 𝑛𝑎𝑡(𝑋 1 ) ← 𝑑𝑢𝑎𝑙 ∧ 𝑋 1 = 0 ∧ 𝑡𝑟𝑢𝑒 }, and applying again the same definition to:</p><formula xml:id="formula_27">SQL_to_DL (𝑛𝑎𝑡, SELECT n+1 FROM nat) = { 𝑛𝑎𝑡(𝑋 2 ) ← 𝑛𝑎𝑡(𝑌 ) ∧ 𝑋 2 = 𝑌 + 1 ∧ 𝑡𝑟𝑢𝑒 }, and: SQL_to_DL (𝑠, SELECT n FROM nat) = { 𝑠(𝑋 3 ) ← 𝑛𝑎𝑡(𝑍) ∧ 𝑋 3 = 𝑍 ∧ 𝑡𝑟𝑢𝑒 }.</formula><p>Further simplification and unfolding steps done in the system results in a single rule: {(𝑟(𝑋) ← (𝑛𝑎𝑡(0)) ∧ (𝑛𝑎𝑡(𝑌 ) ← 𝑛𝑎𝑡(𝑍) ∧ 𝑌 = 𝑍 + 1) ⇒ 𝑛𝑎𝑡(𝑋))}. □</p><p>[9] provides a theorem for the semantic equivalence of an SQL relation and its counterpart Datalog translation for a subset of the language presented here. An SQL relation is translated into an extended relational algebra relation (ERA) definition (with SQL_to_ERA ), for which an interpretation for a computed answer in terms of the ERA operators is provided. The Datalog program is interpreted with the unified stratified semantics, which provides the set of axioms ℰ for the original database Δ augmented with the translation of the query 𝑄 to this Datalog program. So, the proof inductively proceeds by strata, and for each stratum by cases, showing the semantic equivalence of the translation from the SQL query 𝑄 into an ERA expression for a relation 𝑟 (with SQL_to_ERA ), and the translation of 𝑄 into a Datalog program (with SQL_to_DL ).</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="4.">SQL Puzzles</head><p>This section provides several SQL puzzles <ref type="foot" target="#foot_1">9</ref> provided to students and solved in DES, mainly with its on-line interface DESweb. We use the concrete SQL syntax that DES supports, allowing for omitting the verbose RECURSIVE modifier which, though promoted and required by the standard for recursive queries, it seems to be an unneeded writing burden (a simple program analysis can classify recursive predicates and apply both specific compilations and optimizations). Also, UNION can be used instead of UNION ALL if duplicates are not required. Even when it might seem that discarding duplicates results in a solving overhead, it turns out to be the opposite for recursive queries <ref type="bibr" target="#b17">[18]</ref>. For each puzzle, its problem statement is given, together with an equivalent Datalog formulation, and outcome. A selection of other puzzles can be found in Appendix A.</p><p>Here, we use the concrete syntax of DES, where :-stands for the neck of a rule, the comma (,) for goal conjunction, =&gt; for embedded implication, /\ for rule assumptions, distinct(𝐴) for 𝛿(𝐴), top(𝑁 ,𝐴) for 𝜏 (𝑁, 𝐴), and group_by(𝐴,𝑋𝑠,𝜑) for 𝒢(𝐴, 𝑋𝑠, 𝜑). Relation attributes are not explicitly qualified with the relation name unless necessary.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="4.1.">Euler Number</head><p>Problem Statement: Compute the Euler number 𝑒 as a Taylor series:</p><formula xml:id="formula_28">𝑒 = 1 0! + 1 1! + 1 2! + 1 3! + • • • = ∑︁ 𝑖≥0 1 𝑖!</formula><p>As stop condition implicitly use the system precision for numbers.</p><p>A Solution: A straightforward solution is to define a CTE for the factorials with a schema of two arguments: the index 𝑛 (n) and the value of 𝑛! (factorial). Its base case is (0, 1), and the inductive case just computes (n + 1, n+1*factorial), given an already-computed tuple (n, factorial). Then, define each term in the series as another CTE, say taylor, with a single column (euler) with each term in the series, computed as 1/factorial from the CTE factorials: This translation folds some relations for the deductive engine to be able to solve the query. Instead, a user would alternative write a query like this: An alternative solution is to define a CTE with an argument for the index 𝑛 of the 𝑛-th term in the series, the value of the term (𝑡𝑒𝑟𝑚), and the current value of the running summation (𝑣𝑎𝑙). Thus, the base case is 𝑛 = 0, 𝑡𝑒𝑟𝑚 = 1, and 𝑣𝑎𝑙 = 1, and the inductive case computes the next term for presolved cases delivering 𝑛 + 1, 𝑡𝑒𝑟𝑚/(𝑛 + 1) (which equates to divide the 𝑛-th term by 𝑛 + 1), and accumulating in 𝑣𝑎𝑙 the 𝑛 + 1-th approximation. The stop condition should test if the last term is strictly greater than 0, since otherwise this means that the system numeric precision is met. Datalog Formulation: The following equivalent Datalog query includes the aggregate predicates max/3 and min/3, which are syntax simplifications for a group_by predicate (e.g., max(R,X,M) ≡ group_by(R,[],M=max(X))). Functions concat(A,B) (concatenation of A and B and written as A||B in standard SQL), length(A) (length of A), and substr(A,P,N) (substring of N characters of A taken from position P) are used. </p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="4.5.">Base Conversion</head><p>Problem Statement: Given the table conversion(c:string, fb:int, tb:int), with natural numbers to be converted (c) from a base (fb) to another base (tb), write an SQL query returning a row for each element in the table conversion, with schema (number_fb, fb, number_tb, tb), such that number_fb is the number in base fb equivalent to the number number_tb in base tb.</p><p>A Solution: This problem can be subdivided as usually in two subproblems: Convert to base 10, and then to the target base. We can assume a table digits(n INT, d STRING) containing tuples as { (0,'0'), (1,'1'), . . . , (10,'A'), . . . }.</p><p>For converting to base 10, the approach is to recursively generate tuples with the inspected position 𝑖 (index of the digit from right to left starting with 0) with a value corresponding to the number up to its 𝑖-th position. So, we can think of a schema for this first CTE as to_base_10(c, fb, tb, s, i, n), where original parameters in conversion (c, fb and tb) are kept with their same names, s is the number truncated up to the 𝑖 − 1-th index, i is the index 𝑖, and n is the value (base 10) for the number c up to the 𝑖-th position. The original number is required in this schema because there will be in general several numbers to be converted, so that this first column will discriminate the number for which the conversion is made. A similar requirement applies to the original base fb and the target base fb.</p><p>For the sake of keeping neat the formulation, the base case for to_base_10 starts at index −1, and the original number is appended (with the || operator) with a void −1-th position, delivering a value 0 for it. Otherwise, we could start at index 0, but calculations in the recursive case should be also included in the base case. This recursive case builds tuples from to_base_10(c, fb, tb, s, i, n) itself as follows: its first 3 columns are the original ones, as found in to_base_10. The number s (recall: a string) is right trimmed in 1 character; the index i is incremented, and its quantity (weighted with its position: fb^(i+1)) is added to n, where the value of the digit is taken from the digits table.</p><p>Converting a number in base 10 to another base is a somewhat similar problem, but with schema to_base_b(c, fb, tb, n, st): the three original columns (c, fb and tb), the number in base 10 (n) and the most significant digits already processed (st). Here, the base case comes from the results for the relation to_base_10, selecting the value n for the final calculation (the length of the truncated number is 1: the last, most-significant character in the string). In this case, the index is not used because another approach is taken: dividing the current number by the target base and delivering the digit</p></div><figure xmlns="http://www.tei-c.org/ns/1.0" xml:id="fig_0"><head>Datalog 2 .</head><label>2</label><figDesc>0 2024: 5th International Workshop on the Resurgence of Datalog in Academia and Industry, October 11-14, 2024, Dallas, Texas, USA fernan@sip.ucm.es (F. Sáenz-Pérez) 0000-0001-6075-4398 (F. Sáenz-Pérez)</figDesc></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" xml:id="fig_1"><head>Definition 3 . 1 .</head><label>31</label><figDesc>The function SQL_to_DL takes a relation name and an SQL statement as input and returns a Datalog program as defined by cases as follows:% Basic SELECT statement SQL_to_DL (𝑟, SELECT 𝐸𝑥𝑝𝑠 FROM 𝑅𝑒𝑙 WHERE 𝐶𝑜𝑛𝑑) = { 𝑟(𝑋) ← 𝐷𝐿𝑅𝑒𝑙(𝑌 ) ∧ 𝐷𝐿𝐸𝑥𝑝𝑠(𝑋) ∧ 𝐷𝐿𝐶𝑜𝑛𝑑(𝑍) } ⋃︀ 𝑅𝑒𝑙𝑅𝑢𝑙𝑒𝑠 ⋃︀ 𝐸𝑥𝑝𝑅𝑢𝑙𝑒𝑠 ⋃︀ 𝐶𝑜𝑛𝑑𝑅𝑢𝑙𝑒𝑠,where SQLREL_to_DL (𝑅𝑒𝑙) = (𝐷𝐿𝑅𝑒𝑙(𝑌 ), 𝑅𝑒𝑙𝑅𝑢𝑙𝑒𝑠), SQLEXPS_to_DL (𝐸𝑥𝑝𝑠) = (𝐷𝐿𝐸𝑥𝑝𝑠(𝑋), 𝑡𝑟𝑢𝑒, 𝐸𝑥𝑝𝑅𝑢𝑙𝑒𝑠), and SQLCOND_to_DL (𝐶𝑜𝑛𝑑) = (𝐷𝐿𝐶𝑜𝑛𝑑(𝑍), 𝐶𝑜𝑛𝑑𝑅𝑢𝑙𝑒𝑠).</figDesc></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" xml:id="fig_2"><head>Example 2 .</head><label>2</label><figDesc>Consider the SQL query SELECT SQRT(2) FROM dual WHERE TRUE OR TRUE defining a relation 𝑟. The relation dual, as originally defined by Oracle, contains a single row and a single column, and it was included as a predefined relation to allow for calculations such as this example. DES includes this as a propositional relation instead (there is no need for an argument because it is not intended to be used). Translating this query using Definition 3.1-Basic SELECT statement, where 𝑅𝑒𝑙 = dual, 𝐸𝑥𝑝𝑠 = SQRT(2) and 𝐶𝑜𝑛𝑑 = TRUE OR TRUE results in:SQL_to_DL (𝑟, SELECT SQRT(2) FROM dual WHERE TRUE OR TRUE) = { 𝑟(𝑋) ← 𝐷𝐿𝑅𝑒𝑙 ∧ 𝐷𝐿𝐸𝑥𝑝𝑠(𝑋) ∧ 𝐷𝐿𝐶𝑜𝑛𝑑 } ⋃︀ 𝑅𝑒𝑙𝑅𝑢𝑙𝑒𝑠 ⋃︀ 𝐸𝑥𝑝𝑅𝑢𝑙𝑒𝑠 ⋃︀ 𝐶𝑜𝑛𝑑𝑅𝑢𝑙𝑒𝑠 = { 𝑟(𝑋) ← 𝑑𝑢𝑎𝑙 ∧ 𝑋 = 𝑠𝑞𝑟𝑡(2) ∧ 𝛿(𝑑), 𝑑 ← 𝑡𝑟𝑢𝑒, 𝑑 ← 𝑡𝑟𝑢𝑒 } (rules with respective identifiers 𝑟 1 , 𝑟 2 and 𝑟 3 ), because following Definition 3.2-Extensional/Intensional relation name: SQLREL_to_DL (dual) = (𝐷𝐿𝑅𝑒𝑙, 𝑅𝑒𝑙𝑅𝑢𝑙𝑒𝑠) = (𝑑𝑢𝑎𝑙, {}), following Definition 3.3-Expression: SQLEXPS_to_DL (SQRT(2)) = (𝐷𝐿𝐸𝑥𝑝, 𝐷𝐿𝐴𝑔𝑔, 𝐸𝑥𝑝𝑠𝑅𝑢𝑙𝑒𝑠) = ((𝑋 = 𝑠𝑞𝑟𝑡(2)), 𝑡𝑟𝑢𝑒, {}), and following Definition 3.4-Disjunction: SQLCOND_to_DL (TRUE OR TRUE) = (𝐷𝐿𝐶𝑜𝑛𝑑, 𝐶𝑜𝑛𝑑𝑅𝑢𝑙𝑒𝑠) = (𝛿(𝑑), {𝑑 ← 𝑡𝑟𝑢𝑒, 𝑑 ← 𝑡𝑟𝑢𝑒}). Thus, 𝑠𝑜𝑙𝑣𝑒(𝑟(𝑋), ℰ) = {Δ ⊢ 𝑟 1 • 𝛼 : 𝑟(1.4142)} (where 𝛼 is the fresh identifier introduced by Definition 2.2-Duplicates). Without duplicate elimination (goal 𝑑 instead of 𝛿(𝑑) in rule 𝑟 1 ): 𝑠𝑜𝑙𝑣𝑒</figDesc></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" xml:id="fig_3"><head></head><label></label><figDesc>WITH factorials(n, factorial) AS (SELECT 0, 1 UNION ALL SELECT n+1, (n+1)*factorial FROM factorials) WITH taylor(euler) AS (SELECT 1/factorial FROM factorials) SELECT SUM(euler) FROM (SELECT TOP 18 euler FROM taylor); Note a couple of things: First, there are two nested WITH statements (factorials is only known in the context of the subsequent WITH statement. Alternatively, two consecutive CTE's are also possible. Second, the outcome SQL needs a top-𝑁 clause to limit recursion. Up to now, main RDBMS's as PostgreSQL, DB2, SQL Server, and Oracle do not admit nested WITH statements. Datalog Formulation: Next, it is shown the automatically-generated core Datalog 10 query and program corresponding to the SQL statement. The program is asserted before solving the query and retracted afterwards. factorials(0,1) /\ (factorials(B,C) :-factorials(D,E), B=D+1, C=(D+1)*E) =&gt; answer_1_6(A). answer_1_6(A) :-(taylor(B) :-factorials(_C,D), B=1/D) =&gt; answer_1_8(A). answer_1_8(A) :-group_by(answer_1_10(B),[],A=sum(B)). answer_1_10(A) :-top(18,taylor(B)), B=A.</figDesc></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" xml:id="fig_4"><head></head><label></label><figDesc>factorials(0,1) /\ ( factorials(D,E) :-factorials(F,G), D=F+1, E=(F+1)*G ) =&gt; (taylor(B) :-factorials(_C,D), B=1/D) =&gt; group_by(top(18,taylor(B)),[],A=sum(B)).</figDesc></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" xml:id="fig_5"><head></head><label></label><figDesc>plot(x, fx) AS (SELECT $x0$ xi, $f$ UNION SELECT x+$dx$ xi, $f$ FROM plot WHERE x &lt;= $x1$), bars(bar) AS (SELECT ' ' UNION SELECT bar||' ' FROM bars WHERE length(bar)&lt;$d$) SELECT substr((select max(bar) bar from bars), 1, round($d$*(fx-(SELECT min(fx) FROM plot))*(SELECT 1/(max(fx)-min(fx)) FROM plot))) FROM plot;</figDesc></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" xml:id="fig_6"><head>(</head><label></label><figDesc>plot($x0$,F) :-F=sin($x0$) ) /\ ( plot(B,C) :-plot(D,_E), D=&lt;$x1$, B=D+$dx$, C=sin(D+$dx$) ) /\ bars(' ') /\ ( bars(H) :-bars(G), length(G)&lt;$d$, H=concat(G,' ') ) =&gt; plot(_A,_B), max(bars(_K),_K,_H), min(plot(_L,_M),_M,_C), group_by(plot(_N,_O),[],(_F=1/(max(_O)-min(_O)))), A=substr(_H,1,round($d$*(_B-_C)*_F)).</figDesc></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" type="table" xml:id="tab_0"><head></head><label></label><figDesc>Next three definitions specify the functions SQLREL_to_DL , SQLEXPS_to_DL and SQLCOND_to_DL which are used by SQL_to_DL . The function SQLREL_to_DL takes an SQL relation (either a relation name, or a join of relations, or an SQL statement) as input and returns both a Datalog goal and program as defined by cases as follows: % Extensional/Intensional relation name SQLREL_to_DL (𝑅𝑒𝑙𝑁 𝑎𝑚𝑒) = (𝑅𝑒𝑙𝑁 𝑎𝑚𝑒(𝑋), {}) where 𝑋 are the 𝑛 variables corresponding to the 𝑛-ary relation 𝑅𝑒𝑙𝑁 𝑎𝑚𝑒.</figDesc><table><row><cell>Definition 3.2. % Join of relations</cell></row><row><cell>SQLREL_to_DL ((𝑅𝑒𝑙 1 , . . . , 𝑅𝑒𝑙 𝑛</cell></row></table><note>SQL 1 ) ⋃︀ SQL_to_DL (𝑡, SQL 2 ) % WITH statement SQL_to_DL (𝑟, WITH 𝑟 1 AS SQL 1 , ..., 𝑟 𝑛 AS SQL 𝑛 SQL ) = { 𝑟(𝑋) ← ⋀︀ ({SQL_to_DL (𝑟 𝑖 , SQL 𝑖 ) | 1 ≤ 𝑖 ≤ 𝑛}) ⇒ 𝑠(𝑋) } ⋃︀ SQL_to_DL (𝑠, SQL ) where ⋀︀ (𝐵𝑎𝑔) denotes 𝐵 1 ∧ • • • ∧ 𝐵 𝑚 (𝐵 𝑖 ∈ 𝐵𝑎𝑔).</note></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" type="table" xml:id="tab_1"><head></head><label></label><figDesc>Next, the translation of a recursive WITH statement is illustrated. Consider the SQL query in Subsection 1.1 defining natural numbers. Translating this query follows Definition 3.1-WITH statement, where 𝑟 1 = nat, SQL 1 = SELECT 0 UNION ALL SELECT n+1 FROM nat, and SQL = SELECT n FROM nat:</figDesc><table><row><cell></cell><cell>,</cell></row><row><cell>indicating a superfluous condition.</cell><cell>□</cell></row><row><cell>Example 3.</cell><cell></cell></row></table></figure>
			<note xmlns="http://www.tei-c.org/ns/1.0" place="foot" n="8" xml:id="foot_0">This work was supported by the State Research Agency (AEI) of the Spanish Ministry of Science and Innovation under grant PID2019-104735RB-C42 (SAFER).</note>
			<note xmlns="http://www.tei-c.org/ns/1.0" place="foot" n="9" xml:id="foot_1">At the time of posing these puzzles and up to the best of our knowledge, most of these puzzles were novel in SQL (we only found a statement for primes), and solutions to them are reported here for the first time, both in SQL and Datalog.</note>
			<note xmlns="http://www.tei-c.org/ns/1.0" place="foot" n="10" xml:id="foot_2">Core Datalog is the language directly processed by the deductive engine. (User) Datalog is the language that the user can use at the top-level, and that enables high-level formulations for expressions and some metapredicates.</note>
			<note xmlns="http://www.tei-c.org/ns/1.0" place="foot" n="11" xml:id="foot_3">https://www.countryliving.com/life/news/a45720/white-christmas-song-history.</note>
			<note xmlns="http://www.tei-c.org/ns/1.0" place="foot" xml:id="foot_4">--Dimension of the plot (d+1) rows and (d+1) columns: /set d 50 --Start x: /set x0 0.0 --End x: /set x1 4*pi --Delta x: /set dx ($x1$-$x0$)/$d$ --Function: /set f sin(xi) WITH</note>
		</body>
		<back>

			<div type="acknowledgement">
<div xmlns="http://www.tei-c.org/ns/1.0"><head>54-68</head><p>formulations to solve those puzzles because SQL queries are translated into a Hypothetical Datalog program. Both the syntax and the inference system for the Hypothetical Datalog system in <ref type="bibr" target="#b8">[9]</ref> have been extended to support expressions in conditions and other meta-predicates needed for expressing SQL more complex queries. The implementation can be greatly enhanced in several ways; for example, replacing its prototype SQL parser with a more performant one, and supporting the semi-naïve differential optimization <ref type="bibr" target="#b18">[19]</ref>, which hugely improves performance for recursive problems, and fixing some known issues. Additionally, more puzzles will be developed for the enjoyment of students (and the teacher).</p></div>
			</div>


			<div type="availability">
<div xmlns="http://www.tei-c.org/ns/1.0"><p>1 https://wiki.postgresql.org/index.php?title=Cyclic_Tag_System&amp;oldid=15106 2 https://hourofcode.com 3 https://programmingpraxis.com 4 http://codekata.com <ref type="bibr" target="#b4">5</ref> Face the challenge! https://www.aceptaelreto.com <ref type="bibr" target="#b5">6</ref> SQLzoo https://sqlzoo.net, HackerRank https://www.hackerrank.com/domains/sql <ref type="bibr" target="#b6">7</ref> Desktop applications for different OS's and Prolog host systems (https://des.sourceforge.io), and an on-line system DESweb (https://desweb.fdi.ucm.es) which includes the last development version are available.</p></div>
			</div>

			<div type="annex">
<div xmlns="http://www.tei-c.org/ns/1.0"><head>WITH</head><p>re(n,term,val) AS (SELECT 0, 1.0, 1.0 UNION SELECT n+1, term/(n+1), val+term/(n+1) FROM re WHERE term/(n+1) &gt; 0) SELECT MAX(val) AS euler FROM re; Datalog Formulation: re(0,1,1) /\ ( re(B,C,D) :-re(E,F,G), H=F/(E+1), H&gt;0, B=E+1, C=F/(E+1), D=G+F/(E+1) ) =&gt; group_by(re(_B,_C,D), [], A=max(D)).</p><p>By submitting this user Datalog query at the top-level, the system compiles it to an almost equal core Datalog query and program as shown above for the SQL case. Such compilations can be inspected with the command /show_compilations on. Outcome: The query returns in the SICStus implementation:</p><p>answer(euler:float) -&gt; { answer(2.7182818284590455) }</p><p>Obviously, the precision of the approximation to the Euler number depends on the underlying system arithmetics. Here, the last digit should read 2 instead of 5. This outcome is available by submitting the command display_answer on.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="4.2.">All Time Greatest Hits</head><p>Problem Statement: We are given the table hits(theme string, copies int), 11 holding song titles and number of sold copies for each title. Write a recursive SQL query to assign the rank of each song in terms of its sold copies (number 1 is for the most sold song, number 2 for the next and so on). If there are two or more songs with the same number of copies, they will receive the same rank number. A Solution: An idea to solve this puzzle is to build pairs with an integer representing the rank and the number of copies for hits such that there no other hits with a higher number of copies. Then, return the maximum rank for each group of hits with the same number of copies, adding to the output the song titles (known from the table hits and their number of copies).</p><p>The base case in the recursive part is rank 1 for all hits. The inductive case rec is the next rank in rec such that the copies in hits is strictly less than the copies in rec, i.e., once all copies receive a rank 1, the rank 2 is received to all copies but the one with the maximum number of copies, and so on. Its SQL formulation is as follows:</p><p>WITH rec(ranking, copies) AS (SELECT 1, copies FROM hits UNION SELECT ranking+1, hits.copies FROM hits, rec WHERE hits.copies &lt; rec.copies) SELECT ranking, theme, hits.copies FROM hits, (SELECT MAX(ranking) AS ranking, copies FROM rec GROUP BY copies) m WHERE m.copies = hits.copies; Datalog Formulation: Observe that a Datalog equivalent query is neater than its SQL counterpart: </p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>Outcome:</head><p>answer(h1.theme:varchar(50),h1.copies:int,pos:int) -&gt; { answer <ref type="bibr">(</ref> </p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="4.3.">Prime Numbers</head><p>Problem Statement: Compute the first 𝑛 prime numbers, where 𝑛 is a natural bound. A Solution: The sieve of Eratosthenes can be expressed in SQL by generating numbers and getting rid of those which can be divided by a lesser number. So, a natural number generator can be defined as a CTE, and then the factors for each number as another CTE. For a number to be a factor of another number it suffices to check that the division remainder is 0. The CTE factor below delivers pairs of 𝑥,𝑓 , where 𝑥 is a number and 𝑓 is one of its factors. The outcome selects each 𝑛 for which there is only one factor.</p><p>/set bound 100 WITH number(n) AS (SELECT 0 UNION SELECT n+1 FROM number WHERE n &lt; $bound$), factor(x, f) AS (SELECT x.n, f.n FROM number x, number f WHERE x.n &gt; f.n AND f.n &gt; 0 AND x.n mod f.n = 0) SELECT x FROM (SELECT x, COUNT(*) c FROM factor GROUP BY x) WHERE c=1;</p><p>Note that DES includes user variables which can be used as parameters, such as bound in this example, which are set with the command /set Variable Value. Datalog Formulation: Again, the translation seems to be more compact than the source SQL statement. </p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>Outcome:</head><p>answer(factor.x:int) -&gt; { answer <ref type="bibr" target="#b1">(2)</ref>, answer(3), answer <ref type="bibr" target="#b4">(5)</ref>, answer(7), ..., answer(97) } Info: 25 tuples computed.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="4.4.">Graph of an Explicit Function</head><p>Problem Statement: Plot the sine function as depicted in the figure below. A Solution: Here we define two CTE's: One working on the real plane (plot) which relates 𝑥 and 𝑦 coordinates via a function (parametrically specified with the user variable f), with square dimensions. The second CTE works on the "pixel" plane (bars) by building a string of spaces with as many spaces as pixels in the ordinates (horizontally represented instead of vertically), which will be truncated to the required length with respect to the value of the function at each 𝑥 coordinate. Observe that strings in the display are quoted and ended with the characters "'),", so that it visually resembles the plot.</p><p>Both plot and bars are built in a similar way natural numbers are defined: a base case with the first point in the plane, and with a single space, respectively. The recursive case of plot adds pairs (x+dx, fx) for 𝑥 coordinates up to its bound, whilst for bars, a space is added up to reaching its top length.</p><p>Once both relations are defined, the outcome query truncates (with the function substr: substring) the longest bar up to the value of the corresponding 𝑦 coordinate for each 𝑥 coordinate found in plot.</p><p>corresponding to the remainder of the division as the next digit, from the less to the most significant digits. Then, the recursive case builds the outcome by appending the calculated digit to the left of the former outcome.  </p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="4.6.">Universal Turing Machine</head><p>Problem Statement: Implement a universal Turing machine as a state transition system, following https://aturingmachine.com/. Possible transitions are specified in the input table transitions(state, symbol, newstate, newsymbol, move), and the initial state is given in initial_state(state, tape, pos). Here, state is a numeric value identifying the state, tape is a string containing a sequence of symbols 0's and 1's, pos is the position of the scanned symbol (the leftmost character of the tape is always the position 1 even when the tape can can grow indefinitely to the right or to the left), move can be either be 'L' (to the left) or 'R' (to the right). Input Data: The two input tables are filled as shown next to implement a binary counting machine. It counts from 0 upwards without stopping. Inspecting its outcome can be done by adding a stop condition on the number of the transitions (steps). A Solution: Implementing a universal Turing machine can be done with a recursive query where the base case contains the initial state, and the recursive case selects the next state in terms of the symbol in the current tape position. This must consider that the tape can grow both the left and to the right. For the last case, the string tape can be concatenated with a new symbol and the index at the first position does not change. For the former case, a new blank symbol is prepended and the index 1 is for this position. </p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>Datalog Formulation:</head><p>(m(E,F,G,1) :-initial_state(E,F,G)) /\ (m(H,I,J,K) :transitions(L,M,H,N,O), m(L,P,Q,R), '$substr'(P,Q,1,M), R&lt;40, S=Q-1, '$substr'(P,1,S,T), '$concat'(T,N,U), V=Q+1, '$substr'(P,V,W), '$concat'(U,W,X), '$concat'(' ',N,Y), Z=Q+1, '$substr'(P,Z,AA), '$concat'(Y,AA,AB), AC=Q-1, '$substr'(P,1,AC,AD), '$concat'(AD,N,AE), '$concat'(AE,' ',AF), AG=Q-1, '$substr'(P,1,AG,AH), '$concat'(AH,N,AI), AJ=Q+1, '$substr'(P,AJ,AK), '$concat'(AI,AK,AL), '$case'([((O='L',Q&gt;1),Q-1),((O='L',Q=1),1),(O='R',Q+1)],null,J), K=R+1, '$case'([((O='L',Q&gt;1),X),((O='L',Q=1),AB),((O='R','$length'(P,AM),AM=Q),AF), ((O='R','$length'(P,AN),AN&gt;Q),AL)],null,I)) =&gt; m(B,D,C,A).</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="5.">Conclusions and Future Work</head><p>SQL puzzles for challenging students' skills have been presented and solved in the DES system, which has been selected because it helps students with syntax and semantic warnings about SQL queries. Since the system is based on intuitionistic logic programming, it allows for neater and simpler SQL</p></div>			</div>
			<div type="references">

				<listBibl>

<biblStruct xml:id="b0">
	<analytic>
		<title level="a" type="main">Universality in elementary cellular automata</title>
		<author>
			<persName><forename type="first">M</forename><surname>Cook</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="j">Complex Systems</title>
		<imprint>
			<biblScope unit="volume">15</biblScope>
			<date type="published" when="2004">2004</date>
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b1">
	<analytic>
		<title level="a" type="main">Using puzzles in teaching algorithms</title>
		<author>
			<persName><forename type="first">A</forename><surname>Levitin</surname></persName>
		</author>
		<author>
			<persName><forename type="first">M.-A</forename><surname>Papalaskari</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="j">SIGCSE Bull</title>
		<imprint>
			<biblScope unit="volume">34</biblScope>
			<biblScope unit="page" from="292" to="296" />
			<date type="published" when="2002">2002</date>
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b2">
	<monogr>
		<title level="m" type="main">Joe Celko&apos;s SQL Puzzles and Answers, Second Edition (The Morgan Kaufmann Series in Data Management Systems</title>
		<author>
			<persName><forename type="first">J</forename><surname>Celko</surname></persName>
		</author>
		<imprint>
			<date type="published" when="2006">2006</date>
			<publisher>Morgan Kaufmann Publishers Inc</publisher>
			<pubPlace>San Francisco, CA, USA</pubPlace>
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b3">
	<monogr>
		<author>
			<persName><forename type="first">S</forename><surname>Wikipedia</surname></persName>
		</author>
		<ptr target="https://books.google.es/books?id=4X_hngEACAAJ" />
		<title level="m">Esoteric Programming Languages: Brainfuck, Intercal, Befunge, Esoteric Programming Language, Kvikkalkul, One Instruction Set Computer</title>
				<meeting><address><addrLine>Unlambda, Malbo</addrLine></address></meeting>
		<imprint>
			<publisher>University-Press Org</publisher>
			<date type="published" when="2013">2013</date>
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b4">
	<analytic>
		<title level="a" type="main">DES: A Deductive Database System</title>
		<author>
			<persName><forename type="first">F</forename><surname>Sáenz-Pérez</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="j">Electronic Notes on Theoretical Computer Science</title>
		<imprint>
			<biblScope unit="volume">271</biblScope>
			<biblScope unit="page" from="63" to="78" />
			<date type="published" when="2011">2011</date>
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b5">
	<analytic>
		<title level="a" type="main">Applying constraint logic programming to sql semantic analysis</title>
		<author>
			<persName><forename type="first">F</forename><surname>Sáenz-Pérez</surname></persName>
		</author>
		<idno type="DOI">10.1017/S1471068419000206</idno>
	</analytic>
	<monogr>
		<title level="j">Theory and Practice of Logic Programming</title>
		<imprint>
			<biblScope unit="volume">19</biblScope>
			<biblScope unit="page" from="808" to="825" />
			<date type="published" when="2019">2019</date>
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b6">
	<analytic>
		<title level="a" type="main">Declarative Debugging of Wrong and Missing Answers for SQL Views</title>
		<author>
			<persName><forename type="first">R</forename><surname>Caballero</surname></persName>
		</author>
		<author>
			<persName><forename type="first">Y</forename><surname>García-Ruiz</surname></persName>
		</author>
		<author>
			<persName><forename type="first">F</forename><surname>Sáenz-Pérez</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="m">Eleventh International Symposium on Functional and Logic Programming (FLOPS 2012)</title>
				<imprint>
			<publisher>Springer</publisher>
			<date type="published" when="2012">2012</date>
			<biblScope unit="volume">7294</biblScope>
			<biblScope unit="page" from="73" to="87" />
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b7">
	<analytic>
		<title level="a" type="main">Hypothetical Datalog: Complexity and Expressibility</title>
		<author>
			<persName><forename type="first">A</forename><forename type="middle">J</forename><surname>Bonner</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="j">Theoretical Computer Science</title>
		<imprint>
			<biblScope unit="volume">76</biblScope>
			<biblScope unit="page" from="3" to="51" />
			<date type="published" when="1990">1990</date>
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b8">
	<analytic>
		<title level="a" type="main">Intuitionistic Logic Programming for SQL</title>
		<author>
			<persName><forename type="first">F</forename><surname>Sáenz-Pérez</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="m">Logic-Based Program Synthesis and Transformation</title>
				<editor>
			<persName><forename type="first">M</forename><forename type="middle">V</forename><surname>Hermenegildo</surname></persName>
		</editor>
		<editor>
			<persName><forename type="first">P</forename><surname>Lopez-Garcia</surname></persName>
		</editor>
		<meeting><address><addrLine>Cham</addrLine></address></meeting>
		<imprint>
			<publisher>Springer International Publishing</publisher>
			<date type="published" when="2017">2017</date>
			<biblScope unit="page" from="293" to="308" />
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b9">
	<analytic>
		<title level="a" type="main">The Deductive Database System LDL++</title>
		<author>
			<persName><forename type="first">F</forename><surname>Arni</surname></persName>
		</author>
		<author>
			<persName><forename type="first">K</forename><surname>Ong</surname></persName>
		</author>
		<author>
			<persName><forename type="first">S</forename><surname>Tsur</surname></persName>
		</author>
		<author>
			<persName><forename type="first">H</forename><surname>Wang</surname></persName>
		</author>
		<author>
			<persName><forename type="first">C</forename><surname>Zaniolo</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="j">TPLP</title>
		<imprint>
			<biblScope unit="volume">3</biblScope>
			<biblScope unit="page" from="61" to="94" />
			<date type="published" when="2003">2003</date>
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b10">
	<analytic>
		<title level="a" type="main">Tabling with support for relational features in a deductive database</title>
		<author>
			<persName><forename type="first">F</forename><surname>Sáenz-Pérez</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="j">ECEASST</title>
		<imprint>
			<biblScope unit="volume">55</biblScope>
			<date type="published" when="2012">2012</date>
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b11">
	<analytic>
		<title level="a" type="main">Adding Negation-as-Failure to Intuitionistic Logic Programming</title>
		<author>
			<persName><forename type="first">A</forename><forename type="middle">J</forename><surname>Bonner</surname></persName>
		</author>
		<author>
			<persName><forename type="first">L</forename><forename type="middle">T</forename><surname>Mccarty</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="m">Proceedings of the North American Conference on Logic Programming (NACLP)</title>
				<editor>
			<persName><forename type="first">E</forename><forename type="middle">L</forename><surname>Lusk</surname></persName>
		</editor>
		<editor>
			<persName><forename type="first">R</forename><forename type="middle">A</forename><surname>Overbeek</surname></persName>
		</editor>
		<meeting>the North American Conference on Logic Programming (NACLP)</meeting>
		<imprint>
			<publisher>The MIT Press</publisher>
			<date type="published" when="1990">1990</date>
			<biblScope unit="page" from="681" to="703" />
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b12">
	<analytic>
		<title level="a" type="main">Restricted predicates for hypothetical datalog</title>
		<author>
			<persName><forename type="first">F</forename><surname>Sáenz-Pérez</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="j">Electronic Proceedings in Theoretical Computer Science</title>
		<imprint>
			<biblScope unit="volume">200</biblScope>
			<biblScope unit="page" from="64" to="79" />
			<date type="published" when="2015">2015</date>
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b13">
	<analytic>
		<title level="a" type="main">Implementing tabled hypothetical datalog</title>
		<author>
			<persName><forename type="first">F</forename><surname>Sáenz-Pérez</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="m">Proceedings of the 25th IEEE International Conference on Tools with Artificial Intelligence, ICTAI&apos;13</title>
				<meeting>the 25th IEEE International Conference on Tools with Artificial Intelligence, ICTAI&apos;13</meeting>
		<imprint>
			<date type="published" when="2013">2013</date>
			<biblScope unit="page" from="596" to="601" />
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b14">
	<monogr>
		<author>
			<persName><forename type="first">J</forename><forename type="middle">D</forename><surname>Ullman</surname></persName>
		</author>
		<title level="m">Principles of Database and Knowledge-Base Systems</title>
				<imprint>
			<publisher>Computer Science Press</publisher>
			<date type="published" when="1988">1988</date>
			<biblScope unit="volume">II</biblScope>
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b15">
	<monogr>
		<idno>SQL:2016 ISO/IEC 9075-1:2016</idno>
		<title level="m">Standard</title>
				<imprint>
			<date type="published" when="2016">2016</date>
		</imprint>
	</monogr>
	<note>ISO/IEC</note>
</biblStruct>

<biblStruct xml:id="b16">
	<analytic>
		<title level="a" type="main">The Art of Prolog</title>
		<author>
			<persName><forename type="first">L</forename><surname>Sterling</surname></persName>
		</author>
		<author>
			<persName><forename type="first">E</forename><surname>Shapiro</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="m">Advanced Programming Techniques</title>
				<meeting><address><addrLine>Cambridge, MA, USA</addrLine></address></meeting>
		<imprint>
			<publisher>MIT Press</publisher>
			<date type="published" when="1994">1994</date>
		</imprint>
	</monogr>
	<note>2Nd Ed</note>
</biblStruct>

<biblStruct xml:id="b17">
	<analytic>
		<title level="a" type="main">HR-SQL: An SQL Database System with Extended Recursion and Hypothetical Reasoning</title>
		<author>
			<persName><forename type="first">S</forename><surname>Nieva</surname></persName>
		</author>
		<author>
			<persName><forename type="first">F</forename><surname>Sáenz-Pérez</surname></persName>
		</author>
		<author>
			<persName><forename type="first">J</forename><surname>Sánchez</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="m">XV Jornadas sobre Programación y Lenguajes, PROLE2015</title>
				<imprint>
			<publisher>SISTEDES</publisher>
			<date type="published" when="2015">2015</date>
			<biblScope unit="page" from="1" to="15" />
		</imprint>
	</monogr>
	<note>Ongoing Work</note>
</biblStruct>

<biblStruct xml:id="b18">
	<analytic>
		<title level="a" type="main">A generalization of the differential approach to recursive query evaluation</title>
		<author>
			<persName><forename type="first">I</forename><surname>Balbin</surname></persName>
		</author>
		<author>
			<persName><forename type="first">K</forename><surname>Ramamohanarao</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="j">The Journal of Logic Programming</title>
		<imprint>
			<biblScope unit="volume">4</biblScope>
			<biblScope unit="page" from="259" to="262" />
			<date type="published" when="1987">1987</date>
		</imprint>
	</monogr>
</biblStruct>

				</listBibl>
			</div>
		</back>
	</text>
</TEI>
