Atendimento

  • Em qualquer altura: via correio electrónico pressionando aqui (garantir sempre que "CP" faz parte do assunto). Qualquer outro meio de contacto será considerado informal, não se sentindo a equipa docente vinculada a dar uma resposta em tempo útil.

  • Durante o período de aulas: o atendimento presencial será feiro de acordo com o horário que se segue, sujeito a marcação verbal ou por email, com um mínimo de uma semana de antecedência, junto do respectivo docente:

Dia Hora Cursos Docente
3.ª-feira 8h30-9h30 MiEI J.B. Barros
5.ª-feira 10h00-12h00 MiEI R. Neves
5.ª-feira 11h00-13h00 MiEI A. Madeira
5.ª-feira 17h00-20h00 MiEI/LCC J.N. Oliveira
6.ª-feira 10h00-13h00 MiEI/LCC O.M. Pacheco
6.ª-feira 18h00-20h00 MiEI/LCC J.N. Oliveira

 

Atendimento electrónico (FAQs)

Q1 - Tenho dificuldades a resolver o exercício 2.8 dos apontamentos (pág. 25).

R: O diagrama representa a equação

[x,y] = [k,g].(id+id >< f)

que se quer resolver em ordem a x e y. Por absorção (etc), o lado direito fica [k,g.(id >< f)] ; pela igualdade de eithers tem-se, de imediato,

x = k
y = g.(id >< f)

Quanto aos pontos de interrogação, comecemos pelo tipo genérico da seta vertical, que é a soma de uma identidade com um produto:

A + (B >< C) <-- id + (id >< f) -- A + (B >< D)

(repetimos A e B por estarem ligados a identidades). Como nada sabemos sobre k e g, ter-se-á

E <--- [k,g] --- A + (B >< C)

Logo, os pontos de interrogação são os tipos genéricos (paramétricos) A + (B >< D) (em cima); E (em baixo, à esquerda) e A + (B >< C) (à direita).


Q2 - Gostaria de saber se a função (A x C + B x D) -- [π2,π2] --> C + D está bem tipada.

R: Para estar seria preciso que as duas instâncias de π2 tivessem o mesmo tipo de saída. Ora isso não acontece: tem-se A x C -- π2 --> C num caso e B x D -- π2 --> D no outro, ambos diferentes de C + D. Já se escrever π2 + π2 em lugar de [π2,π2] terá uma expressão funcional bem tipada.


Q3 - Tenho uma dúvida sobre o primeiro problema do trabalho prático: a declaração do tipo de dados data Op = Op String não faz uma recursão infinita?

R: Não! O 'Op' do lado esquerdo designa o tipo de dados, enquanto o do lado direito designa um construtor. Comparando com, por exemplo, a declaração do tipo 'LTree', o primeiro 'Op' está para 'LTree' assim como o segundo está para 'Leaf'. Em Haskell, a disjunção desses "name spaces" é garantida por construção da linguagem.


Q4 - Defini a função show' que envio em anexo tal como é pedido no exercício 3 do problema 1. Contudo, quando chamo quickCheck prop_inv no terminal, o programa fica a correr infinitamente. O que poderei estar a fazer de errado?

R: Essa tarefa pode demorar bastante tempo, até a 1 minuto será normal. Isto não quer dizer, contudo, que não seja possível melhorar o seu show'...


Q5 - No problema 2, aparecem dois exercicios que não têm uma explicação clara do que é pedido, nomeadamente, collectLeafs e dimen. Se pudessem explicar o resultado que pretendem com estas funções agradecia.

R: A função collectLeafs retorna todas as folhas de um elemento do tipo X a b. A sua assinatura é a seguinte:

collectLeafs :: X a b -> [a]

A função dimen tem como objectivo calcular as dimensões de um elemento do tipo X Caixa Tipo, com base na suas caixas e o posicionamento relativo das últimas. A assinatura desta função é a seguinte:

dimen :: X Caixa Tipo -> (Float, Float)


Q6 - A nossa solução para show' passa nos 100 testes. No entanto, apresenta Num(a) como '(a)' e não como 'a'. Está bem assim ou é suposto aparecer apenas um 'a', sem parênteses?

R: A vossa implementação acrescenta parênteses desnecessariamente, e portanto tem espaço para ser melhorada.

Por volta dos anos 60, E. Dijkstra proferiu a seguinte frase, que ficou célebre: "Testing shows the presence, not the absence of bugs". O facto de a vossa função passar nos testes não implica a ausência de falhas ou a impossibilidade de a melhorar.


