Metonymie.com :: Apuntes » 2009 » May
Bloque de Colores

Armonizando escalas con Haskell

Icono de Post May 22 2009 :: Haskell ::

Este es el primer programita en Haskell que hice por gusto propio, principalmente para afianzar un poco conceptos y además para probar tipos de datos y sobre todo de pensar desde Haskell. Lo fantástico es que estas cosas las hacia a mano, cuando tenía 17 años y estaba aprendiendo armonía (Por mi cuenta, obviamente).

Primero definí un tipo de datos Nota y una función sucesor cíclica (dado que estoy interesado en relaciones puramente armónicas).


data Nota = A | Bb | B | C | Db | D | Eb | E | F | Gb | G | Ab deriving (Eq)

suc :: Nota -> Nota
suc A = Bb; suc Bb = B; suc B = C; suc C = Db; suc Db = D; suc D = Eb; suc Eb = E; suc E = F; suc F = Gb; suc Gb = G; suc G = Ab; suc Ab = A;

Después hice que el tipo de datos Nota fuera instancia de la clase show, dando una definición especifica de la función show para mi tipo de datos para tratar los problemas del doble nombre de determinadas notas ( equivalencias enarmonicas ).


instance Show Nota where
	show A = show "A"
	show Bb = show "A#/Bb"
	show B = show "B"
	show C = show "C"
	show Db = show "C#/Db"
	show D = show "D"
	show Eb = show "D#/Eb"
	show E = show "E"
	show F = show "F"
	show Gb = show "F#/Gb"
	show G = show "G"
	show Ab = show "G#/Ab"

A partir de esto puedo definir la función intervalo, que toma un número natural (de 0 a 11, aunque se puede considerar al tipo Nota y a la función intervalo como compartiendo propiedades con la aritmética mod(12), por lo que n puede tomar valores mayores a 11 y los resultados van a ser los mismos a intervalo _ (n mod (12))). En un principio había pensado que se podía pensar como un isomorfismo, pero no estoy convencido, aunque si tomamos aplicación parcial de intervalo x como una función en si misma, ahí si podría serlo.


intervalo :: Nota -> Integer -> Nota
intervalo a 0 = a
intervalo a 1 = suc(a)
intervalo a n = suc( intervalo a (n-1))

No intente definir los intervalos a partir de sus nombres usuales sino simplemente desde su distancia (ascendente) a partir de la nota base. O sea, se sobreentiende que si le doy un valor de uno representa a una segunda menor, de 4 a una tercera mayor, etc. (Por otro lado es como siempre me acerque al concepto de intervalo).

Paso siguiente construir funciones para definir las cuatro triadas básicas.


type Triada = (Nota, Nota, Nota) 

maj :: Nota -> Triada
maj a = (a, intervalo a 4, intervalo a 7)

men :: Nota -> Triada
men a = (a, intervalo a 3, intervalo a 7)

aug :: Nota -> Triada
aug a = (a, intervalo a 4, intervalo a 8 )

dim :: Nota -> Triada
dim a = (a, intervalo a 3, intervalo a 6)

Y luego definir las escalas y modos básicos.


escala :: Nota -> [Integer] -> [Nota]
escala a [] = []
escala a (x:xs) = intervalo a x : escala a xs

escala_cromatica :: Nota -> [Nota]
escala_cromatica a = escala a [0..11]

escala_mayor :: Nota -> [Nota]
escala_mayor a = escala a [0,2,4,5,7,9,11]

escala_menor :: Nota -> [Nota]
escala_menor a = escala a [0,2,3,5,7,8,10]

escala_menor_armonica :: Nota -> [Nota]
escala_menor_armonica a = escala a [0,2,3,5,7,8,11]

escala_menor_melodica :: Nota -> [Nota]
escala_menor_melodica a = escala a [0,2,3,5,7,9,11]

modo_dorico :: Nota -> [Nota]
modo_dorico a = escala a [0,2,3,5,7,9,10]

modo_frigio :: Nota -> [Nota]
modo_frigio a = escala a [0,1,3,5,7,8,10]

modo_lidio :: Nota -> [Nota]
modo_lidio a = escala a [0,2,4,6,7,9,11]

modo_mixolidio :: Nota -> [Nota]
modo_mixolidio a = escala a [0,2,4,5,7,9,10]

modo_locrio :: Nota -> [Nota]
modo_locrio a = escala a [0,1,3,5,6,8,10]

