@@ -9,7 +9,7 @@ It is presumed that the audience for this tutorial has at least some minimal bac
99From the project-m36 source directory, execute ```cabal run tutd``` to start the interactive TutorialD interpreter. You will be greeted by the interactive prompt:
1010
1111```
12−TutorialD (master):
12+TutorialD (master/main):
1313```
1414
1515"master" refers to the name of the branch to which the current transaction will be potentially committing.
@@ -32,7 +32,7 @@ With regards to boolean values, be sure not to conflate ```t``` or ```f``` as a
3232Project:M36 will complain loudly if the expected types do not match. Automatic type coercion does not exist.
3333
3434```
35−TutorialD (master): :showexpr S:{more:=add(10,@sname)}
35+TutorialD (master/main): :showexpr S:{more:=add(10,@sname)}
3636ERR: AtomFunctionTypeError "add" 2 IntAtomType StringAtomType
3737```
3838
@@ -84,7 +84,7 @@ Each section assumes a fresh instance of the Date examples. The relation variabl
8484A relational expression combines relational operators to create a new relation. ```tutd``` can display the result of executing a relational expression with ":showexpr".
8585
8686```
87−TutorialD (master): :showexpr p
87+TutorialD (master/main): :showexpr p
8888┌──────┬─────┬──┬─────┬──────┐
8989│city │color│p#│pname│weight│
9090├──────┼─────┼──┼─────┼──────┤
@@ -100,7 +100,7 @@ TutorialD (master): :showexpr p
100100To show all relation variables in the current session, use ```:showrelvars```:
101101
102102```
103−TutorialD (master): :showrelvars
103+TutorialD (master/main): :showrelvars
104104┌─────────────────────────────────────────────────┬──────────┐
105105│attributes::relation {attribute::Text,type::Text}│name::Text│
106106├─────────────────────────────────────────────────┼──────────┤
@@ -146,7 +146,7 @@ Relational operators generate new relations from existing relations. The operato
146146The 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.
147147
148148```
149−TutorialD (master): :showexpr s rename {city as town}
149+TutorialD (master/main): :showexpr s rename {city as town}
150150┌──┬─────┬──────┬──────┐
151151│s#│sname│status│town │
152152├──┼─────┼──────┼──────┤
@@ -165,7 +165,7 @@ Projection is applied by adding curly braces and attribute names following a rel
165165For example:
166166
167167```
168−TutorialD (master): :showexpr p{color,city}
168+TutorialD (master/main): :showexpr p{color,city}
169169┌──────┬─────┐
170170│city │color│
171171├──────┼─────┤
@@ -181,7 +181,7 @@ TutorialD (master): :showexpr p{color,city}
181181Restriction is applied using a "where" clause, much like in SQL.
182182
183183```
184−TutorialD (master): :showexpr p where color="Blue" and city="Paris"
184+TutorialD (master/main): :showexpr p where color="Blue" and city="Paris"
185185┌─────┬─────┬──┬─────┬──────┐
186186│city │color│p#│pname│weight│
187187├─────┼─────┼──┼─────┼──────┤
@@ -192,7 +192,7 @@ TutorialD (master): :showexpr p where color="Blue" and city="Paris"
192192The 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:
193193
194194```
195−TutorialD (master): :showexpr s where ^lt(@status,20)
195+TutorialD (master/main): :showexpr s where ^lt(@status,20)
196196┌─────┬──┬─────┬──────┐
197197│city │s#│sname│status│
198198├─────┼──┼─────┼──────┤
@@ -205,7 +205,7 @@ TutorialD (master): :showexpr s where ^lt(@status,20)
205205Joins 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
206206
207207```
208−TutorialD (master): :showexpr s join sp
208+TutorialD (master/main): :showexpr s join sp
209209┌──────┬──┬───┬──┬─────┬──────┐
210210│city │p#│QTY│s#│sname│status│
211211├──────┼──┼───┼──┼─────┼──────┤
@@ -228,7 +228,7 @@ TutorialD (master): :showexpr s join sp
228228The 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.
229229
230230```
231−TutorialD (master): :showexpr S union S
231+TutorialD (master/main): :showexpr S union S
232232┌──────┬──┬─────┬──────┐
233233│city │s#│sname│status│
234234├──────┼──┼─────┼──────┤
@@ -247,7 +247,7 @@ The union of any relation with itself is itself.
247247The 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.
248248
249249```
250−TutorialD (master): :showexpr s:{status2:=add(10,@status)}
250+TutorialD (master/main): :showexpr s:{status2:=add(10,@status)}
251251┌──────┬──┬─────┬──────┬───────┐
252252│city │s#│sname│status│status2│
253253├──────┼──┼─────┼──────┼───────┤
@@ -279,7 +279,7 @@ The unary group operator groups the argument attributes into subrelations for ea
279279Grouping 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".
280280
281281```
282−TutorialD (master): :showexpr s group ({sname,status,s#} as subrel)
282+TutorialD (master/main): :showexpr s group ({sname,status,s#} as subrel)
283283┌──────┬─────────────────┐
284284│city │subrel │
285285├──────┼─────────────────┤
@@ -308,7 +308,7 @@ TutorialD (master): :showexpr s group ({sname,status,s#} as subrel)
308308The unary ungroup operator "unwraps" subrelations in a relation-valued attribute. There is no equivalent in SQL.
309309
310310```
311−TutorialD (master): :showexpr (s group ({sname,status,s#} as subrel)) ungroup subrel
311+TutorialD (master/main): :showexpr (s group ({sname,status,s#} as subrel)) ungroup subrel
312312┌──────┬──┬─────┬──────┐
313313│city │s#│sname│status│
314314├──────┼──┼─────┼──────┤
@@ -331,8 +331,8 @@ While relational operators compose to relational expressions representing querie
331331The relation variable assignment mentioned above certainly changes the state of the database.
332332
333333```
334−TutorialD (master): newrelvar:=relation{tuple{age 3}}
335−TutorialD (master): :showexpr newrelvar
334+TutorialD (master/main): newrelvar:=relation{tuple{age 3}}
335+TutorialD (master/main): :showexpr newrelvar
336336┌───┐
337337│age│
338338├───┤
@@ -347,8 +347,8 @@ All further operators are convenience operators and could be implemented with si
347347To signal that a relation variable should be forgotten, undefine it.
348348
349349```
350−TutorialD (master): undefine s
351−TutorialD (master): :showexpr s
350+TutorialD (master/main): undefine s
351+TutorialD (master/main): :showexpr s
352352ERR: RelVarNotDefinedError "s"
353353```
354354
@@ -357,8 +357,8 @@ ERR: RelVarNotDefinedError "s"
357357The 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.
358358
359359```
360−TutorialD (master): insert s relation{tuple{city "Boston",s# "S10",sname "Gonzalez",status 10}}
361−TutorialD (master): :showexpr s
360+TutorialD (master/main): insert s relation{tuple{city "Boston",s# "S10",sname "Gonzalez",status 10}}
361+TutorialD (master/main): :showexpr s
362362┌──────┬───┬────────┬──────┐
363363│city │s# │sname │status│
364364├──────┼───┼────────┼──────┤
@@ -381,8 +381,8 @@ s:=s union relation{tuple{city "Boston",s# "S10",sname "Gonzalez",status 10}}
381381The update operator accepts a relation argument and a predicate, optionally filters and creates new tuples based on the original relation.
382382
383383```
384−TutorialD (master): update s where status=20 (sname:="Mr. Twenty")
385−TutorialD (master): :showexpr s
384+TutorialD (master/main): update s where status=20 (sname:="Mr. Twenty")
385+TutorialD (master/main): :showexpr s
386386┌──────┬──┬──────────┬──────┐
387387│city │s#│sname │status│
388388├──────┼──┼──────────┼──────┤
@@ -397,8 +397,8 @@ TutorialD (master): :showexpr s
397397This is logically equivalent to:
398398
399399```
400−TutorialD (master): s:=(((s where status=20){city,s#,status}):{sname:="Mr. Twenty"}) union (s where not status=20)
401−TutorialD (master): :showexpr s
400+TutorialD (master/main): s:=(((s where status=20){city,s#,status}):{sname:="Mr. Twenty"}) union (s where not status=20)
401+TutorialD (master/main): :showexpr s
402402┌──────┬──┬──────────┬──────┐
403403│city │s#│sname │status│
404404├──────┼──┼──────────┼──────┤
@@ -417,8 +417,8 @@ This query means: "Drop the sname attribute from S filtered where status equals
417417The 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.
418418
419419```
420−TutorialD (master): delete sp where s#="S4"
421−TutorialD (master): :showexpr sp
420+TutorialD (master/main): delete sp where s#="S4"
421+TutorialD (master/main): :showexpr sp
422422┌──┬───┬──┐
423423│p#│QTY│s#│
424424├──┼───┼──┤
@@ -437,7 +437,7 @@ TutorialD (master): :showexpr sp
437437This is logically equivalent to:
438438
439439```
440−TutorialD (master): sp:=sp where not s#="S4"
440+TutorialD (master/main): sp:=sp where not s#="S4"
441441```
442442
443443Note the inverted predicate.
@@ -453,7 +453,7 @@ Chris Date identified that all constraints can be represented as inclusion depen
453453Uniqueness 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.
454454
455455```
456−TutorialD (master): key s_key_constraint {s#} s
456+TutorialD (master/main): key s_key_constraint {s#} s
457457```
458458
459459This expression creates a constraint named "S_key_constraint" and ensure that the values of the "s#" attribute are unique in the "S" relational expression.
@@ -463,7 +463,7 @@ This expression creates a constraint named "S_key_constraint" and ensure that th
463463Foreign 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.
464464
465465```
466−TutorialD (master): foreign key s#_in_sp sp{s#} in s{s#}
466+TutorialD (master/main): foreign key s#_in_sp sp{s#} in s{s#}
467467```
468468
469469This expression ensure that any sp{s#} must also appear as a value in s{s#}.
@@ -475,7 +475,7 @@ Unlike SQL databases, Project:M36 includes first-class support for functional de
475475To create a functional dependency:
476476
477477```
478−TutorialD (master): funcdep sname_status (sname) -> (status) s
478+TutorialD (master/main): funcdep sname_status (sname) -> (status) s
479479```
480480
481481In this example, the functional dependency is named "sname_status" and creates a constraint which ensures that the "sname" value is functionally determines "status" value in the relation variable "s", though the final argument can be any relational expression. Multiple attribute names are separated by a comma.
@@ -485,7 +485,7 @@ In this example, the functional dependency is named "sname_status" and creates a
485485All other constraints can be represented by a set of inclusion dependencies.
486486
487487```
488−TutorialD (master): constraint s_status_less_than_50 (s where ^lt(50,@status)){} in false
488+TutorialD (master/main): constraint s_status_less_than_50 (s where ^lt(50,@status)){} in false
489489```
490490
491491This expression ensures that the relation variable's relation can never include a tuple with status greater than 50.
@@ -499,7 +499,7 @@ Aggregate queries in TutorialD are able to provide much more information than SQ
499499SQL supports aggregate queries using aggregate functions (SUM(), COUNT(), AVERAGE(), etc.) and GROUP BY while the aggregate functions in the relational algebra simply accept relation values as arguments.
500500
501501```
502−TutorialD (master): :showexpr s group ({s#,sname,status} as subrel):{citycount:=count(@subrel)}
502+TutorialD (master/main): :showexpr s group ({s#,sname,status} as subrel):{citycount:=count(@subrel)}
503503┌──────┬─────────┬─────────────────┐
504504│city │citycount│subrel │
505505├──────┼─────────┼─────────────────┤