Objetivo LFS: Un lenguaje funcional sencillo

Anuncio
Pontificia Universidad Católica de Chile
Escuela de Ingenierı́a
Departamento de Ciencia de la Computación
Tarea 1
Programas que programan
IIC2622 – Taller de Inteligencia Artificial
Primer Semestre, 2004
Fecha de Entrega: 31 de marzo.
Objetivo
En esta tarea usted deberá experimentar con la técnica de programación genética para programación de
computadores y autómatas celulares.
LFS: Un lenguaje funcional sencillo
El elemento principal en un lenguaje funcional es la función. Una función puede recibir 0 o más parámetros
y siempre retorna una expresión. A diferencia de los lenguajes imperativos, una función en un lenguaje
funcional siempre retorna el mismo valor cuando recibe los mismos parámetros (esto se debe, entre otras
razones, a que no existen variables globales). Una caracterı́stica de los lenguajes funcionales es que todas las
expresiones del lenguaje se pueden evaluar matemáticamente.
En LFS, todas las expresiones del lenguaje retornan números enteros (y por lo tanto, todas las funciones
retornan números enteros). Para ocupar el n-ésimo parámetro, se utiliza la expresión paramn .
Para definir la semántica de las expresiones, usaremos la función Vβ J·K, que dada una expresión, retorna
el entero al que corresponde. El subı́ndice β es una función que sirve para obtener los valores tienen los
parámetros de la función.
Vβ JeK = e si e es número entero.
Vβ Jparami K = β(i) (1 ≤ i ≤ n).
Vβ J(? e1 e2)K = Vβ Je1K ? Vβ Je2K, donde ? ∈ {+, −, ∗, /}.
(
Vβ Je2K si Vβ Je1K 6= 0
Vβ J(if e1 e2 e3)K =
Vβ Je3K en otro caso
(
1 si Vβ Je1K ? Vβ Je2K
Vβ J(? e1 e2)K =
con ? ∈ {>, ≥, <, ≤, =}.
0 en otro caso
(
0 si Vβ Je1K = 0 o Vβ Je2K = 0
Vβ J(and e1 e2)K =
1 en otro caso
(
0 si Vβ Je1K = 0 y Vβ Je2K = 0
Vβ J(or e1 e2)K =
1 en otro caso
(
1 si Vβ JeK = 0
Vβ J(not e1)K =
0 en otro caso
Vβ J(g e1 e2 . . . en )K = Vγ Jexpg K, si g es una función y expg es la expresión que la define y γ es tal que
γ(i) = Vβ Jei K.
Si f es una función matemática que está implementada por una función LSF f y p1 , . . . , pn son enteros,
entonces para calcular el valor f (p1 , . . . , pn ) basta con computar Vβ J(f p1 p2 · · · pn )K, con β una función
arbitraria.
Pn
A manera de ejemplo, para calcular f (n) = i=0 i2 , se puede definir la función f en LSF de la siguiente
manera:
(if (= param1 0)
0
(+ (* param1 param1)
(f (- n 1))))
Autómatas Celulares
Un autómata celular (AC) es una máquina discreta que puede realizar cierto tipo de cómputos. Un
autómata celular unidimensional (ACU) está compuesto por una “grilla” unidimensional de n celdas (o
células). Cada celda puede estar en un estado tomado de un conjunto finito de estados. Además, cada celda
tiene un conjunto finito de celdas vecinas, definidas a través de una relación de vecindad uniforme (es decir,
la vecindad es la misma para todas las celdas). Normalmente, la vecindad de una celda incluye a la misma
celda.
El cambio en los estados de las celdas se define a través de una función de transición discreta y temporal,
que indica cuál será el estado de una celda en el instante t + 1 basada en los estados de sus vecinas y de ella
misma en el tiempo t. La función es la misma para todas las celdas.
La siguiente es una representación gráfica de un ACU de n celdas en el espacio y en el tiempo.
Espacio
Tiempo
ct (1)
...
ct (i − 2) ct (i − 1) ct (i)
...
ct+1 (i)
ct (i + 1) ct (i + 2)
...
ct (n)
...
El siguiente es un ejemplo de una función de transición de radio 1 (se le llama de radio 1 porque las
vecinas de la celda i son las que están a distancia 1 de ella)1 .
(
1 si 1 ≤ ct (i − 1) + ct (i) + ct (i + 1) ≤ 2
ct+1 (i) =
(1)
0 en otro caso
A pesar de lo simple que son las funciones de transición, los ACUs pueden generar comportamientos bastante
complejos. Por ejemplo, en la siguiente figura se muestra cómo a partir de una configuración inicial muy
simple, se obtiene un comportamiento que podrı́amos considerar como bastante complejo usando la función
definida arriba2 :
1 Normalmente
se acostumbra a considerar que la vecina izquierda de la primera celda es la última celda, y que la vecina
derecha de la última celda es la primera.
2 Las celdas blancas representan un 0 y las negras un 1
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
Es interesante notar que una función de transición se puede escribir directamente en LSF. Por ejemplo, la
ecuación (1) se puede computar por una función definida por la expresión:
(if (and (>=
(+ (+ param1 param2)
param3)
1)
(<=
(+ (+ param1 param2)
param3)
2))
1
0)
donde param1, param2 y param3 corresponden a los estados de las celdas i − 1, i e i + 1, respectivamente.
Parte 1: Aprendiendo funciones conocidas y desconocidas
En esta parte usted deberá construir un programa que, usando la técnica de programación genética,
pueda sintetizar programas en LSF para:
1. Calcular la serie de números de Fibonacci.
2. Generar una función recursiva que genere las salidas en el archivo desconocida.csv, publicado en la
página web del curso
Oportunidades de bonus: Probar con funciones que contengan partes crecientes y partes decrecientes. Probar
con funciones más complejas como bsinh(x)c. Probar todo lo anterior usando más de una función (o funciones
auxiliares). Por ejemplo, f calcula una función de interés y en su código puede llamar a g y a f . Por otro
lado, se puede imponer que la función auxiliar g puede ser recursiva, pero que no llame a f .
Parte 2: Descubriendo cómo programar un ACU
En esta parte se pide que, usando programación genética, usted descubra una función de transición de
radio 2 para un ACU de 51 celdas que resuelve el problema de clasificación. En este problema, el ACU
inicialmente contiene celdas que pueden estar en dos estados 0 o 1. La función de transición debe ser tal que,
se converja a una situación en la que todas las celdas están en estado 0 si habı́a en el estado inicial mayorı́a
de 0’s, y que converja a un estado sólo con 1’s en caso contrario.
Antecedentes adicionales: Las mejores funciones de transición escritas por humanos para el problema de
clasificación, lo resuelven con una precisión sólo del 82,1 %. En 1996, el inventor de la programación genética,
John Koza, sintetizó una regla con una precisión del 82.326 %. ¿Podrá usted encontrar una mejor? Puede
encontrar más detalles en el artı́culo publicado en el sitio web del curso.
La tarea se podrá realizar en grupos de hasta 2 personas
Descargar