| Contato: | thanos@imd.ufrn.br |
| Playlist: | IRI |
| Monitoria/TA: | fmc.imd.ufrn.br |
| Turmas self: | ../ |
| Turmas FMC1: | /teaching/fmc1 |
Info
Pré-requisitos
O IntroProof.
Além disso, é necessário que tu tens tempo e vontade para estudar, fazer os trabalhos atribuídos, etc.
(Obs.: estudar ≠ ler.)
Conteúdo
(Baseado no módulo correspondentes desta proposta.)
Os naturais e o tipo Nat; seus construtores (zero, sucessor) e sua teoria: implementação recursiva das suas principais operações, e verificação indutiva das suas principais propriedades. O tipo dos booleanos, Bool. Ordens sobre os naturais: especificação e verificação de suas propriedades. Outras funções e relações, e suas propriedades. Indução como princípio e técnica de demonstração em matemática. A unicidade dos naturais (a menos de isomorfismo). List Nat e List α: tipos de dados de listas: implementação recursiva e verificação indutiva de suas principais propriedades. Outros tipos de dados recursivos: tipos de árvores; tipos de expressões aritméticas; tipos de fórmulas; termos de cálculo-λ. Numerais binários, definição de semântica e seu uso para verificação de corretude.
Objetivos de aprendizagem
Neste módulo estudamos como definir tipos de dados, funções, e relações recursivamente, e como demonstrar propriedades sobre tais coleções de dados por indução.
Prática com o uso da linguagem matemática e das principais técnicas de demonstração e refutação. Prática com a escrita de definições por recursão e demonstrações por indução. Recursão e indução estrutural sobre tipos de dados recursivos. Apreciação de coleções potencialmente infinitas do ponto de vista implementacional, recursivo, e verificação matemática de suas propriedades de interesse. Casamento de padrões e seu uso em definições, demonstrações, e cálculos. Recursão mútua, indução aninhada. Ganhar familiaridade com inferência de tipos e evitar erros de tipagem. Notação e nomenclatura matemática e computacional. Apreciar a diferença e a conexão entre sintaxe e semântica.
Bibliografia e referências
Conhece o libgen?
Principal
- Eu: Matemática fundacional para computação [fmcbook] (Capítulo 4)
Auxiliar
- Bird & Wadler (1986): Introduction to Functional Programming (Cap. 1,2,3,5,9)
- Mendelson (1973): Number Systems and the Foundations of Analysis (Cap. 2)
- Avigad, Lewis, van Doorn (2017): Logic and Proof (Cap. 17)
- Avigad, de Moura, and Soonho Kong (2017): Theorem proving in Lean (Cap: 7,8)
- Steffen, Rüthing, Huth (2018): Mathematical Foundations of Advanced Informatics, vol 1 (Cap: 4, 5)
- Hutton (2016): Programming in Haskell, 2nd ed.
- Pierce et al.: Software Foundations, Vol 1 (Cap: Basics, Induction, Lists)
- Fejer, Simovici (1991): Mathematical Foundations of Computer Science, Vol 1 (Cap. 4)
Para cada um dos assuntos que tratamos, procure também a secção «Leitura complementar» no capítulo correspondente do fmcbook para mais referências.
Dicas
- James Munkres: Comments on style
- Jean-Pierre Serre: How to write mathematics badly
- Don Knuth: Mathematical writing
- Paul Halmos: How to write mathematics
- Por que tantos livros? Qual é o melhor? Vale a pena ler esse excerto do livro Linear Algebra de Jänich.
Links
- NNG (Offline? Tente esse mirror também.)
- Lean & Lean web editor
- Haskell
- Minicurso TeX 2018.2
- Detexify
- Minicurso Unix 2019.2
- The Missing Semester of your CS Education
- Overleaf online (La)TeX editor/compilador
Tecnologias & ferramentas
Obs.: (Instalem e/ou criem uma conta para usar onde necessário.)
- PAPEL (um caderno para dedicar à disciplina) e LAPIS/CANETA.
- Zulip (leia o FAQ).
- O proof assistant Lean para algumas atividades (leia o FAQ).
- A linguagem de programação funcional Haskell para algumas atividades.
- Git (leia o FAQ).
- Muito recomendado mas não necessário: um sistema Unix (veja o minicurso Unix 2019.2).
- Muito recomendado mas não necessário: (neo)vim e Emacs.
- Pouco de (La)TeX (veja o minicurso TeX 2018.2). Online editor/compilador: Overleaf.
A parte IRI será auxiliada usando a linguagem de programação funcional Haskell e o proof assistant Lean. Usando uma linguagem de programação funcional é imediato implementar todas as suas definições para rodá-las no computador. Usando um proof assistant, formalizamos tanto as definições recursivas, quanto as demonstrações indutivas usando a mesma linguagem. (Mas o foco continua sendo o papel; não o computador!)
FAQs
Dynamic content
Provas
- Prova 2.1 de FMC1 de 2022.2 { censored , uncensored , answers , correções }
- Prova 2.2 de FMC1 de 2022.2 (NNG)
- Prova 2.3 de FMC1 de 2022.2 { censored , uncensored , answers , correções , quadro }
Sessões
Leia bem o FAQ sobre hw. Note também que:
- Homeworks são atribuidos também durante as aulas e no Zulip.
- Homeworks marcados assim são auxiliares; tente apenas se tu tem resolvido uma parte satisfatória dos outros.
IRI (1) [video]
- introdução
- um resumo da abordagem (axiomática) que usamos em IDMa
- especificação vs implementação; implementação-agnóstico
- a abordagem desta disciplina (IRI): mais contrastes de abordagem
- algebraic data types
- o tipo Nat: espectativas e 4 maneiras de definir um tipo de dados recursivamente
- sintaxe: o que queremos descrever
- o desafio dos «…» numa definição
- exemplo de chefe de programação sem noção comunicando pedido
- Naturais vs Nats; Números vs Numerais
- Linguagem vs Metalinguagem; Variáveis vs Metavariáveis
- «Nada mais»
- Regras de inferência e lida de cima para baixo e de baixo para cima
- Como mostrar que algo é um Nat
- arvores de inferência, folhas abertas e fechadas; regras e comandos
- casamento de padrão com expressão: primeiro encontro
- gramáticas e a notação BNF: nada demais!
- Mal entendido: «os inteiros que a gente conheceu»—Nope.
- Mal entendido: «uns inteiros são naturais»—Nope.
- type casting
- a aplicação duma função no seu argumento, e a inferncia de tipo relevante
- Tem como implementar os inteiros usando os naturais, e mais uns teasers
- Regras e arvores de inferência, comandos vs proposições
- Um exemplo de inferência: SSSO : Nat
- Definição recursiva vs tijolo
- um exemplo: fact : Nat → Nat
- Como traduzir uma linha sem premissas para código
hw
- Jogue o NNG. Tente completar o mais rápido possivel; sua entregá é a Prova 2.2. Veja o FAQ relevante também.
IRI (2) [video]
- ocorrências livres e ligadas de variáveis
- construtor vs função
- uns açúcares sintácticos
- uns preconceitos sobre funções e sua notação
- ocorrências ligadas e livres de variáveis
double : Nat → Nat;id : Nat → Nat- padrões de argumentos
- o presente da recursão
- Como calcular (modelo computacional)
- double 2 = ?
- valores canônicos
- casamento de padrões
- Duas maneiras de escrever cálculos
- A adiçaõ: (+)
- prefix, postfix, infix, mixfix
- Um cálculo e teorema: 2 + 3 ≟ 5
- Arvore sintáctica (Abstract Syntax Tree), parsing, (veja também: lexer)
- Precedência sintáctica
- Associatividade sintáctica
- Associatividade vs associatividade sintáctica: axiomas e especificação vs implementação
- Currificação
- como definir o
addFivenível boss - Aplicação parcial
hw
- Calcule os:
double (double (S O))double ((S O) + (S (S O)))
- Defina multiplicação e exponenciação.
- Olhando para as funçoẽs binárias e famosas que temos até agora (adição, multiplicação, exponenciação), perceba que tem um “padrão”. Use isso para definir a “próxima” operação. Denote por ⇈.
- Defina a função
Pd : Nat → Natde “predecessor”, onde consideramos que o predecessor de zero é o próprio zero mesmo: AVISO: a maioria das vezes que um aluno de 2022.1 usou aPdem outras definições, estava errando - Defina a função
∸ : Nat → Nat → Natque comporta como subtração, mas caso que o resultado era pra ser negativo, retorna O mesmo. - Defina as funções:
fact : Nat → Natfib : Nat → Natdist : Nat → Nat → Natmin : Nat → Nat → Natmax : Nat → Nat → Natdiv : Nat × Nat → Nat × Natquot : Nat × Nat → Natrem : Nat × Nat → Natgcd : Nat × Nat → Natlcm : Nat × Nat → Natcomb : Nat → Nat → Natperm : Nat → Nat → Nat
IRI (3,4) [video]
- construtor vs função
- D: multiplicação
- o uso de lemmas: m-idR, e-idR
- uma demonstração simples: (·)-idR
- ∀: como usar
- ∀: como atacar
- qual resultado incompleto é melhor?
- lazy vs strict
- estratégia de evaluação vs precedência de operador
- notação de aplicação de função por espaço:
f x - acordos sintácticos sobre a aplicação-de-função: precedência, associatividade sintáctica à esquerda:
f x y z ≡ ((f x) y) z, e os seus porquês - Θ. Associatividade da
(+) - A disjunção escondida em cada Nat.
- ∃: como usar
- ∨: como usar
- tem como continuar a demonstração?
- escolhendo variáveis com «linhas»: x’, x’’, etc.
- igualdade entre Nats
- o problema que temos demonstrando esse teorema
hw
- (i) instale a Haskell no teu computador; (ii) Completa o getting started e o first steps do ghcup; (iii) configure teu editor (sendo ou um editor que presta (emacs ou neovim), ou o VS Code) para integrar com Haskell. Dúvidas nos
#programminge#tech, obviamente! - Implementa o
Natnum módulo Haskell, junto com todas as funções que definimos até agora, incluindo os hw. Comece teu arquivo assim:module Nat where data Nat = O | S Nat deriving ( Eq , Show )
IRI (5): Nat [video]
- dois princípios sobre os construtores e os valores construidos
- escolhendo o padrão na direita duma equação para substituir na direção (←)
- o problema que temos demonstrando a (+)-associatividade
- A regra de inferência Ind-φ. (Onde φ : Nat → Prop.)
- Demonstração por indução
- A associatividade da (+): umas demonstrações por indução diferentes.
- Análise das duas melhores demonstrações da (+)-associatividade: legalzinho vs legalzão
- Inventar teoremas-propriedades sobre nossos programas
hw
- Resolva tudo na §«Demonstrando propriedades de naturais com indução»
- Asserte propriedades sobre teus programas do hw do IRI (2), e demonstre cada uma delas!
- Enuncie e demonstre que quaisquer fibonaccis consecutivos são coprimos.
IRI (6,7): Nat, Bool [video]
- currificação: versão currificada vs descurrificada da mesma função
- associatividade sintáctica
- inferência de tipo de aplicação de função
- conexão com uso de implicação; propositions-as-types
- prerequisito para perguntar sobre igualdade: mesmos tipos!
- Como implementar o tipo
Bool(e suas operações) em termos deNat: problemas - pra quem esse return 0 está retornando tal 0 nas mains dos programas?
- os booleanos precisam suas operações também
- booleanos em python e type casting
- a diferença entre a parte (e tipagem) estática e a parte (e tipagem) dinâmica
- type sistem e checagem de tipo vs evaluação de expressão para achar um valar
- O tipo
Bool(de verdade) - Ordem: (≤) vs leq: mundo-objeto e mundo-meta
- corretude (soundness & completeness) de programas
(≤) : Nat → Nat → Propleq : Nat → Nat → Bool- Relações vs funções-com-codomínio-Bool
- Como representar predicados sobre os naturais (Nat → Prop, Nat→Nat→Prop, etc.) como se fossem funções que retornam
Bool. - A corretude da
leq - internalização de conceito
- O uso de underscore nos padrões
- uma convenção sobre a ordem de equações numa definição recursiva
- Sobre funções parciais vs totais
- side effects (efeitos colaterais) e funções puras
- Type inference; como/quando aproveitar a inferência de tipos
- even e odd (pares e impares): como internalizar e como demonstrar corretude
ev, od : Nat → Bool- treis maneiras diferentes de definir: precisando 3 equações; precisando o not; com recursão mútua
- recursão mútua
- backticks para notação infixa
- Como usar o underscore (_) como «variável sem nome» num padrão.
hw
- Defina e demonstre a corretude das funções:
leq : Nat → Nat → Boolev : Nat → Boolod : Nat → BoolisMul₃ : Nat → Booldivides : Nat → Nat → Boolcongmod : ?isZero : Nat → Bool
- Demonstre que a
(≤) : Nat → Nat → Propé: reflexiva; transitiva; antissimétrica; total - Demonstre que todo Nat é par ou ímpar.
- Defina os operadores booleanos.
- Como definarias uma função
if_then_else_ : Bool → Nat → Nat → Nat? - Demonstre a corretude das funções definidas no hw do IRI (2).
- O lemma de divisão de Euclides para os Nats:
- enuncie
- demonstre
Prova 2.2
Complete o NNG.
IRI (8): Nat, Bool, Weekday, Unit, Empty, ListNat [video]
- Type synonym
- Desafio: Int parzinhos-de-Nats, vetores-de-Nats
- isBool : Nat → “Bool”
- O que acontece em linguagem que autoafirmam ter «tipos dinâmicos»
- Corretude de definição de função (programa): correção e completude
- Mais tipos de dados simples:
Weekday - O tipo
Unitcom seu único habitánte/construtor:⋆ : Unit - Quem é mesmo esse
void? - Indução do Nat e quando não usar
- Q: faz sentido adicionar como açúcar sintáctico para o lem n m assumir papel de Prop? A: Não.
- Como implementar listas:
ListNat - Os construtores
Empty(ouNil) eCons - ListNat: sintaxe, açúcar e associatividade sintáctica
- Como escolher a ordem dos argumentos: aplicação parcial e currificação
- ListNat é um tipo recursivo
- Como representar a lista [2,0,8] com nosso tipo
- definindo a
length : ListNat → Nat - Calculando o
length [3,2,0] - Plicker: quantos construtores preciso para definir o tipo Int?
hw
- Implemente como Nats:
- os inteiros (já sabes a sua especificação pelo IDMa!)
- os parzinhos-de-Nats
- os vetores-de-Nats como Nat
- Implemente como novo tipos, tendo já definido o Nat:
- os inteiros
- os parzinhos-de-Nats
- os vetores-de-Nats como Nat
- Defina as:
length : ListNat → Natelem : Nat → ListNat → Boolsum : ListNat → Natproduct : ListNat → Nat(++) : ListNat → ListNat → ListNatreverse : ListNat → ListNatmin : Nat → Nat → Natmax : Nat → Nat → NatallEven : ListNat → BoolanyEven : ListNat → BoolallOdd : ListNat → BoolanyOdd : ListNat → BoolallZero : ListNat → BoolanyZero : ListNat → BooladdNat : Nat → ListNat → ListNatmultNat : Nat → ListNat → ListNatexpNat : Nat → ListNat → ListNatenumFromTo : Nat → Nat → ListNatenumTo : Nat → ListNattake : Nat → ListNat → ListNatdrop : Nat → ListNat → ListNatelemIndices : Nat → ListNat → ListNatpwAdd : ListNat → ListNat → ListNatpwMult : ListNat → ListNat → ListNatisSorted : ListNat → BoolfilterEven : ListNat → ListNatfilterOdd : ListNat → ListNatminimum : ListNat ⇀ Natmaximum : ListNat ⇀ NatisPrefixOf : ListNat → ListNat → Boolmix : ListNat → ListNat → ListNatintersperse : Nat → ListNat → ListNat
- Defina as:
head : ListNat → Nattail : ListNat → ListNatinit : ListNat → ListNatlast : ListNat → Nat
- Defina a
(<) : Nat → Nat → Prope sua internalização, e demonstre a sua corretude.
IRI (9): Nat, Bool, Unit, Empty, ListNat [video]
- Definições de
sum : ListNat → Nateproduct : ListNat → Nat- como escolher o valor certo para o
sum []e oproduct []
- como escolher o valor certo para o
reverse,append, e concatenação binária(⧺)- parenteses e convenções sintácticas do ␣
- mal-entendido entre função currificada-vs-descurrificada e notação infixa-vs-prefixa
- aplicação parcial e um cálculo relacionado
- «redex»
- a notação de “sections” de operadores binários
- um problema com as
headetail - um teaser sobre a soma de tipos
- Construtores vs Destrutores
- Corretude de programas sobre ListNat: propriedades que gostariamos de demonstrar
- Tentativa de demonstrar uma delas
- Como chegar aos principios de indução para os outros tipos
- O conceito de «respeitar/preservar uma propriedade».
- Do $\mathrm{Ind}^{\mathsf{Nat}}_{\varphi}$ para o $\mathrm{Ind}^{\mathsf{ListNat}}_{\varphi}$.
- Indução do
Bool - Indução do
Unit - Indução do
Empty - Indução do
ListNat
- Indução do
- Como interpretar a indução e suas várias versões dos inteiros agora
- Uma maneira de pensar sobre indução: como separação-em-casos-com-extras
- Conexão entre recursão e indução
- Definição por recursão vs Demonstração por indução
- O presente de recursão vs o presente da indução
- Quantos quantificadores e por quê?
- Quantos destrutores e por quê?
hw
- Demonstre os teoremas (escolhe algo interessante para botar nos
??)(∀xs,ys:ListNat) [ sum (xs ++ ys) = ?? ](∀xs,ys:ListNat) [ product (xs ++ ys) = ?? ](∀ℓ:ListNat) [ length (filterEven ℓ ++ filterOdd ℓ) = ?? ](∀ℓ:ListNat) [ reverse (filterEven ℓ) = ?? ](∀n:Nat)(∀ℓ:ListNat) [ length (addNat n ℓ) = ?? ](∀n:Nat)(∀ℓ:ListNat) [ sum (addNat n ℓ) = ?? ](∀n:Nat)(∀ℓ:ListNat) [ sum (multNat n ℓ) = ?? ](∀n:Nat)(∀ℓ:ListNat) [ product (multNat n ℓ) = ?? ](∀n:Nat)(∀ℓ:ListNat) [ product (expNat n ℓ) = ?? ](∀n:Nat)(∀ℓ:ListNat) [ isSorted (addNat n ℓ) = ?? ](∀ℓ:ListNat) [ isEven (product ℓ) = anyEven ℓ ](∀ℓ:ListNat) [ isEven (sum ℓ) = isEven (length (filterOdd ℓ)) ](∀ℓ:ListNat) [ isZero (sum ℓ) = ?? ](∀ℓ:ListNat) [ isZero (product ℓ) = ?? ](∀n,m:Nat)(∀ℓ:List Nat) [ addNat (n + m) ℓ = ?? ](∀n,m:Nat)(∀ℓ:List Nat) [ multNat (n · m) ℓ = ?? ]
- Demonstre também:
(∀xs,ys:ListNat) [ length (xs ++ ys) = ?? ](∀xs,ys:ListNat) [ reverse (xs ++ ys) = ?? ](∀n:Nat)(∀xs,ys:ListNat)[ addNat n (xs ++ ys) = ?? ](∀ℓ:ListNat) [ reverse (reverse ℓ) = ?? ](∀ℓ:ListNat) [ length (reverse ℓ) = ?? ]- Associatividade da
(++) []é uma(++)-identidade
- Pense em mais propriedades, enuncie, e demonstre!
- (INTRO) Demonstre ou refute as leis seguintes (cada uma tem duas proposições independentes para investigar, e para cada uma tome o cuidado seguinte: se precisar saber que o tipo A é habitado, veja se e como isso afeta a tua resposta):
- (∀x:A)[φ ⇒ ψ(x)] ⇐≟⇒ φ ⇒ (∀x:A)[ψ(x)]
- (∀x:A)[φ(x) ⇒ ψ] ⇐≟⇒ (∀x:A)[φ(x)] ⇒ ψ
- (∃x:A)[φ ⇒ ψ(x)] ⇐≟⇒ φ ⇒ (∃x:A)[ψ(x)]
- (∃x:A)[φ(x) ⇒ ψ] ⇐≟⇒ (∃x:A)[φ(x)] ⇒ ψ
Prova 2.1 (IRI)
IRI (10a) [video]
- Polimorfismo de tipos, e o type constructor
List : Type → Type - Construtores de tipos (type constructors) vs Construtores de valores (data constructors)
- type variables vs data variables
- polimorfismo: de
lengthNat : List Nat → Natparalength : List α → Nat
hw
- Generalize todas as funções dos hw 2022-11-04 e 2022-10-31 que envolvem
ListNatpara funções que envolvemList αou, se não for possível,List Nat. - Defina as:
concat : List (List α) → List αifthenelse : Bool → α → α → αand : List Bool → Boolor : List Bool → BoolsplitAt : Nat → List α → (List α × List a)zip : List α → List β → List (α × β)unzip : List (α × β) → (List α × List β)
- Defina um tipo para conseguir uma resolução no problema de querer listas cujos membros podem ser
NatouBool. - Defina um tipo cujos habitantes serão usados para representar listas que garantam:
- ter tamanho ≥ 1 (
IList) - ter tamanho par (
EList) - ter tamanho ímpar (
OList)
- ter tamanho ≥ 1 (
mais hw
- URGENTE! Continua (ou começa, pelamor de Curry) o hw do IRI (3,4), para incluir as funções que envolvem listas. O arquivo poderia começar assim:
{-# LANGUAGE GADTs, EmptyDataDecls #-} module IRI where data Nat where O :: Nat S :: Nat -> Nat deriving (Eq, Show) data Unit where Star :: Unit data Empty data List a where Nil :: List a Cons :: a -> List a -> List a deriving (Eq, Show)
IRI (10b, 11) [video]
- polimorfismo: função(ões)
id - o tipo de
bottom - Nats bottomosos (⊥, nats parciais, o nat infinito)
- mais um tira-gosto/teaser da idéia de propositions-as-types
- funções de ordem superior (higher-order functions)
- como agir se precisar numa lista ter naturais e booleanos: NatOrBool
- abstração de ordem superior: de
addNat : Nat → List Nat → List NatparamapNat : (Nat → Nat) → List Nat → List Nat - abstração de ordem superior: de
mapNat : (Nat → Nat) → List Nat → List Natparamap : (α → β) → List α → List β - a função map:
map : (α → β) → List α → List β - a função filter: a
filter : (α → Bool) → List α → List α - novas implementações das funções antigas
- Do $\mathrm{Ind}^{\mathtt{ListNat}}_{\varphi}$ para o $\mathrm{Ind}^{\mathtt{List~α}}_{\varphi}$.
- o
Maybe : Type → Type - comparação dos tipos
Maybe (List α)eList (Maybe α) - Idéia ruim: usar um valor arbitrário para o
head [] - as versões não-gambiarrosas de
headetail - Resolução legal:
safeHead : List α → Maybe α - Resolução legal:
safeTail : List α → Maybe (List α) - desafio: como generalizar as sum, product, concat
- por que não podemos tipar a sum com List α → α?
- Uma find melhor que as gambiarras C’osas:
findFirst : α → List α → Maybe α
hw
- Gambiarra 1:
safeHead : ListNat → ListNat - Gambiarra 2:
safeHead : ListNat → Bool × Nat - Gambiarra 3:
defaultHead : Nat → ListNat → Nat
mais hw
- Defina as:
replicate : Nat → α → List αmap : (α → β) → List α → List βfilter : (α → Bool) → List α → List α- a generalização
alldas:allZero,allEven,allOdd - a generalização
anydas:anyZero,anyEven,anyOdd - a generalização
pointwisedas:pwAdd,pwMult - a generalização
folddas:sum,product,and,or,concat - simplifique as definições antigas para aproveitar essas funções poderosas
takeWhile : (α → Bool) → List α → List αdropWhile : (α → Bool) → List α → List αhead : List α → Maybe αtail : List α → Maybe (List α)init : List α → Maybe (List α)last : List α → Maybe αpick : Nat → List α → Maybe αfindFirst : α → List α → Maybe Natfind : α → List α → List Natcurry : ?uncurry : ?flip : ?
- Qual seria uma melhor tipágem para a
pw : (α → α → α) → List α → List α → List α?
mais hw
- Descubra o
foldNat: defina e mostre um uso dele
IRI (12,13) [video]
- os destrutores são, em geral, parciais; versões seguras
- de
NatOrBoolparaEither α β - Produto de tipos: α × β
- Soma de tipos (coproduto): α + β
- O que usar para representar erros em vez de gambiarras tipo Strings e Números
- pw (zipWith, zip; veja sobre zipping)
- findFirst: primeira tentativa
- uma idéia sobre como resolver nosso problema:
(⟨$⟩)/fmap - uma outra idéia sobre como resolver nosso problema: pattern matching: match-expression
- de volta para a primeira idéia: fmap e Functors
- Functors, fmap, deriving ( Functor )
- Leis de Functor
- Abuso de List α para assumir papel de Maybe α
- Duas interpretações computacionais dos habitantes de List α
- Functorialidade do Either ε
- Composição de funções: (∘)
- programação tácita: point-free, point-less, …
- Como implementar os Ints usando Nats: igualdade
- Teaser sobre arvores
hw
- Demonstre a associatividade da
(∘) - Defina tipos para cada um estilo de árvore que tu já viu ou imaginou
- Formulize os correspondentes princípios/regras de indução para cada um deles
- Mostre como cada um deles pode virar um Functors
- Demonstre as leis de Functor para o
List : Type → Typecom omapque definimos:map id = id [functor law 1] map (f . g) = map f . map g [functor law 2] - Demonstre:
(∀f:α→β)(∀p:β→Bool) [ filter p ∘ map f = map f ∘ filter (p ∘ f) ] - Adivinha um lado direito certo e interessante, e demonstre:
take n xs ++ drop n xs = take m . take n = take m . drop n = drop m . take n = drop m . drop n = map g . map f = sum . map double = sum . map sum = sum . sort = map f . reverse = concat . map concat = filter p . map f = length . reverse = reverse . reverse = - Quais das seguintes são válidas e quais não?
map f . take n =?= take n . map f map f . reverse =?= reverse .map f map f . sort =?= sort . map f reverse . concat =?= concat . reverse . map reverse filter p . concat =?= concat . map (filter p) - Demonstre:
xs ++ (ys ++ zs) = (xs ++ ys) ++ zs [associatividade da (++)] length (xs ++ ys) = length xs + length ys filter p (xs ++ ys) = filter p xs ++ filter p ys map f (xs ++ ys) = map f xs ++ map f ys - Demonstre:
sum (xs ++ ys) = sum xs + sum ys product (xs ++ ys) = product xs * product ys concat (xss ++ yss) = concat xss ++ concat yss - Podemos definir uma generalização da
pw : (α → β → γ) → (F α → F β → F γ)sabendo apenas que oFpossui umfmapcom qual ele se torna um Functor? - Implemente os racionais!
mais hw
- Na última aula percebemos que
Eithernão tinha sequer chances de se candidatar para virar um Functor, poisEithernão é umType → Type(mas sim umType → Type → Type. Mesmo assim, conseguimos verificar que aplicando parcialmente oEithernum tipoεsó, chegamos mesmo noEither εque é mesmo umType → Type, e logo tem chances de ser um Functor, e descubrimos qual seria afmapcerta pra isso (demonstre se não demonstrou—o que é pra demonstrar mesmo??). Aqui mais duas coisinhas que estão tambémType → Type → Type: o próprio(→)e o(×). Investigue para cada um deles, e para cada aplicação parcial dele, se pode ser munida com umfmappara conseguir ser um Functor:(δ →) : Type → Type(→ γ) : Type → Type(α ×) : Type → Type(× β) : Type → Type
IRI (14) [video]
- corretude: estipular e demonstrar propriedades dos nossos programas
- e sobre igualdade intensional entre funções
- uns tipos de arvores
- a map das listas e outras fmaps e as leis de Functor
- maneiras de escrever uso de indução é os detalhes possivelmente enganadores e implícitos
- a List com o map é um Functor: demonstração da 2a lei
- demonstração: a segunda lei de Functor para a map de List α
- Composição de Functors
- a propaganda mentirosa de «tipos dinâmicos» e a verdade decepcionante
- como funcionam linguagens de “tipos dinâmicos” e runtime errors
hw
- Prática para indução nos naturais: resolva o [Problem Set 2 de 2021.2][ps2-2021.2].
- Na aula de IDMb definimos uma
(·) : Real × Seq(Real) → Seq(Real)em duas formas: implemente ambas em Haskell e demonstre a sua equivalência.
IRI (15,16) [video]
- Eficiência “por algebra”
- Eficiência “por indução”
- eliminando o (⧺) da
reverse“por indução”
- eliminando o (⧺) da
- Arvores
- típos de árvores e umas funções relevantes
- size, nodes, depth, flatten, mapTree, foldTree, …
- Sintaxe vs semântica
- Numerais binários
- Um toque de expressões e ASTs
- BNF
- ArEx, ArExV
- semântica operacional
- semântica denotacional
- eval, step, bigstep
- funções fold: fold
hw
- Ordenação (sorting)
- Defina sozinhos os: merge sort; quick sort ;insertion sort
- ASTs
- Defina tipos para representar:
- expressões de aritmética sem variáveis:
- expressões de aritmética com variáveis;
- expressões de lógica proposicional
- Defina funções de
evalestepapropriadamente para cad um dos teus tipos
- Defina tipos para representar:
- Arvores
- Defina as:
nodesize : BinTree α → Natsize : BinTree α → Natdepth : BinTree α → Natleaves : BinTree α → List αmapTree : ?mirror : BinTree α → BinTree αflatten : BinTree α → List αfindTree : α → GenTree α → List (List Nat)sumTree : BinTree Nat → Nat
- Adivinhe uma conexão entre o número
size te o númeronodes t: enuncie e demonstre! - Θ.
size t ≤ 2 ^ depth t - Θ.
depth t ≤ length (flatten t) - Verifique que tu passou EM & ME mesmo, reescrevendo o que demonstrou acima utilizando
log₂ - Defina o resto dos tipos de arvores discutidos nas aulas (peça detalhes no Zulip!)
- BinSearchTree α
- BinLabTree α β
- RoseTree α
- Demonstre como todos teus típos de árvores viram Functors
- Demonstre:
length ∘ flatten = ??flatten ∘ mirror = ??mirror ∘ mirror = ??depth ∘ mirror = ??depth ∘ fmap f = ??fmap f ∘ mirror = ??
- Defina as:
- Eficiência “por indução” / parametro acumuladora: use a metodo que encontramos na aula eliminando o (⧺) da
reversepara:- eliminá-lo da tua
flatten - eliminá-lo da tua
leaves
- eliminá-lo da tua
- Folds & lists
- Defina uma foldT para os tipos de arvores que faz sentido definir
- Defina uma foldE para os tipos de Either
- Discuta qual deveria ser o tipo de uma
unfoldque cria listas a partir de outros valores; depois defina! reverse (xs ⧺ ys) = reverse ys ⧺ reverse xs- Demonstre a lei de fusão do
foldrque é: dado ??, temos:f ∘ foldr g a = foldr h b
Prova 2.3
Em um universo paralelo
- Expressões e ASTs
- Fórmulas de Lógica Proposicional
- Funções em fórmulas
- Recursão aninhada
- Ackermann
- Recursão para contagem