all done :)
This commit is contained in:
parent
09b0157694
commit
daa3a00025
1 changed files with 126 additions and 28 deletions
|
@ -1229,17 +1229,15 @@ rightSide = cons . (split (singl . p1) ((map cons) . lstr . (id >< concat)))
|
||||||
}
|
}
|
||||||
\end{eqnarray*}
|
\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.
|
Desenhando o diagrama do catamorfismo de árvores |Exp|, a partir do seu funtor, descobri o tipo de entrada do gene.
|
||||||
|
Tendo isto em mente, comecei por analisar qual seria o significado, para este contexto, do tipo de entrada, e cheguei à conclusão
|
||||||
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 alternativa, representa o conteúdo de uma folha da àrvore, logo será um elemento sem descentes.
|
||||||
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 alternativa, o primeiro elemento do par representa o "pai"
|
||||||
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 do segundo elemento par, que contém os resultados das chamadas recursivas. Tendo isso em conta, conservo e crio
|
||||||
de todos os elementos da lista, que contém os resultados das chamadas recursivas. Tendo isso em conta, aplico um split, que
|
lista com o "pai", e uma lista com todos os seus descendentes. Esta lista é obtida da seguinte forma:
|
||||||
resulta numa lista com um habitante, 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,
|
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
|
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 pelo split.
|
para juntar o par.
|
||||||
|
|
||||||
% fazer diagrama do hilo
|
% 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
|
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
|
acm_hylo = hyloExp gene_post gene
|
||||||
\end{code}
|
\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 -----------------
|
% ------------ Problema 3 -----------------
|
||||||
\subsection*{Problema 3}
|
\subsection*{Problema 3}
|
||||||
\begin{code}
|
\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)
|
sub_side_to_y ((x,y),s) = ((x,y-s),s)
|
||||||
\end{code}
|
\end{code}
|
||||||
|
|
||||||
|
Função de conversão de listas em |Rose| Trees:
|
||||||
\begin{code}
|
\begin{code}
|
||||||
rose2List = cataRose gr2l
|
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,
|
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.
|
representado por |(A^*)^*| e adicionar conteúdo do nodo, representado por |A| à cabeça da lista.
|
||||||
|
|
||||||
|
Componentes da função |constructSierp|:
|
||||||
\begin{code}
|
\begin{code}
|
||||||
carpets = reverse . anaList gcarp
|
carpets = reverse . anaList gcarp
|
||||||
|
|
||||||
|
@ -1419,19 +1433,21 @@ gprst = either (return . nil) (alpha . (((>> await) . drawSq) >< id)) where
|
||||||
\ar[r]^-{|outList|}
|
\ar[r]^-{|outList|}
|
||||||
\ar[d]_-{|present|}
|
\ar[d]_-{|present|}
|
||||||
&
|
&
|
||||||
1 + |Square| \times (|Square|^*)^*
|
1 + |Square|^* \times (|Square|^*)^*
|
||||||
\ar[d]^-{id + id \times |present|}
|
\ar[d]^-{id + id \times |present|}
|
||||||
\\
|
\\
|
||||||
|IO(1)|^*
|
|IO(1)|^*
|
||||||
&
|
&
|
||||||
1 + |Square| \times |IO(1)|^*
|
1 + |Square|^* \times |IO(1)|^*
|
||||||
\ar[l]^-{grst}
|
\ar[l]^-{grst}
|
||||||
|
\ar[d]^-{|nil| + |((>>await) . drawSq)| \times id}
|
||||||
|
\\
|
||||||
|
&
|
||||||
|
1 + |IO(1)| \times |IO(1)|^*
|
||||||
|
\ar[ul]^-{|either return alpha|}
|
||||||
}
|
}
|
||||||
\end{eqnarray*}
|
\end{eqnarray*}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
\subsection*{Problema 4}
|
\subsection*{Problema 4}
|
||||||
\subsubsection*{Versão não probabilística}
|
\subsubsection*{Versão não probabilística}
|
||||||
Gene de |consolidate'|:
|
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)
|
add_pair ((x,y),t) = (x, y + maybe 0 id (List.lookup x t)):(filter(\(a,b) -> a != x) t)
|
||||||
\end{code}
|
\end{code}
|
||||||
|
|
||||||
\begin{eqnarray*}
|
\begin{eqnarray*}
|
||||||
\xymatrix@@C=2cm{
|
\xymatrix@@C=2cm{
|
||||||
(A \times B)^*
|
(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|}
|
\ar[l]^-{|cgene|}
|
||||||
}
|
}
|
||||||
\end{eqnarray*}
|
\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:
|
Geração dos jogos da fase de grupos:
|
||||||
|
|
||||||
\begin{code}
|
\begin{code}
|
||||||
pairup [] = []
|
pairup [] = []
|
||||||
pairup (x:xs) = pairs x xs ++ pairup xs where
|
pairup (h:t) = curry lstr h t ++ pairup t
|
||||||
pairs x [] = []
|
\end{code}
|
||||||
pairs x (y:ys) = (x,y) : pairs x ys
|
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
|
||||||
matchResult crit m@(t1,t2) = teamPoints m (crit m)
|
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) Nothing = [(t1,1),(t2,1)]
|
||||||
teamPoints (t1,t2) (Just t) = if t1 == t then [(t1,3),(t2,0)] else [(t2,3),(t1,0)]
|
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
|
glt = (id -|- ((cons >< id) . assocl . (id >< divideList))) . out where
|
||||||
divideList l = (take (length l `div` 2) l, drop (length l `div` 2) l)
|
divideList l = (take (length l `div` 2) l, drop (length l `div` 2) l)
|
||||||
\end{code}
|
\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}
|
\subsubsection*{Versão probabilística}
|
||||||
\begin{code}
|
\begin{code}
|
||||||
pinitKnockoutStage = return . initKnockoutStage
|
pinitKnockoutStage = return . initKnockoutStage
|
||||||
\end{code}
|
\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}
|
\begin{code}
|
||||||
pgroupWinners :: (Match -> Dist (Maybe Team)) -> [Match] -> Dist [Team]
|
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
|
fmapBody = best 2 . consolidate . concat
|
||||||
\end{code}
|
|
||||||
|
|
||||||
\begin{code}
|
|
||||||
pmatchResult criteria match = do {dist <- criteria match ; return (teamPoints match dist)}
|
pmatchResult criteria match = do {dist <- criteria match ; return (teamPoints match dist)}
|
||||||
\end{code}
|
\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) -------------------------%
|
%----------------- Índice remissivo (exige makeindex) -------------------------%
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue