LMAN: Máquina Abstracta del Cálculo NTCC para Programación Concurrente de Robots LEGO MARIA DEL PILAR MUÑOZ RINCON ANDRES RENE HURTADO RODRIGUEZ PONTIFICIA UNIVERSIDAD JAVERIANA FACULTAD DE INGENIERIA INGENIERIA DE SISTEMAS Y COMPUTACION SANTIAGO DE CALI 2003 LMAN: Máquina Abstracta del Cálculo NTCC para Programación Concurrente de Robots LEGO MARIA DEL PILAR MUÑOZ RINCON ANDRES RENE HURTADO RODRIGUEZ Tesis de grado para optar el tı́tulo de Ingeniero de Sistemas y Computación Director CAMILO RUEDA CALDERON Profesor titular, Universidad Javeriana-Cali PONTIFICIA UNIVERSIDAD JAVERIANA FACULTAD DE INGENIERIA INGENIERIA DE SISTEMAS Y COMPUTACION SANTIAGO DE CALI 2003 Santiago de Cali, Enero 19 del 2004 Ingeniero ANDRES JARAMILLO BOTERO Decano Académico de la Facultad de Ingenierı́a Pontificia Universidad Javeriana Ciudad Certifico que el presente proyecto de grado, titulado “LMAN: Máquina Abstracta del Cálculo NTCC para Programación Concurrente de Robots LEGO” realizado por MARIA DEL PILAR MUÑOZ RINCON y ANDRES RENE HURTADO RODRIGUEZ, estudiantes de Ingenierı́a de Sistemas y Computación, se encuentra terminado y puede ser presentado para sustentación. Atentamente, Ing. CAMILO RUEDA CALDERON Director del Proyecto Santiago de Cali, Enero 19 del 2004 Ingeniero ANDRES JARAMILLO BOTERO Decano Académico de la Facultad de Ingenierı́a Pontificia Universidad Javeriana Ciudad Por medio de ésta, presentamos a usted el proyecto de grado titulado “LMAN: Máquina Abstracta del Cálculo NTCC para Programación Concurrente de Robots LEGO” para optar el tı́tulo de Ingeniero de Sistemas y Computación. Esperamos que este proyecto reúna todos los requisitos académicos y cumpla el propósito para el cual fue creado, y sirva de apoyo para futuros proyectos en la Universidad Javeriana relacionados con la materia. Atentamente, MARIA DEL PILAR MUÑOZ RINCON ANDRES RENE HURTADO RODRIGUEZ ARTICULO 23 de la Resolución No 13 del 6 de Julio de 1946 del Reglamento de la Pontificia Universidad Javeriana. “La Universidad no se hace responsable por los conceptos emitidos por sus alumnos en sus trabajos de Tesis. Sólo velará porque no se publique nada contrario al dogma y a la moral Católica y porque las Tesis no contengan ataques o polémicas puramente personales; antes bien, se vea en ellas el anhelo de buscar la Verdad y la Justicia” Nota de Aceptación: Aprobado por el comité de Trabajo de Grado en cumplimiento de los requisitos exigidos por la Pontificia Universidad Javeriana para optar el tı́tulo de Ingeniero de Sistemas y Computación. ANDRES JARAMILLO BOTERO Decano Académico de la Facultad de Ingenierı́a CAMILO RUEDA CALDERON Director de la Carrera de Ingenierı́a de Sistemas y Computación CAMILO RUEDA CALDERON Director de Tesis PERSONA1 Jurado PERSONA2 Jurado Maria del Pilar Muñoz Rincon A Dios por iluminar mis pasos cada dı́a. A mis padres Benjamı́n y Edilma y a mis hermanos Carlos Octavio y Maritza por darme acompañamiento constante, apoyo, ánimo y guı́a en la realización de mis sueños. Andrés René Hurtado Rodrı́guez A Dios por apoyarme y ser el pilar en mi caminar. A mi padre Rene y a mi madre Alba Felisa, a mis hermanas Maritza, Alba Lucia y Carmen Beatriz, no serı́a nada sin ustedes Ficha del Proyecto Titulo Facultad Estudiantes Director Grupo de investigación Palabras clave Resumen del proyecto LMAN: Máquina Abstracta del Cálculo NTCC para Programación Concurrente de Robots LEGO MindStorm. INGENIERÍA - Ingenierı́a de Sistemas y Computación MARIA DEL PILAR MUÑOZ RINCON ANDRES RENE HURTADO RODRIGUEZ CAMILO RUEDA CALDERON AVISPA (Ambientes Visuales de Programación Aplicativa) Cálculo de Procesos, Máquina Abstracta, Máquina Virtual, Robots LEGO, Concurrencia, Restricciones, LMAN. El actual proyecto de grado describe LMAN, máquina abstracta del cálculo NTCC para programación concurrente de robots LEGO. LMAN incluye tanto la especificación de la máquina abstracta, como la implementación de la máquina virtual, que actúa como el ejecutor notacional del cálculo NTCC. El modelo formal presentado en forma de máquina abstracta, provee la especificación de la máquina virtual. La máquina virtual está compuesta de un conjunto de instrucciones, registros y de un modelo de memoria; que actuando junto con un protocolo de comunicaciones, permiten controlar y ejecutar de manera eficiente y en tiempo real programas escritos en NTCC sobre los robots LEGO MindStorm. Cuadro 1: Ficha del proyecto i Agradecimientos A Camilo Rueda, director de la carrera de Ingenierı́a de Sistemas y Computación de la Universidad Javeriana – Cali, y director del proyecto, por sus ideas, apoyo y asesorı́a incondicional en la consecución del presente proyecto de grado. A Frank Valencia, post–doctoral researcher en el Departamento de Tecnologı́a de Información en la Universidad de Uppsala – Sweden, y asesor del proyecto por sus aportes y colaboración en el desarrollo del presente proyecto de grado. A Antal Buss, profesor de la carrera de Ingenierı́a de Sistemas y Computación de la Universidad Javeriana – Cali, por todas sus ideas y retroalimentación en las etapas iniciales del proyecto. A Catherine Garcı́a, profesora de la carrera de Ingenierı́a de Sistemas y Computación de la Universidad Javeriana – Cali, por su ayuda y sus aportes en el acople del módulo del Sistema de Restricciones con el presente proyecto. A Marı́a Constanza Pabón, profesora de la carrera de Ingenierı́a de Sistemas y Computación de la Universidad Javeriana – Cali, por su colaboraciòn y apoyo en la consecuciòn del módulo del compilador asociado al presente proyecto. Igualmente agradecemos a todos los estudiantes que estuvieron participando en el proyecto, en especial a Federico Rocha y Johana Chalá. Al grupo AVISPA. A Dios, por ser nuestra guı́a. A nuestras familias, por su apoyo incondicional, por su acompañamiento y por darnos ánimo en todos los momentos, en especial en los más difı́ciles. A Lady Janeth y a Jorge Alonso por ser pacientes, comprensivos y por su apoyo. ii A todas aquellas personas que de una otra manera colaboraron para la consecución del presente proyecto de grado. iii Índice general Índice de cuadros VIII Índice de figuras X Índice de Anexos XII 1. ANTECEDENTES 1 1.1. CONCURRENCIA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.2. CALCULOS DE PROCESOS . . . . . . . . . . . . . . . . . . . . . . . 2 1.2.1. CCP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 1.2.2. Default-TCC . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 1.3. MAQUINAS ABSTRACTAS Y MAQUINAS VIRTUALES . . . . . . . 10 1.3.1. Definiciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 1.3.2. Máquina Abstracta y Virtual de TyCO . . . . . . . . . . . . . . 11 1.3.3. Máquina Abstracta de PiCO . . . . . . . . . . . . . . . . . . . . 20 1.4. OBJETIVOS Y CONTRIBUCIONES DE ESTE TRABAJO DE TESIS 28 2. CALCULO NTCC 31 2.1. Descripción General . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 2.2. Sintaxis de NTCC 32 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iv 2.3. Semántica de NTCC . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 2.3.1. Sistema de Restricciones Aritmético-Modular . . . . . . . . . . 34 2.3.2. Semántica Operacional . . . . . . . . . . . . . . . . . . . . . . . 34 2.4. Definiciones Recursivas . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 2.4.1. Codificación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 2.5. Celdas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 2.6. Aplicaciones y Ejemplos . . . . . . . . . . . . . . . . . . . . . . . . . . 39 2.6.1. Controladores RCX: Ejemplo de Zig-Zag . . . . . . . . . . . . . 40 2.6.2. Sistemas Multiagentes: Presa y Predador . . . . . . . . . . . . . 41 2.6.3. Aplicaciones Musicales: Control de Improvisación . . . . . . . . 41 3. LMAN: MÁQUINA ABSTRACTA 43 3.1. Análisis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 3.1.1. Entorno de Programación NTCC . . . . . . . . . . . . . . . . . 43 3.1.2. Evaluación de Alternativas de Implementación para la Máquina Abstracta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 3.1.3. Evaluación de Alternativas de la plataforma de implementación para la Máquina Virtual . . . . . . . . . . . . . . . . . . . . . . 46 3.2. Máquina Abstracta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 3.2.1. Especificación formal . . . . . . . . . . . . . . . . . . . . . . . . 51 3.2.2. Sintaxis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 3.2.3. Estado inicial y Final . . . . . . . . . . . . . . . . . . . . . . . . 53 3.2.4. Semántica Operacional: Reglas de Reducción . . . . . . . . . . . 54 3.2.5. Diagrama de Transición . . . . . . . . . . . . . . . . . . . . . . 58 v 4. LMAN: MÁQUINA VIRTUAL 61 4.1. Arquitectura General . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 4.1.1. Memoria de Programa . . . . . . . . . . . . . . . . . . . . . . . 64 4.1.2. Interfaz STORE . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 4.1.3. Interfaz LEGOS . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 4.1.4. ControlLMAN . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 4.2. Funcionamiento de LMAN . . . . . . . . . . . . . . . . . . . . . . . . . 83 5. COMPILADOR NTCC–LMAN 87 5.1. Sintáxis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 5.1.1. Conjunto de Caracteres . . . . . . . . . . . . . . . . . . . . . . . 88 5.1.2. Reglas de Producción . . . . . . . . . . . . . . . . . . . . . . . 89 5.2. Semántica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 5.3. Generación de Código 93 . . . . . . . . . . . . . . . . . . . . . . . . . . . 6. Ejemplos y Pruebas 94 6.1. Ejemplos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94 6.1.1. Programa Zig-Zag . . . . . . . . . . . . . . . . . . . . . . . . . . 94 6.1.2. Programa de Evasión de Obstáculos . . . . . . . . . . . . . . . . 100 6.1.3. Aplicaciones Musicales . . . . . . . . . . . . . . . . . . . . . . . 103 6.2. Pruebas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107 6.2.1. Etapa de pruebas de LMAN . . . . . . . . . . . . . . . . . . . . 107 6.2.2. Comparación entre LMAN , ESTEREL y La Máquina estándar de LEGO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7. CONCLUSIONES Y TRABAJO FUTURO vi 111 113 ANEXOS 116 ANEXOS 125 Bibliografı́a 127 vii Índice de cuadros 1. Ficha del proyecto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . i . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 1.2. Semántica de CCP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 1.3. Sintaxis de TCC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 1.4. Semántica de TCC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 1.5. Registros de la máquina virtual de TyCO . . . . . . . . . . . . . . . . . 19 1.6. Conjunto de Registros de MAPiCO . . . . . . . . . . . . . . . . . . . . 28 2.1. Sintaxis de NTCC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 2.2. Semántica de NTCC . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 1.1. Sintaxis de CCP 3.1. Evaluación de Alternativas de Implementación para la Máquina Abstracta 45 3.2. Evaluación de alternativas de la plataforma de implementación para la Máquina Virtual . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 3.3. Sintaxis de LMAN . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 4.1. Formato de Instrucciones de LMAN . . . . . . . . . . . . . . . . . . . . 65 4.2. Alternativas de programación de RCX . . . . . . . . . . . . . . . . . . 79 4.3. Alternativas de programación de RCX . . . . . . . . . . . . . . . . . . 80 viii 5.1. Palabras reservadas en el Compilador NTCC-LMAN . . . . . . . . . . 89 5.2. Operadores sobre restricciones . . . . . . . . . . . . . . . . . . . . . . . 91 6.1. Desempeño del programa Zig-Zag . . . . . . . . . . . . . . . . . . . . . 108 6.2. Desempeño del programa Evasión de Obstáculos . . . . . . . . . . . . . 109 6.3. Desempeño del programa Canon en Do mayor . . . . . . . . . . . . . . 110 6.4. comparación de LMAN, ESTEREL y Máquina estándar de LEGOS . . 112 ix Índice de figuras 1.1. Modelo de un entorno CCP . . . . . . . . . . . . . . . . . . . . . . . . 4 1.2. Ejemplo de un ambiente TCC . . . . . . . . . . . . . . . . . . . . . . . 8 1.3. Categorı́as básicas del lenguaje de programación TyCO . . . . . . . . . 12 1.4. Nuevas Categorı́as del lenguaje de programación TyCO . . . . . . . . . 12 1.5. Gramática del lenguaje de programación TyCO . . . . . . . . . . . . . 13 1.6. Reglas de Reducción de la máquina abstracta de TyCO . . . . . . . . . 16 1.7. Areas de Memoria de la máquina virtual de TyCO . . . . . . . . . . . . 17 1.8. Flujo de datos del sistema TyCO . . . . . . . . . . . . . . . . . . . . . 20 1.9. Reglas de Reducción de la máquina abstracta MAPiCO, parte I . . . . 25 1.10. Reglas de Reducción de la máquina abstracta MAPiCO, parte II . . . . 26 1.11. Diseño de MAPiCO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 3.1. Flujo del entrono de programación NTCC . . . . . . . . . . . . . . . . 44 3.2. Diagrama de Transición LMAN . . . . . . . . . . . . . . . . . . . . . 59 4.1. Bloques Funcionales de LMAN . . . . . . . . . . . . . . . . . . . . . . 62 4.2. Conjunto de Instrucciones de LMAN . . . . . . . . . . . . . . . . . . . 66 4.3. Especificación de Fuentes Src1 y Src2 . . . . . . . . . . . . . . . . . . . 67 4.4. Sintáxis para la especificación de Fórmulas de Primer Orden en LMAN 68 x 4.5. Instrucciones para construcción de restricciones en LMAN . . . . . . . 69 4.6. Arbol binario infijo que representa una restricción en LMAN . . . . . . 70 4.7. Ambiente LEGO en LMAN . . . . . . . . . . . . . . . . . . . . . . . . 71 4.8. Protocolo del lado de la estación de trabajo en LMAN . . . . . . . . . 76 4.9. Protocolo del lado del RCX en LMAN . . . . . . . . . . . . . . . . . . 77 4.10. RCX LEGO brick . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 4.11. Algunos ejemplos de modelos LEGO . . . . . . . . . . . . . . . . . . . 80 4.12. Gestión del controlLMAN . . . . . . . . . . . . . . . . . . . . . . . . . 83 4.13. Requerimientos Hardware del Sistema LMAN . . . . . . . . . . . . . . 84 4.14. Requerimientos Software del Sistema LMAN . . . . . . . . . . . . . . . 84 4.15. Funcionamiento del Sistema LMAN . . . . . . . . . . . . . . . . . . . . 86 4.16. Comportamiento reactivo del Sistema LMAN . . . . . . . . . . . . . . 86 6.1. Ejecución del programa Evasión de obstáculos . . . . . . . . . . . . . . 109 xi Índice de Anexos Anexo A. Traducción de procesos NTCC a código de bytes de LMAN . . . . 116 Anexo B. Librerı́as para la construcción de Programas en LMAN . . . . . . 125 xii Resumen NTCC (Non-deterministic Temporal Concurrent Constraint Calculus) [Val03] es una extensión de TCC[SJG94] para modelar dos nociones primordiales: No-determinismo y Asincronı́a en Sistemas Discretos-Temporales-Reactivos. Estas dos nociones, junto con su naturaleza simple, expresiva, formal y su propiedad de combinar una vista operacional, algebraica y declarativa de los procesos, hacen de NTCC un cálculo de gran aplicabilidad sobre sistemas multiagentes, dispositivos robóticos y aplicaciones musicales. Con ésta motivación en mente, surge la idea de implementar NTCC mediante una Máquina Abstracta, modelando en particular uno de los posibles aplicativos propuestos para NTCC: Programación de controladores RCX en robots LEGO MindStorm. De ésta manera, el presente trabajo de grado tiene como objetivos, tanto la especificación de la máquina abstracta de NTCC, como su implementación mediante una máquina virtual. La máquina abstracta actúa como el componente que da formalidad a la máquina virtual, siendo la máquina virtual propiamente el ejecutor notacional del cálculo NTCC. La especificación de la máquina abstracta incluye las reglas de reducción, la definición de estados inicial – final y las transiciones posibles. La máquina virtual por su parte, se compone de un conjunto de instrucciones, de registros y de un modelo de memoria que, actuando junto con un Sistema de Restricciones y un Protocolo de Comunicaciones, permiten controlar y ejecutar de manera eficiente y en tiempo real programas escritos en NTCC sobre los Robots LEGO MindStorm. xiii Introducción Los Cálculos Computacionales constituyen la base teórica formal de los lenguajes de programación. Sobre esta base es posible demostrar formalmente propiedades como correctitud y completitud en las construcciones hechas en el lenguaje. Los cálculos se caracterizan básicamente por una sintaxis para describir fórmulas bien formadas y una semántica que define las reglas de reducción. Existen diversos cálculos para modelar diferentes ambientes computacionales; NTCC [Val03] es un cálculo para programación de sistemas reactivos, heredero de los modelos CC[SRP91], TCC[SJG94] y CCS Calculi[Mil99]. Este trabajo busca implementar una máquina abstracta para NTCC y analizar su desempeño programando sistemas reactivos como los dispositivos robóticos LEGO. La Máquina Abstracta (LMAN) que se describe en el presente documento, incluye también la implementación de una Máquina Virtual que es realmente el ejecutor notacional de NTCC. La máquina abstracta es el componente formal que define las reglas de reducción y las transiciones posibles en las que se fundamenta la máquina virtual en su ejecución. La máquina virtual se compone de un conjunto de instrucciones, de registros y de un modelo de memoria que, fundamentados en la definición formal de la máquina abstracta, permiten ejecutar eficientemente y en tiempo real construcciones de NTCC. Esta máquina virtual ha sido construı́da en bloques funcionales brindando modularidad a la implementación. Consta de una interfaz con los robots LEGO MindStorm (interfaz LEGOS) que permite modelar la interacción constante con el ambiente propia de un sistema reactivo, una interfaz con un Sistema de Restricciones (interfaz STORE) (imprescindible en una implementación de programación CC[SRP91]) de dominios finitos, de una memoria de programa y, finalmente, de un control o cerebro operacional (controLMAN). A diferencia de otras implementaciones de máquinas virtuales [Lop99], [AB98] LMAN incluye no solo la noción de planeación de procesos, sino también la xiv noción de planeación de máquinas en el tiempo. Respecto al desempeño de LMAN, los resultados obtenidos en las pruebas demuestran eficiencia en la ejecución. Ha sido probada ejecutando construcciones NTCC[Val03] tales como evasión de obstáculos y movimiento en zigzag. Cabe notar que los programas se ejecutan en tiempo real, pese a que conllevan la resolución de restricciones aritméticas de dominio finito. En cuanto a la interfáz de programación que el actual proyecto provee al usuario, el propósito es construı́r alrededor de LMAN un ambiente de programación aplicativa, que incluye un Lenguaje VISUAL VIN [FQ04] para programación icónica en alto nivel y un compilador NTCC–LMAN [RCP03] que toma las entradas en NTCC y genera “Código de Bytes” para LMAN. El presente trabajo incluye el diseño e integración del compilador NTCC–LMAN, su implementación se describe en [RCP03] por F. Rocha, J.Chalá y M. Pabón; éste componente posibilita la programación en alto nivel, ya que los programas son escritos en NTCC, compilados y posteriormente ejecutados por LMAN sobre el robot LEGO. Este documento ha sido dividido en 7 capı́tulos: Capı́tulo 1, presenta los antecedentes involucrados en el desarrollo del proyecto, tales como la teorı́a CCP, el cálculo TCC, las definiciones de máquina abstracta y virtual, y las máquinas para cálculos de procesos que fueron referencia del actual trabajo: TyCO y MAPiCO. Capı́tulo 2, está dedicado al cálculo NTCC, enfatizando la sintáxis, la semántica y los aplicativos relacionados. Capı́tulo 3, trata la máquina abstracta definida para LMAN: análisis, especificación formal, reglas de reducción, estados y transiciones. Capı́tulo 4, describe la implementación de la máquina virtual, presentando la división en bloques funcionales: interfaz con el Sistema de Restricciones, interfaz con el dispositivo LEGO, el modelo de memoria y el Control. Se describe adicionalmente el funcionamiento de la aplicación y todos los elementos utilizados en la implementación. Capı́tulo 5, presenta el diseño del compilador NTCC–LMAN: sintáxis, semántica y generación de código. También se trata su integración con el actual trabajo de grado. xv Capı́tulo 6, se describen los ejemplos y pruebas realizadas ejecutando construcciones NTCC sobre LMAN. Se muestran comparaciones entre LMAN, el lenguaje ESTEREL[MR] y la máquina virtual estándar de LEGO. Capı́tulo 7, muestra las conclusiones del presente trabajo, enfatizando las actividades a futuro y las recomendaciones a partir de éste trabajo base. En la actualidad, no se ha reportado previamente en la literatura ninguna implementación de un cálculo temporal, concurrente, por restricciones validado sobre robots LEGO. En nuestro conocimiento, el actual trabajo de tesis constituye la primera implementación de este tipo. No obstante, es importante mencionar los desarrollos JCC [SRP03] y ESTEREL[MR] que están en la misma lı́nea formal de este trabajo y que han sido probados en programación de robots LEGO. xvi 1 ANTECEDENTES A lo largo de este capı́tulo encontrará los principales aspectos metodológicos utilizados en el desarrollo del actual trabajo de tesis; se tratarán las nociones generales sobre conceptos como concurrencia, cálculos de procesos y máquinas abstractas y virtuales; ésto con el propósito de establecer una base conceptual clara que permita comprender el presente trabajo. Al final del capı́tulo se recopilan los objetivos y las contribuciones del desarrollo que aquı́ se reporta. 1.1. CONCURRENCIA La definición de concurrencia está asociada con sistemas de múltiples agentes, también llamados procesos, que interactúan entre si en un mismo ambiente y al mismo tiempo. Esta definición cubre una gran variedad de modelos de la vida real, como lo son las aplicaciones sobre Internet, la programación de dispositivos robóticos, la computación móvil y los sistemas reactivos, entre otros. Observando ésta variedad de aplicaciones que tiene la computación concurrente, se hace necesario tener herramientas para analizar y razonar en torno a la misma. Estas herramientas deben ser confiables y precisas, por lo cual es necesario que tengan una base matemática y lógica, como la que existe ya para el modelo secuencial de programación a través del lambda calculo. El problema es que modelos como el anterior no son adecuados para la concurrencia debido a algunas propiedades inherentes a ésta, tales como: No-determinismo, representa la escogencia aleatoria de una opción entre múltiples. Computación Reactiva, mediante la cual se modelan sistemas de agentes que no 1 presentan un estado final debido a que responden a estı́mulos del ambiente en cualquier momento. Movilidad, referencia procesos que pueden cambiar sus enlaces y configuración de comunicación. Teniendo la necesidad de crear modelos precisos y confiables para procesos concurrentes y dado el gran campo de aplicaciones que tienen, es necesario construı́r modelos que traten comportamientos especı́ficos y que posean al menos algunas de las caracterı́sticas mencionadas anteriormente. Un modelo de esta naturaleza debe tener las siguientes propiedades: Debe ser simple, es decir que su base deben ser principios básicos. Debe ser expresivo, permitir modelar diferentes situaciones. Debe ser formal, fundamentado en bases matemáticas y lógicas. Debe aportar técnicas para poder razonar sobre los procesos. Una vez completado el modelo puntual podrán surgir extensiones a éste para incluir más propiedades dentro del dominio de problemas particular que se considera, como es el caso de los problemas que involucran números reales y aquellos que manejan la noción de tiempo(TCC), como se tratará a continuación. 1.2. CALCULOS DE PROCESOS La necesidad de obtener herramientas precisas y confiables que permitan demostrar propiedades como correctitud y completitud, da origen a los cálculos computacionales. Los cálculos llegan a constituirse en la base teórica formal de los lenguajes de programación. Los componentes básicos de un cálculo computacional son: Sintaxis, descripción de fórmulas bien formadas en el cálculo. Semántica, definición de las reglas de reducción y la forma como se interpretan cada una de las fórmulas. 2 Existe diversidad de cálculos para modelar diferentes ambientes computacionales como los cálculos π, CCP, TyCO, PiCO, ρ(cálculo del lenguaje OZ), entre otros. No obstante, el enfoque de éste trabajo de tesis son los cálculos de procesos. A continuación se tratarán los cálculos de procesos pertinentes a éste trabajo de tesis: CCP y DefaultTCC 1.2.1. CCP El cálculo concurrente de programación por restricciones (CCP)[VS91] es uno de los más conocidos formalismos para concurrencia. La noción básica de CCP considera múltiples agentes (procesos) ejecutándose al mismo tiempo y comunicándose por medio de variables compartidas que se encuentran en un almacén común o Store. En el Store la noción del valor de una variable se toma como un conocimiento parcial sobre ésta (ej: x se encuentra entre 10 y 20); conocimiento que se acumula dentro del almacén por medio de una restricción, que es una representación de un conjunto de posibles valuaciones (ej: 10 ≤ x ≤ 20). El sistema de restricciones asociado a un ambiente CCP, es quien se encarga de la interacción de los procesos con el Store. Intuitivamente puede considerarse que el Store almacena o acumula las restricciones; en el modelo, sin embargo, el Store representa la conjunción lógica de las mismas; por lo tanto, éste será monotónico; lo cual quiere decir, que la información que se agregue debe ser coherente con la que ya se tiene. Los procesos se comunican adicionando (operación tell ) al Store (en el sentido descrito arriba) y consultando (ask) información sobre las variables. Cuando en el Store no se tiene suficiente información para decidir si una restricción es verdadera o falsa, se suspende la ejecución del proceso hasta tener suficiente información para dar una respuesta; esta es la forma en que los procesos se sincronizan en el cálculo. Ejemplo 1.2.1. Considere el siguiente comportamiento; se tienen dos agentes, (A) es el encargado de reportar la temperatura en un edificio y (B ) será el encargado de activar la alarma de incendios, ejecutado un proceso Q si la temperatura es mayor que 75 grados centı́grados. Estos dos agentes se comunican por medio de una variable en común (t). Suponga que A comenta que la temperatura es mayor de 25 grados centı́grados (tell t > 25), después B pregunta si la temperatura es mayor que 75 (ask t > 75). Como en este 3 momento la información brindada por A no es suficiente para tomar una decisión, B queda suspendido. Dos horas más tarde, digamos, A reporta que la temperatura es igual a 80 grados (tell t = 80); en ese momento B puede obtener más información sobre el valor temperatura y activa la alarma contra incendios. La figura 1.1 presenta el modelo del problema. Figura 1.1: Modelo de un entorno CCP CCP posee varias extensiones: movilidad, comportamiento estocástico y una de las más significativas para el presente trabajo, la noción del tiempo. A continuación se definen el sistema de restricciones utilizado por CCP y algunas extensiones. 1.2.1.1. Sistema de Restricciones Se utilizará la definición de sistemas de restricciones encontrada en la tesis doctoral de Frank Valencia[Val03]: Definición 1.2.1.1 Un sistema de restricciones se define como una tupla (Σ, 4), en donde Σ representa un conjunto de constantes, funciones y sı́mbolos de predicado, y 4 es una lógica de primer orden consistente que opera sobre Σ. Siendo (Σ, 4) el sistema de restricciones, se definira Γ como su lenguaje de primer orden; el cual consiste en una tupla (Σ, V, S), donde V es un conjunto de variables {x, y, ..., z}, y S es un conjunto de operadores lógicos como ¬, ∧, ∨, ⇒, ∃, ∀, true, f alse los cuales hacen referencia a: la negación, la conjunción, la disyunción, la implicación, los cuanti4 ficadores universales y existenciales, y los sı́mbolos de verdadero y falso. El sistema de restricciones está compuesto por restricciones, denotadas por c, d, ..., que son fórmulas de primer orden sobre Γ. Se dirá que c deduce a d bajo 4, escrito c ⇒4 d si y solo si c ⇒ d es verdadero de acuerdo a la relación lógica 4. Por comodidad se escribirá c ⇒ d en vez de c ⇒4 d. Se dirá c ≈ d si y solo si c ⇒ d y d ⇒ c son verdaderos bajo 4. Algunos ejemplos de sistemas de restricciones son Herbrand y Getzen [VSG96]. 1.2.1.2. Cálculo CCP La sintaxis de CCP está dada por el cuadro 1.1: Agentes A, B, ... := Def iniciones D := P rogramas P, Q := true no haga nada | tell(σ) tell σ | ask(σ) → A ask σ | (vX)A Esconda X | A||B Ejecucion en paralelo | p(X) Def inicion de llamada ∈ | p(X) :: A |D.D Def inicion de agente D.A Cuadro 1.1: Sintaxis de CCP Donde: σ denota una o más restricciones primitivas. X, Y... hace referencia a las variables del cálculo. A denota un agente o proceso. D denota una secuencia de declaraciones de procesos y P, Q... es la definición de un programa. Los procesos se describen de la siguiente manera: El proceso true es equivalente a vacı́o; representa inactividad o el proceso que no hace nada. El proceso tell se encarga de adicionar la restricción σ al Store. El proceso ask pregunta al Store si la restricción σ se deduce de la información allı́ consignada; si puede deducirse, se ejecuta A, si deduce la negación de σ, se descarta A y si no puede deducir nada, el proceso queda suspendido hasta que se tenga suficiente información para tomar una decisión. EL proceso (vX)A sirve para ocultar o crear una variable local al proceso A con el objetivo de que esta solo sea visible para aquel. A||B denota la ejecución en paralelo, lo cual dice que A 5 y B se ejecutarán independientemente, pero se pueden comunicar y complementar de acuerdo a las acciones de cada uno. El proceso p(X) es la definición de llamada a un proceso. 1.2.1.3. Reglas Semánticas de CCP La descripción de las reglas semánticas expuestas aquı́, están de acuerdo a la semántica operacional, que interpreta un proceso como un conjunto de pasos computacionales. Se define la relación →(τ,τ 0 ) como la transición del Store τ al τ 0 . Las reglas semánticas se ilustran en el cuadro 1.2: T ELL ASK P AR HIDE tell(σ) →(τ,τ tσ) true (ask(σ)→A)→(τ,τ ) A A→(τ,τ ) A0 B→(τ,τ ) B 0 , 0 A||B→(τ,τ ) A ||B A||B→(τ,τ ) A||B 0 A→(τ,τ ) A0 (vX)A→(τ,τ ) A0 si τ ` σ si X es f resca Cuadro 1.2: Semántica de CCP La regla T ELL especifica la acción de añadir la restricción σ al Store mientras que el proceso original reduce a true. La regla del ASK modela el caso en que el Store puede deducir σ del Store τ , ejecutandose el proceso A. P AR especifica que la reducción puede ocurrir en cualquiera de los dos procesos, más no en ambos en el mismo paso computacional. HIDE implica el concepto de localidad de la variable X para el proceso A, lo que quiere decir que solo este proceso (y sus subprocesos) tendrá acceso a ella. 1.2.2. Default-TCC El modelo de programación concurrente por restricciones CCP ha demostrado ser muy efectivo y de gran ayuda para modelar propiedades de concurrencia en problemas reales; sin embargo, muchos de los problemas reales incluyen la noción de tiempo, que CCP no modela. 6 Para dar solución a esta falencia, se ha propuesto la extensión al calculo CCP denominada TCC – Temporal Concurrent Constraint Programming –. A partir de TCC surgieron posteriormente otras extensiones y variantes, tales como Default-TCC y NTCC –Non-deterministic Temporal Concurrent Constraint Programming – bases para el actual trabajo de tesis. TCC implementa la noción de tiempo discreto para poder modelar sistemas reactivos. Basado en la programación sincrónica (Berrey & Gonthier(1992), Halbwachs et al. 1991, Harel(1987)) TCC plantea agrupar todos los modelos temporales que se han trabajado anteriormente, basándose en la noción de tiempo multiforme y preemption (proceso interruptible), que implica que cualquier señal puede ”servir como unidad de tiempo”. Un sistema reactivo se define por su continua interacción con su ambiente de ejecución. Un claro ejemplo se puede ver en los dispositivos robóticos, que interactúan constantemente con su ambiente, para reaccionar, por ejemplo, cuando se presiona un sensor o se detecta un cambio en la percepción de la luz. Los sistemas de tiempo multiforme permiten modelar eventos condicionales de tiempo (time-outs) y retardos (unit-delays), entre otros. Un ejemplo de esto son ciertas acciones de tipo time-out que puede presentar un dispositivo robótico: si en una determinada cantidad de tiempo no ha recibido señal alguna, ejecuta una acción o proceso determinado. Con base en los sistemas reactivos y la noción de tiempo multiforme, TCC divide el tiempo en unidades discretas. En una unidad de tiempo TCC se captura el estado del ambiente, después se procesa esa entrada y, cuando se termina de procesar, se emite una salida al ambiente. Es posible que queden algunos procesos residuales que se ejecutarán en la siguiente unidad de tiempo. Es importante observar que en TCC el Store se vacı́a cada vez que una unidad de tiempo inicia. Ejemplo 1.2.2. Suponga un proceso P que se ejecuta en todas la unidades; P interactúa con el ambiente evaluando si la variable del ambiente x se encuentra en “1”. Cada vez que esto sucede, el ambiente deberá de ejecutar un proceso Q, de lo contrario, no se ejecuta nada. La figura 1.2 ilustra la ejecución del proceso. 1.2.2.1. Propiedad por Defecto (Default) Debido a que el modelo de programación por restricciones CCP maneja la noción de un Store monotónico, lo cual implica que la información nueva debe de ser coherente con 7 Figura 1.2: Ejemplo de un ambiente TCC la información actual, surgen problemas para expresar tanto la ausencia de información como la información negativa. La ausencia de información hace referencia a aquella información que no existe en el Store sobre la restricción que se pregunta, y la información negativa referencia aquella información que no es coherente con la información que ya contiene el Store. Debido al problema mencionado anteriormente, se ha propuesto modelar la propiedad Default, que representa un valor por defecto para una variable en caso de que el Store no tenga información sobre ésta. Esta propiedad no es obligatoria, es decir no todas las variables deben de tener un default. 1.2.2.2. Sintaxis de Default-TCC Al ser TCC una extensión de CCP, su sintaxis es similar. Se adicionan algunos constructores nuevos para manejar propiedades del tiempo y se perciben cambios de forma al escribir los procesos. La sintaxis de TCC está dada por el cuadro 1.3: A, B, .. = tell(σ) tell σ | if σ then A ask σ | if σ else A ask negativo σ | A, B Composicion paralela | hence A Ejecucion de A a partir de ahora | new X in A Encapsulamiento Cuadro 1.3: Sintaxis de TCC Donde: A, B, .. Denota un agente o proceso, X, Y, ... hace referencia a las variables del 8 calculo. σ representa una o más restricciones primitivas. Las descripción de los procesos es la siguiente: La acción de tell(σ) consiste en añadir la restricción σ al Store. El proceso if σ then A verifica si se puede deducir del Store la restricción σ; si esto es posible, se ejecuta el proceso A (note que este proceso tiene cierta similitud con ask(σ → A) en CCP). El tercer proceso if σ else A es el opuesto del anterior: si no se puede deducir σ del Store, entonces se ejecuta A, aclaración: el que no se pueda deducir σ no implica que se cumpla ¬σ).“Estos dos procesos cumplen con la propiedad de supuesto por defecto del calculo CC, ya que sirven para asegurar un supuesto”. A, B es el proceso de composición paralela, el cual representa dos procesos A y B que se ejecutan independientemente sobre el mismo Store. hence A es el operador del manejo del tiempo en TCC; significa que se impondrán las restricciones del proceso A en cada instante a partir de la ejecución del hence. new X in A es el proceso que construye la relación de encapsulamiento en TCC, que significa que solo el proceso A puede ver a X. 1.2.2.3. Semántica de Default-TCC La descripción de las reglas semánticas expuestas aquı́ es tomada de [VSG96]. Se define Γ, ∆, .. como multiconjuntos de programas,“que se entienden como procesos” , σ(Γ) como el conjunto de todos los tell que hay en Γ y la relación →b , como una transición binaria indexada por los supuestos finales b que serán usados para evaluar las acciones con default. La semántica de los procesos está dada por el cuadro 1.4: σ(Γ)`a T ELL Γ`(tell(a),∆) ς(Γ)`a ASK1 ((Γ,if a then B),∆)→b ((Γ,B),∆) ς(Γ)6`a ASK2 ((Γ,if a else B),∆)→b ((Γ,B),∆) P AR ((Γ, (A, B)), ∆) →b ((Γ, A, B), ∆) HEN CE ((Γ, hence A), ∆) →b (Γ, (A, hence A, ∆)) N EW ((Γ, new X in A), ∆) →b ((Γ, A[Y /X]), ∆) para Y no libre en A y Γ ∃b∈D (Γ,φ)→∗b (Γ0 ,∆)6→b σ(Γ0 )=b OBS → − Γ;new Y in δ Cuadro 1.4: Semántica de TCC 9 La regla T ELL se modela de manera similar que en CCP, especificando la acción de añadicionar la restricción σ al Store. ASK1 representa el caso en que se puede deducir a del Store, por lo tanto se ejecuta el proceso B.La segunda regla ASK2, describe el caso en que no hay suficiente información para deducir a, por lo que se ejecuta el proceso B.P AR presenta la ejecución de dos procesos en paralelo, bajo la condición que se reduce uno de los dos en cada paso computacional o transición interna.HEN CE describe la ejecución del proceso A y la posterior ejecución de HEN CE para el siguiente instante. Este proceso hace una analogı́a con la replicación, del cálculo π, para este cálculo.La regla N EW implica el concepto de encapsulamiento para la variable X en el proceso A, este proceso remplaza al HIDE de CCP. La última regla OBS se utiliza para definir una transición observable. Una transición observable indica las acciones visibles de un proceso para los espectadores externos a este; además de representar en este cálculo el paso de la unidad actual de tiempo a la siguiente. OBS se activa cuando el Store actual a alcanzado un estado de quietud implicando que no se pueda deducir conocimiento nuevo y que ninguna de las reglas anteriormente expuestas pueda realizar alguna reducción; de esta manera se finaliza la unidad actual de tiempo, dando las instrucciones que debe ejecutar el ambiente(∃− → σ(Γ)) y Y presentado los procesos que se deben ejecutar en el siguiente instante. Es importante mencionar que esta regla es la única transición observable de TCC . 1.3. MAQUINAS ABSTRACTAS Y MAQUINAS VIRTUALES 1.3.1. Definiciones Una Máquina Abstracta [Com00] puede definirse como un procedimiento para ejecutar un conjunto de instrucciones en algún lenguaje formal, tomando una entrada de datos y generando una salida. Algunas máquinas abstractas no pretenden ser implementadas en Hardware. Ejemplo: Máquina de Estados Finitos, Máquina de Turing, entre otras. Algunas máquinas abstractas implementan cálculos como PICT para π, MA TyCO para TyCO y MAPiCO para PiCO. Una Máquina Virtual [Com00] es un procesador no implementado en Hardware, pero que actúa como el ejecutor notacional de un Lenguaje de Programación particular. 10 Se compone de un conjunto de instrucciones, registros y un modelo de memoria. Es un Software de emulación para un ambiente fı́sico de computación o Hardware. Ejemplo: Máquina Virtual de Java y la Máquina Virtual de TyCO. 1.3.2. Máquina Abstracta y Virtual de TyCO TyCO (Typed Concurrent Objects) [Lop99], es un cálculo de procesos que implementa los conceptos presentes en los Lenguajes Orientados-Objetos combinado con la Programación Concurrente, todo en un ambiente de paso de mensajes y objetos que se comunican asincrónicamente. Este cálculo se origina en el CCS (Calculus of Communicating Processes)[Mil89] y toma del cálculo π las caracterı́sticas acerca de la definición de objetos, mensajes ası́ncronos y definiciones de plantillas, que se constituyen como las entidades fundamentales de TyCO. Este cálculo formalmente describe la interacción concurrente de objetos por medio de una comunicación ası́ncrona. La comunicación sı́ncrona es implementada incorporando en los mensajes un nombre extra para cubrir el resultado de la comunicación. Las plantillas se usan para modelar clases y un comportamiento tı́pico unbounded. Un sistema de tipos asigna tipos monomórficos a las variables y tipos polimórficos a las plantillas. A diferencia de otras implementaciones, la máquina virtual de TyCO descrita en [Lop99], involucra la definición de un lenguaje basado en el cálculo TyCO y provee una semántica estática, en la forma de un sistema de inferencia de tipos y una semántica dinámica, en forma de una máquina abstracta. Este marco formal es el que define la base para el diseño de la máquina virtual y el compilador del lenguaje asociado. La máquina virtual ejecuta programas TyCO traducidos en un formato de ”código de bytes”. Cuenta con una arquitectura compacta e independiente, y su desempeño resulta favorable al comparase con otras implementaciones de su tipo. La máquina ha sido afinada para TyCO, pero puede ser usada para implementar otro cálculo incluyendo los cambios necesarios o extensiones a su semántica. Es implementada como un emulador de ”código de bytes”, definiendo un montón (heap) para las estructuras de datos dinámicas, una cola de ejecución (run–queue) para planificación del ”código de bytes, un arreglo para las variables locales y una pila de operandos para la evaluación de expresiones. El lenguaje de programación TyCO se define como un lenguaje tipado low–level kernel, con una sintaxis y semántica muy cercanas al cálculo mismo; solamente incluye 11 unos pocos constructores derivados y tipos de datos. El sistema de inferencia de tipos es el encargado de asegurar correctitud de tipos en los programas, en los nombres y adicionalmente garantiza que no existirán errores de protocolo en tiempo de ejecución. 1.3.2.1. Lenguaje de programación TyCO El lenguaje de programación TyCO utiliza una sintaxis muy cercana al cálculo mismo. Toma como base la sintaxis del cálculo TyCO y define las categorı́as básicas para el lenguaje de programación subyacente que se observan en la figura 1.3. Figura 1.3: Categorı́as básicas del lenguaje de programación TyCO La novedad en el lenguaje TyCO es la introducción de dos nuevas categorı́as sintácticas: instrucciones e hilos(threads), (Ver figura 1.4). Las instrucciones están muy relacionadas con los procesos TyCO y son elementos del conjunto Instr, nombrado como I. Los hilos son elementos del conjunto Thread de colas de instrucciones, nombrado como T. Figura 1.4: Nuevas Categorı́as del lenguaje de programación TyCO La sintaxis del cálculo fuente del lenguaje TyCO utiliza los hilos como la categorı́a principal, su gramática se describe en la figura 1.5. 12 Figura 1.5: Gramática del lenguaje de programación TyCO Para ilustrar el cálculo TyCO se presenta un ejemplo tomado de [Lop99], que da solución al problema de la Criba de Eratóstenes, tal como se describe a continuación. Se define una secuencia de procesos plantillas los cuales generan un flujo de números naturales y chequean cuales de ellos son primos. Todos los números primos encontrados se adicionan a la cadena de cribas que crece dinámicamente; de modo que se adiciona una criba por cada número primo encontrado. Esta cadena de cribas, filtra los naturales mientras ellos son generados en Nats. El código que resuelve éste problema en TyCO sigue a continuación. def Nats = (n m sieve) sieve![n] ; if n < m then Nats[n+1 m sieve] and Sieve = (self prime nextsieve) self ? (n done) (if n % prime != 0 then nextsieve![n done] else done![]) | Sieve[self prime nextsieve] and Sink = (self) 13 self ? (n done) io!put[n] | new newsieve Sink[newsieve] | Sieve[self n newsieve] | done![] in io!put[2] | new sieve Nats[2 1000 sieve] | Sink[sieve] Del ejemplo anterior se observa que Nats es quien genera el flujo de naturales entre n y m, donde cada natural es enviado a la primera criba en la cadena de cribas (sieve) para su chequeo. La generación de un natural por Nats es sincronizada con señales generadas cuando se realizan actualizaciones en la cadena. Sieve es una plantilla definida para las cribas en la cadena. El procedimiento, toma el natural n y lo pasa de criba en criba en la cadena chequeando que éste no pueda dividirse por ninguna. Si sucede lo último, el natural se olvida y la criba envı́a una señal a Nats para proceder a generar un nuevo número natural. Sink (llave) es quien señaliza el final de la cadena; de modo que, un natural que logra llegar hasta el final se toma como un primo y se imprime. El proceso finaliza, extendiendo la cadena al adicionar una nueva criba cuyo primo es n, situando sink luego del nuevo primo para demarcar y enviando una señal a Nats para generar un nuevo número. En el anterior bloque de código, se llama a Nats para un flujo de naturales entre 2 y 1000. 1.3.2.2. Máquina Abstracta de TyCO La semántica dinámica del lenguaje de programación TyCO se define en forma de una máquina abstracta. De ésta manera, la máquina abstracta es quien confiere el componente de formalidad al flujo de implementación que incluye el lenguaje, el compilador y la máquina virtual. A continuación se mencionan cada uno de los aspectos más importantes en la definición de la máquina abstracta de TyCO. 1.3.2.2.1. Categorı́as Sintácticas . La definición de la máquina abstracta incluye las siguientes categorı́as sintácticas: 14 Ambiente de un hilo, representado como un mapeo de variables a valores: VBind = Var 7→ Val. Se denota B. Plantillas, son representadas como un mapeo de variables a pares de variables y abstracciones: TBind = Tvar 7→ VBind x Abs. Se denotan K. Mensajes, llevan una etiqueta y una secuencia de valores. Se mantienen en las colas de: QComm = QueueLabel x Name*. Se nombran como ms. Objetos, contienen una tabla de métodos y ligaduras de variables libres. Se mantienen en las colas de: QMeth = Queue(VBind x Meth). Se nombran como Ms. Canales, son elementos del conjunto QBind = Name 7→ (QComm S QMeth) de colas de mensajes u objetos. Se nombran como Q. Cola de ejecución, es un elemento del conjunto RunQueue = Queue(VBind x Thread) donde los hilos y sus ambientes se mantienen esperando por ejecución. Se nombra como R. Estado–de–Máquina, denotado por S, es una tupla en el conjunto State = TBind x VBind x QBind x Thread x RunQueue. 1.3.2.2.2. Estados Inicial y Final . Para la máquina abstracta de TyCO se definen los estados inicial y final como sigue: Estado Inicial: Dado un hilo T, la máquina abstracta inicia la computación con una cola de ejecución vacı́a, sin variables ni plantillas de ambientes y sin colas en los canales. El estado inicial es representado por: ∅, ∅, ∅, T, • Estado Final: La máquina se detiene cuando ninguna regla puede ser aplicada; es decir, cuando se alcanza el estado final de la forma: , , , •, • 15 1.3.2.2.3. Reglas de reducción . Las reglas de reducción descritas en la figura 1.6, realizan transformaciones de estados en estados. Cada una de estas reglas requiere ciertas condiciones para que las reducciones sean exitosas; de lo contrario, la máquina llega a un estado de bloqueo. Figura 1.6: Reglas de Reducción de la máquina abstracta de TyCO 1.3.2.2.4. Propiedades de la máquina abstracta . La máquina abstracta de TyCO presenta las siguientes propiedades[Lop99]: 1. La máquina abstracta es sana, es decir, que cada transición puede ser vista como una reducción o una congruencia entre las reglas y el cálculo. 2. En cualquier momento de computación, las colas asociadas con nombres están vacias o tienen solamente comunicaciones o tienen clausuras de métodos (methodclosures). 16 3. Para programas correctos la máquina no presenta bloqueos. Esta propiedad está ligada a la caracterı́stica del sistema de tipos que garantiza que no existirán errores de protocolo en tiempo de ejecución. 4. La máquina abstracta es justa, es decir que, dado un hilo, éste siempre se ejecuta un tiempo después de que llega a la cola de ejecución. 1.3.2.3. Máquina Virtual de TyCO La especificación formal presentada anteriormente como máquina abstracta, define la implementación de la máquina virtual de TyCO. El diseño e implementación fue inspirada en STG-Machine[Jon92, JNO97], la Máquina Virtual de Java[LY97] y WAM[War83]; no obstante, el modelo computacional es tomado de la especificación formal de la máquina abstracta. A continuación se describe los componentes asociados a la implementación de la máquina virtual de TyCO. 1.3.2.3.1. Arquitectura de Memoria . Para la máquina virtual de TyCO se definen cinco áreas de memoria. Ver figura 1.7 Figura 1.7: Areas de Memoria de la máquina virtual de TyCO 1. Area de Programa: mantiene las instrucciones en código de bytes a ser ejecutadas. El código de bytes se compone de bloques de instrucción y tablas de metodos (secuencias de punteros a los bloques de código). 2. Montón: es un espacio de direcciones planas donde las estructuras de datos dinámicas como objetos, mensajes y canales son localizados. El bloque constructor 17 básico del montón es la palabra(machine word); y la unidad de alocación básica es el marco(frame) y consiste de uno o más palabras contiguas con un descriptor para la recolección de basura. La máquina manipula tres clases básicas de procesos en tiempo de ejecución: mensajes, objetos e instancias. Los mensajes y objetos se localizan en canales compartidos, y son vistos externamente como marcos. Los marcos de mensaje esperan por una etiqueta y una lista de argumentos. Los marcos de objetos esperan por un puntero al código donde se encuentra la tabla de métodos, más las ligaduras de las variables libres asociadas a los métodos. Un marco de instancia espera por una referencia al código que ubica las plantillas, ligaduras y argumentos de una instancia. Los canales finalmente son marcos especiales utilizados en la comunicación entre colas e implementan la noción de nombres en el cálculo. 3. Cola de Ejecución: espera vm threads o bloques de instrucciones contiguas asociados a un hilo, listos para ejecución y sus respectivos ambientes. Esta cola crece en la misma dirección del montón. Cada vm thread consiste de una estructura de datos con una referencia al código del programa, una referencia a un marco con los parámetros y una referencia a un marco en el montón con las variables libres. Cada vez que una reducción ocurre, un nuevo vm thread es creado y colocado, junto con su ambiente, en la cola de ejecución donde espera ser planificado para ejecución. 4. Arreglo de variables locales: Ya que cada vm thread crea nuevas variables locales; cada vez que una variable local es creada, la siguiente posición disponible en el arreglo de variables locales es asignada y ligada al canal que ya ha sido definido. Cada que un vm thread termina, las ligaduras locales se descartan y se sobreescriben las asignaciones cada vez que el siguiente vm thread pase a ejecución. 5. Pila de Operandos: la máquina virtual admite directamente tipos de datos definidos en TyCO; es decir, que existen instrucciones que implementan operaciones booleanas sobre booleanos, operaciones aritméticas sobre enteros y flotantes y operaciones relacionales sobre enteros, flotantes y cadenas. Para las cadenas también existen instrucciones para computar su tamaño y para concatenar. La implementación actual admite listas. Todas estas operaciones se realizan en el área de memoria denominada pila de operandos. Cuando las expresiones son simples como constantes o variables que no requieren evaluación, son directamente 18 copiadas al montón para procesar; de lo contrario, las expresiones que requieren de evaluación pasan del montón a la pila para evaluación y de nuevo a una nueva ubicación en el montón para ejecución. 1.3.2.3.2. Registros . La máquina virtual utiliza registros globales para controlar el flujo del programa y manipular la máquina y las estructuras de datos asociadas. El conjunto de registros se muestra en el cuadro 1.5. Registros Descripción PC (Program Counter) HP (Heap Pointer) apunta a la siguiente instrucción a ser ejecutada. apunta a la siguiente posición disponible en el montón. apunta al inicio de la cola de ejecución. apunta al final de la cola de ejecución. apunta al ultima posición utilizada de la pila. apunta a la base del arreglo de variables. apunta al canal actualmente usado en la reducción. espera por marcos temporales hasta que ellos sean encolados o usados en una reducción. se utiliza cuando se esta ejecutando una reducción. espera por variables libres. espera por parámetros. SQ (Start Queue) EQ (End Queue) OS (Operand Stack) LV (Local Variable Array) CC (Current Channel) CF (Current Frame) OF (Other Frame) FV (Free Variable bindings) PM (Parameter bindings) Cuadro 1.5: Registros de la máquina virtual de TyCO 1.3.2.3.3. Conjunto de Instrucciones . La máquina virtual de TyCO utiliza un tamaño minimizado en el formato de instrucciones para fines de eficiencia. Las instrucciones son identificadas por un código de operación único apuntado por el registro del PC y han sido implementadas como funciones tipo C, sin parámetros. 1.3.2.3.4. Flujo de Datos TyCO . 19 Finalmente, es importante mencionar que la implementación de TyCO incluye un compilador de código fuente a código ensamblador, un ensamblador de código de bytes y un emulador de código de bytes. El emulador es básicamente la implementación de la máquina abstracta. El código ha sido escrito en lenguaje C buscando eficiencia. La figura 3.1 ilustra el flujo de datos en el sistema TyCO. Figura 1.8: Flujo de datos del sistema TyCO 1.3.3. Máquina Abstracta de PiCO El diseño e implementación de la máquina abstracta para el cálculo PiCO[ADQV98], MAPiCO[AB98], no realiza la diferenciación entre máquina abstracta y máquina virtual, tal como se presentó en la sección anterior para TyCO. Sin embargo, esta diferenciación está implı́cita, ya que, para MAPiCO se define la máquina abstracta en forma de reglas de reducción y, adicionalmente, se implementa el emulador subyacente. Para MAPiCO, igualmente, se define un flujo de datos que incluye el lenguaje visual CORDIAL, un compilador de PiCO a MAPiCO y el emulador denominado MAPiCO. A continuación se describen los componentes más importantes de la implementación de MAPiCO. 1.3.3.1. Especificación Formal PiCO[ADQV98] es un cálculo que integra objetos concurrentes y restricciones como elementos básicos. El modelo de objetos se extiende adicionando la noción de un sistema 20 de restricciones, además de la noción de delegación de mensajes, confiriendo una manera natural de expresar comportamientos de comunicación usando sincronización en el paso de mensajes. Uno de las aplicaciones de éste cálculo es la representación musical, de manera que es posible utilizar PiCO para modelar objetos musicales como armonı́as, patrones, secuencias de acordes y melodı́as, entre otros. Como ilustración del cálculo PiCO se muestra la codificación de factorial [AB98]. Primero se muestra la definición recursiva y luego su codificación en PiCO. f act(x, r) ::= r = 1 |r = f ac(x − 1) ∗ x f act(3, r) si x = 1 si x > 0 .(v x y)(v f ac)((∗f ac . [input : (n, r)(?(n = 0).!(r = 1) |?(n > 0).(v y a)((!y = n − 1) . |(f ac/ input[y, a])) |!(r = a ∗ n)))]) . . |!(x = 3).f ac/ input[x, y]) . MAPiCO es la máquina abstracta que implementa el cálculo PiCO. En MAPiCO se definen todos los componentes que confieren formalidad a la implementación, de modo que se logre un nivel de correspondencia entre el cálculo y la máquina. 1.3.3.1.1. Estructuras de Datos . Las estructuras de datos usadas por MAPiCO en la especificación formal se describen en la siguiente tabla: RunQ: cola de ejecución. Obj: cola de objetos suspendidos. MsgQ: cola de mensajes suspendidos. AskQ: cola de procesos ask suspendidos. S: Store. Memoria de Ligaduras: memoria dinámica que almacena las pilas de procesos y el arbol sintáctico con las restricciones. 21 Memoria del Programa: memoria estática que almacena las instrucciones a ejecutar. Registros internos: se definen cinco registros internos para la máquina. 1.3.3.1.2. Estados Inicial y Final . Cada vez que se ejecuta un hilo, el proceso asociado cambia de estado; los estados de un proceso se definen, de acuerdo a su actividad actual, en: ejecución, listo, suspendido o finalizado. Un estado en MAPiCO se representa como: Hilo, HBind, HAux, ObjQ, MsgQ, AskQ, RunQ, Store donde Hilo, HBind y HAux representan el proceso que está siendo ejecutado. La memoria de programa no se referencia en la definición de estado ya que ésta es estática; por lo tanto, no se modifica en tiempo de ejecución. Los estados inicial y final se definen a continuación (• es utilizado para indicar que la cola está vacia y :: indica concatenación de colas). Estado Inicial: la máquina comienza en un estado donde las colas de objetos, de mensajes, de ask y de ejecución, están vacias y no hay ligaduras; además, el Store está inicialmente vacı́o. P~ P~ , ∅, ∅, •, •, •, •, ∅ Estado Final: a éste estado solo se llega cuando no hay nada más que planificar en la cola de ejecución. La máquina reconoce que los procesos que han quedado suspendidos en Oq, Msq y Aq están suspendidos y que no pueden ser reducidos. nil, B, H, Oq, Msq, Aq, •, S 1.3.3.1.3. Reglas de reducción . En la semántica operacional de MAPICO las reglas de reducción son transiciones de estados a estados. Las reglas de reducción se muestran en las figuras 1.9 y 1.10. 22 En MAPiCO cada regla toma el primer proceso de la cola de ejecución RunQ y ejecuta una paso de reducción en el proceso. La regla SCHED remueve el proceso actual en ejecución, permitiendo que el siguiente pueda reducirse. NEW-REF es la regla → − que define la creación de nuevas variables; de modo que, el proceso (vx) P crea un nuevo enlace de x a L, donde L es el nuevo nombre generado por el sistema. La regla PARALLEL crea un nuevo proceso Q, lo situa al final de la cola RunQ, y sigue con la ejecución del proceso P. TELL define la forma en que se comenta al Store; asi, para → − e es comentada al Store y los procesos reducir un proceso tell(!φ. P ), la restricción φ(L) suspendidos en las colas Aq y Msq pasan a ejecución para intentar ser reducidos, se → − continúa con la ejecución de P . Para ASK se definen tres casos: ASK1 donde si el → e la máquina continúa ejecutando (− store deduce φ(L), P ); ASK2 donde si el store logra e la máquina elimina el proceso actual; y finalmente ASK3 caso en el deducir ¬φ(L), e ni tampoco ¬φ(L), e luego, se suspende el proceso y cual el Store no pude deducir φ(L), se envia a la cola Aq. En cuanto a las reducciones relacionadas con mensajes; MSgEnQ es la regla que define la reducción de un paso de mensaje a un objeto que no se encuentra en la cola Oq, caso en el cual se suspende el mensaje en la cola Msq. La regla MsgComm define que si → e − el proceso es un mensaje I / li : [K]. P a un objeto en la cola Oq y la etiqueta del mensaje li concuerda con una en el conjunto de métodos del objeto, éste último se → − e se envı́an a la cola elimina y el cuerpo del método Pi , con el nuevo enlace para K RunQ para ejecución. MsgDel define la reducción en caso que el objeto (I 0 , J 0 ) . [l1 : − → −→ (xe1 P1 , . . . , lm : (f xn )Pm ] exista en la cola Oq, no exista una etiqueta li para comunicarse → e − con I / li : [K]. P , pero si posea una dirección de delegación; entonces, el receptor del mensaje se cambia por la dirección de delegación. De igual manera si el objeto anterior existe en Oq, noy ha una etiqueta li para comunicarse, y no tiene una dirección de delegación, el mensaje se suspende en la cola Msq como se describe en la regla MsgWODel. Para objetos se tienen las siguientes reglas; ObjEnQ que define la situación en la cual no → −→ f − hay ningún mensaje para comunicarse con el objeto (I, J). [l1 : (x1) P 1, . . . , lm : (f xn )Pm ] en la cola Msq para comunicarse, por lo tanto el objeto es pasado a la cola de objetos Oq → e − para posterior reducción. ObjComm presenta el caso en que el mensaje I/ li : [K]. P − → −→ espera comunicarse con el objeto (I, J). [l1 : (xe1 )P1 , . . . , lm : (f xn )Pm ], y existe una etique li ; luego el mensaje es eliminado de la cola Msq, y la continuación del mensaje → − P puesto para ejecución, seguido por el cuerpo del método con el nuevo enlace para 23 e ObjDel describe la misma situación anterior, con delegación, pero sin etiqueta li ; K. luego el mensaje es pasado al final de la cola RunQ,pero cambiando el objeto receptor pr la dirección de delegación y el objeto es pasado a la cola Oq. Por último, para el mismo caso, pero sin delegación, ni etiqueta, el objeto se pasa a la cola Oq, como se muestra en ObjWoDel. 1.3.3.2. Diseño de MAPiCO MAPiCO está compuesta por dos áreas de memoria, cuatro colas para los diferentes estados de ejecución de un proceso, y un sistema de restricciones que provee, tanto el almacenamiento de restricciones, como las operaciones ask y tell [AB98]. La entrada de la máquina es código de bytes y se asume que es correcta, por lo que no se realizan chequeos. La implementación fue realizada en lenguaje Java. El diseño se muestra en la figura 1.11. Los elementos básicos en el cálculo PiCO son: objetos, mensajes, restricciones, variables y nombres, los cuales se modelados uno a uno en la máquina. Existen cuatro colas de procesos: una cola para los objetos que aún no han establecido comunicación o son replicados, otra para los mensajes y en tercer lugar una cola de ask que han quedado suspendidos. Debido a la naturaleza de PiCO como cálculo de procesos concurrente y por restricciones, la implementación de MAPiCO está asociada a un Sistema de Restrticciones que mantiene un Store monotónico donde se almacena la información, y al que se accede via operaciones ask para hacer preguntas y tell para adicionar información. El programa se ubica en una memoria estática o Memoria de Programa donde se almacenan todas las instrucciones en código de bytes para ser ejecutadas. Por ultimo, existe un área de memoria dinámica o Memoria de Traducción utilizada para mantener las ligaduras de variables y nombres. En ésta área de memoria también son almacenados los parámetros usados por los métodos y el árbol sintáctico que representa una restricción. 1.3.3.2.1. Registros . En MAPiCO se definen cinco registros de uso especı́fico que guardan información de la 24 Figura 1.9: Reglas de Reducción de la máquina abstracta MAPiCO, parte I 25 Figura 1.10: Reglas de Reducción de la máquina abstracta MAPiCO, parte II memoria y de los procesos, los cuales se muestran en el cuadro 1.6. 1.3.3.2.2. Formato de Instrucciones . Las instrucciones estan representadas por un código de operación y de 0 a 3 atributos. Las instrucciones pueden ser clasificadas en tres grupos: para manipular procesos, para definición de objetos y para la construcción de predicados de primer orden. Los atributos utilizados en el formato de instrucciones se describen a continuación: Opcode: código de operación de la instrucción, 8 bits Dir: dirección válida en la memoria de programa, 32 bits Ind: indice dentro de alguna de las listas de variables o nombres, 16 bits Num: número constante entero. Para objetos especifı́ca el número de métodos. Para métodos y mensajes especifı́ca su nombre o referencia, 16 bits. 26 Figura 1.11: Diseño de MAPiCO Fun: código de la función, 8 bits para el sistema de restricciones actual. Pred: código del predicado del átomos, 8 bits Ari: aridad de la función o del átomo, 8 bits Con: código del conector, and (0), or (1), 8 bits Cuan: código del cuantificador o negacións, ∃ (1) ∀ (2) not (0) 8 bits 1.3.3.2.3. Sistema de Restricciones . En PiCO las restricciones se definen como predicados de primer orden(∅)[AB98] bajo una sintáxis de términos, átomos y sentencias. Ası́ en MAPiCO, éstos predicados son modelados por instrucciones que permiten construir el árbol sintáctico que describe la 27 Registros Descripción PCA (Puntero a Código Actual) PVA (Puntero a Variables Actual) PNA (Puntero a Nombres Actual) PAA (Puntero Auxiliar Actual) PAUX (Puntero Auxiliar) apunta a la instrucción en ejecución. apunta al PV del proceso en ejecución. apunta al PN del proceso en ejecución. apunta al PA delproceso en ejecución. usado en la manipulación y ejecución de procesos. Cuadro 1.6: Conjunto de Registros de MAPiCO restricción. Esta particularidad permite que el sistema de restricciones se adicione paramétricamente a la máquina; es decir, que dado un sistema de restricciones que exprese sus restricciones en terminos de predicados de primer orden, éste puede adicionarse a MAPiCO sin mayores modificaciones. El sistema de restricciones que utiliza la actual implementación de MAPiCO define restricciones de dominio finito; este sistema se describe en [CG01]. Se fundamenta en el modelo de Bjorn Carlson [Car95] y fue implementado en lenguaje C. 1.4. OBJETIVOS Y CONTRIBUCIONES DE ESTE TRABAJO DE TESIS El presente trabajo de tesis utiliza el cálculo de procesos NTCC – Non-deterministic Temporal Concurrent Constraint Calculus – [Val03] para definir e implementar su máquina abstracta y virtual; la máquina se prueba en aplicaciones asociadas a NTCC: Programación concurrente de controladores RCX en robots LEGO. NTCC es una extensión de TCC [SJG94], que adiciona las nociones de No-determinismo y Asincronı́a actuando sobre sistemas Discretos-Temporales-Reactivos. NTCC permite modelar: retardos unitarios o unit-delays, para forzar la ejecución de un proceso en el siguiente instante de tiempo; time-outs, que esperan durante el instante actual a que una pieza de información esté presente y, de lo contrario, activan un proceso para ejecutar en el siguiente instante; preemption y tiempo multiforme, que permiten que los procesos sean “regulados” por otros procesos, dando la posibilidad de definir múltiples formas de tiempo en vez de tener un único reloj global. Finalmente, modelan sincronı́a 28 al igual que TCC. La asincronı́a es modelada como operaciones de retardos finitos pero no limitados o unbounded-finite-delays y el no-determinismo por operaciones de eventualidad limitada o bounded-eventuality. La perspectiva reactiva de éste cálculo, hace que NTCC sea de gran aplicabilidad en programación de diversos dominios de concurrencia tales como: Shared Variables Communication Systems, donde agentes interactúan escribiendo y leyendo información de una locación central o Store; Reactive Systems, donde se mantiene una interacción continua con el ambiente; Timed Systems, en los que agentes se restringen por requerimientos temporales y, finalmente, Syncronous y Asyncronous Systems. La aplicabilidad sobre estos sistemas permite ilustrar la expresividad de NTCC, y para el caso del actual trabajo de tesis permite ilustrar la aplicabilidad de NTCC para programar sistemas reactivos como los dispositivos robóticos LEGO. En la actualidad existen algunos lenguajes que permiten programar estos dispositivos siguiendo esta lı́nea, tales como LUSTRE y ESTEREL [MR]; lenguajes sı́ncronos para robots LEGO y JCC[SRP03] que permite integrar Timed Default Concurrent Constraint Programming con Java. Este trabajo de tesis describe el diseño e implementación de la máquina abstracta y la máquina virtual de NTCC (LMAN). Adicionalmente, se describe el diseño y acople del compilador NTCC-LMAN, que permite escribir programas NTCC en alto nivel para la máquina. Los objetivos de éste trabajo se describen a continuación: Construir la máquina abstracta del cálculo NTCC, manteniendo una equivalencia entre la máquina y el cálculo. Diseñar e Implementar la máquina virtual del cálculo NTCC, asegurando eficiencia y ejecución en tiempo real sobre Robots LEGO MindStorm. Acoplar un Sistema de Restricciones de dominios finitos y asegurar ortogonalidad en su adición a la máquina. Diseñar y Acoplar un Compilador NTCC-LMAN que permita crear programas en alto nivel para LMAN. LMAN toma principalmente como referencia las máquinas para cálculos de procesos TyCO[Lop99] y MAPiCO[AB98] descritas en brevedad en las secciones anteriores. La semántica utilizada es realmente cercana a la definción del cálculo mismo, demostrando ası́ su expresividad. La especificación de una máquina asbtracta para el cálculo le 29 confiere una base formal a la implementación de la máquina virtual, idea tomada de la máquina de TyCO[Lop99]; adicionalmente, facilita las pruebas formales de correspondencia entre el cálculo y la actual implementación. La máquina virtual es implementada como un emulador de código de bytes que se compone de cuatro bloques funcionales: memoria de programa, Interfáz LEGO, Interfáz STORE, y el ControlLMAN. A diferencia de otras implementaciones de otras máquinas para cálculos de procesos[AB98, Lop99] LMAN maneja no solo la noción de planificación de procesos, sino también de planficación de máquinas en el tiempo. Un sistema de restricciones de dominio finito[CG01] ha sido adicionado a LMAN. La definición de restricciones como fórmulas de primer orden en LMAN, idea adoptada de la implementación de MAPiCO[AB98], asegura que el sistema de restricciones se adiciona de forma paramétrica a la actual implementación, de modo que para extensiones futuras cualquier sistema de restricciones que exprese sus restricciones como fórmulas de primer orden puede ser adicionado. Respecto a la ejecución, LMAN resulta completa y eficiente ya que aunque se ejecuta desde una estación de trabajo y requiere de un protocolo de comunicaciones con el robot LEGO, se observa que los programas NTCC corren eficientemente y en tiempo real. Adicionalmente, su implementación posibilita modelar problemas que involucran hasta dos agentes robóticos; con algunas adiciones es posible modelar sistemas multiagentes. LMAN ha sido desarrollada para servir como ambiente de pruebas y para la enseñanza introductoria de lenguajes de programación concurrente y por restricciones. Para ello. ha sido diseñado e implementado el compilador NTCC-LMAN y un lenguaje Visual[FQ04], haciendo que la interfáz con el usuario resulte amigable. En la actualidad, no conocemos de otra implementación de un cálculo de procesos, temporal, concurrente por restricciones validado sobre robots LEGO. Consideramos que la máquina que aquı́ se reporta es la primera implementación de ésta naturaleza. En particular, LMAN constituye una implementación completa y eficiente del cálculo NTCC; ésta modela de manera cercana las reglas de reducción del cálculo, facilitando las pruebas formales de correctitud en la actual implementación. 30 2 CALCULO NTCC En este capı́tulo se describe el cálculo NTCC [Val03], base del presente trabajo de tesis. Se describe en brevedad la sintáxis, semántica operacional y ejemplos de aplicaciones NTCC. 2.1. Descripción General La extensión TCC agrega la noción de tiempo a CCP. Existen, sin embargo, otras caracterı́sticas que se hace necesario modelar; dos de ellas son la asincronı́a y el nodeterminismo. Procesos como: “el sistema debe entregar un mensaje pero no hay un limite de tiempo preciso sobre cuándo debe hacerlo”, “el sistema debe ejecutar la tarea c en alguna de las siguientes t unidades de tiempo” o la posibilidad de escoger entre múltiples opciones correctas para ejecutar una tarea (Ejemplo: la decisión que toma un dispositivo robótico en el momento de moverse al ejecutar zig-zag), no son expresables en TCC. Con los ejemplos anteriores es posible concluir lo siguiente: “la asincronı́a da libertad a los procesos de responder a una velocidad relativamente indeterminada. Solo asegura que los procesos se ejecutan en algún momento, más no asegura cuándo. El no-determinismo es importante para modelar respuestas y comportamientos correctos e impredecibles de los procesos. ”[Val03]. Estas propiedades también facilitan la tarea de describir procesos computacionales, sin necesidad de sobre-especificarlos. Debido a las necesidades de modelar y utilizar los beneficios de las propiedades anteriormente expresadas, surge el cálculo NTCC (Non-Deterministic Temporal Concurrent Constraint Programming ), que es una extensión ortogonal del calculo TCC, 31 al que se adicionan las propiedades de no-determinismo y asincronı́a. En NTCC es posible modelar con facilidad: retardos unitarios, para forzar la ejecución de un proceso en el siguiente instante de tiempo; time-outs, que esperan durante el instante actual a que una pieza de información este presente y, de lo contrario, activan un proceso para ejecutar en el siguiente instante; preemption y tiempo multiforme, que permiten que los procesos sean “regulados”por otros procesos, dando la posibilidad de definir múltiples formas y señales de tiempo en vez de tener un único reloj global. Finalmente, modela también sincronı́a al igual que TCC. La asincronı́a en NTCC es representada por operaciones de retardos finitos pero no limitados o unbounded-finite-delays y el nodeterminismo por operaciones de eventualidad limitada o bounded-eventuality, que se tratan en los procesos ∗P y σ when ci do Pi respectivamente. NTCC es de gran aplicabilidad en la programación de dispositivos robóticos, sincronización de procesos musicales y sistemas multiagentes; aplicaciones en que se presentan ciclos en los que se recibe una entrada del ambiente, se procesa y luego se regresa de nuevo al ambiente la correspondiente salida, comportamiento propio de sistemas reactivos. NTCC sigue el mismo comportamiento de TCC, en cuanto al manejo de la unidad de tiempo; es decir, el lapso entre el retorno de una respuesta al ambiente y la recepción de la entrada del mismo, define una unidad de tiempo. A partir de esta concepción reactiva-temporal es que se definen nuevos procesos y propiedades en estos cálculos temporales. 2.2. Sintaxis de NTCC La sintaxis de NTCC difiere en forma respecto a la de TCC, pero los conceptos globales son similares; además de incluir nuevos operadores para las propiedades de nodeterminismo y asincronı́a. La sintaxis de NTCC está dada en el cuadro 2.1. c, d, ... denotan las restricciones. P, Q, A, ... representan los procesos del cálculo. x, y, .. se utilizan para hacer referencia a las variables de los procesos. El proceso skip es utilizado para representar inactividad. El proceso tell c adiciona la restricción c al Store en el intervalo de tiempo actual; operación que puede causar inconsistencias en el Store, si c no es coherente con la información actual. 32 P, Q, ... = skip N o haga nada |tell(c) tell c P | i∈I when (ci ) do Pi Seleccione un Pi , si ci , i ∈ I |P ||Q Ejecucion en paralelo |Local x in P Localidad |next P Ejecute P en la siguiente unidad de tiempo |unless (c) do next P A menos que deduzca c ejecute next P |!P Replicacion |?P Retardo inf inito pero no limitado de P Cuadro 2.1: Sintaxis de NTCC P El proceso i∈I when (ci ) do Pi , llamado selección múltiple con guarda (guarded-choice), donde I es un conjunto de ı́ndices, tiene como tarea escoger no-deterministicamente algún Pj , j ∈ I, para el cual cj pueda deducirse de la información contenida en el Store. Si se logra deducir cj , se ejecuta Pj y los demás procesos Pi , i ∈ I − j serán eliminados. Si el Store deduce la negación de todas las guardas cj ( ¬cj , ∀j∈I ), se eliminan todos los Pj ; y finalmente, si no hay suficiente información para deducir cj , entonces se suspende P el proceso . Este proceso modela el no-determinismo en el cálculo. El proceso local x in P modela el encapsulamiento, mediante la definición de una variable local x utilizada únicamente por P ; la información acerca de x no puede ser vista por ningún proceso, excepto P . El proceso next P ejecuta P en la siguiente unidad de tiempo; es decir que espera una unidad para ejecutar P . Este proceso junto con !P es la única forma que un proceso perdure en el tiempo. La composición P ||Q, denota la ejecución paralela de P y Q. Su comunicación se hace solo a través de la información en el Store. La primitiva unless (c) do next P , también conocida como el ask negativo, ejecuta P en la siguiente unidad de tiempo, a menos de que, c pueda deducirse en la unidad de tiempo y Store actuales. Esta primitiva permite modelar “time-outs”, ya que espera que en la unidad actual se presente la información c; de lo contrario, se activa P en la siguiente unidad. !P modela el proceso de replicación, que consiste en crear una copia de p de manera no limitada en la unidad actual y en cada unidad de tiempo futura. Esta es la forma de 33 modelar un comportamiento infinito en este cálculo. Finalmente, ?P activa P en algún instante de tiempo, ya sea el actual o alguno futuro, permitiendo modelar asincronı́a de procesos. 2.3. Semántica de NTCC 2.3.1. Sistema de Restricciones Aritmético-Modular El sistema de restricciones que usa el calculo NTCC, llamado Sistema de Restricciones Aritmético-Modular, se apoya en la definición del sistema de restricciones presentada en el cápitulo anterior (ver definición 1.2.1.1), modificando algunos aspectos, que se describen a continuación. Definición 2.3.1 Sea n > 0, Se define A[n] como un sistema de restricciones tal que: Σ esta dado por 0, 1, 2....n − 1, succ, pred, +, x, =, <. 4 es el conjunto de sentencias válidas de la aritmética módulo n. Se entenderá por A[n] un sistema de restricciones sobre los naturales, módulo n; es decir, que el rango de los posibles valores es 0..n − 1. Se utilizará v para referenciar cualquier posible valor; los operadores aritméticos también estarán sujetos al módulo n. Este sistema se asumirá como sistema de restricciones por defecto para el calculo NTCC, de aquı́ en adelante. NTCC tiene parametrizado su sistema de restricciones por lo cual no tiene que limitarse a utilizar uno solo. Pueden utilizarse otros sistemas de restricciones, tales como: Intervalos racionales, tipos enumerados, sistemas de restricciones Kahn y Getzen[VSG96], entre otros. 2.3.2. Semántica Operacional La semántica operacional de NTCC [Val03] está dada en términos de las relaciones de reducción → y ⇒. 34 Las transiciones de un proceso a otro modelan el transcurso de una computación: definen paso a paso la ejecución de un ”programa”en el cálculo. Se define una transición interna (no observable) de la forma < P, d >→< P 0 , d0 >, que se lee ”P con Store d reduce, en un paso interno, a P 0 con Store d0 ”, donde P 0 es una evolución interna de P . Una transición externa (observable) de la forma P →(c,d) R, se lee ”P , con entrada c del ambiente, reduce en una unidad de tiempo a R, con salida d al ambiente”, donde R es una evolución observable de P . La reglas de la semántica operacional se exponen en el cuadro 2.2: T ELL <tell(c),d>→<skip,d∧c> SU M < P i∈I when ci do Pi ,d>→<Pj ,d> if d |= cj , j ∈ I 0 ,d> P AR <P<P,c>→<P ||Q,c>→<P 0 ||Q,d> U N L <unless c next P,d>→<skip,d> if d |= c 0 0 x d>→<P ,c > LOC <(local x,c)<P,c∧∃ P,d>→<(local x,c0 ) P 0 ,d∧∃x c0 > ST AR <?P,d>→<nextn P,d> if n ≥ 0 REP <!P,d>→<P ||next !P,d> →γ2 0 0 ST R γγ10 →γ 0 if γ1 ≡ γ1 y γ2 ≡ γ2 1 OBS 2 <P,c>→∗<Q,d>6→ if P =⇒(c,d) R R ≡ F (Q) Cuadro 2.2: Semántica de NTCC En el cuadro 2.2, la notación de las reglas cumple”. P Q se lee, çuando P se cumple, entonces Q se La regla T ELL adiciona c al Store d, quedando un nuevo Store d ∧ c y el proceso reducido a skip. 35 SU M escoge, no-deterministicamente, una guarda cj que pueda deducir el Store y ejecuta entonces el proceso Pj . Si se deduce lo contrario de cada una de las guardas ci ( ¬ci , ∀i∈I ), no se ejecuta ningún proceso Pi . Si no hay suficiente información para P deducir algún ci , se suspende el proceso i∈I when ci do Pi . La regla P AR especifica que en una transición interna solo se reducirá uno de los dos procesos. U N L modela la ejecución de P siempre y cuando la condición c no sea deducida por el Store. Esto se presenta de dos formas: la primera ocurre al deducirse ¬c y la segunda es cuando el Store una vez alcanzado el estado de quietud no tiene suficiente información para deducir si c se cumple. LOC representa la propiedad de encapsulamiento creando una variable x a la que solo puede aceder el proceso P ; esto se modela ocultando a P la información de alguna x que se encuentre en el Store global mediante la cuantificación existencial de esta (∃x d). A su vez P oculta al Store global la información de la variable x mediante un Store local c, el cual contendra toda la información sobre la x local. La regla ST AR activa, no-deterministicamente, el proceso P , sea en la unidad de tiempo actual o en una futura; se modela ası́ la espera de tiempo limitada, mas no definida. REP especifica la ejecución de P en todos las unidades de tiempo, modelando el comportamiento infinito de un proceso. La regla ST R dice que procesos estructuralmente congruentes tienen reducciones que producen procesos congruentes. Las anteriores reglas se agrupan bajo el nombre de transiciones internas. La regla OBS dice que una transición observable de P , etiquetada por < c, d >, se obtiene al realizar una secuencia interna de transiciones desde la configuración inicial < P, c > a la configuración final < Q, d >, en la que ya no es posible hacer más evoluciones internas. El proceso residual R a ser ejecutado en la siguiente unidad de tiempo, es equivalente a (F (Q)) ( Futuro de Q) . Futuro de Q se obtienen eliminando de Q las sumatorias que no dispararon actividad en el intervalo actual, junto con la información local almacenada en Q y eliminado el Store actual, dejando sólo los procesos next y unless[Val03]. 36 Es importante mencionar cómo NTCC, al igual que TCC, introduce la programación reactiva-temporal [Val03]. El ambiente estimula a un proceso Pi dándole una entrada ci . El proceso P reacciona en una cantidad de tiempo finita al ambiente dándole una salida c0i y evolucionando al proceso Pi+1 . Cada respuesta a estos estı́mulos definen una unidad de tiempo. Los observadores externos al proceso no observan las transiciones internas, solamente las entradas y salidas definidas. 2.4. Definiciones Recursivas Resulta conveniente especificar determinados comportamientos mediante la recursión. Por éste motivo, se describirá la forma de codificarla en NTCC. NTCC define la recursión de la siguiente forma [Val03]. q(x) =def Pq Donde q es el nombre de un proceso y Pq su cuerpo, que puede tener como máximo una ocurrencia de q, y antepuesta al operador next; lo anterior es para forzar que se tenga una respuesta de q(x) en cada unidad de tiempo, pues no se quiere que Pq haga infinitos llamados recursivos a q en la misma unidad de tiempo. Para tratar los llamados q(t), se considera a t como una variable con un valor v (el Store puede deducir que t = v), obteniéndose Pq [v/x], donde la operación [v/x] denota el remplazo de toda ocurrencia de x por v. En NTCC se debe evitar que las variables que ocurren libres en Pq sean capturadas por el alcance de las variables locales. Se hace necesario entonces utilizar el alcance estático, con la siguiente notación: q(x)[y1 , ....., yn ] =def Pq Donde y1 , ....., yn son las variables que pueden ocurrir libres en P . Se expondrá el siguiente ejemplo para aclarar la diferencia entre alcance estático y dinámico [Val03]. Ejemplo 2.4 Sea q(x) =def tell(y = 1)||next(localy)(q(x)||when y do P ) 37 Si se considera alcance dinámico, en el momento que se ejecute el llamado recursivo ((localy)(q(x)||when y do P )) se asumira que el proceso tell(y = 1) hace referencia a la variable local y, lo cual no es cierto porque tell(y = 1) utiliza una variable global. Si se desea obtener la independencia de variables entre el proceso tell(y = 1) y el when y do P , es necesario utilizar alcance estático, mencionando las variables que pueden ocurrir libres en q(x). 2.4.1. Codificación A continuación se presenta la codificación para modelar recursión en NTCC. Un proceso q(t) que representa el primer llamado recursivo, se define de la siguiente forma: d (local q qarg)(pq(x) =def Pq q || q(t)) donde: El proceso recursivo pq(x) =def Pq q es: cq )) !(when call(q) do (local x)(x ← qarg || P siendo: - call q(t) la abreviación de x = 1. - x ← t la abreviación de Σv when t = v do !tell(x = v) d tell(call(q)) || tell(qarg = t) q(t): q y qarg dos variables no libres en Pq Se utilizan las variables locales q y qarg, para abolir posibles interferencias entre los llamados recursivos externos. 38 2.5. Celdas Las celdas proveen herramientas para el análisis y especificación de estructuras de datos persistentes y variables, por lo cual es importante modelarlas en el cálculo NTCC. Para el modelamiento de las celdas se debe asumir que el sistema de restricciones cuenta con un predicado que pueda expresar el estado de cambio de una variable; este predicado será change. Definición 2.5.“ Se define una celda x : (v) como una estructura x cuyo valor actual es v y que puede mantenerse o cambiar en el futuro” [Val03]. Una celda x : (v) tiene la forma: \ next x : (z) x : (z) =def tell(x = z) || unless change(x) La anterior definición representa una celda x, cuyo valor actual es z y, a menos que se \ = 1) x, tomará el mismo valor z en el próximo decida cambiar este valor, (tell chage(x) instante. Además de la definición de la celda existe otro operador utilizado. Se trata del operador \ exchg [x, y], llamado operador de intercambio (exchage). Se utiliza para asignar nuevos valores sobre las celdas. Sea exchg [x, y], v el valor actual de x y y otra celda y g(v) la función que calcula el siguiente valor de x. Se tiene: \ \ exchg [x, y] = Σv when x = v do ( tell(change(x)) || tell(change(y)) || next(x : (g(v)) || y : (v))) El uso del operador exchg [x, y] podrá ser apreciado en la siguiente sección de Aplicaciones y Ejemplos. 2.6. Aplicaciones y Ejemplos Se ha mencionado anteriormente que por las propiedades reactivas-temporales, el nodeterminismo y la asincronı́a que modela NTCC, existe un gran número de aplicaciones en las que se pueden demostrar la expresividad de éste cálculo, tales como: la programación de dispositivos robóticos, la sincronización de procesos musicales y los sistemas 39 multiagentes. En esta sección se mostrarán algunos ejemplos, enfatizando la aplicación principal de este trabajo de tesis: Programación Concurrente de controladores RCX en dispositivos LEGO. Los ejemplos expuestos aquı́ son tomados de [Val03]. 2.6.1. Controladores RCX: Ejemplo de Zig-Zag “Un RCX es un dispositivo programable fabricado por LEGO, con el cual se pueden crear diferentes clases de robots autónomos [LP99]. La tarea de zig-zag [Fre99] consiste en que el robot-RCX se mueva aleatoriamente de izquierda a derecha con las siguientes condiciones: 1. el robot no puede ir hacia adelante si su ultima acción fue ir adelante. 2. no puede girar a la derecha si su penúltima acción fue ir a la derecha, 3. la segunda condición aplicada a la izquierda”[Val03]. La solución que se plantea evita la sobre-especificación, planteando solo los aspectos que conciernen a la descripción de la solución. Se usarán dos celdas a1 y a2 para tener una referencia de los dos últimos movimientos que ha hecho el RCX. Además, se definirán las constantes f, r, l ∈ D − 0 para denotar los predicados f =adelante(forward), r=derecha(right), l=izquierda (left). La solución es la siguiente: goF =def goR =def goL =def Zigzag =def GoZigzag =def exchf [a1 , a2 ] || tell(forward) exchr [a1 , a2 ] || tell(right) exchl [a1 , a2 ] || tell(left) !(when (a1 6= f ) do GoF + when (a2 6= r) do GoR + when (a2 6= l) do GoL) a1 : (0) || a2 : (0) || Zigzag Inicialmente las celdas a1 y a2 contendrán valores diferentes de f , r y l, lo cual hace que se escoja no-deterministicamente la dirección de arranque; después el RCX se dirigirá por las condiciones 1, 2 y 3, grabando en a1 y a2 los movimientos anteriores. A continuación se da un ejemplo de la función exch[a1 , a2 ]: exchf [a1 , a2 ] =def P v∈f,r,l,0 when a1 = v do ( tell(change(a1 )) || tell(change(a2 )) || next( a1 : (f ) || a2 : (v))) Las demás operaciones exch[a1 , a2 ] (exchr [a1 , a2 ] y exchl [a1 , a2 ]) son similares a la definición anterior. 40 2.6.2. Sistemas Multiagentes: Presa y Predador “El juego Presa y Predador [MBD86] es muy famoso debido a que sus múltiples análisis desde diferentes puntos de vista [HS96], permiten representar entornos multi-agentes [SV00]. Este ejemplo puede ser modelado con múltiples robots-RCX.” El juego consiste en que los predadores y la presa se mueven en un tablero toroidal; si llegan al final de éste, salen por el otro lado del mismo. La presa y el predador se pueden mover horizontal o verticalmente, en cualquier dirección. Los predadores tendrán cierta ventaja sobre su presa, ya que corren dos casillas del tablero mientras que la presa solo puede correr una. El objetivo del predador es capturar a la presa; esto ocurre cuando la presa se mueve a una posición entre las tres casillas que el predador puede atacar: la casilla donde se encuentra actualmente el predador, la anterior a donde se encontraba o la casilla de la mitad. El juego comienza con la presa ubicada al frente de los predadores y estos posicionados en la misma fila. El comportamiento que debe adoptar la presa para poder escapar es ejecutar un zigzag no predecible sobre el mundo, mientras que la estrategia de los predadores es cooperar entre ellos para capturar a la presa. De tal manera que, cuando un predador se encuentre frente a la presa, se declarará como lı́der del ataque y los otros predadores serán sus cooperadores en la captura de la presa. Como consecuencia, la posición de lı́der se alterna dependiendo de quién esté más cerca de la presa. 2.6.3. Aplicaciones Musicales: Control de Improvisación Un ejemplo de las aplicaciones musicales que tiene el cálculo NTCC es el control de improvisación. Este consiste en tener un conjunto de músicos m, que tocarán un número fijo de notas (en este caso se tomará 3). Cada músico puede escoger qué notas tocar, pero se le establece un tiempo que puede utilizar entre las notas del bloque. Ejemplo: sea la partitura del músico 1 [5,6,2], ésto quiere decir que entre la primera y la segunda nota tiene un espacio de 5 silencios para improvisar, entre la segunda y tercera 6 y después de la tercera 2. Cuando el músico termine su interpretación de las tres notas correspondientes, debe esperar a la señal del conductor que le dice que todos los músicos ya han terminado de tocar su bloque y el puede volver a empezar. El tiempo entre los 41 bloques consecutivos de cada músico no está determinado, pero hay la restricción de que no debe demorarse más que la suma de todos los tiempos de las partituras de los otros músicos. Los dos anteriores ejemplos se profundizan en [Val03], PHD Tesis de Frank d. Valencia. 42 3 LMAN: MÁQUINA ABSTRACTA Este capı́tulo describe el Análisis y la Especificación formal de la Máquina Abstracta LMAN . Se presenta la evaluación de alternativas sobre la implementación, seguida de la especificación de la máquina abstracta: notación, sintaxis de los procesos, las reglas de reducción que describen su funcionamiento y constituyen su núcleo, los estados inicial y final, finalizando con un diagrama de transiciones que resume su funcionamiento. 3.1. Análisis A continuación se muestran las consideraciones que se tomaron en la etapa del análisis de éste trabajo de tesis, las cuales fueron determinantes para las siguientes etapas de diseño e implementación. 3.1.1. Entorno de Programación NTCC LMAN , hace parte de un flujo de implementación que tiene como objetivo proveer un entorno de programación aplicativa. Este entorno de programación NTCC [Val03] se divide en 5 bloques funcionales(ver figura 3.1). El bloque superior VIN se encuentra en desarrollo como proyecto de grado independiente al presente[FQ04] y su objetivo es elevar el nivel de programación en el cálculo, programando en un lenguaje icónico. El siguiente módulo es el COMPILADOR NTCC-LMAN que además de que actúa como un componente integrador entre el lenguaje visual y LMAN, permite programar NTCC en alto nivel; su diseño se trata en el capı́tulo 5. Los últimos tres bloques hacen referencia a LMAN y la base que la soporta; éstos bloques funcionales se tratan en el 43 siguiente capı́tulo que describe la máquina virtual. El H8/300L es el microprocesador del RCX brick y legOS es el sistema operativo que LMAN utiliza como interfaz con este microprocesador. La integración del lenguaje visual, el compilador y LMAN se hace posible, dado que los tres utilizan el cálculo NTCC base; de ésta manera, el lenguaje visual genera código NTCC, que el compilador entiende como entrada para la generación de código de bytes LMAN. Figura 3.1: Flujo del entrono de programación NTCC 3.1.2. Evaluación de Alternativas de Implementación para la Máquina Abstracta En el desarrollo de LMAN, máquina que implementa el cálculo NTCC [Val03] para programación de dispositivos robóticos LEGO se presentaron varias alternativas para su implementación. Por ésta razón, se hizo conveniente establecer una análisis de alternativas que permitiera decidir de manera objetiva, cual era la opción óptima. Los criterios que se consideraron pertinentes para evaluar cada alternativa se describen a continuación: Eficiencia en Tiempo de Ejecución: Trata el factor del tiempo en la ejecución de un programa sobre la implementación de la máquina. Manejo Sistema de Restricciones: Trata la integración e interacción entre la máquina y el sistema de restricciones. Eficiencia en el Manejo de Memoria: Trata el manejo de memoria eficiente sobre la implementación de la máquina. 44 El modo de calificación de cada indicador, fue dado cuantitativamente en modo ascendente, siendo 1 la opción mas desfavorable y 10 la más conveniente. El cuadro 3.1, muestra la evaluación de alternativas, posteriormente se sustenta la puntuación asignada para cada una de las opciones en los criterios evaluados. Criterios/Indicadores Eficiencia Tiempo de Ejecución Manejo de Sistema de Restricciones Eficiencia Manejo de Memoria Total Traductor 10 8 6 21 Máquina Virtual 8 10 8 25 Cuadro 3.1: Evaluación de Alternativas de Implementación para la Máquina Abstracta Las alternativas propuestas y su análisis de criterios sigue a continuación. Los argumentos dados toman como referencia otras implementaciones similares a las alternativas en análisis.[LY97][Leg00]. Descripción: • Traductor : Un traductor [AB98] como su nombre lo indica, se encarga de traducir un programa durante la etapa de compilación, de un lenguaje de alto nivel a uno equivalente en un lenguaje que pueda ejecutar el computador o el dispositivo robótico. • Máquina Virtual : La máquina virtual [Com00] es un procesador no implementado en Hardware, que actúa como el ejecutor notacional de un lenguaje de programación particular. Eficiencia en Tiempo de Ejecución: • Traductor : Debido a que la traducción se realiza en tiempo de compilación, el programa será ejecutado directamente por el dispositivo robótico; luego el tiempo en ejecución serı́a óptimo. Valoración: 10. • Máquina Virtual : La máquina virtual interpreta el programa en tiempo de ejecución, luego comparando con un traductor su desempeño no serı́a el mejor. Valoración: 8. Manejo Sistema de Restricciones: 45 • Traductor : Debido a que el traductor actúa en tiempo de compilación, su integración con el módulo del sistema de restricciones se harı́a extensa; ya que serı́a necesario unir ambos bloques de código para asegurar un funcionamiento en conjunto. Valoración: 8. • Máquina Virtual : La implementación de una máquina virtual confiere modularidad, lo cual combinado con su caracterı́stica de interpretación del programa en tiempo de ejecución; posibilita la adición del sistema de restricciones como un módulo funcional, definiendo solamente una interfaz que le permita interactuar con el control de la máquina. Valoración: 10. Eficiencia en el Manejo de Memoria: • Traductor : Un traductor combinarı́a en tiempo de ejecución el bloque de control que implementa la semántica operacional del cálculo, con el código del programa a ejecutar. Esto generarı́a que los programas traducidos fuesen de mayor tamaño en memoria y que posiblemente requirieran de mayores recursos mientras se realiza la traducción. Valoración: 6. • Máquina Virtual : La máquina virtual interpreta los programas en tiempo de ejecución; por lo cual se separa el control de las construcciones hechas en el cálculo. Esto permitirı́a un manejo mas eficiente de memoria, ya que solo se consumirı́an los recursos de ejecución. Valoración: 8. Como conclusión de las valoraciones dadas, la alternativa que se escoge para implementación es una máquina virtual . Una máquina virtual confiere modularidad a la implementación, eficiencia en el manejo de memoria, adminte la integración de una manera transparente del sistema de restricciones y el fundamento sobre la base formal de una máquina abstracta. 3.1.3. Evaluación de Alternativas de la plataforma de implementación para la Máquina Virtual Para implementar una máquina virtual sobre un dispositivo robótico LEGO, existen varias alternativas de plataformas de programación; por este motivo se hace conveniente establecer un análisis para decidir objetivamente cual es la alternativa óptima. Los criterios que se consideraron pertinentes para evaluar cada alternativa son los siguientes: 46 Eficiencia: Evalúa el tiempo de ejecución, la gestión de memoria y el manejo del microprocesador. Escalabilidad y Mantenimiento: Evalúa las ventajas de la plataforma: facilidad de instalación, lenguajes admitidos, transparencia en las actualizaciones, manejo de periféricos del robot. Restricciones Legales: Evalúa el tipo de restricciones que existen en la adquisición y utilización de la plataforma. Compatibilidad: Evalúa la portabilidad y el nivel de acceso por el usuario final a la plataforma. El modo de calificación de cada indicador, fue dado cuantitativamente en modo ascendente, siendo 1 la opción mas desfavorable y 10 la más conveniente. El cuadro 3.2, muestra la evaluación de alternativas, posteriormente se sustenta la puntuación asignada para cada una de las opciones en los criterios evaluados. Criterios/Indicadores LEJOS (java) Eficiencia Escalabilidad y Mantenimiento Restricciones Legales Compatibilidad Total 5 10 10 7 32 BrickOS Máquina NQC (legOS) Estándar de (c++ y c) LEGO 8 10 9 10 1 6 10 10 10 8 7 8 36 28 33 Cuadro 3.2: Evaluación de alternativas de la plataforma de implementación para la Máquina Virtual Las alternativas propuestas y su análisis de criterios sigue a continuación. Los argumentos dados toman como referencia la documentación y pruebas realizadas sobre las alternativas en análisis.[LY97][Leg00]. Descripción: • LEJOS : Implementación de la máquina virtual de JAVA para los robots LEGO. Permite el manejo de todos los periféricos del RCX, el control total de 47 los 32Kb de RAM y la programación orientada a objetos en JAVA. El driver de la torre LEGO USB se encuentra bajo desarrollo (para Linux solamente). Funciona sobre Linux y Windows. [SR00]. • BrickOS : Sistema operativo de código abierto para robots LEGO, antes llamado legOS. Permite programar en lenguajes C y C++ el RCX brick, admite el manejo de todos los periféricos del RCX ,el control total de los 32Kb de RAM y la programación orientada a objetos. El driver de la torre LEGO USB se encuentra bajo desarrollo (para Linux solamente); el driver de la torre serial ha sido desarrollado y probado en Linux. Funciona sobre Linux, Windows y MacOS. [MLNP00]. • Máquina estándar de LEGO: El RCX tiene un firmware original en forma de máquina virtual para su control. Permite el manejo de todos los periféricos y la programación se realı́za por medio de una interfase visual básica llamada RIS (Robotic Invention System) SDK que funciona solo en Windows y Mac. Esta máquina admite un número de variables globales de 32 y locales de 16, un número máximo de programas en memoria de 5, cada uno con máximo 10 tareas y 8 subrutinas. Tiene soporte USB y serial. [Leg00]. • NQC(Not Quite C): Es un compilador de código de bytes nativo,que utiliza la máquina estándar de LEGO en su funcionamiento. Toma los programas escritos con una sintaxis básica muy similar al lenguaje C, de ahı́ su nombre; y los traduce al código de bytes que entiende la máquina virtual estándar. Tiene limitaciones en el manejo de variables (32),no se pueden definir estructuras de datos,las subrutinas no pueden retornar valores y no admiten parámetros. Funciona en Windows, Linux y MacOS.[Bau00]. Eficiencia: • LEJOS : La máquina virtual de JAVA es interpretada y maneja objetos, razones que pueden generar más consumo de memoria y extender el tiempo de ejecución de los programas sobre el robot LEGO, tal como se ha observado en otras implementaciones de máquinas virtuales en JAVA ejecutándose sobre estaciones de trabajo [AB98]. Valoración: 5. • BrickOS : Se ha demostrado que la programación C y C++ resulta eficiente, adicionalmente admite una programación estructurada y orientada a objetos que confiere modularidad a las implementaciones. Lo anterior, en conjunto 48 con las habilidades de BrickOS para el control del hardware de robot, permiten lograr una buena combinación en eficiencia. Valoración: 8. • Máquina estándar de LEGO: la programación directamente en el código de bytes asegura un buen desempeño, ya que se estarı́a tratando directamente con las instrucciones nativas del microprocesador del RCX. Valoración: 10. • NQC : Aunque la sintaxis de NQC es básica, su propiedad de compilar al código de bytes la hace eficiente en tiempo de ejecución. No obstante el manejo de memoria no resulta tan eficiente, debido a las limitaciones del lenguaje. Valoración: 9. Escalabilidad y Mantenimiento: • LEJOS : La implementación de una máquina virtual confiere modularidad, como se ha mencionado antes; esto hace de LeJOS un sistema administrable. La programación en lenguaje JAVA posibilita realizar construcciones completas y complejas. La programación de los periféricos del RCX se realiza mediante librerı́as, además de que es posible utilizar las librerı́as estándar. Las actualizaciones son transparentes, ya que solo se requiere actualizar a una nueva versión de la màquina virtual, de modo que los programas siguen ejecutándose sin modificaciones de fondo. Valoración: 10. • BrickOS : Es un sistema operativo que continuamente está actualizándose en versiones. El uso del lenguaje C como herramienta de programación, le confiere eficiencia a las construcciones en cuanto al control del hardware del robot y la programación convencional.Aunque la instalación es un poco dispendiosa, existen muchas ayudas para completarla. Es una de las plataformas más robustas y más usadas para programación de robots LEGO. Valoración: 10. • Máquina estándar de LEGO: Las actualizaciones son realizadas eventualmente y entregadas directamente por LEGO Group. Para programar utilizando ésta máquina virtual se requiere un largo estudio de su arquitectura, las instrucciones y de la generación del código de bytes. Valoración: 1. • NQC : Al actuar como una interfaz de alto nivel con la máquina virtual de LEGO, la programación resulta mucho más manejable que el lenguaje ensamblador de la máquina virtual. Sin embargo, las construcciones hechas 49 en NQC, conllevan las limitaciones de su sintaxis; lo cual se convertirı́a en un factor limitante para la implementación. Valoración: 4. Restricciones Legales: • Tanto LEJOS como BrickOS y NQC se han trabajado como proyectos GNU/Linux. El firmware estándar de LEGO es propiedad de Lego Group, sin embargo su uso no está limitado. Valoración: 10. Compatibilidad: • LEJOS : Es multiplataforma (Linux, Windows, MacOS entre otros). Su instalación puede resultar compleja. Valoración: 7. • BrickOS : Es multiplataforma (Linux, Windows, entre otros) y adicionalmente es compatible con otras soluciones para programaciòn de RCX como se describe los cuadros 4.2 y 4.3. Su instalación puede resultar compleja. V̇aloración: 8. • Máquina estándar de LEGO: Es multiplataforma. Valoración: 7. • NQC : Es multiplataforma (Linux, Windows, Mac, entre otros), su instalación es relativamente sencilla. Valoración: 8. Teniendo en cuenta el total para las valoraciones asignadas a las diferentes alternativas de implementación; la alternativa seleccionada para implementación de la máquina virtual es el Sistema operativo BrickOS(legOS) y el lenguaje de programación C . Esta plataforma es realmente estable, funciona como proyecto alrededor de una comunidad GNU por lo cual facilita la búsqueda de información y ayuda en las tareas de configuración, acople y desarrollo; es multiplataforma de modo que confiere portabilidad a la solución de la máquina virtual y permite controlar eficientemente el hardware de los robots. El uso del lenguaje de programación C confiere eficiencia a la implementación, admite programación estructurada y cuenta con la funcionalidad necesaria para realizar la implementación de la máquina virtual. 3.2. Máquina Abstracta A continuación se define la máquina abstracta del cálculo NTCC [Val03] para programación concurrente de robots LEGO. Se presenta la especificación formal, la sintaxis, la 50 definición de estados inicial y final, las reglas de reducción y el diagrama de transiciones que muestra el funcionamiento de la máquina abstracta. 3.2.1. Especificación formal La Máquina Abstracta LMAN se define formalmente como sigue a continuación: 3.2.1.1. Procesos Un proceso en LMAN está conformado por una tupla < P, B > donde P es un proceso y B es una función que contiene todas las variables que puede alcanzar el proceso, siendo B el ambiente, o asociación de localidades a variables: B : LOC− > V AR. 3.2.1.2. Store El Store(S) se define como una conjunción de todas las restricciones iniciales más las adicionadas al Store en el instante actual. S : c1 ∧ c2 ∧ c2 ∧ ................. ∧ cn 3.2.1.3. Colas de ejecución Las colas representan procesos concurrentes de la forma: P1 ||P2 ||P3 ||.......||P n Se define una cola C como una concatenación de procesos de la forma < P, B >: C : < P1 , B1 > || < P2 , B2 > || < P3 , B3 > ||.......|| < P n, Bn > La representación de una cola vacı́a es ∅. La notación C ::< P, B > representa una cola cuyo primer elemento es < P, B > y cuyo residuo de elementos es la cola C. 51 3.2.1.4. Estructura de LMAN La estructura de la máquina está dada por: <<< P, B >, CL, CA, CU >, CC, S > Donde: P : es el proceso en ejecución. B: es el conjunto de variables asociadas al proceso P. CL: Es la cola de procesos listos a ejecutar. CA: Es la cola de procesos ask suspendidos por falta de información en el Store. CU : Es la cola de procesos unless. CC: Es la cola de construcción, donde se almacenan los procesos residuales del instante actual, que serán ejecutados en el siguiente o siguientes instantes de tiempo. S: Es el Store común, donde se almacenan las restricciones asociadas al instante en ejecución. La tupla más a la izquierda (< P ; B >) define un proceso en la máquina; la siguiente estructura (<< P ; B >; Cl; CA; CU >) define la máquina que se está ejecutando en el instante actual y la tupla más a la derecha (<<< P ; B >; Cl; CA; CU >; CC; S >) define la estructura utilizada para construir la máquina en el siguiente instante. El Store se trata como una estructura global a la definición de la máquina. En LMAN se maneja la noción de “planeación de máquinas”. Esta noción implica que se construye una sola máquina por instante de tiempo; es decir que al final de cada instante se destruye tanto la máquina actual como el Store. La máquina para el próximo instante se construye a partir de la cola CC, donde se encuentran todos los procesos residuales de la actual unidad de tiempo. 52 3.2.2. Sintaxis Los procesos que implementa la máquina son esencialmente los expresados en la sintaxis de NTCC. La única diferencia está realmente en el proceso de ejecución eventual (∗P ), que se delimita por eficiencia en la implementación en un rango dado. La máquina considera solamente procesos primitivos del cálculo (la excepción es nextn P ), pero no las construcciones derivadas que se mencionan en [Val03](página 31). El cuadro 3.3 muestra la sintaxis de los procesos válidos en LMAN . P, Q, ... = skip Inactividad |tell(c) tell c P | i∈I when (ci ) do Pi Seleccione un Pi , si ci , i ∈ I |P ||Q Ejecucion en paralelo |Local x in P Localidad |next P Ejecute P en la siguiente unidad de tiempo |nextn P Ejecute P en la n − −esima unidad de tiempo |unless (c) next P A menos que deduzca c, ejecute next P |!P Replicacion | ? [i, j]P Retardo inf inito pero no limitado de P Cuadro 3.3: Sintaxis de LMAN Donde: c, d, ... denotan las restricciones. P, Q, A, ... representan los procesos del cálculo. x, y, .. se utilizan para hacer referencia a las variables de los procesos. El proceso nextn P representa una abreviación del proceso (next(next(...(nextP )...))), con n ocurrencias de next. El proceso ?[i, j]P modela eventualidad limitada en un intervalo entre i y j, donde j es mayor que i, de modo que, P se ejecuta en una unidad de tiempo eventual en este intervalo. La equivalencia los anteriores dos procesos con los procesos primitivos se encuentra en [Val03]. 3.2.3. Estado inicial y Final El estado inicial de la máquina está dado por la siguiente configuración: 53 <<< skip, B >, CL, ∅, ∅ >, ∅, S > Donde: S es el Store inicial, B contiene todas las variables globales de la máquina y CL contiene todos los procesos a ejecutar. Las variables globales son visibles y modificables por todos los procesos de la máquina actual. El cálculo NTCC modela sistemas reactivos, los cuales pueden permanecer inactivos por grandes periodos de tiempo y luego pueden volver a activarse. Ası́ siguiendo ésta noción, no se define un estado final para la máquina. Solo detiene su computación a menos que exista un fallo funcional o un bloqueo por inconsistencias en el Store. 3.2.4. Semántica Operacional: Reglas de Reducción Las reglas de reducción de la máquina están basadas en la semántica operacional del cálculo NTCC; apoyándose en la siguiente definición de ESTADO y la relación →: EST ADO : P x B x CL x CA x CU x CC x S →: ⊆ EST ADO x EST ADO La regla SCHED se encarga de la planeación de los procesos que se encuentran en la máquina. Se divide en tres casos. El primer caso es cuando un proceso llega a su final (skip), por lo cual se continúa con el siguiente en la cola CL. El segundo caso es cuando la cola CL se encuentra vacı́a; entonces se procede a ejecutar los procesos de la cola CU . La tercera regla determina el paso a la siguiente unidad de tiempo y la construcción de una nueva máquina; ésto sucede solo si las colas CL y CU se encuentran vacı́as; lo que quiere decir, que no hay procesos que se puedan reducir. Adicionalmente, se destruye el Store anterior(S) y se crea el nuevo Store(S 0 ) el cual contiene solamente el estado inicial del ambiente. SCHED1 : <<< skip, B >, CL ::< P, B 0 >, CA, CU >, CC, S >→<<< P, B 0 >, CL, CA, CU >, CC, S > 54 SCHED2 : <<< skip, B >, ∅, CA, CU ::< P, B 0 >>, CC, S >→<<< P, B 0 >, ∅, CA, CU >, CC, S > SCHED3 : <<< skip, B >, ∅, CA, ∅ >, CC, S >→<<< skip, B 0 >, CC, ∅, ∅ >, ∅, S 0 > La regla T ELL necesita del sistema de restricciones para agregar la restricción c al Store, en la unidad de tiempo actual. T ELL : <<< tell(c), B >, CL, CA, CU >, CC, S >→<<< skip, B >, CL, CA, CU > CC, S ∧ c > La regla ASK presenta los siguientes cuatro casos. El primer caso (ASK1), es para la información positiva; esto quiere decir, que el ask da una respuesta afirmativa de acuerdo con la restricción c. El segundo caso (ASK2,1), sucede cuando el Store deduce lo contrario de uno de los ask de la sumatoria que le ha sido preguntado (¬c ), entonces elimina ese proceso particular de la sumatoria. El tercer caso (ASK2,2) es cuando P no hay más procesos ask en la sumatoria, entonces se elimina el proceso de la cola CL. Y finalmente, el cuarto caso (ASK3), se presenta cuando el Store no puede deducir ninguna de las opciones anteriores por ausencia de información, por lo tanto, P se suspende el procesos en la cola CA. ASK1 : <<< S |= cj ∧ j ∈ K ask c do P , B >, CL, CA, CU >, CC, S >→<<< Pj , B >, CL, CA, CU >, CC, S > k k k∈K P ASK2,1 : <<< S|=¬cj ∧j∈K P ask c do P ,B>,CL,CA,CU >,CC,S>→<<< k k k∈K k∈K−{j} ask ck do Pk ,B>,CL,CA,CU >,CC,S> P ASK2,2 : <<< K=∅ j∈K ask ck do Pk , B >, CL, CA, CU >, CC, S >→<<< skip, B >, CL, CA, CU >, CC, S > P 55 ASK3 : <<< K6=∅∧¬∃j∈k .(S|=cj ∨ S|=¬cj ) P ask c do P ,B>,CL,CA,CU >,CC,S>→<<<skip,B>,CL,< k k k∈K k∈K ask ck do Pk ,B>::CA,CU >,CC,S> P La regla U N LESS presenta tres casos. El primer caso es cuando hay todavı́a procesos en la cola CL, por lo cual se pospone la ejecución del proceso unless adicionándolo a la cola CU . El segundo activa el unless solo si, CL se encuentra vacı́a y la guarda no se deduce. Finalmente, el tercer caso considera la no activación del proceso unless debido a que se cumple la guarda(c). U N LESS1 : CL6={} <<<unless c do next P,B>,CL,CA,CU >,CC,S>→<<<skip,B>,CL,CA,<unless c do next P,B>::CU >,CC,S> U N LESS2 : S2c <<< unless c do next P >, B, ∅, CA, CU >, CC, S >→<<< next P, B >, ∅, CA, CU >, CC, S > U N LESS3 : S |= c <<< unless c do next P, B >, ∅, CA, CU >, CC, S >→<<< skip, B >, ∅, CA, CU >, CC, S > La regla LOC permite crear variables locales al proceso P , de modo que la nueva variable solamente pueda ser vista por P ; para esto se selecciona una nueva etiqueta L del universo de posibles etiquetas Uloc que haya sido utilizada en el rango de localidades (ran(B)). LOC : L ∈ Uloc − ran(B) <<< local x in P, B >, CL, CA, CU >, CC, S >→<<< P, B + (L ← |x) >, CL, CA, CU >, CC, S > La regla N EXT 1 ejecuta el proceso en el siguiente instante de tiempo, por lo cual se adiciona a la cola CC. N EXT 1 : <<< next P, B >, CL, CA, CU >, CC, S >→<<< skip, B >, CL, CA, CU >, < P, B >:: CC, S > 56 La segunda regla de N EXT 2 sirve para manejar la abreviación de nextn , que se denota (next(next......(nextP ))), n veces. N EXT 2 : n>1 <<< nextn P, B >, CL, CA, CU >, CC, S >→<<< skip, B >, CL, CA, CU >, < nextn−1 P, B >:: CC, S > La regla P AR ejecuta Q y adiciona P a la cola CL para su futura ejecución. P AR : <<< (P |Q), B >, CL, CA, CU >, CC, S >→<<< Q, B >, < P, B >:: CL, CA, CU >, CC, S > La regla REP ejecuta el proceso P y crea una “copia” que es adicionada a la cola CC para ejecución en los siguientes instantes. REP : <<<!P, B >, CL, CA, CU >, CC, S >→<<< P, B >, CL, CA, CU >, <!P, B >:: CC, S > Por ultimo la regla ST AR permite modelar una espera aleatoria finita de un evento, escogiendo una unidad de tiempo entre i y j para activar P . ST AR : n ∈ i..j <<< ?[i, j]P, B >, CL, CA, CU >, CC, S >→<<< skip, B >, CL, CA, CU >, < nextn P, B >:: CC, S > Las siguientes propiedades pretenden expresar la relación entre la definición formal de la máquina abstracta y el cálculo NTCC: 3.2.4.1. Conjetura 1: Correctitud de Transiciones No Observables Sea P un proceso NTCC y d un Store. Entonces en NTCC < P, d >→∗ < Q, d0 > si y solo si << skip, ∅, << P, var(P ) >, ∅, ∅ >, ∅, d >→∗ << skip, B, << Q, B 0 >>, CA, CU >, CC, d0 > 57 3.2.4.2. Conjetura 2: Correctitud de Transiciones Observables Sean R y P procesos de NTCC. Entonces: P ⇒(c,d) R si y solo si << skip, ∅, << P, var(P ) >, ∅, ∅ >, ∅, c >⇒(c,d) << skip, B, ∅, CA, ∅ >, << R, B 0 >>, d0 > Donde: V ar(p) es la asociación de localidades con las variables libres de P ⇒(c,d) representa en la máquina, la transición por medio de multiples reducciones entre el inicio de una unidad de tiempo con Store c y el final de la misma con Store d. Es importante mencionar que la regla expresada en la Conjetura 2, es quien define el input-output behavior de la máquina con respecto a NTCC y el ambiente. El proceso que comienza en la unidad de tiempo actual P se representa como el único proceso que contiene la cola de listos (CL), tal como se define en la regla SCHED1; después de presentar múltiples transiciones no observables (Conjetura 1) llega a la regla SCHED3, dando como resultado un Store final d, que contiene las instrucciones para a ejecutar por el ambiente y el proceso residual R en la cola de construcción CC para ejecución en instantes posteriores. De ésta manera, todos los instantes en la máquina pueden ser modelados siguiendo el anterior comportamiento; lo cual resulta similar al comportamiento que presenta NTCC en su definición de input-output behavior [Val03]. 3.2.5. Diagrama de Transición En la figura 3.2, se muestra el diagrama de transición de la máquina abstracta, el cual se construye con base en las reglas de reducción descritas anteriormente. El comportamiento del diagrama de transición es el siguiente: 1. Cuando el proceso en ejecución llega a skip, se pasa el siguiente proceso de la cola CL para ejecución(regla SCHED1). 58 Figura 3.2: Diagrama de Transición LMAN 2. Si se encuentra un proceso next P o nextn P en ejecución se pasa a la cola CC(regla N EXT 1 y N EXT 2). 3. Si el proceso en ejecución es replicación (!), se deja P y se pasa !P a CC(regla REP ). 4. Cuando el proceso en ejecución es when y no se puede resolver por falta de información en el Store, se encola en CA(regla ASK3). 5. Cuando el proceso en ejecución es un unless y la cola CL no esta vacı́a, el proceso se encola en CU (regla U N L1). 6. Si el proceso en ejecución es un tell, los procesos suspendidos en CA se adicionan a la cola CL(regla T ELL). 7. Si la cola CL se encuentra vacı́a, se pasan a ejecución los procesos en CU (regla SCHED2). 8. Cuando CL y CU se encuentren vacı́as, se crea una nueva máquina y se transfiere el contenido de CC a CL en la nueva máquina(regla SCHED3). 59 Se observa que el ciclo de transiciones está determinado por las tres reglas SCHED, que definen la forma en que se mueven los procesos en las colas: primero deben ejecutarse todos los procesos en la cola CL(SCHED1), luego los procesos en la cola CU (SCHED2) y por ultimo cuando las dos colas anteriores se encuentran vacı́as, se construye a partir de los procesos residuales en CC(SCHED3), la nueva máquina para el siguiente instante de tiempo. 60 4 LMAN: MÁQUINA VIRTUAL En éste capı́tulo se describe la arquitectura e implementación de la máquina virtual de NTCC para programación concurrente de robots LEGO. El objetivo principal es diseñar una máquina eficiente, modular y que provea la funcionalidad básica para programación concurrente, particularmente sobre robots LEGO. El modelo formal presentado en el capı́tulo anterior provee la especificación para la máquina virtual. Es importante notar, que en LMAN se modela además de la programación concurrente, la programación temporal (al definir instantes de tiempo para ejecución), y la programación por restricciones con el uso de un Sistema de Restricciones para gestionar el almacenamiento de la información. Todos estos componentes han sido integrados en LMAN, de modo que es posible aplicarlos para programar dispositivos robóticos LEGO. A continuación se presentan los aspectos de diseño e implementación de la máquina virtual. 4.1. Arquitectura General La máquina virtual de LMAN consta de cuatro bloques funcionales: memoria de programa, interfaz LEGO, interfaz STORE y controlLMAN , interactuando tal como se muestra en la figura 4.1. La memoria de programa guarda las instrucciones del programa en código de bytes y es estática, es decir, que no es modificable en tiempo de ejecución. La interfaz STORE es el módulo que permite interactuar con el Sistema de Restricciones asociado a LMAN. Este bloque funcional crea el Store donde se almacenan las restricciones durante el instante actual y luego lo destruye al final del mismo. La interfaz LEGO es el bloque encargado de manejar el ambiente externo. 61 Figura 4.1: Bloques Funcionales de LMAN ControlLMAN, actúa como el cerebro ejecutor de la máquina virtual. Este bloque es el encargado de planear máquinas y procesos, de ejecutar el programa almacenado en la memoria de programa, de comunicarse con la Interfaz STORE por medio de operaciones ask y tell, de comunicarse con la Interfaz LEGO para sensar el ambiente y ejecutar instrucciones sobre el robot y, finalmente, es el encargado de construir el siguiente instante, asegurando siempre continuidad en la ejecución, a menos de que exista un bloqueo en el Store. Como se ha mencionado anteriormente, LMAN a diferencia de otras implementaciones de máquinas para cálculos de procesos [AB98, Lop99], introduce la noción de Planeación de Máquinas. Esta noción hace referencia a que solo debe existir una y solo una máquina activa por instante de tiempo; esto se representa en la figura 4.1 como una lı́nea punteada rodeando la máquina activa en el instante actual. De ésta manera, aunque se define una cola de máquinas al interior del control, siempre existirá una y solo una máquina activa por instante de tiempo. La Planeación de Procesos en LMAN hace referencia al 62 manejo de colas y registros que permiten ejecutar cada una de las instrucciones LMAN equivalentes a un proceso en NTCC. Para cada máquina en LMAN se definen tres registros y tres colas de procesos: PCN es el registro contador de programa, PAN es el registro utilizado para construir árboles sintácticos de restricciones y PAUX es el registro auxiliar. Respecto a las colas, CL almacena los procesos listos para ejecución, CA almacena los procesos ask suspendidos y CU almacenan los procesos unless que se ejecutan solo al final de cada instante. La cola CC se define externamente a la máquina activa, ya que almacena los procesos residuales del instante actual, que pasaran a ejecución en los siguientes instantes de tiempo. LMAN ha sido diseñada en bloques funcionales de modo que se confiera modularidad a la implementación. El código ha sido escrito en C por eficiencia, y sigue la estructura de un kernel de sistema operativo para efectividad en la ubicación de los archivos relacionados en la implementación. Inicialmente, LMAN pretendı́a ser ejecutada desde el robot LEGO, siendo almacenada en los 10K o 14K de memoria RAM destinada para el bloque del programa LEGO. Sin embargo, debido a que LMAN integra la implementación de un Sistema de Restricciones paramétrico inicialmente creado para el cálculo PiCO [CG01], el tamaño de la implementación excedió el tamaño del espacio disponible. Por lo tanto, para suplir éste inconveniente en la implementación, se diseñó un ambiente de ejecución particular para LMAN. En este ambiente de ejecución, LMAN y el Sistema de Restricciones asociado corren sobre una estación de trabajo, donde LMAN se comunica con el LEGO vı́a protocolo LNP(Lego Network Protocol). En el LEGO por su parte, se ejecuta un segundo componente de LMAN que realiza dos funciones: en primer lugar, se encarga de sensar el ambiente del robot y enviarlo a la máquina y en segundo lugar, se encarga de recibir el resultado de la computación y de ejecutarlo sobre el robot LEGO, exhibiendo las tareas programadas. Cada uno de los componentes de la arquitectura de la máquina virtual anteriormente mencionados y su funcionamiento, serán tratados en detalle en las siguientes secciones de este capı́tulo. 63 4.1.1. Memoria de Programa La memoria de programa es una memoria estática, es decir que no es modificable en tiempo de ejecución. Su función es almacenar el código del programa expresado en código de bytes, por lo cual se implementa como un arreglo en memoria fı́sica. En el modelo de memoria de LMAN, no se utiliza una memoria dinámica o de traducción para el manejo de variables. Tomando ventaja de la definición de recursión que confiere el cálculo NTCC, en donde la recursión es reemplazada por replicación “ !”, por lo cual cada llamado recursivo se extiende al siguiente instante de tiempo, y también buscando eficiencia en el desempeño de la máquina; se delega la tarea del manejo de variables, particularmente de la generación de nuevas variables y sus alcances o ligaduras, al compilador. A continuación se describen cada uno de los aspectos relacionados con la memoria del programa y su implementación. 4.1.1.1. Estructura de Datos La estructura de datos que representa la memoria del programa en LMAN sigue a continuación: #define MAX_ARCH 1500 //memoria del programa char fp[MAX_ARCH]; 4.1.1.2. Formato de Instrucciones El cuadro 4.1 describe el formato de instrucciones utilizado en el código de bytes de LMAN. Para fines de optimización se eligió un formato fijo de longitud 24 bytes, que admite 64 instrucciones de máquina y direccionar máximo 8192 lı́neas de código. Se manejan además de un opcode, dos fuentes en la definición de las instrucciones. 64 Opcode 6 src1 13 src2 5 Cuadro 4.1: Formato de Instrucciones de LMAN 4.1.1.3. Conjunto de Instrucciones La figura 4.2 describe el conjunto de instrucciones, opcode, src1 y src2 de LMAN. En el cuadro 4.3 se encuentran las especificaciones dadas para los campos fuentes Src1 y Src2. Obsérvese que cada una de estas instrucciones corresponde a los procesos definidos en la semántica de NTCC. El uso de las instrucciones de LMAN se trata en detalle en el anexo A sobre Traducción de procesos NTCC a código de bytes de LMAN. 4.1.2. Interfaz STORE Con el fin de lograr que el Sistema de Restricciones asociado a LMAN se adicione paramétricamente, las restricciones son definidas como fórmulas–de–primer–orden (f po). Una f po es una expresión construida a partir de fórmulas atómicas combinadas con conectores lógicos not, and, or, y cuantificadores ∃, ∀; los átomos básicamente tienen la construcción de ecuaciones o inecuaciones matemáticas. Ejemplos: (x+y > 6)∧(z = 1), x = 2 , entre otras. Teniendo en cuenta la definición anterior, cualquier Sistema de Restricciones que pueda expresar sus restricciones como f po, puede ser integrado a LMAN. En la actual implementación ha sido acoplado el Sistema de Restricciones optimizado para el Lenguaje CORDIAL[CG01] y la Máquina MAPICO [AB98]. LMAN usa la sintáxis que se muestra en la figura 4.4 para la especificación de f po[McA92]; ésta se toma de la definición usada por MAPICO[AB98] en su adición del Sistema de Restricciones ya mencionado[CG01]. Este sistema de restricciones de dominios finitos[CG01] usado en LMAN, contiene el P sistema de restricciones aritmético–modular propuesto para NTCC. está dado por >, <, ≤, ≥ . +, −, ∗, /, =, <>. Es paramétrico como ya se ha mencionado anteriormente; de modo que, utiliza f po como entradas representadas en estructuras de árbol. Se basa en el modelo de Bjorn Carlson [Car95], ası́ que utiliza la noción de indexicals y algoritmos de arco-consistencia en su implementación. Por eficiencia, fue implementando en lenguaje C, registrandose tiempos de ejecución aceptables para diversos problemas 65 Figura 4.2: Conjunto de Instrucciones de LMAN 66 Figura 4.3: Especificación de Fuentes Src1 y Src2 en el dominio de concurrencia. Para el acople del sistema de restricciones con LMAN, se realizaron algunas modificaciones. Estas se describen a continuación: Para asegurar equivalencia entre las estructuras para representar restricciones usadas en el sistema de restricciones y en LMAN, se modificó la implementación de árboles con encadenamiento sencillo, por árboles con encadenamiento al padre. El doble puntero se hizo necesario para asegurar consistencia en el árbol cuando se construye la restricción a partir del código de bytes de LMAN. Al final de cada instante de tiempo, se hace necesario realizar una consulta al Store (Browse) acerca de las variables de ambiente. El resultado de ésta consulta es enviando al LEGO para ejecución. De esta manera, se adicionó al sistema de restricciones una función que consulta el estado de las variables; particularmente en LMAN se consultan solamente las variables del ambiente. Si la variable tiene un valor fijo, se envı́a ese valor; de lo contrario, si la variable tiene asociado un rango, se realiza un selección aleatoria de un valor en el rango. El valor de n para el sistema de restricciones se redefinió en 500 (aritmética– módulo 501). De ésta manera, es posible asignar rangos de 0 a 500. En el acople del sistema de Restricciones con LMAN, se implementaron árboles binarios; es decir, que los predicados y funciones deben definirse de aridad 2. No obstante, la sintàxis de fórmulas bien formadas usada para expresar restricciones 67 en LMAN admite la definición de aridad n, de manera que serı́a posible extender su uso. Figura 4.4: Sintáxis para la especificación de Fórmulas de Primer Orden en LMAN 4.1.2.1. Estructura de Datos La estructura de datos que representa la interfaz con el STORE se muestra a continuación: typedef struct InterfazSTORE{ Store s; Indexicals Stamp st; int i; indextemp; }InterfazSTORE; 68 4.1.2.2. Instrucciones asociadas al Sistema de Restricciones de LMAN Las instrucciones para construir f po en LMAN se describen en la figura 4.5. Figura 4.5: Instrucciones para construcción de restricciones en LMAN Los posibles valores que se definen para funciones y predicados se describen a continuación. El sistema de restricciones actualmente usado por LMAN, no modela conectores lógicos, ni rangos, ni cuantificadores. Funciones: ADD, SUBS, MULT, DIV, MOD. Pred: IGUAL, DIF, MAY, MAI(mayor o igual), MEN, MEI(menor o igual). 4.1.2.3. Construcción de Restricciones en LMAN A partir de las instrucciones presentadas en la figura 4.5, se construyen las restricciones en LMAN. La siguiente restricción, se expresa en LMAN como un árbol binario de notación infija (ver figura 4.6). 69 ( y + 2) = (x ? 4) – (z ÷ 6) Figura 4.6: Arbol binario infijo que representa una restricción en LMAN Del árbol de la figura 4.6, que contiene una restricción expresada como formula–de– primer–orden se construye la restricción que recibirá el Sistema de Restricciones usado por LMAN. Teniendo en cuenta las instrucciones descritas en la figura 4.5 y asumiendo que la variable “x” tiene la etiqueta 74, “y” la etiqueta 75 y “z” la etiqueta 76; el código necesario para construir la restricción es el siguiente: 1 ATOM IGUAL 2 // = 2 TERMF ADD 2 // + 3 TERMV 75 0 // y 4 5 TERMC TERMF 2 SUBS 0 2 // 2 // - 6 TERMF MULT 2 // * 7 TERMV 74 0 // x 8 9 TERMC TERMF 4 DIV 0 2 // 4 // / 10 TERMV 76 0 // z 11 TERMC 6 0 // 6 Del anterior bloque de código, se aprecia cómo la restricción se construye siguiendo una notación infija donde primero se describe el operador y luego los términos varia70 bles o constantes asociados a la operación. En el Sistema de Restricciones actual las restricciones se construyen como árboles binarios, luego la aridad aceptada es 2. ( ari = 2).YA que LMAN acepta cualquier Sistema de Restricciones paramétrico; la sintaxis de restricciones requiere que la aridad se haga explicita como un parámetro. (Ver figura 4.5). 4.1.3. Interfaz LEGOS Un RCX es un microcontrolador programable basado en LEGO brick con un Hitachi H8/300 como corazón y 32K en memoria RAM. Este puede operar simultáneamente tres actuadores, tres sensores y un sistema IR; adicionalmente, con el RCX se incluye una baterı́a y diferentes piezas intercambiables para crear variedad de dispositivos robóticos autónomos. Es posible programar RCX en alto nivel utilizando combinaciones de firmwares como legOS, lejOS, Lego MindStorm firmware junto con lenguajes como C, Java, NQC, entre otros. El módulo de la interfaz LEGOS es el encargado de la interacción con el ambiente, en otras palabras, es el encargado de controlar las variables asociadas al RCX. En LMAN el ambiente se define como una estructura que permite controlar los motores, los sensores, el sonido y la baterı́a; definiendo para cada uno de estos componentes los atributos necesarios para modelar adecuadamente el comportamiento del robot. La figura 4.7 ilustra la estructura usada para modelar el ambiente y para construir el paquete de datos que se transmite entre el computador y el RCX. Nótese que éste módulo permite programar el doble de dispositivos de un RCX convencional, con el fin de admitir expansiones sobre los RCX o para modelar sistemas colaborativos entre RCX. Figura 4.7: Ambiente LEGO en LMAN Al finalizar ésta sección que define la interfaz LEGOS, se presenta una breve descripción de los dispositivos LEGOS y sus capacidades. 71 4.1.3.1. Estructura de Datos Las estructuras de datos utilizadas para modelar el ambiente LEGO se definen a continuación: //entrada define el estado y el valor typedef struct { char est; char val; }entrada; //sensor define el tipo, estado y el valor de los sensores typedef struct { char tipo; char est; char val; }sensor; //soundl define el estado, la nota y la duracion de los controladores de sonido typedef struct { char est; char nt; char dur; }soundl; //se modela el ambiente LEGO typedef struct { //definicion de motores entrada mot[7]; //definicion de sensores de movimiento sensor sen[7]; //definicion de bateria entrada bat[3]; //definicion para manejo de musica soundl snd[3]; 72 }ambiente; 4.1.3.2. Ambiente LEGO En LMAN las variables son representadas por etiquetas numéricas únicas, que comienzan desde 1 y van incrementándose de uno en uno. Para modelar la interacción de LMAN con el ambiente, se reservan unas etiquetas fijas destinadas para definir variables de entrada, las cuales informan sobre cómo se encuentra el ambiente y variables de salida, que contienen la información de qué va a ser ejecutado sobre el LEGO. Se debe de tener en cuenta, que para dar escalabilidad a la implementación de LMAN, se habilitaron el doble de dispositivos de un RCX convencional. Es decir, que LMAN permite trabajar con 6 sensores, 6 motores, 2 baterı́as y 2 manejadores de sonido. El LCD o display que permite visualizar mensajes en el LEGO no fue modelado, ya que el Sistema de Restricciones no incluye la posibilidad del manejo de cadenas. No obstante, el LCD se utiliza para visualizar mensajes de depuración durante la ejecución de programas. A continuación se describe en detalle el uso de variables que hace LMAN. La notación utilizada para las variables es mayúscula, ya que se definen como constantes en la máquina virtual. 4.1.3.2.1. Variables de Entrada . Las variables de entrada comienzan en la etiqueta 1 y van hasta 34, estas se encuentran divididas de la siguiente forma: Motores: Cada uno de los 6 Motores, contiene 2 variables para indicar los atributos a continuación. El total de variables de Motores es 12. Estado: Indica si está encendido el motor y en que dirección se desplazará. Los valores posibles: 0 Apagado, 1 Adelante, 2 Atrás, 3 Frenar. Ejemplo: IMOTEST1 = 1, indica que el motor 1 tiene estado Adelante. Valor: Indica la velocidad que tiene el motor. Valores: 0 a 255. Ejemplo: IMOTSP1=80 indica que la velocidad del motor 1 se configura en 73 80. Sensores: Cada uno de los 6 Sensores contiene 2 variables para indicar los atributos a continuación. El total de variables definidas para los sensores es 12. Tipo: Indica el tipo de sensor que se utiliza: 1 tacto, 2 luz, 3 rotacion, 4 temperatura; 5 y 6 se reservan en caso de que se adiciones más sensores. Estos valores deben asignarse a las constantes que definen los tipos de sensores en la interfaz LEGO. Estado: Indica si el sensor se ha habilitado o no. Valores: 1 o 0. Ejemplo: ISENEST1=1 indica que el sensor 1 se encuentra activo. Valor: Indica el valor del sensor, por ejemplo si el sensor es de tacto dice si esta oprimido o no. Ejemplo: ISENVAL1=1 para un sensor de tacto, indica que el sensor ha sido oprimido. Baterı́as: Cada una de las 2 Baterı́as contiene 2 variables para indicar los atributos a continuación. El total de variables definidas para baterı́as es 4. Estado: Indica si la Baterı́a esta en funcionamiento o no. Valores: 1 o 0. Ejemplo: IBATEST1=1, indica que la baterı́a 1 está en funcionamiento. Valor: Indica le nivel de energı́a de la Baterı́a. Valores: 0 a 255. Ejemplo: IBATVAL1=180, indica que la baterı́a 1 tiene un nivel de energı́a de 180. Sonido: Cada uno de los 2 controladores de Sonido contiene 3 variables para indicar los atributos a continuación. El total de variables asociadas a los controladores de sonido es 6. Estado: Indica si está en funcionamiento el controlador de Sonido o no. Valores: 1 o 0. Ejemplo: ISNDEST2=1, idica que el estado del controlador 2es activo. Nota: Indica la Nota y la escala de la misma. Valores: 0 a 255. Ejemplo: ISNDNT2=55, representa la nota LA en escala 5 para el controlador 2. 74 Duración: Variable opcional para delimitar el tiempo de duración de la nota. Valores: 0 a 255. Ejemplo: ISNDDUR2=2, representa duración de una octava para una nota ya definida en el controlador 2. 4.1.3.2.2. Variables de Salida . El manejo de las variables de salida es similar a las variables de entrada, con la diferencia que inician en la etiqueta 35 y terminan en la etiqueta 68. Para el caso de las constantes que definen las etiquetas, solo se hace el cambio de la letra inicial I (INPUT) por la O (OUTPUT). Ejemplo: Variable de Entrada: ISNDDUR1 Variable de Salida: ONDDUR1 4.1.3.2.3. Variables de Usuario . A partir de la etiqueta 69 inician las variables que pueden usar los programas de usuario. 4.1.3.3. Protocolo de comunicaciones LMAN utiliza en su funcionamiento el protocolo LNP (Lego Network Protocol ) del Sistema Operativo LegOS. Este protocolo posibilita la comunicación entre varios RCX y varias estaciones de trabajo. Existe sobre los lenguajes C, Java y Python. Actúa como un protocolo UDP (User Datagram Protocol ), por lo cual no realiza acuso de recibo o chequeos de integridad en la recepción de paquetes. LNP es usado en la implementación de LMAN, para suplir el inconveniente de tamaño en memoria, por el cual se imposibilitaba la ejecución de la máquina desde el mismo dispositivo LEGO. Consecuentemente, se hizo necesario implementar un protocolo de entrega y recepción de datos que usa LNP para el envı́o, tal como se describe a continuación. El protocolo modelado no es complejo, utiliza asincronı́a y time-out para asegurar entrega de datos. Una Bandera determina el tipo del enlace. 75 Protocolo del lado de la estación de trabajo: Ver figura 4.8 1. Se envı́a al LEGO, la BANDERA en estado de sensar (1). 2. La estación de trabajo espera la respuesta con el ambiente sensado por el RCX. 3. Si se presenta un time-out(No se recibe respuesta), se regresa al paso 1. 4. Se envı́a al LEGO, la BANDERA en estado de ejecutar (2). Figura 4.8: Protocolo del lado de la estación de trabajo en LMAN Protocolo del ladol RCX: Ver figura 4.9 1. El RCX espera la BANDERA. 2. Si el estado de la BANDERA es sensar (1), el RCX sensa el ambiente. 3. EL RCX envı́a el ambiente sensado a la estación de trabajo. 4. Si el estado de la BANDERA es ejecutar (2), el RCX captura el ambiente recibido. 5. El RCX ejecuta el ambiente. 4.1.3.4. Dispositivos Robóticos LEGO El RCX 2.0 Robotics Command System (Ver figura 4.10) es un dispositivo brick programable [Gro00]. Cuenta con 3 puertos de entrada para sensores, 3 puertos de salida, 76 Figura 4.9: Protocolo del lado del RCX en LMAN cuatro botones de control, un display LCD, y un transmisor de infrarrojos. Adicionalmente, posee un microprocesador para el procesamiento de programas, una memoria interna para almacenar el firmware y los programas y un speaker para producir beeps y tonos. 4.1.3.4.1. LEGO Brick . Los puertos de sensores permiten conectar sensores de luz, tacto, rotación y temperatura. Los dos últimos no se incluyen en el kit LEGO MindStorm. Los puertos de salida permiten conectar motores y otros dispositivos como luces que no se incluyen en el kit. Adicionalmente es posible conectar otros LEGO bricks. Internamente el dispositivo cuenta con 3 sensores internos: temporizador, para mantener un rastro del tiempo; un manejador de mensajes, que espera por mensajes enviados por otros RCX y por último, variables definidas por el usuario. Por medio de éstos dispositivos, el robot puede moverse y reaccionar con su ambiente.El brick requiere 6 baterı̀as AA/LR6 de 1.5 voltios para su funcionamiento. La torre IR es la encargada de establecer un enlace inhalámbrico entre la estación de trabajo y el RCX. Por medio de la torre IR que utiliza señales infrarrojas para enviar mensajes, se descarga el firmware y los programas a la memoria del RCX. Para descarga la distancia sugerida entre la torre y el RCX es 10-12 cm; en condiciones óptimas de luz se puede transmitir hasta una distancia de 30 metros usando una torre USB. 77 Figura 4.10: RCX LEGO brick 4.1.3.4.2. Firmware y lenguajes de programación . El firmware es un software especial que posibilita la comunicación entre una estación de trabajo y el RCX. Actúa como el sistema operativo del RCX. En la actualidad existen diversos métodos para programar RCX; los cuadros 4.2 y 4.3 resumen algunos de los más utilizados. 4.1.3.4.3. Modelos de Robots . Las piezas intercambiables de LEGO pueden utilizarse para construir diferentes tipos de robots, la figura 4.11 muestra algunas de las opciones más utilizadas. EL presente trabajo se prueba sobre un modelo Roverbot. 78 Firmware Autor Tipo Lenguajes Plataformas Descripción Firmware Autor Tipo Lenguajes Plataformas Descripción Firmware Autor Tipo Lenguajes Plataformas Descripción BrickOS (legOS) Markus L. Noga Reemplazo de Firmware C,C++ Desarrollado sobre x86 GNU/Linux, probado sobre PPC Linux. Es portable en Cygwin-DJGPP sobre MSWindows y soportado en Mac. LegOs es un sistema operativo multitarea para el RIS (Robotics Invention System). Los programas son escritos en C,C++ compilados en la estación usando gcc-cross-compiler y luego descargados al RCX para ejecución. Incluye random, punto flotante, hilos con semáforos, y almacenamiento múltiple de programas. Permite recibir y enviar datos entre estaciones windows o linux. Usa la velocidad nativa del mircroprocesador (16 MHz) y utiliza LNP como protocolo de comunicación basado en transmisor de infrarrojo con el RCX. Es una poderosa alternativa para RCX. Not Quite C (NQC) Dave Baum compilador de código de bytes nativo lenguaje similar a C, llamado Not Quite C. GNU/linux, MS Windows, y Macintosh. NQC es un compilador de código de bytes que toma programas escritos en una sintáxis similar a C y la traduce a un código de bytes que el firmware utilizado en el LEGO pueda entender. NQC tiene limitaciones en el numero de variables dispobibles que es 32, no existen estructuras de datos, las subrutinas no pueden retornar valores, solo pueden usarse variables globales y las subrutinas no admiten paramétros. Tiny VM y leJOS José Solorzano Reemplazo de firmware Java GNU/Linux, Win32. Tiny VM es una implementación de la Máquina Virtual de Java que se descarga en el RCX para sustituir el firmware estandar. Los programas para Tiny VM, pueden usar algunas librerı́as java estandar y una librerı́a disponible para el control de sensores y motores del LEGO. Los programas escritos en java, requieren ser compilados y luego descargados en el RCX para su ejecución. leJOS es un proyecto similar realizado por el mismo autor, que incluye adiciones como soporte de punto flotante y cadenas. Cuadro 4.2: Alternativas de programación de RCX 79 Firmware Autor Tipo Lenguajes Plataformas Descripción Firmware Autor Tipo Lenguajes Plataformas Descripción Pylnp Les Smithson Libreria de control remoto Phyton GNU/Linux. Pylnp es una libreria de control remoto que a difrencia de otras librerias, interactúa con legOS y no con el firmware estandar. Esto posibilita que el usuario pueda invocar funcionalidades legOS. Lego::RCX.pm John C. Quillan Remote control library Perl GNU/Linux, MS Windows y Solaris Lego::RCX.pm es una librerı́a perl para el control remoto de el RCX utilizando la torre IR para enviar los comandos al firmware estandar para que éste, los interprete y actúe. Cuadro 4.3: Alternativas de programación de RCX Figura 4.11: Algunos ejemplos de modelos LEGO 80 4.1.4. ControlLMAN Con todos los módulos anteriores dispuestos, controlLMAN es quien se encarga de gestionar recursos, tareas y el tiempo. Cabe mencionar que el instante de tiempo definido para LMAN no se rige por un reloj explı́cito; el fin del instante lo define la ausencia de procesos en las colas. Es decir, que el instante termina cuando tanto la cola de procesos listos (CL) como la cola de procesos Unless(CU) se encuentran vacias. 4.1.4.1. Estructura de Datos La estructura de Datos que modela el control se muestra a continuación. ColaM es la implementación de colas de máquinas y ColaP es la implementación de colas de procesos. LZumatoria es la implementación de listas de guardas, donde el TAD guarda es utilizado para modelar la lista de ask del proceso guarded-choise en el cálculo. Solo se admite un nivel en ésta estructura, es decir que no puede definirse un proceso sumatoria dentro de otro proceso sumatoria. Las estructuras de máquinas y procesos se muestran a continuación: typedef struct controlLMAN{ //cola de máquinas, se define una máquina por instante ColaM cMaquinas; //cola de construcción de la máquina del siguiente instante ColaP cConstruccion; //memoria del programa char fp[MAX_ARCH]; //store InterfazSTORE iStore; }ControlLMAN; typedef struct MAQUINA { int PCN; //registro contador PCN de la maquina FrameConst PAN; //registro apuntador de restricciones de la maquina FrameConst PAUX; //registro auxiliar de la máquina ColaP cListos; //cola de procesos listos ColaP cAsk; //cola de procesos ask suspendidos 81 ColaP cUnless; } Maquina; //cola de procesos unless typedef struct PROCESO { int PC; FrameConst PA; //registro contador del programa //registro apuntador al arbol restricciones FrameConst PAux; //registro auxiliar int instante; //almacena instante actual, usado para reglas star y next ListaG lZumatoria; } Proceso; //guarda la lista de when asociadas a una zumatoria typedef struct GUARDA { int PC; FrameConst PA; //registro contador del programa //registro apuntador arbol restricciones char marca; //utilizada para la regla gask, ndet } Guarda; 4.1.4.2. Gestión de ControlLMAN La gestión que realiza el control puede resumirse en la figura 4.12. ControlLMAN es quien regula la ejecución de la máquina ”mientras no se presente un error ”, es decir que mientras existan reducciones que no generen bloqueos o errores en la máquina, ésta se ejecutará infinitamente. El control define un nuevo instante e inicia el estado de ”Planeación de Máquinas”. En este estado y para un instante diferente al inicial, el control destruye la máquina y el Store anterior, crea la nueva máquina y Store para el instante actual; y procede a sensar el ambiente y a comentar su resultado en el Store. Si se trata del instante inicial, simplemente crea la máquina y el Store para comenzar la computación. A continuación llega al estado de Ejecución, en donde ejecuta secuencialmente las instrucciones almacenadas en la memoria de programa. En éste estado es donde realiza la planeación de procesos, que involucra la ejecución de las reglas de reducción definidas en la máquina abstracta, en otras palabras, ejecuta las transiciones internas. Luego que termina la computación de reglas, llega al estado PonerAmbiente, en donde pregunta al 82 Store por el estado final de las variables asociadas al ambiente y procede a enviar esta información al LEGO para su ejecución. Con éste último estado, finaliza el instante, es decir que se produce una transición observable y de nuevo el control inicia su ciclo reactivo. Figura 4.12: Gestión del controlLMAN 4.2. Funcionamiento de LMAN LMAN requiere como plataforma de Hardware (Ver figura 4.13) los siguientes elementos: RCX 2.0 dispuesto en un modelo de robot LEGO. Torre USB/serial. La transmisión vı́a LNP ha sido probada utilizando una torre serial. Estación de trabajo para la comunicación y procesamiento de LMAN. El sistema ha sido probado ejecutándose desde una estación Pentium III a 930Mhz, 256KB RAM con linux Debian Woody 3.0. LMAN requiere como plataforma de Software (Ver figura 4.14) los siguientes elementos: 83 Figura 4.13: Requerimientos Hardware del Sistema LMAN Sistema operativo BrickOS, ejecutando Cross Compiler gcc y H8300binutils para controlar el microprocesador del RCX. El sistema ha sido probado para BrickOS versión 2.6.1. Módulo de Comunicación LNP. Driver USB/serial. LMAN incluyendo los módulos del Sistema de Restricciones y el Compilador asociados. Figura 4.14: Requerimientos Software del Sistema LMAN Sobre la estación de trabajo se ejecutan LMAN, el Sistema de Restricciones y el Compilador. El RCX debe contener BrickOS (legOS) como firmware y el componente de LMAN diseñado para sensar el ambiente y ejecutar comandos sobre el robot. Con todos estos requisitos dispuestos correctamente, el flujo de datos en el sistema se realiza tal como se muestra en la figura 4.15. 84 La entrada de datos al Sistema se produce desde el editor VINE del Lenguaje Visual VIN o desde el editor de texto gvin configurado para chequear sintaxis NTCC. Ası́, una vez construido el programa NTCC en una de estas dos herramientas y guardado con extensión .lmn, se compila haciendo uso del Compilador NTCC-LMAN que traduce entradas NTCC a código de bytes de LMAN, generando un archivo extensión .out. La máquina virtual toma como entrada el archivo generado por el compilador e inicia el ciclo reactivo de computación mientras no se produzcan fallos de comunicación o bloqueos en el Store. Si no es el instante inicial, el control crea la máquina y Store actuales destruyendo los anteriores, y envı́a una señal al RCX (Bandera=1) para indicarle que debe sensar. El RCX recibe la señal y captura el estado de su mundo; empaqueta ésta información del ambiente y la envı́a hacia LMAN usando la torre IR y el modulo LNP. LMAN entonces, comenta ésta información al Store y con ella inicia el procesamiento del programa y las reducciones hasta determinar el fin de la unidad de tiempo. Cuando las colas de ejecución y de procesos unless se encuentran vacı́as, el control consulta el estado final del Store, y procede a empaquetar ésta información y enviarla al RCX(Bandera=2) para ejecución; en este momento se determina el fin de la unidad de tiempo y de nuevo se da inicio al ciclo reactivo. Si entre el envı́o de la señal de sensar(Bandera=1) y la recepción del paquete con la información del ambiente, la máquina no recibe respuesta; se genera un time–out que retorna al paso de envı́o de señal para sensar. Si durante 5 intentos continuos la máquina no recibe el paquete, se aborta la ejecución. En éste momento no ha sido liberado el driver USB para legOS, por lo tanto la comunicación vı́a LNP en la actual implementación se hace utilizando una torre serial. La figura 4.16 muestra el comportamiento reactivo que sigue LMAN. Cada unidad de tiempo comienza con un Store Inicial Si . Durante la unidad la máquina procesa con esta información como entrada y al final genera una salida que se envı́a al robot para ejecución. Este procedimiento lo realiza infinitamente mientras no exista un bloqueo en el Store o un fallo en la comunicación. 85 Figura 4.15: Funcionamiento del Sistema LMAN Figura 4.16: Comportamiento reactivo del Sistema LMAN 86 5 COMPILADOR NTCC–LMAN Como ya se ha mencionado en capı́tulos anteriores, la implementación del Cálculo NTCC define un flujo que incluye 3 módulos: un LENGUAJE VISUAL VIN, un COMPILADOR NTCC-LMAN y una MAQUINA ABSTRACTA LMAN para finalmente permitir programación concurrente de robots LEGO MindStorm. El módulo del COMPILADOR NTCC–LMAN, es usado para definir una interfáz de programación de alto nivel para el usuario. Por medio del editor gvin configurado para chequear sintaxis NTCC; el usuario puede construir programas usando la sintaxis propia del cálculo, y posteriormente compilarlos para generar el código de bytes de LMAN. En éste punto, ya LMAN toma el código de bytes, procesa y ejecuta sobre el robot. Adicionalmente, debido a que tanto el lenguaje visual VIN ya mencionado, como el compilador utilizan la sintaxis básica del cálculo, se hace posible integrarlos. De ésta manera, el lenguaje visual genera código NTCC, que el compilador interpreta y traduce a código de bytes de LMAN para ejecución. Ası́ con estos tres módulos dispuestos, se completa el flujo de implementación de NTCC que permite al usuario programar utilizando, sea el lenguaje icónico, el editor NTCC o directamente en las intrucciones de la máquina virtual. A continuación se describen las consideraciones del diseño del compilador NTCCLMAN; su desarrollo no está considerado entre los alcances del actual trabajo de tesis. La implementación de éste, fue realizada como proyecto de semestre en el curso de compiladores en la Pontificia Universidad Javeriana–Cali por F. Rocha, J. Chalá y M. Pabón [RCP03]. De común acuerdo con el profesor del curso se diseñó el compilador, y se motivó a los estudiantes continuamente para lograr una buena implementación. Al finalizar el semestre se seleccionó la mejor implementación[RCP03], se acopló con la implementación de LMAN y se realizaron las pruebas pertinentes de funcionamiento y desempeño arrojando los resultados esperados en efectividad y eficiencia. 87 5.1. Sintáxis 5.1.1. Conjunto de Caracteres El conjunto de caracteres básico esta formado por: Letras mayúsculas, minúsculas, dı́gitos y caracteres especiales: ( ) * [ > < ] ! & .. | \# = + . -\&\& / , Los identificadores de las constantes deben escribirse con letras mayúsculas y los de las variables empiezan con letras minúsculas y pueden seguir con letras mayúsculas o minúsculas y numeros. Debido a que LMAN interactúa con el robot, es necesario definir una serie de variables que manejan su ambiente. Estas actúan como variables globales a todo proceso en NTCC y se definen de dos tipos: de entrada anteponiendo la letra i al listado que se describe a continuación, y de salida anteponiendo la letra o. Ejemplo: imot1, omot1 ... isen1, osen1 ... ivalsnd2, ovalsnd2, entre otras. mot1,mot2, ..., mot6. Identifican los motores del robot. spmot1, spmot2, ..., spmot6. Identifican las velocidades de los motores. sen1,sen2, ..., sen6. Identifican los sensores en funcionamiento. valsen1,valsen2, ..., valsen6. Identifican el estado de los sensores. bat1, bat2. Identifican las baterı́as en funcionamiento. valbat1, valbat2. Identifican el estado de las baterı́as. snd1, snd2. Identifican el sonido en funcionamiento. valsnd1, valsnd2. Identifican el estado del sonido activo. 88 when unless next do tell local max min in succ pred skip Cuadro 5.1: Palabras reservadas en el Compilador NTCC-LMAN Las palabras propias del cálculo son reservadas y no pueden ser usadas como nombres definidos por el usuario; estas se muestran en el cuadro 5.1 Las variables son de tipo entero y tienen un rango definido en los números enteros positivos de 0 a n, donde n es una constante definida previamente. Para efectos de este compilador, se tomará n = 500. Las variables de salida no pueden tener asignaciones directas mayores a 255, esto se debe las limitaciones de los dispositivos LEGO descritas en la sección Interfáz LEGO del capı́tulo que describe la máquina virtual. Ejemplo: tell(omot1=289) no es válido pues es una asignación directa a una variable de salida mayor a 255. Los comentarios en NTCC se efectúan con dos guiones adyacentes “ —- ” en cualquier posición de una lı́nea, y terminan con nueva lı́nea. Ejemplo: -- Proceso TELL de NTCC (tell x=5) 5.1.2. Reglas de Producción En la definición de la sintaxis para el compilador se tienen las siguientes consideraciones: <nombre> identifica el nombre de un sı́mbolo (terminal o no terminal) “→” especifica una regla de producción y “|” separa las reglas de producción que corresponden a un mismo sı́mbolo no terminal. En una regla de producción, los sı́mbolos que no están encerrados entre” <>” son palabras o sı́mbolos propios del lenguaje. Cuando la definición no se hace con una regla de producción (no lleva → ), ésta corresponde a una descripción (no formal) del sı́mbolo. 89 A continuación se describe las reglas de producción utilizadas por el compilador: 5.1.2.1. Variables y Constantes Los identificadores no declarados se asumen como variables globales. La declaración de variables locales tiene la siguiente forma: < V ar dec > → local < ID list > in | ( local < ID list > ) < ID list > lista de nombres de variables La declaración de constantes tiene la forma: < Const dec > → | < const dec > const < ID constante > = < Lit int > < Lit int > literal entero < ID constante > nombre de una constante 5.1.2.2. Restricciones El Store se define como una conjunción lógica de restricciones expresadas como fórmulas de primer orden. Las reglas para expresar restricciones como fórmulas de primer orden siguen a continuación: < Constraint > → < Expresion > < Expresion > → < Lit expresion > | < V ar ref erence > |(< Expresion >) | < Expresion > < Operador > < Expresion > | < V ar ref erence > in < Rango > |succ(< Expresion >) |pred(< Expresion >) < Rango > → < Constante > :: < Constante > |– (< Rango >) |min(< Rango >) |max(< Rango >) | < Rango > && < Rango > | < Constante > .. < Constante > 90 < V ar ref erence > → < ID variable > | < ID constante > < Lit expresion > → < Lit int > < Operador > son todos los operadores del cuadro 5.2. < ID variable > nombre de una variable < Constante > → < Lit int > | < ID constante > Los operadores para la construcción de restricciones se definen en el cuadro 5.2. En la definición del rango el sı́mbolo “::” significa unión, el sı́mbolo “–” significa complemento, el sı́mbolo “&&” intersección, y el sı́mbolo “..” representa un rango (inicio y fı́n). Clase de Operador Lógico Negación Relacionales Aritméticos Operador &|| Not = |! = | < | > | ≤ | ≥ +| − | ∗ |/| % Cuadro 5.2: Operadores sobre restricciones 5.1.2.3. Procesos A continuación se muestran las reglas que definen los procesos NTCC: <P >→ when < Constraint > do P | < P > || < P > | ∗[< Constante >, < Constante >] < P > |!<P > | unless < Constraint > next < P > | next < Const op > < P > | (< P >) | var dec < P > |<P >+<P > | tell < Constraint > | skip < Const op > constante opcional 91 5.1.2.4. Programa Un programa está formado por la declaración de constantes y una serie de procesos: < P rograma > → < Const dec > < P rocesos > < P rocesos > → < P > | < P rocesos > < P > Ejemplos de programas NTCC se muestran en el capı́tulo 7 de pruebas y ejemplos. 5.2. Semántica Los chequeos semánticos que realiza el compilador tratan las operaciones aritméticas, relacionales y lógicas de las restricciones. Adicionalmente trata los tres puntos que se describen a continuación: Gramática Ambigua . Para evitar que la gramática definida para el compilador resultara ambigua, se realizó una modificación a la notación con paréntesis utilizada en [Val03]. Esta modificación obliga que toda restricción debe escribirse entre paréntesis. Precedencia de Procesos . La precedencia de procesos se presenta a continuación. Es importante notar, que los procesos están organizados según su alcance. !,*,next,unless,local ligan al mas cercano || liga al proceso mas cercano de la suma (+) Ejemplo: P + local x in next Q || R Significa: P + ((local x in (next Q)) || R) Se observa que el local x in P también se puede escribir como (local x)P Restricción Semántica . No pueden definirse procesos local < ID list > in ( when < Constraint > do < P > + when < Constraint > do < P > + . . . ). Lo anterior hace referencia al caso particular en que el programa NTCC incluya !!P en ciertas condiciones, lo cual generarı́a un estado de inconsistencia en la máquina. Para solucionar lo anterior, se define que “!!P ∼ = !P sii P tiene un local 92 con determinismo“; es decir que, mientras no exista un proceso tipo guardedchoise en un local para P, se puede asegurar que !!P se ejecuta como !P. 5.3. Generación de Código La generación de código es el paso final en la compilación, en el cual se genera el archivo con la traducción al código de bytes de LMAN. La descripción de cómo se traducen los procesos, se describe detalladamente en el Anexo A, acerca de Traducción de procesos NTCC a código de bytes LMAN. El Anexo B describe todas las librerias usadas por el compilador para construir programas en código de bytes LMAN. 93 6 Ejemplos y Pruebas En este capı́tulo se describen ejemplos de programación y pruebas realizadas sobre la máquina virtual LMAN ejecutado construcciones NTCC. Como se mencionó anteriormente en la sección 1.4, no conocemos alguna otra implementación de un cálculo de procesos, temporal, concurrente por restricciones validado sobre robots LEGO; por lo cual una comparación entre LMAN y otras máquinas virtuales no serı́a realmente equitativa; sin embargo, en éste capı́tulo se expone una comparación a nivel de recursos entre LMAN, el lenguaje formal ESTEREL[MR82] y la máquina virtual estándar LEGO. 6.1. Ejemplos A continuación se expondrán los ejemplos que fueron compilados usando el compilador NTCC-LMAN y ejecutados en LMAN. 6.1.1. Programa Zig-Zag El ejemplo de zig-zag fue expuesto anteriormente en el capı́tulo del cálculo NTCC (ver sección 2.6.1), ahora se muestra su implementación de acuerdo a la sintáxis valida en LMAN : Programa ZIG ZAG --Definición de constantes para el programa const VEL = 50 const FWD = 1 94 const BACK = 2 const RGHT = 5 const LFT = 7 !( -- Procesos 1 y 2:Asignación de velocidades (tell (ospmot1=VEL)) || (tell (ospmot3=VEL)) || --Proceso 3: ZIG ZAG ( (when (a!=FWD) do (tell (gf=1)) ) + (when (b!=RGHT) do (tell (gr=1)) ) + (when (b!=LFT) do (tell (gl=1)) ) ) || --CELDAS --Proceso 4: Implementación de la primera celda (ca) (when (ca=1) do ( (next tell (ca=1)) || (unless (changea=1) next ( (when (a=0) do (next tell (a=0))) + 95 (when (a=FWD) do (next tell (a=FWD))) + (when (a=RGHT) do (next (tell (a=RGHT)))) + (when (a=LFT) do (next ( tell (a=LFT)))) ) ) ) ) || --Proceso 5: Implementación de la segunda celda (cb) (when (cb=1) do ( (next tell (cb=1)) || (unless (changeb=1) next ( (when (b=0) do (next tell (b=0))) + (when (b=FWD) do (next tell (b=FWD))) + (when (b=RGHT) do (next tell (b=RGHT))) + (when (b=LFT) do (next tell (b=LFT))) ) ) ) ) || --Proceso6: exchf, exchange forward. (when (exchf=1) do ( (tell (changea=1)) || (tell (changeb=1)) 96 || (next (tell (a=FWD))) || ( (when (a=0) do (next tell (b=0))) + (when (a=FWD) do (next tell (b=FWD))) + (when (a=RGHT) do (next tell (b=RGHT))) + (when (a=LFT) do (next tell (b=LFT))) ) ) ) || --Proceso7: exchr, exchange right. (when (exchr=1) do ( (tell (changea=1)) || (tell (changeb=1)) || (next (tell (a=RGHT))) || ( (when (a=0) do (next tell (b=0))) + (when (a=FWD) do (next tell (b=FWD))) + (when (a=RGHT) do (next tell (b=RGHT))) + (when (a=LFT) do (next tell (b=LFT))) ) ) ) 97 || --Proceso 8: exchl, exchange left. (when (exchl=1) do ( (tell (changea=1)) || (next (tell (a=LFT))) || (tell (changeb=1)) || ( (when (a=0) do (next tell (b=0))) + (when (a=FWD) do (next tell (b=FWD))) + (when (a=RGHT) do (next tell (b=RGHT))) + (when (a=LFT) do (next tell (b=LFT))) ) ) ) || --Procesos que determinan el movimiento y el exchange a ejecutar --Proceso 9: gf, goforward ( when (gf=1) do ( (tell (exchf=1)) || (next (tell (omot1=FWD))) || (next (tell (omot3=FWD))) ) ) || --Proceso 10: gr, goright 98 ( when (gr=1) do ( (tell (exchr=1)) || (next (tell (omot1=FWD))) || (next (tell (omot3=BACK))) ) ) || --Proceso 11: gl, goleft ( when (gl=1) do ( (tell (exchl=1)) || (next (tell (omot1=BACK))) || (next (tell (omot3=FWD))) ) ) ) || --Inicialización de celdas --Proceso 12 y 13 (tell (a=0)) || (tell (b=0)) Descripción del programa: En la primera parte, los primeros dos procesos comentan restricciones sobre las velocidades en los motores uno y tres, utilizando para ello las variables de salida del ambiente de LMAN (ospmot1 = V EL, ospmot3 = V EL). 99 La segunda parte define el proceso encargado de escoger el siguiente movimiento del robot (tarea Zig-Zag) activando un proceso, esta decisión se representa con una sumatoria no-deterministica similar al ejemplo original de NTCC. Los siguientes cinco procesos modelan las celdas (a y b) y el proceso exchage con sus variantes; éstas definiciones son similares a las que presenta el ejemplo dado en [Val03] para el cálculo NTCC ; sin embargo, el programa contiene algunas modificaciones aplicadas, como lo son la generación de guardas solo con los valores 0, FWD, RIGHT y LEFT. La cuarta parte, procesos nueve, diez y once, modela la ejecución de los movimientos del robot; estos procesos son los encargados de asignar la dirección a las variables de ambiente de LMAN, que controlan la dirección de los motores y su estado actual(omot1, omot3). Finalmente, la última parte es la encargada de dar valores iniciales a las celdas (a y b), en la primera unidad de tiempo para ejecutar el programa. Es importante mencionar que las guardas ejercen control sobre la ejecución del bloque de procesos al cual se antepone. Con esto se modela procedimientos y la llamada de un proceso por otro; de lo contrario, todos los procesos se ejecutarı́an concurrentemente sin control, generando un comportamiento no esperado, fallas y bloqueos en el Store. 6.1.2. Programa de Evasión de Obstáculos El siguiente programa es la tarea de evasión de obstáculos, que consiste ”en que el robot se mueva hacia adelante y cuando encuentre un obstáculo, gire en alguna dirección, en éste caso hacia la izquierda, y posteriormente continué avanzando hacia adelante”[Val00], el objetivo de esta tarea es como su nombre lo explica, el movimiento del robot superando los obstáculos que encuentre. PROGRAMA DE EVASIÓN DE OBSTÁCULOS ( --Proceso 1: Run Evasion !( when (re=1) do 100 ( when (ivalsen1=1) do next tell (gb=1) || when (ivalsen3=1) do next tell (gb=1) || when (ivalsen1=0) do ( unless (ivalsen3=1) next ) || --Procesos que determinan el movimiento a ejecutar --Proceso 2: goForward when (gf=1) do ( tell (omot1=1) || tell (omot3=1) || next tell (re=1) ) || --Proceso 3: goBack when (gb=1) do ( tell (omot1=2) || tell (omot3=2) || next tell (tl=1) ) || --Proceso 4: turnLeft when (tl=1) do ( tell (omot1=1) || tell (omot3=0) || next tell (re=1) ) || 101 tell (gf=1)) --Proceso 5 y 6: Asignación de velocidades tell (ospmot1>80) || tell (ospmot3>80) || --Proceso 7: Activación del Sensor 1 tell (osen1=1) ) || --Activación del proceso Run Evasion tell (re=1) ) Descripción del programa: El primer proceso re es el encargado de decidir cual es el siguiente movimiento que ejecutará el robot LEGO. Si alguna de las variables de ambiente de entrada que contiene LMAN para indicar los estados de los sensores 1 y 3 tiene el valor de oprimido(1); entonces el robot LEGO a detectado un obstáculo, por lo cual retrocederá (gb) y girará a la izquierda(tl), de lo contrario continuará su trayectoria(gf ). Los siguientes tres procesos se encargan de ejecutar los movimientos que deberá hacer el robot LEGO, asignando el valor a las variables de ambiente de LMAN que controlan la dirección de los motores y su estado actual(omot1, omot3). Los procesos cuatro y cinco son los encargados de comentar las restricciones sobre las velocidades de los motores uno y tres, utilizando para ello las variables de salida del ambiente de LMAN (ospmot1 = V EL, ospmot3 = V EL). El proceso seis, se encarga de encender el sensor uno, por medio de la variable de salida del ambiente de LMAN (ospmot1 = V EL, ospmot3 = V EL). Finalmente, el ultimo proceso se encarga de iniciar la tarea de evasión de obstáculos (re), en el primer instante. 102 6.1.3. Aplicaciones Musicales Para mostrar los diversos ambientes de aplicación del cálculo NTCC, se incluye éste ejemplo que consiste en interpretar una melodı́a en el robot LEGO. Las notas se modelan teniendo en cuenta que cada unidad de tiempo vale por una corchea, por ejemplo; para que una nota suene como negra,se debe tocar como corchea en dos unidades de tiempo consecutivas. Su implementación es la siguiente: PROGRAMA CANON EN DO MAYOR --Constantes para el programa const ON = 1 const CORCHEA = 4 const BT = 38 const CC = 39 const CMC = const DC = 40 41 const DMC = 42 const EC = 43 const FC = const FMC = 44 45 const GC = 46 const GMC = 47 const AC = const AMC = 48 49 const BC = 50 const CQ = 51 const CMQ = const DQ = 52 53 const DMQ = 54 const EQ = 55 const FQ = const FMQ = 56 57 const GQ = 58 const GMQ = 59 103 const AQ = const AMQ = 60 61 const BQ 62 = ( --Proceso 1: Activación del sonido (! tell (osnd1=ON)) || --Proceso 2: Duración de la nota (! tell(osnddur=CORCHEA)) || --Proceso 3: Interpretacion de notas (next 1 || tell (ovalsnd1=GC)) (next 2 tell (ovalsnd1=GC)) || (next 3 || tell (ovalsnd1=CC)) (next 4 tell (ovalsnd1=DC)) || (next 5 tell (ovalsnd1=EC)) || (next 6 tell (ovalsnd1=FC)) || (next 7 tell (ovalsnd1=GC)) || (next 8 tell (ovalsnd1=GC)) || (next 9 tell (ovalsnd1=CC)) || (next 10 tell (ovalsnd1=CC)) || (next 11 tell (ovalsnd1=CC)) || (next 12 tell (ovalsnd1=CC)) 104 || (next 13 tell (ovalsnd1=AC)) || (next 14 tell (ovalsnd1=AC)) || (next 15 tell (ovalsnd1=FC)) || (next 16 tell (ovalsnd1=GC)) || (next 17 tell (ovalsnd1=AC)) || (next 18 tell (ovalsnd1=BC)) || (next 19 tell (ovalsnd1=CQ)) || (next 20 tell (ovalsnd1=CQ)) || (next 21 tell (ovalsnd1=CC)) || (next 22 tell (ovalsnd1=CC)) || (next 23 tell (ovalsnd1=CC)) || (next 24 tell (ovalsnd1=CC)) || (next 25 tell (ovalsnd1=FC)) || (next 26 tell (ovalsnd1=FC)) || (next 27 tell (ovalsnd1=GC)) || (next 28 tell (ovalsnd1=FC)) || (next 29 tell (ovalsnd1=EC)) || 105 (next 30 tell (ovalsnd1=DC)) || (next 31 tell (ovalsnd1=EC)) || (next 32 tell (ovalsnd1=EC)) || (next 33 tell (ovalsnd1=FC)) || (next 34 tell (ovalsnd1=EC)) || (next 35 tell (ovalsnd1=DC)) || (next 36 tell (ovalsnd1=CC)) || (next 37 tell (ovalsnd1=DC)) || (next 38 tell (ovalsnd1=DC)) || (next 39 tell (ovalsnd1=EC)) || (next 40 tell (ovalsnd1=DC)) || (next 41 tell (ovalsnd1=CC)) || (next 42 tell (ovalsnd1=BT)) || (next 43 tell (ovalsnd1=CC)) || (next 44 tell (ovalsnd1=CC)) || (next 45 tell (ovalsnd1=CC)) || (next 46 tell (ovalsnd1=CC)) ) 106 Descripción del programa: El primer proceso activa en todas las unidades de tiempo el soporte de sonido en robot LEGO; mediante las variables(osnd1) de salida del ambiente de LMAN. El segundo proceso se encarga de dar la duración de cada nota (en este caso una corchea) para todos los instantes; ésto se hace mediante las variables globales de LMAN (osnddur1). Los siguientes procesos interpretan una nota de la melodı́a en cada unidad de tiempo. 6.2. Pruebas En esta sección se comentan los resultados de la ejecución de pruebas de los ejemplos anteriores, y se muestran los resultados de pruebas en otras caracterı́sticas de la máquina virtual como tolerancia a fallos y depuración de errores. Finalmente, se hacen comparaciones con las máquina virtual estándar de LEGO[Leg00] y el compilador de ESTEREL. 6.2.1. Etapa de pruebas de LMAN Esta etapa, fue realizada probando cada uno de los módulos de la máquina por separado y una vez superada la prueba individual de cada uno, se procedió a probar la máquina en su totalidad. En cada módulo de LMAN se puede encontrar un makef ile que genera un ejecutable que corresponde a la prueba individual del respectivo módulo. Luego de integrar cada uno de los módulos, se probo la máquina por completo ejecutando los ejemplos anteriormente expuestos en una estación de trabajo con procesador pentium III a 930 Mhz, 256 Kb de memoria RAM y sistema operativo Linux Debian Woddy 3.0. Cada uno de estos ejemplos utiliza propiedades particulares del cálculo y de la máquina, a continuación se resaltan los detalles de la ejecución de cada uno: 107 6.2.1.1. Programa Zig-Zag Entre las propiedades del cálculo que utiliza el programa Zig-Zag se encuentran el no– P determinismo, mediante el proceso de sumatoria when cdo P , la replicación infinita de procesos (!) y la comunicación con el Store a través del proceso tell c El programa Zig-Zag se ejecutó en una superficie homogénea de 80 cm, con una torre de comunicación serial ubicada a 80 cm de altura y un robot LEGO modelo roverbot. La ejecución del programa fue satisfactoria, con un tiempo de ejecución promedio por instante de 302.5 milisegundos (ver cuadro 6.1). Durante las pruebas, no presentó problemas de comunicación con la torre serial, debido a que se encontraba en un ambiente libre de obstáculos. Programa Tiempo de Unidad (milisegundos) ZigZag 305 ZigZag 305 ZigZag 300 ZigZag 300 Promedio 302.5 Cuadro 6.1: Desempeño del programa Zig-Zag 6.2.1.2. Programa de Evasión de Obstáculos Entre las propiedades del cálculo que se prueban en el programa de Evasión de Obstáculos, se encuentran la información negativa con el unless c next P , la sincronización de procesos a través del Store when c do P y la percepción del entorno por medio de las variables de entrada y salida del ambiente de LMAN que denotan el estado de los periféricos del robot LEGO (sensores). El programa de evasión de obstáculos se ejecutó en un laberinto de superficie de icopor de 60 x 30 cm , con una torre de comunicación serial ubicada a 80 cm de altura y un robot LEGO modelo roverbot (Ver figura 6.1). El desempeño del programa resultó satisfactorio, con un tiempo de ejecución promedio por una unidad de NTCC de 287.5 milisegundos (ver cuadro 6.2), y tiempo de ejecución promedio de 2893 milisegundos cuando se presentaron inconvenientes de comunicación con la torre Serial. El tiempo 108 promedio de solución del laberinto fue 1 minuto con 11 segundos, al evaluar este tiempo se debe tener en cuenta el retardo que ocasionado por los inconvenientes de transmisión. Figura 6.1: Ejecución del programa Evasión de obstáculos Programa Evasión de obstáculos Evasión de obstáculos Evasión de obstáculos Evasión de obstáculos Promedio Tiempo de Unidad Tiempo de Tiempo de Solución (milisegundos) Unidad con Retardo (minutos) (milisegundos) 290 2893 1.18 280 2666 1.05 290 2690 1.07 290 2825 1.17 287.5 2768.5 1.11 Cuadro 6.2: Desempeño del programa Evasión de Obstáculos 6.2.1.3. Aplicaciones Musicales El programa de la interpretación de un fragmento de Canon en Do mayor permite probar propiedades de NTCC como la noción de tiempo multiforme, el modelamiento en que cada unidad se considera una corchea, el retardo en la ejecución de procesos, entre otros. Los procesos next i (P ), posponen la ejecución de P , i unidades de tiempo. Con éste programa, también se prueba el manejo del módulo de sonido del robot LEGO, usando las variables de ambiente de LMAN. 109 El programa Canon sobre el robot se ejecutó en una superficie homogénea de 80 cm, con una torre de comunicación serial ubicada a 80 cm de altura y un robot LEGO modelo roverbot. El desempeño del programa resultó aceptable con un tiempo de ejecución promedio por instante de 281.25 milisegundos (ver cuadro 6.3). Durante la ejecución no se presentaron problemas de comunicación con la torre serial, debido a que no hubo movimiento del robot LEGO, ni obstáculos en la comunicación. Programa Tiempo de Unidad Canon 280 Canon 285 Canon 280 Canon 280 Promedio 281.25 Cuadro 6.3: Desempeño del programa Canon en Do mayor 6.2.1.4. Recuperación de Errores LMAN permite recuperación de errores en la transmisión y admite depuración de errores en la ejecución por medio de mensajes de error. Debido a que el protocolo de transmisión LNP es tipo UDP no tiene verificación en la recepción; razón por la cual se hace necesario añadir un protocolo de control y recuperación de errores que sea capaz de identificar si hay comunicación con el RCX, y de lo contrario permita reintentar para establecer comunicación. El funcionamiento del protocolo se trata en la sección 4.1.3.3 del capı́tulo 4. La depuración de errores en LMAN, informa al usuario el tipo y descripción del error que se presentó al ejecutar un programa. Los errores más comunes suceden por inconsistencias en el Store, éstado que genera un bloqueo en la máquina. Esta caracterı́stica de LMAN es de gran ayuda para diagnosticar errores en el código o funcionamiento de un programa. 110 6.2.2. Comparación entre LMAN , ESTEREL y La Máquina estándar de LEGO Se hará una comparación de manejo de los recursos con la máquina estándar de LEGO[Leg00] y el lenguaje formal de programación deterministica ESTEREL[MR82]. Antes de iniciar la comparación se dará una breve descripción de cada uno de los items a tratar: Máquina Estándar de LEGO: Como ya se ha mencionado en capı́tulos anteriores, es el firmware original del robot LEGO. Tiene capacidad de almacenar 5 programas y realizar 10 tareas y 18 subrutinas por cada uno de ellos; maneja 32 variables globales para todas las tareas y 16 locales por cada una de las tareas, permite controlar todos los periféricos del robot LEGO: sensores, motores, timers, LCD. ESTEREL: ESTEREL como herramienta de programación, es un compilador que realiza la transformación del lenguaje sı́ncrono deterministico ESTEREL[MR82] a codigo C del sistema operativo BrickOS(LegOS). Este compilador permite manejar una cantidad mayor de 10 tareas en paralelo y controla todos los perifericos del robot LEGO. El número de variables está limitado por la cantidad disponible de memoria que tenga el robot LEGO. A continuación se realiza la comparación entre LMAN, ESTEREL y la Máquina Estándar de LEGO, los criterios que se compararan son; expresividad, manejo de memoria de programa y manejo de tareas concurrentes. Expresividad: LMAN maneja programación formal temporal, concurrente por restricciones y es no-deterministica, propiedades que le confieren un nivel más alto en expresividad del que maneja ESTEREL y la Máquina estándar de LEGO. Capacidad de Memoria: Debido a que el núcleo principal de LMAN se ejecuta en una estación de trabajo, la capacidad de memoria que maneja es superior a la de ESTEREL y a la máquina estándar de LEGO que se ejecutan internamente desde el RCX. Esto permite ejecutar problemas complejos, que demanden nivel de procesamiento y memoria que talvez desde el LEGO no sea posible ejecutar. Si se observa de la manera anterior, la ejecución del núcleo de la máquina desde una estación de trabajo, y el componente de transmisión adicionado en LMAN no resultaron realmente en desventaja frente a otras herramientas. 111 Manejo de tareas concurrentes: Ya que LMAN utiliza como plataforma de desarrollo y ejecución el sistema operativo BrickOS(LegOS)[MLNP00] y gracias a la propiedad del cálculo de modelar tareas concurrentes, el numero de tareas concurrentes admitidas por LMAN es n. Lo cual es superior en funcionamiento a la máquina estándar de LEGO. ESTEREL admite el modelamiento de tareas concurrentes. A continuación se presenta un cuadro que resume las caracterı́sticas de cada uno de los item comparados. Criterios LMAN ESTEREL Expresividad No-determninismo (formal) Limitada por hardware de la estación Superior (10 o más procesos) Determinismo (formal) Limitada por hardware del robot LEGO Superior 10 o más procesos) Capacidad de Memoria Manejo de tareas concurrentes Máquina Estándar de LEGO Determinismo Muy limitada Básico (10 procesos) Cuadro 6.4: comparación de LMAN, ESTEREL y Máquina estándar de LEGOS Por las pruebas y los datos registrados en éste capı́tulo, es posible concluir que la implementación de LMAN que se reporta, resulta ser eficiente, robusta, tolerante a fallos y de funcionamiento en tiempo real, a pesar que los programas realizados en ella conllevan la resolución de restricciones aritméticas y el modulo de transmisión de instrucciones por torre serial/USB al robot LEGO. 112 7 CONCLUSIONES Y TRABAJO FUTURO El objetivo propuesto para el presente trabajo de tesis, involucra el diseño e implementación de una máquina abstracta para el cálculo NTCC, de modo que sea posible ejecutar construcciones NTCC sobre robots LEGO. No obstante, para proveer una funcionalidad completa, se hizo fundamental involucrar en los objetivos del proyecto, acoplar un sistema de restricciones para implementar el componente CC del cálculo subyacente, junto con un compilador para proveer una interfáz en alto nivel de programación para la máquina. La máquina LMAN resulta una implementación completa y eficiente del cálculo NTCC, que permite controlar y ejecutar en tiempo real programas escritos en NTCC sobre Robots LEGO MindStorm. Su base formal en este cálculo le confiere la expresividad suficiente para modelar problemas complejos del mundo del robot, de una manera más natural y sin caer en detalles especı́ficos en la implementación. Por ejemplo, no se necesita especificar una velocidad fija para el robot, simplemente se da un rango (velocidad > 80); tampoco es necesario especificar al robot una vı́a de acción determinada (cuando encuentre un obstáculo, gire hacia la izquierda), se le deja una escogencia no–determinı́stica de la acción; permite modelar problemas de la realidad como la interpretación de melodı́as, en donde se define una unidad de tiempo como un nota (un instante equivale a una corchea) y finalmente permite dar solución a problemas que usan la asincronı́a para asegurar que el robot realiza una acción (chequear la temperatura), en un instante de tiempo no determinado. El modelo formal presentando en forma de máquina abstracta, provee la especificación de la máquina virtual para LMAN. Esta formalidad aseguró en LMAN un diseño completo y consistente, de modo que, la implementación fue transparente, fluida y el 113 comportamiento de la máquina siempre fue el esperado. Una vez finalizó la etapa de implementación con base en el diseño formal realizado, no fue necesario realizar modificaciones de fondo al código fuente. El diseño modular de LMAN actúa como un componente integrador. Además de que combina los paradigmas de programación reactiva, temporal, concurrente y por restricciones en un entorno eficiente de programación para dispositivos robóticos LEGO, LMAN integra otros proyectos. De ésta manera, se ha logrado acoplar a LMAN el trabajo de grado que implementa el sistema de restricciones [CG01] para el cálculo PiCO, la gramática que describe formulas de primer orden descrita en el trabajo de grado de la máquina abstracta MAPiCO[AB98], el compilador NTCC-LMAN desarrollado como proyecto de semestre en el curso de Compiladores (PUJ) [RCP03], el trabajo de grado que implementa el lenguaje visual VIN, y por supuesto el cálculo subyacente NTCC [Val03]. El desarrollo de LMAN alrededor de una comunidad de código abierto y de un alto nivel investigativo, agilizó el aprendizaje, la consecución de soluciones y el desarrollo colaborativo. El contacto continúo con otros grupos de investigación y comunidades de desarrollo sobre Internet, fue determinante para hallar solución a los problemas en implementación de LMAN, principalmente en lo relacionado con el manejo de los dispositivos robóticos LEGO. Gracias a ésta colaboración fue posible diseñar e implementar un ambiente de ejecución eficiente para LMAN, utilizando un protocolo de comunicaciones, por medio del cual la máquina virtual se ejecuta en una estación de trabajo y se comunica via infrarrojo con el dispositivo robótico para ejecución. Como trabajo futuro, se han considerado varias actividades y recomendaciones que permitirán afinar la implementación actual. Estas pueden clasificarse en dos grupos, los cuatro primeros puntos tratan actividades y recomendaciones relacionadas con el componente formal de LMAN y las siguientes están relacionadas con el componente funcional. La máquina abstracta de LMAN modela de manera cercana el cálculo NTCC. No obstante, para probar su correctitud es importante realizar la prueba formal de bisimilitud, desde el cálculo hacia la máquina y desde la máquina hacia el cálculo NTCC. Se recomienda implementar la definición de celdas para NTCC dada en [Val03] a 114 nivel de la máquina virtual. Esto reducirı́a el código de programa necesario para modelar celdas en el cálculo, además de que actuarı́a como una plantilla genérica que es posible usar en cualquier problema computacional que implique el uso de celdas. Para lograr aún mas eficiencia y proveer mayor expresividad en las construcciones NTCC ejecutadas sobre la máquina, es importante desarrollar un sistema de restricciones propio para NTCC, tal como se describe en [Val03]. Gracias a la propiedad de LMAN de definir restricciones como fórmulas de primer orden, su acople serı́a casi transparente siempre y cuando el nuevo sistema de restricciones también exprese las restricciones de ésta manera. La sintáxis de la máquina abstracta y consecuentemente las instrucciones de la máquina virtual, puede ser extendidas para modelar los procesos derivados del cálculo NTCC. La máquina virtual permite definir hasta 64 instrucciones. Para futuras versiones de RCX que admitan mayores recursos de Hardware y gracias a la modularidad del diseño de LMAN, se puede lograr optimizar la máquina de tal modo que pueda ejecutarse desde el RCX, omitiendo ası́ el módulo que realiza la transmisión. Esta optimización debe partir de un sistema de restricciones propio para aplicaciones NTCC, tal como se ha mencionado anteriormente. Con la actual implementación de LMAN que permite el control del doble de dispositivos de los RCX convencionales, es posible diseñar ambientes colaborativos logrando crear programas que involucren la interacción de dos o más RCX. La modularización de LMAN posibilita el acople de herramientas de simulación. La interfáz LEGO actuarı́a como el componente integrador entre el simulador y la máquina virtual. LMAN actualmente ha sido probada ejecutándose sobre LINUX; es posible hacerla portable a Windows y MacOS. Adicionalmente, es importante que exista el uso del driver USB para la transmisión via LNP, ésto mejorarı́a el desempeño de la transmisión. . En la actualidad LNP admite solamente torre serial. Finalmente con todo el paquete afinado es importante generar una herramienta de instalación, que disminuya todas las tareas alrededor de la configuración de LMAN para su funcionamiento. 115 Anexo A. Traducción de procesos NTCC a código de bytes de LMAN Anexo A. Traducción de procesos NTCC a código de bytes de LMAN Las siguientes tablas describen la construcción de los procesos de LMAN en el código de bytes entrada de la Máquina Virtual. Las instrucciones que se utilizan en éste apéndice, se definen en el archivo opcodes.h como constantes para un mejor entendimiento. Las construcciones descritas a continuación fueron usadas para la generación de código desde el compilador. A.1 Tell La instrucción tell < constraint > se traduce a LMAN escribiendo las instrucciones que corresponden a la restricción, seguidas de las instrucciones lTELL y SKIP. Ejemplo: para tell ( x > 5), se genera el código: Lı́nea Opcode Src1 Src2 1 2 ATOM TERMV MAY 74 2 3 TERMC 5 4 lTELL 5 SKIP A.2 When La instrucción when < constraint > do < P >, se traduce escribiendo las instrucciones que corresponden a la restricción, seguidas de la instrucción ASK que lleva como parámetro la dirección de la última instrucción del proceso hijo (P), finalizando con las instrucciones correspondientes al proceso P. Ejemplo: para when (x = 1) do tell (y = 0), se genera el código: Lı́nea Opcode Src1 Src2 1 ATOM IGUAL 2 2 3 TERMV TERMC 74 1 4 5 lASK ATOM 9 IGUAL 6 TERMV 75 7 TERMC 0 8 9 lTELL SKIP 2 A.3 Composición Paralela La instrucción < P > || < P >, se traduce escribiendo la instrucción PAR que lleva como parámetro la dirección de la primera instrucción del segundo proceso, seguida de las instrucciones que corresponden al primer proceso, y por último las instrucciones del segundo proceso. Ejemplo: para tell (x > 5) || tell (y > 1), se genera el código: Lı́nea Opcode Src1 Src2 1 2 PAR ATOM 7 MAY 2 3 TERMV 74 4 TERMC 5 5 6 lTELL SKIP 7 ATOM MAY 8 TERMV 75 9 10 TERMC lTELL 1 11 SKIP 2 A.4 Unless La instrucción unless < constraint > next < P >, se traduce escribiendo las instrucciones que corresponden a la restricción, seguidas de la instrucción UASK que tiene como parámetro la dirección de la última instrucción del proceso hijo (P), finalmente las instrucciones del proceso P. 118 Ejemplo: para unless (x > 5) next tell (y < 80), se genera el código: Lı́nea Opcode Src1 Src2 1 ATOM MAY 2 2 3 TERMV TERMC 74 5 4 UASK 9 5 ATOM MEN 6 7 TERMV TERMC 75 80 8 TELL 9 SKIP 2 A.5 Next La traducción de la instrucción next < Const op > < P >, depende de la existencia o no de la constante opcional. Cuando la constante es vacı́a, se traduce escribiendo la instrucción NEXT que lleva como parámetro la dirección la última instrucción del proceso hijo (P), seguida de las instrucciones que corresponden al proceso P. Cuando la constante no es vacı́a, se traduce escribiendo la instrucción NEXTN que lleva como parámetro el número de instantes que deben transcurrir antes de realizar el proceso, seguida de la instrucción JMP que tiene como parámetro la dirección de la última instrucción del proceso hijo (P), y finaliza con las instrucciones que corresponden al proceso. Ejemplos: Para next ( tell (x = 1)), se genera el código: Lı́nea Opcode Src1 Src2 1 2 NEXT ATOM 6 IGUAL 2 3 TERMV 74 4 TERMC 1 5 6 TELL SKIP 119 Para next 2 ( tell ( x =1)), se genera el código: Lı́nea Opcode Src1 1 NEXTN 2 2 JMP 7 3 4 ATOM TERMV IGUAL 74 5 TERMC 1 6 TELL 7 SKIP Src2 2 A.6 Replicación La instrucción ! < P >, se traduce escribiendo la instrucción REP sin parámetros, seguida de las instrucciones que corresponden al proceso. Ejemplo: para !tell (x > 80), se genera el código: Lı́nea Opcode Src1 Src2 1 2 REP ATOM MAY 2 3 TERMV 74 4 TERMC 80 5 6 LTELL SKIP A.7 Asincronı́a Para traducir la instrucción *[< constante >, < constante >] < P >, el compilador debe generar un valor aleatorio (random) en el rango comprendido entre los valores de las dos constantes. Luego, se traduce escribiendo la instrucción STAR, cuyo parámetro es el número aleatorio generado, seguida de la instrucción JMP que lleva la dirección de la última instrucción del proceso hijo (P), finalizando con las instrucciones que corresponden a P. 120 Ejemplo: para * [1,7] tell (x=1), se genera el siguiente código.Se asume que el random genera el 4 (Src1 de la primera lı́nea). Lı́nea Opcode Src1 1 2 STAR JMP 4 7 3 ATOM IGUAL 4 TERMV 74 5 6 TERMC TELL 1 7 SKIP Src2 2 A.8 No determinismo Los procesos de la instrucción < P > + < P > + < P > . . . , tienen dos interpretaciones posibles: Si el proceso NO es un when < constraint > do < P > (es cualquiera de los otros procesos posibles), este se debe interpretar como when true do P, dado que en NTCC no existen las constantes true o false, se crea una restricción que siempre sea verdadera: when (0=1) do P, donde 0 es una etiqueta que siempre se comenta al Store con valor 1. Por ejemplo, si se tiene tell (a+b>5) + next tell(a=10), esto se interpretarı́a como la instrucción when (1=1) do tell (a+b>5) + when (1=1) do next tell (a=10). Si el proceso es un when < constraint > do < P > se ejecuta nomalmente (evaluando la restricción para decidir si P se ejecuta o no). Finalmente, cada instrucción < P > + < P > + < P > representa una instrucción de la forma when < constraint > do < P > + when < constraint > do < P > + when < constraint > do < P >. La traducción de ésta instrucción es ası́: Cada instrucción when < constraint > do < P > se traduce escribiendo las instrucciones que corresponden a la restricción, seguidas de la instrucción GASK que lleva como primer parámetro la lı́nea donde se inicia el siguiente proceso, y como segundo parámetro 1 o 0 (1 para el primer when de la sumatoria, y 0 para 121 los when restantes), seguidos por las instrucciones del proceso hijo (P), y una instrucción JMP que lleva como parámetro la dirección de la última instrucción de todo el conjunto de procesos (en el caso del ejemplo el skip de la dirección 32) . Los códigos de los procesos se concatenan, y al final se agregan las instrucciones NDET y SKIP. Se debe tener en cuenta que para el GASK del último proceso, el proceso siguiente es el NDET (en el ejemplo el GASK de la lı́nea 24, tiene como parámetro 31, lı́nea del NDET). Ejemplo: para when (x > 40) do tell(y = 1) + tell(y = 1) + when (x =1) do tell(y = 0), se genera el código: Lı́nea Opcode Src1 Src2 1 ATOM MAY 2 2 3 TERMV TERMC 74 40 4 GASK 11 1 5 ATOM IGUAL 2 6 7 TERMV TERMC 75 1 8 lTELL 9 SKIP 10 11 JMP ATOM 32 IGUAL 12 TERMV 0 13 TERMC 1 14 15 GASK ATOM 21 IGUAL 16 TERMV 75 17 TERMC 1 18 19 lTELL SKIP 20 JMP 32 21 ATOM IGUAL 2 0 2 2 122 22 23 TERMV TERMC 74 1 24 GASK 31 0 25 ATOM IGUAL 2 26 27 TERMV TERMC 75 0 28 lTELL 29 SKIP 30 31 JMP NDET 32 SKIP 32 A.9 Skip El proceso skip se usa para sincronizar en LMAN. De esta manera la mayorı́a de procesos a excepción de algunos como replicación (!) y paralelo (||) deben incluir como parámetro un llamado al skip mas cercano, tal como se ha apreciado en lo ejemplos anteriores. A.10 Manejo de Rangos Aunque el Sistema de Restricciones actual no implementa rangos, en LMAN se definen, de modo que, si se adiciona un nuevo Sistema de Restricciones puedan ser utilizados en las construcciones NTCC. Los rangos se definen de la siguiente manera: x in 10.,20 < var ref erence > in < Constante > .. < Constante > Los cuales se representan con la estructura OPERACION / Variable \ RANGE / \ Inicio Fin Ejemplo: Para la restricción x in 10.,20, el árbol que expresa la restricción se representarı́a: 123 IN / \ x RANGE / 10 \ 20 Lo anterior se traduce en código de bytes LMAN como sigue: (se asume que la dirección de x es 79): Lı́nea Opcode Src1 Src2 1 2 ATOM TERMV IN 79 2 3 TERMF RANGE 2 4 TERMC 10 5 TERMC 20 124 Anexo B. Librerı́as para la construcción de Programas en LMAN Anexo B. Librerı́as para la construcción de Programas en LMAN Como resultado de la compilación de NTCC a LMAN, se debe generar un archivo binario, que contendrá el código que ejecutará la máquina virtual. Para ello, se provee un conjunto de librerı́as necesarias para escribir este archivo de forma correcta, las cuales se describen a continuación. Para escribir una lı́nea de código de máquina de LMAN se utiliza la función: escribirLinea(OPCODE, SRC1,SRC2 ,ARCHIVO) que se encuentra definida en el módulo cargador (cargador.h y cargador.o) con los siguientes parámetros: • OPCODE: Es el código de la operación • SRC1: Es el primer parámetro de la operación (si no es necesario va en cero). • SRC2: Es el segundo parámetro de la operación (si no es necesario va en cero). • ARCHIVO: Es el archivo donde se va a escribir el programa. Recuerde que la precondición de escribirLinea es que el archivo esté abierto en modo de escritura (Ejemplo: fopen(”lman.bin”, ”w”)). El archivo binario debe finalizar con la instrucción (0, 0, 0) lo cual indica que es el fin del archivo. Las librerı́as relacionadas para la construcción de programas son las siguientes: • opcodes.h: contiene la definición de los códigos de operación -opcodes- de LMAN. • ValueFrameConst.h: contiene la definición de los valores necesarios para realizar la interacción con el sistema de restricciones (IGUAL, DIF, MAY, ...). • varlman.h: contiene la definición de las variables de ambiente de LMAN tanto las de entrada como las de salida (ISENEST1, IMOTEST6). Bibliografı́a [AB98] M. Heredia . A. Buss. MAPiCO: Máquina Abstracta para el Cálculo Pico. Tesis de Pregrado, Facultad de Ingenieria, Pontificia Universidad Javeriana. 1998. [ADQV98] G. Alvarez, J. Diaz, L. Quesada, and F. Valencia. PiCO: A calculus of concurrent constraint object for musical applications. ECAI98, Workshop of Constraint and the Arts, Brighton, England. 1998. [Bau00] D. Baum. http://www.baumfamily.org/nqc/. 2000. [Car95] B. Carlson. Compiling and Executing Finite Domain Constraints. PhD thesis, Swedish Institute of Computer Science. 1995. [CG01] A. Vasquez C. Garcia. Implementación eficiente de un sistema de dominios finitos para el lenguaje cordial. Tesis de Pregrado, Facultad de Ingenieria, Pontificia Universidad Javeriana. 2001. [Com00] r Dictionary of the Houghton Mifflin Company. The American Heritage c 2000. English Language, Fourth Edition. Copyright [FQ04] D. Fernández and J. Quintero. VIN: Lenguaje Visual basado en el cálculo NTCC. Tesis de Pregrado, Ingenierı́a de Sistemas, Pontificia Univerisidad Javeriana. 2004. [Fre99] J. Fredslund. The assumption architecture. Progress Report, Department of Computer Science, University of Aarhus. 1999. [Gro00] LEGO Group. Constructopedia. LEGO, MindStorms, Robotics Invention System. 1999/2000. [HS96] T. Haynes and S. Sen. Evolving behavioral strtegies in predators and prey. In Proc of the IJCAI Workshop on Adaptation and Learning in Multi-Agent Systems, volume 1042 of Lecture Notes in Artificial Intelligence, pages 113126. Springer Verlag. 1996. 127 [JNO97] S. Jones, T.Ñordin, and D. Oliva. C–:A portable assembly language. In Implementation of Functional Languages. 1997. [Jon92] S. Jones. Implementing Lazy Functional Languages on Stock Hardware: the Spineless Tagless g-machine. Journal of Functional Programmingd Concurrency. Preentice-Hall. 1992. [Leg00] Lego. LEGO MindStorms RCX 2.0 Firmware Command Overview,. 2000. [Lop99] L. Lopes. On the Design and Implementation of a Virtual Machine for Process Calculi. PhD Dissertation, Department of Computer Sciences, University of Porto. 1999. [LP99] H. H. Lund and L. Pagliarini. Robot soccer with LEGO mindstorms. LNCS, 1064:141-151. 1999. [LY97] T. Lindholm and F. Yellin. The Java Virtual Machine Specification. 1997. [MBD86] V. Jagannathan M. Brenda and R. Dodhiawala. On optimal cooperation of Knowledge sources - an empirial investigation. Technical REport BCSG2010-28, Boeing Advanced Techology Center. 1986. [McA92] D. McAllester. First order logic. 1992. [Mil89] R. Milner. Communication and Concurrency. 1989. [Mil99] R. Milner. Communicating and Mobile Systems: the π calculus. Cambridge University Press. 1999. [MLNP00] L. Villa M. L.Ñoga and P. http://brickos.sourceforge.net/. 2000. [MR] C. Mauras and M. Richard. LUSTRE Y ESTEREL synchronous languages. http://www.emn.fr/x-info/lego/. [MR82] J. Marmorat and J. Rigault. http://www-sop.inria.fr/esterel.org/. 1982. [RCP03] F. Rocha, J. Chalá, and M. Pabón. Compilador NTCC-LMAN. Reporte del curso de Compiladores, Pontificia Universidad Javeriana–Cali. 2003. [SJG94] V. Saraswat, R. Jagadeesan, and V. Gupta. Foundations of timed concurrent constraint programming. In Proc. Of the Ninth Annual IEEE Symposium of Logic in Computer Science. 1994. [SR00] J. Solorzano and T. Rinkens. http://lejos.sourceforge.net/index.html. 2000. [SRP91] V. Saraswat, M. Rinard, and P. Panangaden. The semantic foundations of Concurrent Constraint Programming. In ACM, Preceedings of eighteenth annual ACM symposium of Principles of programming languages. 1991. 128 [SRP03] V. Saraswat, M. Rinard, and P. Panangaden. JCC: Integrating Timed Default Concurrent Constraint Programming into java. 2003. [SV00] P. Stone and M. Veloso. Multiagent systems: A survey from a machine learning perspective. Autonomoues nRobots, 8: 345-383. 2000. [Val00] F. D. Valencia. Reactive Constraint programing. Progress Report , Department of Computer Science, University of Aarhus. 2000. [Val03] F. D. Valencia. Temporal Concurrent Constraint Programming. PhD Dissertation, Department of Computer Science, University of Aarhus. 2003. [VS91] P. Panangaden V. Saraswat, M. Rinard. The semantic foundations of concurrent constraint programming. In ACM, Prceedings of eighteenth annual ACM symposium of Principles of programming languages. 1991. [VSG96] R. Jagadeesan V. Saraswat and V. Gupta. Timed Default Concurrent Constraint Programming. J. Symbolic Computation. 1996. [War83] D. Warren. An Abstract Prolog Instruction Set. Technical Report 309, SRI International. 1983. 129