escala_disminuida :: Nota -> [Nota]
escala_disminuida a = escala a [0,2,3,5,6,8,9,11]

escala_aumentada :: Nota -> [Nota]
escala_aumentada a = escala a [0,2,4,6,8,10]

Dado que voy a intentar hacer reconocimiento de acordes, se vuelve necesario definir la función distancia (que es distancia ascendente).


distancia :: Nota -> Nota -> Integer
distancia a b 	| (intervalo a 0) == b 	= 0
		| otherwise 		= 1 + (distancia (suc a) b)

Probar de Reconocer Acordes.


es_triada_mayor :: Triada -> Bool
es_triada_mayor (a,b,c) | (distancia a b) == 4 && (distancia a c) == 7 = True
			| otherwise = False

es_triada_menor :: Triada -> Bool
es_triada_menor (a,b,c) | (distancia a b) == 3 && (distancia a c) == 7 = True
			| otherwise = False

es_triada_disminuida :: Triada -> Bool
es_triada_disminuida (a,b,c) 	| (distancia a b) == 3 && (distancia a c) == 6 = True
				| otherwise = False

es_triada_aumentada :: Triada -> Bool
es_triada_aumentada (a,b,c) 	| (distancia a b) == 4 && (distancia a c) == 8 = True
				| otherwise = False

Ejemplo de uso:


*Main> es_triada_mayor (A,Db,E)
True
*Main> es_triada_mayor (A,C,E)
False

Aclaración: Como el tipo de datos es cíclico a partir de la función suc y estamos trabajando con triadas básicas, no importan las diferentes inversiones de los acordes.

Ver si una triada existe en una escala:


esta_triada_en_escala :: [Nota] -> Triada -> Bool
esta_triada_en_escala xs (a,b,c)	| elem a xs && elem b xs && elem c xs = True
					| otherwise = False
{- 
*Main> esta_triada_en_escala (men A) (modo_dorico A)
True
-}

Ahora ya puedo armonizar escalas por un método de Brute Force, no muy elegante, pero por lo pronto efectivo. Primero creo todas las posibles triadas (4*12 = 48) y después filtro las que corresponden a la escala, además de crear una función que muestre los resultados de una forma visualmente más agradable.


show_triada :: Triada -> String
show_triada (a,b,c) 	| es_triada_mayor (a,b,c) = strip_slashes(show a) ++ " maj"
			| es_triada_menor (a,b,c) = strip_slashes(show a) ++ " min"
			| es_triada_aumentada (a,b,c) = strip_slashes(show a) ++ " aug"
			| es_triada_disminuida (a,b,c) = strip_slashes(show a) ++ " dim"
			| otherwise = strip_slashes(show (a,b,c)) ++ " No es Triada"
			where 
				strip_slashes :: [Char] -> [Char]
				strip_slashes [] = []
				strip_slashes (x:xs) 	| x == '"' = strip_slashes xs
							| otherwise = x : strip_slashes xs		

todas_las_triadas :: Nota -> [Triada]
todas_las_triadas a = concat( map hacer_triadas_de (escala_cromatica a))
			where
			hacer_triadas_de :: Nota -> [Triada]
			hacer_triadas_de a = [(dim a),(men a),(maj a),(aug a)]
armonizar_escala :: [Nota] -> [String]
armonizar_escala (x:xs) = map show_triada (filter (esta_triada_en_escala (x:xs)) (todas_las_triadas x))

{-
*Main> armonizar_escala (modo_dorico A)
["A min","B min","C maj","D maj","E min","F#/Gb dim","G maj"]
*Main> armonizar_escala (escala_menor_armonica E)
["E min","F#/Gb dim","G aug","A dim","A min","B maj","B aug","C dim","C min","C maj","D#/Eb dim","D#/Eb aug"]
*Main> armonizar_escala (escala_aumentada E)
["E aug","F#/Gb aug","G#/Ab aug","A#/Bb aug","C aug","D aug"]
*Main> armonizar_escala (escala_disminuida E)
["E dim","F#/Gb dim","F#/Gb min","F#/Gb maj","G dim","A dim","A min","A maj","A#/Bb dim","C dim","C min","C maj","C#/Db dim","D#/Eb dim","D#/Eb min","D#/Eb maj"]
-}

Detalle: otro ejemplo de currying en esta_triada_en_escala (x:xs).

