@@ -0,0 +1,431 @@
1+# TutorialD Tutorial for Project:M36
2+
3+TutorialD is an logic language designed by Chris Date for interacting with any relational algebra engine. Project:M36 supports this language for the purposes of learning about the relational algebra. TutorialD is not recommended for use in production systems.
4+
5+It is presumed that the audience for this tutorial has at least some minimal background with an SQL-based DBMS.
6+
7+### Starting the TutorialD Interpreter
8+
9+From the project-m36 source directory, execute ```cabal run tutd``` to start the interactive TutorialD interpreter. You will be greeted by the interactive prompt:
10+
11+```
12+TutorialD (master):
13+```
14+
15+"master" refers to the name of the branch to which the current transaction will be potentially committing.
16+
17+### Types
18+
19+TutorialD is strongly-typed. The basic built-in types are:
20+
21+|Type Name|Explanation|Example|
22+|-|-|-|
23+|char|arbitrary text|"The Old Man and the Sea"|
24+|int|any integer|-4|
25+|datetime|timestamp UTC|"2015-02-02 04:05:02"::datetime|
26+|double|floating point number|3.1459|
27+|bool|boolean value|t|
28+
29+With regards to boolean values, be sure not to conflate ```t``` or ```f``` as a boolean value with ```true``` and ```false``` which are relation variables.
30+
31+### Using Relation Variables
32+
33+Relation Variables are named cells which reference relations within a transaction state. The relation can be replaced with another relation through assignment.
34+
35+Definition of a relation variable:
36+```
37+products :: {name char, age int}
38+```
39+This expression creates a new relation variable in the current context which can refer to any relation with the header of "name" of type "char" and "age" of type int.
40+
41+Assignment to a relation variable:
42+```
43+products := relation{tuple{name "Mike",age 6},tuple{name "Sam",age 10}}
44+```
45+This expression assigns a relation containing two tuples to the previously-defined "products" relation.
46+
47+```tutd``` includes two relations by default:
48+* ```true```: the relation with no attributes and a body of one empty-attributed tuple
49+* ```false```: the relation with no attributes and a body of no tuples
50+
51+Chris Date refers to these relations as "TABLE_DUM" and "TABLE_DEE" but such arbitrary names are not so recognizable. ```true``` and ```false``` can be easily remembered as the answer to the question: "Does this relation have any tuples?" which can be formulated in TutorialD as the projection of a relation asking for no attributes:
52+```
53+products{}
54+```
55+
56+### Date's Sample Relations
57+
58+The examples in this tutorial can be executed after loading Chris Date's sample relations using:
59+
60+```
61+:importtutd "scripts/DateExamples.tutd"
62+```
63+
64+Each section assumes a fresh instance of the Date examples. The relation variables created in the script are:
65+
66+|Relation Variable Name|Description|
67+|-|-|
68+|S|suppliers|
69+|P|parts|
70+|SP|contains mapping of which suppliers supply which parts|
71+
72+### Relational Expressions
73+
74+A relational expression combines relational operators to create a new relation. ```tutd``` can display the result of executing a relational expression with ":showexpr".
75+
76+```
77+TutorialD (master): :showexpr P
78+┌──────┬─────┬──┬─────┬──────┐
79+│CITY │COLOR│P#│PNAME│WEIGHT│
80+├──────┼─────┼──┼─────┼──────┤
81+│London│Red │P6│Cog │19 │
82+│Paris │Blue │P5│Cam │12 │
83+│London│Red │P1│Nut │12 │
84+│London│Red │P4│Screw│14 │
85+│Oslo │Blue │P3│Screw│17 │
86+│Paris │Green│P2│Bolt │17 │
87+└──────┴─────┴──┴─────┴──────┘
88+```
89+
90+### Using Relational Operators
91+
92+Relational operators generate new relations from existing relations. The operators form the closed algebra against relations.
93+
94+#### Rename
95+
96+The unary rename operator outputs a new relation with chosen attributes renamed. In SQL, the equivalent is to use "AS" in the column name list of SELECTS.
97+
98+```
99+TutorialD (master): :showexpr S rename {CITY as TOWN}
100+┌──┬─────┬──────┬──────┐
101+│S#│SNAME│STATUS│TOWN │
102+├──┼─────┼──────┼──────┤
103+│S3│Blake│30 │Paris │
104+│S4│Clark│20 │London│
105+│S5│Adams│30 │Athens│
106+│S1│Smith│20 │London│
107+│S2│Jones│10 │Paris │
108+└──┴─────┴──────┴──────┘
109+```
110+
111+#### Projection
112+
113+Projection is applied by adding curly braces and attribute names following a relational expression. Projection in SQL is applied by adding a list of column names to a SELECT statement.
114+
115+For example:
116+
117+```
118+TutorialD (master): :showexpr P{COLOR,CITY}
119+┌──────┬─────┐
120+│CITY │COLOR│
121+├──────┼─────┤
122+│London│Red │
123+│Paris │Blue │
124+│Oslo │Blue │
125+│Paris │Green│
126+└──────┴─────┘
127+```
128+
129+#### Restriction
130+
131+Restriction is applied using a "where" clause, much like in SQL.
132+
133+```
134+TutorialD (master): :showexpr P where COLOR="Blue" and CITY="Paris"
135+┌─────┬─────┬──┬─────┬──────┐
136+│CITY │COLOR│P#│PNAME│WEIGHT│
137+├─────┼─────┼──┼─────┼──────┤
138+│Paris│Blue │P5│Cam │12 │
139+└─────┴─────┴──┴─────┴──────┘
140+```
141+
142+The restriction predicate can be built from "and", "not", and "or". Boolean atom functions can also appear in a restriction as long as they are preceded by "^". For example:
143+
144+```
145+TutorialD (master): :showexpr S where ^lt(@STATUS,20)
146+┌─────┬──┬─────┬──────┐
147+│CITY │S#│SNAME│STATUS│
148+├─────┼──┼─────┼──────┤
149+│Paris│S2│Jones│10 │
150+└─────┴──┴─────┴──────┘
151+```
152+
153+#### Join
154+
155+Joins are binary operators and are applied with the "join" keyword. The equivalent in SQL would be a "NATURAL JOIN". To join attributes which are not identically-named, use the rename operator
156+
157+```
158+TutorialD (master): :showexpr S join SP
159+┌──────┬──┬───┬──┬─────┬──────┐
160+│CITY │P#│QTY│S#│SNAME│STATUS│
161+├──────┼──┼───┼──┼─────┼──────┤
162+│London│P6│100│S1│Smith│20 │
163+│London│P3│400│S1│Smith│20 │
164+│London│P5│400│S4│Clark│20 │
165+│London│P1│300│S1│Smith│20 │
166+│Paris │P2│200│S3│Blake│30 │
167+│Paris │P1│300│S2│Jones│10 │
168+│London│P5│100│S1│Smith│20 │
169+│London│P4│300│S4│Clark│20 │
170+│Paris │P2│400│S2│Jones│10 │
171+│London│P2│200│S1│Smith│20 │
172+│London│P4│200│S1│Smith│20 │
173+└──────┴──┴───┴──┴─────┴──────┘
174+```
175+
176+#### Union
177+
178+The binary union operator merges tuples from both relations if-and-only-if the attributes of both relations are identical. The SQL equivalent is the "UNION" operator. Unlike SQL, however, duplicate tuples are not tolerated, so there is no "UNION ALL" equivalent in the relational algebra.
179+
180+```
181+TutorialD (master): :showexpr S union S
182+┌──────┬──┬─────┬──────┐
183+│CITY │S#│SNAME│STATUS│
184+├──────┼──┼─────┼──────┤
185+│Paris │S3│Blake│30 │
186+│London│S4│Clark│20 │
187+│Athens│S5│Adams│30 │
188+│London│S1│Smith│20 │
189+│Paris │S2│Jones│10 │
190+└──────┴──┴─────┴──────┘
191+```
192+
193+The union of any relation with itself is itself.
194+
195+#### Extend
196+
197+The extend unary operator adds an attribute to a relation's header and body and is represented by a colon ":". The equivalent in SQL is a subselect in a SELECT column list. Typically, extend is used to add information derived from relation.
198+
199+```
200+TutorialD (master): :showexpr S:{STATUS2:=add(10,@STATUS)}
201+┌──────┬──┬─────┬──────┬───────┐
202+│CITY │S#│SNAME│STATUS│STATUS2│
203+├──────┼──┼─────┼──────┼───────┤
204+│Paris │S2│Jones│10 │20 │
205+│Athens│S5│Adams│30 │40 │
206+│Paris │S3│Blake│30 │40 │
207+│London│S1│Smith│20 │30 │
208+│London│S4│Clark│20 │30 │
209+└──────┴──┴─────┴──────┴───────┘
210+```
211+
212+The "@" is required in the above query in order to distinguish the attribute's name from a relation's name.
213+
214+Supported atom functions include:
215+
216+|Function|Purpose|
217+|-|-|
218+|add(int,int)|Return the sum of two integers.|
219+|not(bool)|Invert a boolean expression.|
220+|lt(int,int)|Returns boolean true atom if he first argument is less than the second argument.|
221+|lte(int,int)|Returns boolean true atom if he first argument is less than or equal to the second argument.|
222+|gt(int,int)|Returns boolean true atom if he first argument is greater than the second argument.|
223+|gte(int,int)|Returns boolean true atom if he first argument is greater than or equal to the second argument.|
224+
225+#### Group
226+
227+The unary group operator groups the argument attributes into subrelations for each ungrouped set of attributes. SQL does not support tables as values, though SQL does support a notion of grouping by equal values. However, SQL's "GROUP BY" relies on tuple ordering in a table. A relations' tuples are never ordered.
228+
229+Grouping is useful for aggregate operations (see below) or for summarizing data against a set of attributes; for example, "display all employees grouped by boss name".
230+
231+```
232+TutorialD (master): :showexpr S group ({SNAME,STATUS,S#} as subrel)
233+┌──────┬─────────────────┐
234+│CITY │subrel │
235+├──────┼─────────────────┤
236+│Athens│┌──┬─────┬──────┐│
237+│ ││S#│SNAME│STATUS││
238+│ │├──┼─────┼──────┤│
239+│ ││S5│Adams│30 ││
240+│ │└──┴─────┴──────┘│
241+│London│┌──┬─────┬──────┐│
242+│ ││S#│SNAME│STATUS││
243+│ │├──┼─────┼──────┤│
244+│ ││S1│Smith│20 ││
245+│ ││S4│Clark│20 ││
246+│ │└──┴─────┴──────┘│
247+│Paris │┌──┬─────┬──────┐│
248+│ ││S#│SNAME│STATUS││
249+│ │├──┼─────┼──────┤│
250+│ ││S3│Blake│30 ││
251+│ ││S2│Jones│10 ││
252+│ │└──┴─────┴──────┘│
253+└──────┴─────────────────┘
254+```
255+
256+#### Ungroup
257+
258+The unary ungroup operator "unwraps" subrelations in a relation-valued attribute. There is no equivalent in SQL.
259+
260+```
261+TutorialD (master): :showexpr (S group ({SNAME,STATUS,S#} as subrel)) ungroup subrel
262+┌──────┬──┬─────┬──────┐
263+│CITY │S#│SNAME│STATUS│
264+├──────┼──┼─────┼──────┤
265+│Paris │S3│Blake│30 │
266+│London│S4│Clark│20 │
267+│Athens│S5│Adams│30 │
268+│London│S1│Smith│20 │
269+│Paris │S2│Jones│10 │
270+└──────┴──┴─────┴──────┘
271+```
272+
273+## State Operators
274+
275+While relational operators compose to relational expressions representing queries of the database, state operators change the state of the database.
276+
277+### Relation Variable State Changes
278+
279+#### Define and Assign
280+
281+The relation assignment mentioned above certainly changes the state of the database.
282+
283+```
284+TutorialD (master): newrel:=relation{tuple{age 3}}
285+TutorialD (master): :showexpr newrel
286+┌───┐
287+│age│
288+├───┤
289+│3 │
290+└───┘
291+```
292+
293+All further operators are convenience operators and could be implemented with simple assignment. SQL has no equivalent to relational assignment; instead, one must issue "CREATE TABLE" commands and insert rows into the resultant tables.
294+
295+#### Undefine
296+
297+To signal that a relation variable should be forgotten, undefine it.
298+
299+```
300+TutorialD (master): undefine S
301+TutorialD (master): :showexpr S
302+ERR: RelVarNotDefinedError "S"
303+```
304+
305+#### Insert
306+
307+The insert operators accepts a relation variable and a relation of the same type (a relation having an identical header), and replaces the relation referenced by the relation variable with the union of the previous relation value and the argument's relation value.
308+
309+```
310+TutorialD (master): insert S relation{tuple{CITY "Boston",S# "S10",SNAME "Gonzalez",STATUS 10}}
311+TutorialD (master): :showexpr S
312+┌──────┬───┬────────┬──────┐
313+│CITY │S# │SNAME │STATUS│
314+├──────┼───┼────────┼──────┤
315+│Paris │S3 │Blake │30 │
316+│London│S4 │Clark │20 │
317+│Athens│S5 │Adams │30 │
318+│London│S1 │Smith │20 │
319+│Paris │S2 │Jones │10 │
320+│Boston│S10│Gonzalez│10 │
321+└──────┴───┴────────┴──────┘
322+```
323+
324+This insertion operation is equivalent to:
325+
326+```
327+S:=S union relation{tuple{CITY "Boston",S# "S10",SNAME "Gonzalez",STATUS 10}}
328+```
329+#### Update
330+
331+The update operator accepts a relation argument and a predicate, optionally filters and creates new tuples based on the original relation.
332+
333+```
334+TutorialD (master): update S where STATUS=20 (SNAME:="Mr. Twenty")
335+TutorialD (master): :showexpr S
336+┌──────┬──┬──────────┬──────┐
337+│CITY │S#│SNAME │STATUS│
338+├──────┼──┼──────────┼──────┤
339+│Paris │S3│Blake │30 │
340+│London│S1│Mr. Twenty│20 │
341+│Athens│S5│Adams │30 │
342+│Paris │S2│Jones │10 │
343+│London│S4│Mr. Twenty│20 │
344+└──────┴──┴──────────┴──────┘
345+```
346+
347+This is logically equivalent to:
348+
349+```
350+TutorialD (master): S:=(((S where STATUS=20){CITY,S#,STATUS}):{SNAME:="Mr. Twenty"}) union (S where not STATUS=20)
351+TutorialD (master): :showexpr S
352+┌──────┬──┬──────────┬──────┐
353+│CITY │S#│SNAME │STATUS│
354+├──────┼──┼──────────┼──────┤
355+│Paris │S3│Blake │30 │
356+│London│S1│Mr. Twenty│20 │
357+│Athens│S5│Adams │30 │
358+│Paris │S2│Jones │10 │
359+│London│S4│Mr. Twenty│20 │
360+└──────┴──┴──────────┴──────┘
361+```
362+
363+This query means: "Drop the SNAME attribute from S filtered where STATUS equals 20, extend the resultant relation by SNAME with value 'Mr. Twenty', then union the resultant relation with S filtered by STATUS not equaling 20, and assign that to S."
364+
365+#### Delete
366+
367+The delete operator accepts a relation argument and a filtering predicate, creates a new relation with only the tuples which do not match the predicate, and stores the result in the relation variable argument.
368+
369+```
370+TutorialD (master): delete SP where S#="S4"
371+TutorialD (master): :showexpr SP
372+┌──┬───┬──┐
373+│P#│QTY│S#│
374+├──┼───┼──┤
375+│P3│400│S1│
376+│P4│200│S1│
377+│P2│400│S2│
378+│P2│200│S1│
379+│P6│100│S1│
380+│P1│300│S1│
381+│P2│200│S3│
382+│P1│300│S2│
383+│P5│100│S1│
384+└──┴───┴──┘
385+```
386+
387+This is logically equivalent to:
388+
389+```
390+TutorialD (master): SP:=SP where not S#="S4"
391+```
392+
393+Note the inverted predicate.
394+
395+## Constraints
396+
397+Database constraints are user-specified relational algebra predicates which must be true at all times. If a database expression attempts to violate a database constraint, then the DBMS must reject the expression and ensure that the previous, non-violating state remains.
398+
399+Chris Date identified that all constraints can be represented as inclusion dependencies, but Project:M36 offers some convenience operators.
400+
401+#### Uniqueness Constraints
402+
403+Uniqueness constraints ensure that a set of attributes' values are unique throughout a relational expression. For example, it is useful to ensure that all products' identifiers are unique. The equivalent in SQL is the UNIQUE expression found in table creation.
404+
405+```
406+TutorialD (master): key S_key_constraint {S#} S
407+```
408+
409+This expression creates a constraint named "S_key_constraint" and ensure that the values of the "S#" attribute are unique in the "S" relational expression.
410+
411+#### Foreign Key Constraints
412+
413+Foreign keys are constraints which require that certain values appearing in one relation variable must appear in another. The equivalent in SQL is the FOREIGN KEY() construction in table creation.
414+
415+```
416+TutorialD (master): foreign key S#_in_SP SP{S#} in S{S#}
417+```
418+
419+This expression ensure that any SP{S#} must also appear as a value in S{S#}.
420+
421+#### Other Constraints
422+
423+All other constraints can be represented by a set of inclusion dependencies.
424+
425+```
426+TutorialD (master): constraint S_status_less_than_50 (S where ^lt(50,@STATUS)){} in false
427+```
428+
429+This expression ensures that the relation variable's relation can never include a tuple with STATUS greater than 50.
430+
431+## Aggregate Queries