Q7 - Relativamente ao problema 2 do TP, (1) na parte das soluções não aparecem as funções agrup_caixas e mostra_caixas. São para nós adicionarmos, correcto? (2) Que devem fazer as funções calc e caixasAndOrigin2Pict?

R: (1) Sim. (2) Quanto à função calc: considere duas caixas a) e b). Sabendo a posição absoluta da caixa a), as suas dimensões, e a posição relativa da caixa b) em relação à caixa a), a função, calc :: Tipo -> Origem -> (Float, Float) -> Origem, determina onde colocar a caixa b), i.e. a sua posição absoluta. (Ver também Q22 mais abaixo, sobre este assunto.) Quanto à função caixasAndOrigin2Pict: o seu tipo é (X Caixa Tipo, Origem) -> G.Picture. Esta função converte uma expressão em L2D (portanto uma representação textual de agregações de caixas) numa imagem.


Q8 - No problema 4 do trabalho prático a minha função find passa por vezes nos 100 testes do quickCheck enquanto que noutras vezes fica em "ciclo infinito" e não consigo perceber porquê. O que poderei estar a fazer de errado?

R: O QuickCheck faz a geração dos casos de teste de forma aleatória e por vezes escolhe testes bastante complexos de gerar. O demorar muito tempo não quer dizer que esteja em ciclo infinito, e há uma maneira de ver isso: corra verboseCheck prop_find em vez de quickCheck prop_find e verá os testes que estão a ser gerados.


Q9 - Na alínea 3(e) da ficha nº 5, fiz os diagramas de cada catamorfismo e chego às definições das funções com variáveis através da lei universal-cata e consigo perceber que realmente fazem a mesma coisa; mas não sei se era assim que era suposto resolver...

R: Não: isso mostra, mas não prova! O que queremos provar é que f=g, sendo ambas catamorfismos. Logo podemos usar a lei-universal aplicada a f ou g, à nossa escolha, por exemplo

g = ([ i,i ])
<=> { Universal-cata }
g.in = [i, i] . (id + g)
<=> { função constante i, fusão-+ etc, isomorfismo in/out }
g= i .[ id , g] . out
<=> { função constante i }
g = i

Agora basta verificar se i = f, pelo mesmo processo.


Q10 - Faço o que diz o enunciado para instalar 'lhs2tex', cabal install lhs2tex, corre tudo bem, mas continuo sem ´lhs2tex', e.g. lhs2tex cp1718t.lhs > cp1718t.tex dá erro. (Isto em MAC OS.)

R: Se tudo correu bem na instalação, deverá existir o ficheiro executável Library/Haskell/bin/lhs2tex. O que está a faltar é o "link" para esse ficheiro. Uma maneira simples de o fazer é definir, na shell,

alias lhs2tex='/Users/user/Library/Haskell/bin/lhs2tex'

onde user é o nome do utilizador. Para não terem que fazer isso sempre, acrescentem essa linha ao ficheiro .bashrc, que já deve existir na directoria principal de user. (Este ficheiro é executado sempre que criam uma shell ou abrem um terminal.)


Q11 - Estou sem conseguir resolver a questão 8 do teste de 2011/12: definir um anamorfismo de naturais como um catamorfismo de listas. Tentei usar a lei universal-ana(44) mas fiquei bloqueado a meio.

R: Sim, universal-ana (naturais) é bom começo (expandindo out = [nil,cons]º ):

f = [( (id+p2). [nil,cons]º )]

== { universal-ana (naturais); álgebra in dos naturais é [0,succ] }

f = in. (id + f ) . (id+p2). [nil,cons]º

== { passando isomorfismo [nil,cons]º para o outro lado, "trocando o sinal" }

f . [nil,cons] = in. (id + f ) . (id+p2)

Aqui começa a preparação das coisas para se obter f como catamorfismo de listas. A dificuldade desta questão é que começa com um anamorfismo de naturais (F f = id + f) e termina com um catamorfismo de listas (F f = id + id x f). A mudança de F dá-se a partir do ponto em que se parou acima. Como sempre, as propriedades naturais não se devem ignorar, neste caso a do p2: f.p2 = p2.(g><f). Continuando:

f . [nil,cons] = in. (id + f.p2)

== { f.p2 = p2.(id><f) , cf. natural-p2 }