Obviamente esto un principio y hay un montón de ideas que se me ocurrieron mientras hacia esto. Así que, sera continuado.

Autor: Emiliano Martínez Luque.

Comments Off on Armonizando escalas con Haskell

Funciones de Orden Superior Y Combinadores

Icono de Post May 19 2009 :: Haskell, Programación Funcional ::

Una función de orden superior es una función que devuelve otra función.

Un Combinador es un función de orden superior que encapsula un determinado comportamiento de una clase de funciones y provee un template para la creación de estas. Ej:


iter :: (Integer -> Integer -> Integer) -> Integer -> ( Integer -> Integer )
iter op e = fun
	where 
	fun 0	= e
	fun m@(n + 1) = op m (fun n)

factorial :: Integer -> Integer
factorial = iter (*) 1

sumatorio :: Integer -> Integer
sumatorio = iter (+) 0

Referencias

Razonando con Haskell;Blas C. Ruiz, Francisco Gutiérrez, Pablo Guerrero y José E. Gallardo;Thomson Editores Spain;2004

Autor: Emiliano Martínez Luque.

Comments Off on Funciones de Orden Superior Y Combinadores

Un poco de Análisis en Haskell

Icono de Post May 18 2009 :: Análisis, Haskell, Programación Funcional ::

Teniendo en cuenta que:

Derivada   f   x = lim h   0   f   ( x + h ) f   x h

Se puede hacer una definición de la función derivada en Haskell como:


derivada :: (Double -> Double) -> Double -> Double
derivada f x = ( f(x + h) - f x ) / h
		where h = 0.0001

Considerando que la derivada de f(x) = x2 es f'(x) = 2x, testeamos la definición:


*Main> derivada (x -> x^2) 2
4.0001000000078335

Afinando la definición de h:


derivada :: (Double -> Double) -> Double -> Double
derivada f x = ( f(x + h) - f x ) / h
		where h = 0.00000000001

Da como resultado:


*Main> derivada (x -> x^2) 2
4.000000330961484

Independientemente ( o más bien a pesar ) de los problemas Inherentes a la aritmetica de punto flotante, se ve que Cuando h tiende a 0 más se acerca al resultado esperable.

Aplicación Parcial (Currying)

Se puede usar la definición de derivada anterior para producir una función y no un resultado, ej:


casiPor2 :: (Double -> Double)
casiPor2  = derivada (x -> x^2)

Que si bien no es equivalente a x -> 2 * x, (por los problemas de la aritmetica de punto flotante), se le acerca.

Una versión de testeo con diversos niveles de acercamiento.

Esto es interesante para entender gráficamente el concepto de limite.


derivada3 :: (Double -> Double) -> Double -> Double ->Double
derivada3 f x h = (f(x + h) - f x ) / h

tiendeA0 :: Double -> [Double]
tiendeA0 h = h : ( tiendeA0 (h*0.1) )

Testeo de tender a 0:


*Main> take 10 (tiendeA0 1)
[1.0, 0.1, 1.0000000000000002e-2, 1.0000000000000002e-3, 1.0000000000000003e-4, 1.0000000000000004e-5, 1.0000000000000004e-6, 1.0000000000000005e-7, 1.0000000000000005e-8, 1.0000000000000005e-9]

Ahora considerando que: f(x) = x^3 => f'(x) = 3x^2 y En particular si x=2, f'(x) = 3x^2 = 3.4 = 12; podemos probar su aplicación para ver el comportamiento extraño del punto flotante.


*Main> map ( derivada3 (x -> x^3) 2 ) (take 10 (tiendeA0 1))
[19.0, 12.61000000000001, 12.060099999999705, 12.006000999999596, 12.000600010022563, 12.00006000026121, 12.000006002210734, 12.000000584322374, 11.999999927070343, 12.000000992884447]

Referencias

Razonando con Haskell;Blas C. Ruiz, Francisco Gutiérrez, Pablo Guerrero y José E. Gallardo;Thomson Editores Spain;2004

Calculus; M. Spivak; Editorial Reverte; 1992

Algebra de Boole Aplicada a Circuitos de Computación; M. C. Guinzburg; Biblioteca Técnica Superior; 1998

Autor: Emiliano Martínez Luque.

Comments Off on Un poco de Análisis en Haskell

Razonando sobre corrección de Programas en Haskell

Icono de Post May 18 2009 :: Algoritmia, Combinatoria, Haskell, Lógica ::

