Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
project-3-draft [2021/04/19 11:01] pdmatei |
project-3-draft [2021/04/25 16:07] (current) roxana_elena.stiuca prerequisite for taskset3 |
||
---|---|---|---|
Line 26: | Line 26: | ||
| Cartesian (Row -> Row -> Row) [String] Query Query | | Cartesian (Row -> Row -> Row) [String] Query Query | ||
| Projection [String] Query | | Projection [String] Query | ||
- | -- | forall a. Filter (FilterCondition a) Query | + | | forall a. FEval a => Filter (FilterCondition a) Query |
- | | Graph EdgeOp query | + | | Graph EdgeOp Query |
| | ||
-- where EdgeOp is defined: | -- where EdgeOp is defined: | ||
- | type EdgeOp = Row -> Row -> Value | + | type EdgeOp = Row -> Row -> Maybe Value |
</code> | </code> | ||
**Don't worry about Graph or Filter queries yet.** | **Don't worry about Graph or Filter queries yet.** | ||
- | + | ==== Prerequisite ==== | |
+ | Add the following lines at the beginning of your .hs files: | ||
+ | <code haskell> | ||
+ | {-# LANGUAGE ExistentialQuantification #-} | ||
+ | {-# LANGUAGE FlexibleInstances #-} | ||
+ | </code> | ||
+ | |||
+ | The first line allows ''forall a''. | ||
+ | The second allows ''instance FEval String''. | ||
===== Query Evaluation ===== | ===== Query Evaluation ===== | ||
Line 101: | Line 110: | ||
=== FilterCondition Evaluation === | === FilterCondition Evaluation === | ||
- | Let's take a look at FilterCondition. It is used in a Filter query, in order | + | |
- | to filter the entries (rows) in a table, based on a condition. | + | A ''FilterCondition'' must evaluate to an actual filtering function, which has type: |
- | We are going to define class FEval, which contains function feval, through | + | <code haskell> |
- | which we evaluate a FilterCondition to a function of type FilterOp (defined | + | type FilterOp = Row -> Bool |
- | also below). In order to do so, feval will also receive the column names | + | </code> |
- | (the table head). | + | |
+ | Since such filtering functions work differently for ''FilterCondition Float'' and ''FilterCondition String'', we need a class ''FEval'' which contains function ''feval''. The latter is used to evaluate a ''FilterCondition a'' to a function of type ''FilterOp''. In order to do so, ''feval'' needs to have information about column names (the table head), hence it's type is shown below. | ||
<code haskell> | <code haskell> | ||
class FEval a where | class FEval a where | ||
feval :: [String] -> (FilterCondition a) -> FilterOp | feval :: [String] -> (FilterCondition a) -> FilterOp | ||
- | type FilterOp = Row -> Bool | ||
</code> | </code> | ||
- | Your task is to write the instances for (FEval Float) and (FEval String). | + | |
+ | **Task 3.x.**: Your task is to write the instances for ''(FEval Float)'' and ''(FEval String)''. | ||
<code haskell> | <code haskell> | ||
instance FEval Float where | instance FEval Float where | ||
Line 119: | Line 129: | ||
... | ... | ||
</code> | </code> | ||
- | Now you can write the evaluation for Filter query (**eval**). | + | |
- | === Graph Query === | + | Now you can write the evaluation for the data constructor ''Filter query'' (see function **eval** from the previous section). |
- | We define a graph as a table with column names: ["From", "To", "Value"]. | + | |
- | Each row defines a weighted edge between node "From" and node "To". | + | |
- | - **Graph edgeop query**: creates a graph starting from the table | + | ===== Graph queries ===== |
- | query evaluates to. | + | |
- | The nodes are the rows in table T. | + | A **graph** is a special kind of table which has precisely the following column names: ''["From", "To", "Value"]''. Each row defines a **weighted edge** between node ''From'' and node ''To''. |
- | The weight of an edge between 2 nodes is given by edgeop. We will only | + | |
- | keep the edge between row1 and row2 if (edgeop row1 row2) > 0. | + | The query ''Graph edgeop query'': creates such a table starting from the result of the evaluation of ''query''. Suppose the query evaluates to a table **T**. |
- | In the resulting table, a row describes an edge between node_i and node_j | + | |
- | and will have the values: | + | * The nodes are the **rows** in table **T**. |
- | "From" = first column from node_i | + | * The weight of an edge between 2 nodes is given by ''edgeop'', which returns a ''Maybe Value''. If ''edgeop row1 row2'' returns ''Nothing'', then we don't have an edge between those 2 nodes. If it returns ''Just val'' then we have an edge between ''row1'' and ''row2'' of weight ''val''. |
- | "To" = first column from node_j | + | * In the resulting table, each row describes an edge between node_i and node_j and will have the values: |
- | "Value" = edgeop node_i node_j | + | * "From" = first column from node_i |
- | The edge node_i-node_j is the same as node_j-node_i, so it should only | + | * "To" = first column from node_j |
- | appear once. "From" value should be lexicographically before "To". | + | * "Value" = edgeop node_i node_j |
- | === Similarities graph, using queries === | + | |
+ | The edge //node_i-node_j// is the same as //node_j-node_i//, so it should only appear once (graphs are unoriented). "From" value should be lexicographically before "To". | ||
+ | |||
+ | **Example:** Suppose **T** is the table shown below: | ||
+ | <code> | ||
+ | Name Grade Class | ||
+ | Mihai 9 321 | ||
+ | Andrei 8 322 | ||
+ | Stefan 10 321 | ||
+ | Ana 9 322 | ||
+ | </code> | ||
+ | |||
+ | If we would like to build a graph that connects all students in the same class, then: | ||
+ | <code haskell> | ||
+ | edgeop [_,_,z] [_,_,c] | ||
+ | | z == c = Just c | ||
+ | | otherwise = Nothing | ||
+ | </code> | ||
+ | |||
+ | and the resulting graph will be: | ||
+ | <code> | ||
+ | From To Value | ||
+ | Mihai Stefan 321 | ||
+ | Ana Andrei 322 | ||
+ | </code> | ||
+ | |||
+ | If we would like to build a graph that connects students with grades equal or with a difference of **at least** a point, then: | ||
+ | <code haskell> | ||
+ | edgeop [_,x,_] [_,y,_] | ||
+ | | abs $ (read x :: Int) - (read y :: Int) <= 1 = Just "similar" | ||
+ | | otherwise = Nothing | ||
+ | </code> | ||
+ | |||
+ | and the resulting graph is: | ||
+ | <code> | ||
+ | From To Value | ||
+ | Andrei Mihai similar | ||
+ | Mihai Stefan similar | ||
+ | Ana Mihai similar | ||
+ | Ana Andrei similar | ||
+ | Ana Stefan similar | ||
+ | </code> | ||
+ | |||
+ | |||
+ | ==== Similarities graph, using queries ==== | ||
We want to check the similarities between students lecture points. | We want to check the similarities between students lecture points. | ||
- | For that, we want to obtain a graph where "From" and "To" are students' | + | * For that, we want to obtain a graph where "From" and "To" are students' emails and "Value" is the distance between the 2 students' points. |
- | emails and "Value" is the distance between the 2 students' points. | + | * We define the distance between stud1 and stud2 as ''the sum of questions where they both received the same points''. Keep only the rows with ''distance >= 5''. |
- | We define the distance between stud1 and stud2 as the sum of questions | + | * The edges in the resulting graph (the rows in the resulting table) should be sorted by the "Value" column. If email is missing, don't include that entry. |
- | where they both received the same points. | + | |
- | Also, the edges in the resulting graph (the rows in the resulting table) | + | Your task is to write ''similarities_query'' as a **sequence of queries**, that once evaluated results in the graph described above. |
- | should be sorted by the "Value" column. Keep only the rows with | + | |
- | distance >= 5. If email is missing, ignore that entry. | + | **Note**: ''similarities_query'' is a Query. The checker applies ''eval'' on it. |
- | Your task is to write **similarities_query** as a sequence of | + | |
- | queries, that once evaluated results in the graph described above. | + | ===== TL;DR Tasks ===== |
- | === TL;DR Tasks === | + | - Enroll ''Query'' in class ''Eval'' (without ''Filter'' or ''Graph''). **0.3p** |
- | 1. Enroll Query in class Eval (without Filter or Graph). 0.2p | + | - Enroll ''FilterCondition'' in class ''FEval'' and implement ''eval'' for ''Filter'' query. **0.2p** |
- | 2. Enroll FilterCondition in class FEval and implement eval for Filter query. 0.2p | + | - Implement ''eval'' for ''Graph'' query. 0.2p |
- | 3. Implement eval for Graph query. 0.2p | + | - Extract similarity graph. 0.3p |
- | 4. Get graph for similarities. 0.3p | + | |
- | === Checker === | + | ===== Checker ===== |
- | === Submit === | + | |
+ | ===== Submit ===== | ||
**Deadline**: 16.05, 23:50. | **Deadline**: 16.05, 23:50. | ||
**Vmchecker**: TBA. | **Vmchecker**: TBA. |