f . [nil,cons] = in. (id + p2.(id><f))

== { natural-id; functor-+ }

f . [nil,cons] = in. (id + p2) .(id + id><f))

== { universal-cata }

f = (| in. (id + p2) |)


Q12 - Estou a tentar resolver a questão 6 do teste de 17 de Junho de 2013: fiz os diagramas de cada catamorfismo e chego às definições das funções com variáveis através da lei universal-cata e consigo perceber que realmente fazem a mesma coisa, mas não sei se era assim que era suposto resolver...

R: Não, isso mostra... mas não prova! O que queremos provar é que f=g, sendo ambas catamorfismos. Logo podemos usar a lei-universal aplicada a f ou g, à nossa escolha, por exemplo

f = ([ (const k), id ])
<=> { Universal-cata }
f.in = [(const k), id] . (id + f)
<=> { simplificação }
f.in = [(const k), f]
<=> { cancelamento-cata (f) }
[const k, const k].(id+f) = [(const k), f]
<=> { simplificação seguida de eq-(+) etc }
f = const k

Agora basta verificar se const k = g, pelo mesmo processo.


Q13 - Gostaria de perceber melhor a razão para haver uma notação funcional com variáveis ("pointfree") e outra sem elas ("pointwise") e qual se deve escolher e em que circunstâncias.

Sem variáveis os programas ficam reduzidos a expressões algébricas sobre as quais se pode raciocinar usando o Cálculo de Programas. Após os cálculos (eg. conversão da função de Fibonacci - recursiva e ineficiente -- num ciclo -- não recursivo, eficiente) converte-se o resultado final de novo para Haskell com variáveis e... "entrega-se ao cliente". Se tentar fazer o mesmo sempre com variáveis os cálculos terão que usar provas por indução matemática e serão mais longos e (para muitos) difíceis de perceber.


Q14 - Tentei resolver o exercicio 6 do exame de 2012 mas não chego ao resultado que era pretendido. De tri f = (| in . B(id,T f) |) inferi, por cancelamento-cata, (tri f) . in = in . B(id,T f) . F(tri f). Sabendo que B(id,T f) = id + id >< T f e F (tri f) = id + id >< tri f (listas) chego a [tri f . nil, tri f . cons] = [nil, cons . (T f x tri f) ] de onde não consigo chegar ao código Haskell dado.

R: O engano está no cálculo da composição

B(id,T f) . F (tri f)
que deverá dar
id + id >< (T f . (tri f))
e não
id + (T f) >< (tri f)
Resolvido este engano, deverá ser imediato.


Q15 - Como mostro a igualdade entre (f . id) x (g + id).i1 e f x (g + id) . ( id x i1)?

R: O problema é a falta de uns parênteses: para f x (g + id) . ( id x i1) tipar bem é preciso colocar parênteses à esquerda da composição: (f x (g + id)) . ( id x i1). Depois é só aplicar a lei functor-x. NB: na nossa notação a composição tem prioridade sobre qualquer outro combinador.


Q16 - Gostaria de saber se a função (A x C + B x D) -- [pi2,pi2] --> C + D está bem tipada.

R: Para estar era preciso que as duas instâncias de pi2 tivessem o mesmo tipo de saída. Ora isso não acontece: tem-se A x C -- pi2 --> C num caso e B x D -- pi2 --> D no outro, ambos diferentes de C + D. Isto explica o que se deve fazer: escrever pi2 + pi2 em vez de [pi2,pi2].


Q17 - Gostaria de saber se a função auxJoin do problema 4 do TP faz parte da valorização, uma vez que esta não se encontra no enunciado do trabalho. Aproveito ainda para perguntar o que é suposto essa função fazer.

R: auxJoin é uma função auxiliar da função rm. O funcionamento da primeira é determinado pelo seu tipo: dada uma lista de valores do tipo A x (B + C) e um valor do tipo D, a função emparelha esse valor com todos os valores na lista cujo elemento à direita é do tipo C. A função auxJoin facilita a navegação por um sistema de ficheiros com base num caminho (análogo ao comando 'cd'), e neste sentido ajuda-nos a dividir o comando rm em dois passos: (1) navegar até à directoria alvo; (2) remover os ficheiros desejados nessa directoria.


Q18 - O enunciado diz: 'O objectivo final deste exercício é implementar então uma função mostra_caixas :: (L2D,Origem) -> IO ()'. Contudo, no anexo D, não aparece mostra caixas mas sim caixasAndOrigin2Pict. Temos que definir mostra_caixas?