Una de las cosas más interesantes de Haskell es lo facil que resulta razonar sobre corrección de programas. Veamos un ejemplo simple; construiremos una función que tome 3 elementos ordenables y los devuelva como una triada ordenada (Ejercicio 2.40 de Razonando con Haskell):


ordena3:: Ord a => a -> a -> a -> (a, a, a )
ordena3 a b c 	| a <= b && b <= c = (a, b, c) 		-- Caso 1
	 	| a <= b = ordena3 a c b		-- Caso 2
		| b <= c = ordena3 b a c		-- Caso 3
		| otherwise = (c, b, a)			-- Caso 4

Las posibles permutaciones de un conjunto de 3 elementos distintos son obviamente 3! = 2 * 3 = 6. Sean 3 elementos ordenables distintos, a los que llamamos 1, 2, 3 tales que 1 < 2 < 3, veamos como trata el programa estas 6 permutaciones distintas:

ordena3 1 2 3 Caso 1 -> (1 ,2 ,3)
ordena3 1 3 2 Caso 2 -> ordena3 1 ,2 ,3; Caso 1 -> (1 ,2 ,3)
ordena3 2 1 3 Caso 3 -> ordena3 1 ,2 ,3; Caso 1 -> (1 ,2 ,3)
ordena3 2 3 1 Caso 2 -> ordena3 2 ,1 ,3; Caso 3 -> ordena3 1 ,2 ,3; Caso 1 -> (1 ,2 ,3)
ordena3 3 1 2 Caso 3 -> ordena3 1 ,3 ,2; Caso 2 -> ordena3 1 ,2 ,3; Caso 1 -> (1 ,2 ,3)
ordena3 3 2 1 Caso 4 -> (1 ,2 ,3)

Las condiciones exhaustuan todos los caso y el algoritmo termina siempre. ( No se consideran los casos en que existen elementos duplicados en la explicación ya que es trivial ver que por el uso de <= en las condiciones están contemplados en la definición de la función. )

Referencias

Razonando con Haskell;Blas C. Ruiz, Francisco Gutiérrez, Pablo Guerrero y José E. Gallardo;Thomson Editores Spain;2004

Autor: Emiliano Martínez Luque.

Comments Off on Razonando sobre corrección de Programas en Haskell

Haskell: Sintaxis Basica II

Icono de Post May 18 2009 :: Haskell, Programación Funcional ::

Algunos detalles más de Sintaxis de Funciones: Uso de Where, de Let y definición de listas por comprensión.

Ej: una función que tomando una cantidad de segundos devuelve las horas, minutos y segundos que representa (Ejercicio 2.26 de Razonando con Haskell)-


aHoras:: Integer -> ( Integer, Integer, Integer )
aHoras x = ( horas, minutos, segundos )
	where
	m = div x 60
	h = div m 60
	segundos = mod x 60
	minutos = mod m 60
	horas = mod h 60

Otro Ej: un listado (no muy eficiente) de los números perfectos. (Ejercicio 6.19)


divideA :: Integer -> Integer -> Bool
divideA x y = mod x y == 0

divisoresDe :: Integer -> [Integer]
divisoresDe n = [x | x <- [1..(n-1)], divideA n x]


perfecto :: Integer -> Bool
perfecto x = suma == x
		where
		ds = divisoresDe x
		suma = sum ds

perfectos :: [Integer]
perfectos = [x | x <- [0..], perfecto x ]

Otra posible definición usando let.


perfectos2 :: [Integer]
perfectos2 = [x | x <- [0..], let ds = divisoresDe x, let suma = sum ds, x == suma]

Listas por extensión, Las ternas pitagóricas (Ejemplo 6.20):


ternasPit :: Integer -> [(Integer, Integer, Integer)]
ternasPit n = [(x,y,z) | let ns = [1..n], x <- ns, y <- ns, z <- ns, x^2 + y^2 == z^2 ]

Una definición de Quicksort (Ejemplo 6.10.3)


quickSort :: Ord a => [a] -> [a]
quickSort [] = []
quickSort (p:xs) = quickSort menores ++ [p] ++ quickSort mayores
		where 
			menores = [x | x <- xs, x < p ]
			mayores = [x | x <- xs, x >= p ]

Otra definición de Quicksort más eficiente (Ejercicio 6.30)


partirPor :: Ord a => (a -> Bool) -> [a] -> ([a], [a])
partirPor f [] = ([], [])
partirPor f [x] | f x = ([x], [])
		| otherwise = ([], [x])
