all done :)

This commit is contained in:
Tiago Sousa 2023-01-15 00:37:35 +00:00
parent 09b0157694
commit daa3a00025

View file

@ -1229,17 +1229,15 @@ rightSide = cons . (split (singl . p1) ((map cons) . lstr . (id >< concat)))
}
\end{eqnarray*}
% explicar post gene
Desenhando o diagrama do catamorfismo de árvores |Exp|, a partir do seu funtor, descobri o tipo de entrada do gene.
De seguida, comecei por analisar qual seria o significado, para este contexto, do tipo de entrada, e cheguei a conclusão
de que o lado esquerdo da soma, que representa o conteúdo de uma folha da àrvore, logo será um elemento sem descentes.
Para este caso apenas tenho de aplicar |singl . singl|. Do lado direito da soma, o primeiro elemento do par representa o "pai"
de todos os elementos da lista, que contém os resultados das chamadas recursivas. Tendo isso em conta, aplico um split, que
resulta numa lista com um habitante, o "pai", e uma lista com todos os seus descendentes. Esta lista é obtida da seguinte forma:
Tendo isto em mente, comecei por analisar qual seria o significado, para este contexto, do tipo de entrada, e cheguei à conclusão
de que o lado esquerdo da alternativa, representa o conteúdo de uma folha da àrvore, logo será um elemento sem descentes.
Para este caso apenas tenho de aplicar |singl . singl|. Do lado direito da alternativa, o primeiro elemento do par representa o "pai"
de todos os elementos do segundo elemento par, que contém os resultados das chamadas recursivas. Tendo isso em conta, conservo e crio
lista com o "pai", e uma lista com todos os seus descendentes. Esta lista é obtida da seguinte forma:
concatenei todos os resultados recursivos, de seguida apliquei ao par |lstr|, para obter uma lista com pares "pai" e lista de descendentes,
depois para todos os elementos aplico cons para que o "pai" seja adicionada a cabeça de todos os elementos. Por fim aplico cons
para juntar o par pelo split.
depois para todos os elementos aplico |cons| para que o "pai" seja adicionado a cabeça de todos os elementos. Por fim aplico |cons|
para juntar o par.
% fazer diagrama do hilo
Sendo tax e post, um anaformismo e um catamorfismo de árvores |Exp|, respetivamente, o problema 2 poderia ser reescrito na forma
@ -1250,6 +1248,22 @@ acm_xls_hylo = acm_hylo acm_ccs
acm_hylo = hyloExp gene_post gene
\end{code}
\begin{eqnarray*}
\xymatrix@@C=2cm{
S^*
\ar[d]_-{|acm_hylo|}
\ar[r]^-{|gene|}
&
S + S \times (S^*)^*
\ar[d]^-{id + id \times |acm_hylo|^*}
\\
(S^*)^*
&
S + S \times ((S^*)^*)^*
\ar[l]^-{|gene_post|}
}
\end{eqnarray*}
% ------------ Problema 3 -----------------
\subsection*{Problema 3}
\begin{code}
@ -1350,7 +1364,7 @@ sub_side_to_x ((x,y),s) = ((x-s,y),s)
sub_side_to_y ((x,y),s) = ((x,y-s),s)
\end{code}
Função de conversão de listas em |Rose| Trees:
\begin{code}
rose2List = cataRose gr2l
@ -1375,7 +1389,7 @@ A partir do diagrama do catamorfismo |rose2List|, facilmente se chega à defini
o seu funtor origina um par, apenas temos de concatenar os resultado das chamadas recursivas,
representado por |(A^*)^*| e adicionar conteúdo do nodo, representado por |A| à cabeça da lista.
Componentes da função |constructSierp|:
\begin{code}
carpets = reverse . anaList gcarp
@ -1419,19 +1433,21 @@ gprst = either (return . nil) (alpha . (((>> await) . drawSq) >< id)) where
\ar[r]^-{|outList|}
\ar[d]_-{|present|}
&
1 + |Square| \times (|Square|^*)^*
1 + |Square|^* \times (|Square|^*)^*
\ar[d]^-{id + id \times |present|}
\\
|IO(1)|^*
&
1 + |Square| \times |IO(1)|^*
1 + |Square|^* \times |IO(1)|^*
\ar[l]^-{grst}
\ar[d]^-{|nil| + |((>>await) . drawSq)| \times id}
\\
&
1 + |IO(1)| \times |IO(1)|^*
\ar[ul]^-{|either return alpha|}
}
\end{eqnarray*}
\subsection*{Problema 4}
\subsubsection*{Versão não probabilística}
Gene de |consolidate'|:
@ -1442,7 +1458,6 @@ cgene = either nil add_pair
add_pair ((x,y),t) = (x, y + maybe 0 id (List.lookup x t)):(filter(\(a,b) -> a != x) t)
\end{code}
\begin{eqnarray*}
\xymatrix@@C=2cm{
(A \times B)^*
@ -1458,41 +1473,124 @@ add_pair ((x,y),t) = (x, y + maybe 0 id (List.lookup x t)):(filter(\(a,b) -> a !
\ar[l]^-{|cgene|}
}
\end{eqnarray*}
Após desenhar o diagram do catamorfismo de |consolidate'|, cheguei à seguinte definição do seu gene. Caso este receba o elemento
nulo, devolve a lista vazia, caso contrário, com a ajuda da função |add_pair|, procura na lista resultante da chamada recursiva
por elementos que tenham a mesma "chave" e, se ela existir adiciona o conteúdo associado ao segundo elemento. Por fim retira todos
os elementos que tenham a mesma "chave" e adiciona a cabeça o novo par.
Geração dos jogos da fase de grupos:
\begin{code}
pairup [] = []
pairup (x:xs) = pairs x xs ++ pairup xs where
pairs x [] = []
pairs x (y:ys) = (x,y) : pairs x ys
matchResult crit m@(t1,t2) = teamPoints m (crit m)
pairup (h:t) = curry lstr h t ++ pairup t
\end{code}
A função |pairup| está encarregue de criar todos as possibilidades de jogos entre equipas. Para isso, recebendo uma lista
de equipas, com o auxílio o função |lstr| cria uma lista com todos os pares entre a cabeça e o resto dos elementos, deste modo
não existirão pares repetidos. Por fim adiciona-os à cabeça da lista resultante da chamada recursiva, retornando
a lista com todos os jogos possíveis não repetidos.
\begin{code}
matchResult crit m = teamPoints m (crit m)
teamPoints (t1,t2) Nothing = [(t1,1),(t2,1)]
teamPoints (t1,t2) (Just t) = if t1 == t then [(t1,3),(t2,0)] else [(t2,3),(t1,0)]
\end{code}
A função |matchResult|, aplica um critério recebido ao jogo também recebido, e de seguida, usando a função |teamPoints| cria a
lista com o resultado do jogo. Caso o resultado seja |Nothing|, que significa um empate, ambas as equipas recebem 1 ponto, caso
contrário a equipa vencedora recebe 3 pontos.
\begin{eqnarray*}
\xymatrix@@C=2cm{
|LTree A|
&
A + |LTree A| \times |LTree A|
\ar[l]_-{|inLTree|}
\\
A^*
\ar[u]^-{|anaLTree glt|}
\ar[r]_-{|glt|}
&
A + A^* \times A^*
\ar[u]_-{id + |anaLTree glt| \times |anaLTree glt|}
}
\end{eqnarray*}
\begin{code}
glt = (id -|- ((cons >< id) . assocl . (id >< divideList))) . out where
divideList l = (take (length l `div` 2) l, drop (length l `div` 2) l)
\end{code}
\begin{eqnarray*}
\xymatrix@@C=2cm{
A^*
\ar[d]^-{|out|}
\\
A + A \times A^*
\ar[d]^-{|id| + |id| \times divideList}
\\
A + A \times (A^* \times A^*)
\ar[d]^-{|id| + |assocl|}
\\
A + (A \times A^*) \times A^*
\ar[d]^-{|id| + |cons| \times |id|}
\\
A + A^* \times A^*
}
\end{eqnarray*}
Para definir o gene de |anaLTree glt|, comecei por desenhar o seu diagrama.
De seguida com ajuda do diagrama acima, apliquei o |out| das listas não vazias, e caso o input seja
uma lista com um só elemento, é conservado e retornado. Caso contrário, reparto a cauda da lista em
2 partes, associo o a cabeça à primeira lista, e finalmente adiciono a cabeça à mesma.
\subsubsection*{Versão probabilística}
\begin{code}
pinitKnockoutStage = return . initKnockoutStage
\end{code}
\begin{eqnarray*}
\xymatrix@@C=2cm{
(|Team|^*)^*
\ar[d]^-{|initKnockoutStage|}
\\
|LTree Team|
\ar[d]^-{|return|}
\\
|Dist (LTree Team)|
}
\end{eqnarray*}
Analisando a função |pgroupStage|, reparei que a função |pinitKnockoutStage| está em composição monádica com a função
|psimulateGroupStage| logo o seu input já será o conteúdo do mónade. Sendo assim pode-se reaproveitar a função definida
para a versão não probabilística, |initKnockoutStage| e de seguida retornar esse resultado, de forma a devolver o mónade
|Dist (LTree Team)|.
\begin{code}
pgroupWinners :: (Match -> Dist (Maybe Team)) -> [Match] -> Dist [Team]
pgroupWinners criteria = fmap (fmapBody) . sequence . map (pmatchResult criteria)
pgroupWinners criteria = fmap fmapBody . sequence . map (pmatchResult criteria)
fmapBody = best 2 . consolidate . concat
\end{code}
\begin{code}
pmatchResult criteria match = do {dist <- criteria match ; return (teamPoints match dist)}
\end{code}
\begin{eqnarray*}
\xymatrix@@C=2cm{
|Match|^*
\ar[d]^-{|pmatchResult criteria|}
\\
(|Dist| (Match \times |Nat0|)^*)^*
\ar[d]^-{|sequence|}
\\
|Dist| ((|Match| \times |Nat0|)^*)^*
\ar[d]^-{|fmap fmapBody|}
\\
|Dist Team|^*
}
\end{eqnarray*}
Para a função |pgroupWinners|, começo por aplicar a função |pmatchResult| a todos os elementos da lista
de jogos, de forma obter uma lista de mónades de distribuições com a lista de todos os resultados possíveis dos jogos.
De seguida, aplicando |sequence| transforma-se a lista de mónades num mónade de listas, em que o seu resultado é
a distribuição probabilística de todas as combinações dos resultados dos jogos. Usando |fmap|, altera-se o
conteúdo do mónade com a função |fmapBody|. Para definir a função |fmapBody|, inicialmente concatenam-se todos os elementos
da lista, neste caso os resultados dos jogos, de seguida |consolidate| de forma a obter os pontos finais das equipas, e
com |best 2| retornam-se as 2 equipas com os melhores resultados. Esta função irá retornar uma distribuição probabilística
das 2 melhores equipas do grupo.
%----------------- Índice remissivo (exige makeindex) -------------------------%