📘 Relations#
Relations are a powerful way to model and query data in a structured manner.
In this tutorial, we will explore how to create and manipulate relations using the
galactic.algebras.relational.core module of the GALACTIC framework.
n-ary Relations#
Concrete n-ary Relations#
n-ary relations are relations that can involve any number of sets.
In the GALACTIC framework, we can define n-ary relations using the
MutableRelation
(or FrozenRelation) class.
Their presence in the GALACTIC
framework is only in an educational capacity, as they are not optimized for performance.
from galactic.algebras.relational.core import MutableRelation
n_ary_relation = MutableRelation(([1, 2, 3], ['a', 'b', 'c'], [True, False]))
n_ary_relation
<galactic.algebras.relational.core.MutableRelation object at 0x76d9af3647c0>
Universes of an n-ary relation can be accessed using the
universes attribute.
display(n_ary_relation.universes)
display(*(list(universe) for universe in n_ary_relation.universes))
(<galactic...MutableUniverse object at 0x76d9d0a726b0>,
<galactic...MutableUniverse object at 0x76d9af7525c0>,
<galactic...MutableUniverse object at 0x76d9d0a18760>)
[1, 2, 3]
['a', 'b', 'c']
[True, False]
A relation is considered a set of tuples, and therefore is considered a set-like object:
The number of tuples in the relation can be accessed using the
lenfunction, which returns the cardinality of the relation.The presence of a tuple in the relation can be checked using the
inkeywordThe relation itself is iterable
The relation supports set operations like
<,<=,>,>=and methods likeisdisjoint(),issubset(),issuperset().
(<galactic...MutableUniverse object at 0x76d9d0a726b0>,
<galactic...MutableUniverse object at 0x76d9af7525c0>,
<galactic...MutableUniverse object at 0x76d9d0a18760>)
[]
0
[1, 2, 3]
['a', 'b', 'c']
[True, False]
tuples can be added or removed from the relation using:
add()method to add tuplesremove()method to remove tuplesdiscard()method to remove tuples without raising an error if the tuple is not presentclear()method to remove all tuples from the relationpop()method to remove and return an arbitrary tuple from the relationextend()method to add multiple tuples to the relation at once
n_ary_relation.add((2, 'b', True))
n_ary_relation.add((1, 'a', False))
n_ary_relation.discard((5, 'e', False)) # Does not raise an error
display(n_ary_relation.pop())
display(list(n_ary_relation), len(n_ary_relation))
n_ary_relation.extend([(3, 'c', True), (1, 'b', True)])
display(list(n_ary_relation), len(n_ary_relation))
n_ary_relation.remove((3, 'c', True))
display(list(n_ary_relation), len(n_ary_relation))
n_ary_relation.clear()
display(list(n_ary_relation), len(n_ary_relation))
(2, 'b', True)
[(1, 'a', False)]
1
[(1, 'a', False), (3, 'c', True), (1, 'b', True)]
3
[(1, 'a', False), (1, 'b', True)]
2
[]
0
Views on n-ary Relations#
Views provide a way to create derived relations based on existing ones without
modifying the original relation. In the GALACTIC framework, we can create views
using the Selection and
Projection classes.
Selection View#
A selection view allows us to filter tuples in a relation based on a specified condition.
from galactic.algebras.relational.core import Selection
n_ary_relation.add((2, 'b', True))
n_ary_relation.add((1, 'a', False))
selection_view = Selection(
n_ary_relation,
{1: 'a'} # Select tuples where the second element is 'a'
)
list(selection_view)
[(1, 'a', False)]
Projection View#
A projection view allows us to create a new relation by selecting specific columns from the original relation.
from galactic.algebras.relational.core import Projection
projection_view = Projection(
n_ary_relation,
[0, 2] # Project the first and third elements of the tuples
)
list(projection_view)
[(2, True), (1, False)]
Binary Relations#
Binary relations are a special case of n-ary relations that involve exactly two sets.
In the GALACTIC framework, we can define binary relations using the
MutableBinaryRelation
(or FrozenBinaryRelation)
class.
from galactic.algebras.relational.core import MutableBinaryRelation
binary_relation = MutableBinaryRelation(([1, 2, 3], ['a', 'b', 'c']))
binary_relation
<galactic.algebras.relational.core.MutableBinaryRelation object at 0x76d9ae91e880>
In addition to properties and methods inherited from n-ary relations, binary relations also provide specialized methods for relational algebra operations such as:
domainto get the domain of the relationco_domainto get the co-domain of the relationsuccessors()to get the successors of an element in the domainpredecessors()to get the predecessors of an element in the co-domain
display(binary_relation.domain, list(binary_relation.domain))
display(binary_relation.co_domain, list(binary_relation.co_domain))
binary_relation.add((1, 'a'))
binary_relation.add((2, 'b'))
binary_relation.add((2, 'c'))
display(binary_relation.domain, list(binary_relation.domain))
display(binary_relation.co_domain, list(binary_relation.co_domain))
display(binary_relation.successors(2), list(binary_relation.successors(2)))
display(binary_relation.predecessors('b'), list(binary_relation.predecessors('b')))
<galactic...MutableUniverse object at 0x76d9af3cae10>
[1, 2, 3]
<galactic...MutableUniverse object at 0x76d9af3cb440>
['a', 'b', 'c']
<galactic...MutableUniverse object at 0x76d9af3cae10>
[1, 2, 3]
<galactic...MutableUniverse object at 0x76d9af3cb440>
['a', 'b', 'c']
<galactic...MutableSuccessors object at 0x76d9af3caf90>
['b', 'c']
<galactic...MutablePredecessors object at 0x76d9ae92c0b0>
[2]
EndoRelation is a
specialized type of binary relation where the domain and co-domain
are the same set. This notion is particularly useful for modeling functions and
transformations within a single set. In the GALACTIC framework, we can define
endo-relations using the
MutableEndoRelation
(or FrozenEndoRelation) class.
Posets and Lattices are also special cases of
endo-relations.