partirPor f (x:xs) 	| f x = (x:ys, zs)
			| otherwise = (ys, x:zs)
			where
				(ys, zs) = partirPor f xs
{-
*Main> partirPor even [1..10]
([2,4,6,8,10],[1,3,5,7,9])
-}

quickSort2 :: Ord a => [a] -> [a]
quickSort2 [] = []
quickSort2 (p:xs) = quickSort2 menores ++ [p] ++ quickSort2 mayores
		where 
			(menores, mayores)= partirPor (x -> x < p) xs 

Trabajando con Funciones como argumentos.

Una función que recibe una lista de funciones y un entero, devuelve la lista de resultados. (Ejercicio 2.28)


(|>)::[Integer -> Integer] -> Integer -> [Integer]
(|>) [] x = []
(|>) (f:fs) x = f x : (|>) fs x

Se puede probar con expresiones lambda:


Main> (|>) [(x -> x * 10), (x -> x +10), (x -> x*20)] 5
[50,15,100]

Una función que devuelve el primer elemento de una lista que cumple con una determinada condición. (Ejercicio 6.18)


primeroQue :: (a -> Bool) -> [a] -> a
primeroQue f (x:xs) 	| f x == True = x
			| otherwise = primeroQue f xs

Seudónimos

La función:

factorial :: Integer -> Integer
factorial 0 = 1
factorial (n + 1) = (n + 1) * factorial n

puede escribirse como:

factorial :: Integer -> Integer
factorial 0 = 1
factorial m@(n + 1) = m * factorial n

donde m = ( n + 1).

Referencias

Razonando con Haskell;Blas C. Ruiz, Francisco Gutiérrez, Pablo Guerrero y José E. Gallardo;Thomson Editores Spain;2004

Autor: Emiliano Martínez Luque.

Comments Off on Haskell: Sintaxis Basica II

Novedades

Icono de Post May 18 2009 :: Uncategorized ::

Estaba un poco frustrado con THRTLMP y no estaba adelantando demasiado con Haskell, así que estuve buscando en las librerías a ver si encontraba un libro nuevo. Sorprendentemente, encontré un libro maravilloso, Razonando con Haskell que es excelente para aprender Haskell además de incluir demostraciones rigurosas sobre corrección de programas y un montón de conceptos avanzados de Programación Funcional (Incluso tiene un capitulo sobre Calculo Lambda puro). Voy a hacer algunos Posts pronto con lo que estuve aprendiendo de nuevo.
Fuera de eso, estoy bastante contento de ver lo mucho que estoy avanzando en matemáticas en general y como estoy pudiendo acercarme a textos y conceptos bastante complejos que hace un par de años me parecían imposibles. Así que, sigamos así!!

Autor: Emiliano Martínez Luque.

Comments Off on Novedades

Equivalencias Básicas de Sumatorias

Icono de Post May 7 2009 :: Algebra, Apuntes ::

Sumatoria de una constante    

Sea k constante se cumple que:

n = 1 m k = mk

Sumatoria de un polinomio

n = 1 m 2 a + b 2 c = n = 1 m 2 a + n = 1 m b 2 n = 1 m c

Sumatoria de un producto

Sea c constante, se cumple que:

n = 0 m ck = c . n = 0 m k

Sumatoria de una potencia ( Progresión geometrica )

Sea | r | > 1:
n = 1 m r n = r n + 1 1 r 1

Equivalencias

n = 0 m n = n ( n + 1 ) 2

n = 0 m n 2 = n ( n + 1 ) ( 2 n + 1 ) 6

n = 0 m n 3 = n 2 ( n + 1 ) 2 4

Estas equivalencias pueden demostrarse facilmente por inducción, hay más para diversos grados de n en esta pagína: PlanetMath: Summation.

Cambio de Limites

n = a b f ( k ) = n = a + r b + r f ( k r )

Autor: Emiliano Martínez Luque.

Comments Off on Equivalencias Básicas de Sumatorias

Relaciones sobre conjuntos (Definiciones y Propiedades Básicas)

Icono de Post May 7 2009 :: Apuntes, Teoría de Conjuntos ::

Definiciones Iniciales

Producto Cartesiano de A × B
A × B = {(a, b) | a ∈ A ∧ b ∈ B }
En particular, si A = B, se escribe A2 = {(a, b) | a ∈ A ∧ b ∈ A}