R: Exacto, é preciso implementar no anexo D a função mostra_caixas. A função caixasAndOrigin2Pict (ver descrição na FAQ Q7) servirá como função auxiliar a esta.


Q19 - Quando corro pdflatex cp1819t aparece o erro File 'xy.sty' not found. Como se resolve este problema?

R: Essa package do LaTeX, que é usada para desenhar diagramas, obtém-se instalando https://ctan.org/pkg/xypic.


Q20 - Ao tentar resolver a questão 5 da ficha 5 obtenho fac . in = [one,mul] . F <succ,fac>, para F f = id + f. Como é que isto me ajuda a responder à questão colocada?

R: O facto de obter F <succ,fac> e não F fac diz-lhe que o factorial não é (directamente) um catamorfismo de naturais. Mais ainda: se relacionar isto com a questão 4 da ficha 7, o que acontece é que fac está em recursividade mútua com succ (etc, etc).


Q21 - Quando escrevo, dentro de um bloco code, 'x^2' e corro o comando para gerar o pdf, o dito 'x ao quadrado' não aparece, mas sim uma seta entre o 'x' e o '2'. Há alguma forma de resolver isto?

R: A seta entre a base e o expoente é uma decisão do próprio lhs2tex, que podia ser revista. Mas uma forma simples de resolver o assunto sem se ter o trabalho de alterar o lhs2tex é a seguinte: (a) define-se

expn a b = a^b

(b) acrescenta-se, logo no início do anexo onde estão a compilar as soluções, a regra de formatação

%format (expn (a) (n)) = "{" a "}^{" n "}"

(c) Usa-se 'expn x 2' onde se usaria 'x^2', etc etc.


Q22 - Será possível serem mais específicos sobre o que "a função, _calc :: Tipo -> Origem -> (Float, Float) -> Origem, determina onde colocar a caixa b)" quer dizer, na resposta à Q7 acima?

R: O princípio base é que a origem de um rectangulo corresponde ao seu canto inferior esquerdo: a partir disto, dados dois rectangulos (a,b),

Ht -> corresponde a posicionar a origem de b no canto superior direito de a;

Hb -> corresponde a posicionar a origem de b no canto inferior direito de a;

H -> corresponde a posicionar a origem de b a meio do lado direito de a;

Faz-se depois um exercício análogo para V*.


Q23 - Na questão 4-3) quando se diz “usando obrigatoriamente catamorfismos, anamorfismos ou hilomorfismos”, estes são sobre o tipo FS, ou podem ser, por exemplo, sobre listas?

R: Não têm que ser só sobre o tipo FS, mas notem que em algumas das alíneas faz mais sentido serem sobre o tipo FS.


Q24 - Quando abro o ghci (MAC OS) e corro ex1Caixas obtenho um erro: ghc[5174:12563511] GLUT Fatal Error: internal error: NSInternalInconsistencyException, reason: nextEventMatchingMask should only be called from the Main Thread! O que quer isto dizer?

R: Esse problema é conhecido. Resolve-se usando uma flag: ghci -fno-ghci-sandbox cp1819t. Para quem quiser saber mais, ver 1.6.1. Highlights.


Q25 - Quando tenho fazer diagramas como é indicado no enunciado, aparece-me tudo desformatado, com eg. '@C=2cm' no PDF. Como resolvo este problema?

R: O caracter '@' é um dos caracteres reservados do lhs2tex. Devem duplicá-lo por forma a ele ser preservado e passado para o LaTeX. Assim, escrevam '@@C=2cm' e não '@C=2cm' para que a instrução seja passada intacta para o LaTeX. (Não esquecer que o lhs2tex é um pré-processador.)


A quem possa interessar tinynew.gif

De 22 a 26 de Julho vai decorrer na UMinho o Verão no Campus. Se alguém estiver disponível ou interessado em apoiar como monitor o módulo (Haskell) da actividade Computação Sem Fronteiras pf diga-me (JNO).

Em dia e meio ensina-se Haskell a alunos do 10º,11º,12º anos usando problemas interessantes, relacionados com as matérias das disciplinas de Física e Matemética. Por exemplo:

- Como escrever da forma mais simples um programa em Haskell que faça a seguinte simulação do voo de regresso à terra da malograda nave Apolo XIII da NASA, em Julho de 1970?