Relación
Sean A, B Conjuntos entonces R ⊆ A × B es una relación de A a B.

Dominio de R
Dom(R) = {a ∈ A | ∃b ∈ B((a, b) ∈ R)}

Rango de R
Ran(R) = {b ∈ B | ∃a ∈ A((a, b) ∈ R)}

Inversa de R
R-1 = {(b, a) ∈ B × A | (a, b) ∈ R}

Composición de S con R
S o R = {(a, c) ∈ A × C | (a, b) ∈ R ∧ (b, c) ∈ S}

Propiedades Posibles de las relaciones

Reflexiva
∀x ∈ R (x R x )

Simétrica
∀x, y ∈ R ( x R y -> y R x)

Transitiva
∀x,y,z ∈ R ( x R y ∧ y R z -> x R z)

Antisimetrica
∀x,y ∈ R ( x R y ∧ y R x -> x = y)

Irreflexiva
∀x ∈ A ((x, x) ∉ R)

Tricotomia
∀x ∈ A, ∀y ∈ A ( x R y ∨ y R x ∨ x = y)

Relaciones de Orden

Sea R una relación sobre un conjunto A, si R es Reflexiva, Transitiva y Antisimétrica se dice que R es un orden parcial sobre A.
Sera un orden total si ademas cumple que:
∀x,y ∈ A( x R y ∨ y R x)

Si R es irreflexiva y transitiva, se la llama un orden parcial estricto. Si ademas cumple Tricotomia, es un orden total estricto.

Elementos menores y mínimos

Sea R un Orden parcial en un conjunto A, B ⊆ A y b ∈ B. b es el elemento menor en B para R si ∀x ∈ B(b R x ). b es un elemento mínimo en B para R si ∀x ∈ B( x R b -> x = b ).

Nota: Sea R es un orden parcial sobre A y B ⊆ A. Se cumple que si B tiene un elemento menor, entonces este elemento es único, es mínimo y es el único mínimo. ( Sin embargo un elemento puede ser mínimo pero no ser menor. ) Si R es un orden total se cumple que si b es un elemento mínimo de B entonces es el menor elemento de B.

Cotas Inferiores y Superiores

Sea R un orden parcial en A, B ⊆ A y a ∈ A. a es una cota inferior de B si ∀b ∈ B( a R b ). Es una cota superior si ∀b ∈ B( b R a).

Sea U el conjunto de todas las cotas superiores de A, Si U tiene un elemento menor entonces este elemento es la cota superior menor de B.
Sea U el conjunto de todas las cotas inferiores de A, Si U tiene un elemento mayor entonces este elemento es la cota inferior mayor de B.

Cerraduras ( Closures )

Sea R una Relación en A. Sea S ⊆ A x A, si se cumple que: R ⊆ S,  S es reflexiva, ∀T ⊆ A x A( R ⊆ T ∧ T es reflexiva -> S ⊆ T) entonces S es la cerradura reflexiva de R.
De forma equivalente se definen las cerraduras Transitiva y Simétrica..

Relaciones de Equivalencia

Sea R una relación en A. Si R es reflexiva, simétrica y transitiva, se la llama una relación de equivalencia en A.  

Supongamos que A es un conjunto y F ∈ P(A), si se cumple que ∀X ∈ F, Y ∈ F( X ≠ Y -> X ∩ Y = ∅ ) se dice que F es disjunto en pares (pairwise disjoint). Si F cumple que: ∪F = A, F es disjunto en pares, ∀X ∈ F( X ≠ ∅ ), entonces F es una partición de A.

Toda relación de equivalencia establece una partición sobre el conjunto sobre el que esta definida.

Sea R una relación de equivalencia sobre A, x ∈ A. La clase de equivalencia de x respecto a R es el conjunto:
[x]R = { y ∈ A | y R x}
Se define entonces el conjunto de todas las clases de equivalencia sobre A determinados por R como A / R ( A modulo R ) tal que:
A / R = { [x]R | x ∈ A } = { X ⊆ A | ∃x ∈ A(X = [x]R)}

Referencias

The Haskell Road To Logic, Math and Programming; Doets, Van Eijck; King´s College London Publications; 2004

How to Prove It: A Structured Approach; Velleman, Daniel; Cambridge University Press; 2006

Autor: Emiliano Martínez Luque.

Comments Off on Relaciones sobre conjuntos (Definiciones y Propiedades Básicas)