Manual Del Usuario Del Psps Iv.

Preview only show first 6 pages with water mark for full document please download

Transcript

PSPS Programa Simulador de Pequeños Sistemas Manual del Usuario PSPS IV Version 1.4 Book Version 2. CopyRight © Josep Riverola. Catalcatel IESE – May 2003. INDICE DE CONTENIDOS Manual del Usuario PSPS IV Indice de Contenenidos. Indice de Contenidos INTRODUCCION Bienvenidos al PSPS IV ………………………………………………………. ¿Para quién es este programa? ………………………………………….. Algo de Historia …………………………………………………………………… Necesidades ………………………………………………………………………… ¿Cómo esta organizado el manual? 2 2 2 3 3 CAPITULO 0: CONCEPTOS FUNDAMENTALES DEL PSPS Transacciones ……………………………………………………………………… Procesadores ………………………………………………………………………. Bloques ………………………………………………………………………………… Acontecimientos ………………………………………………………………….. El Reloj Físico y el Reloj Maestro de Simulación ………………… 6 6 7 7 8 CAPITULO 1: ESTRUCTURA GENERAL DEL LENGUAJE PSPS Sección Constant ………...……………………………………………………… Sección Labels …………………………………………………………………….. Sección Variables ………………………………………………………………… Sección Macros ……………………………………………………………………. Sección Data ……………………………………………………………………….. Sección OnDebug ……………………………………………………………….. Sección System ………………………………...………………………………… 9 11 11 11 12 13 13 CAPITULO 2: ELEMENTOS BASIC OS DEL LENGUAJE PSPS Alfabeto Básico ……………………………………………………………………. Ficheros como comentarios activos ……………………………………. Números ………………………………………………………………………………. Identificadores ……………………………………………………………………. Strings …………………………………………………………………………………. Operadores ………………………………………………………………………….. 15 15 16 16 17 17 CAPITULO 3: DEFINICION DE CONSTANTES Constantes Clásicas ……………………………………………………………. Constantes de Disciplinas de Espera …………………………………. Constantes Lógicas …………………………………………………………….. Constantes de Input/Output ………………………………………………. Constantes de Gráficas ………………………………………………………. Constantes Estadísticas ………………………………………………………. Constantes de Color ……………………………………………………………. Otras constantes …………………………………………………………………. 20 20 21 21 22 23 24 25 CAPITULO 4: DEFINICION DE VARIABLES Variables Escalares ....................................................... Variables Array ............................................................. Variables Stats .......................................................... Manual del Usuario PSPS IV 26 26 30 i Indice de Contenenidos. CAPITULO 5: EL LENGUAJE DE PROGRAMACION PSPAL Sentencias Pspal con valor …………………………………………………. Sentencias Pspal Simples …………………………………………………… Sentencias Pspal Compuestas ……………………………………………. 31 33 40 CAPITULO Definición Funciones Definición 6: DEFINICION DE FUNCIONES Y MACROS de funciones ……………………………………………………….. Predefinidas ……………………………………………………….. de Macros …………………………………………………………… 42 46 59 CAPITULO 7: EL LENGUAJE DE BLOQUES. INICIALIZANDO EL PSPS Sentencias de Definición de Tamaño …………………………………. Sentencias de Objetos ………………………………………………………… Sentencias de Duración de la Simulación ………………………….. Sentencias de Inicialización de variables ………………………….. Sentencias de de Debugging ……………………………………………… Sentencias de Mando de la simulación ………………………………. Sentencias de Inicialización por programa ………………………… Sentencias de Output …………………………………………………………. Sentencias de simulación Continua …………………………………… Sentencias de Generación de Números Aleatorios ……………. Sentencias de Definición de Distribuciones ……………………….. 60 63 65 65 67 69 70 70 71 71 72 CAPITULO 8: EL LENGUAJE DE BLOQUES. DESCRIBIENDO EL SISTEMA DE SIMULACION Control de transacciones y avance del reloj de simulación . Ocupación de Procesadores y Switches …………………………….. Cálculo y modificación de Variables …………………………………… Definición de una secuencia ………………………………………………. Elaboración de estadísticas ………………………………………………… Input Output y Debugging …………………………………………………. Bloques multimedia y gráficos …………………………………………… simulación Continua ………………………………………………………….. 74 86 94 95 97 99 101 103 CAPITULO 9: EL LENGUAJE LISP Tipos básicos de datos ……………………………………………………….. Funciones Aritméticas ………………………………………………………. Funciones de Listas …………………………………………………………….. Funciones Predicado ……………………………………………………………. Funciones Evaluadoras ……………………………………………………….. Funciones de Comparación …………………………………………………. Funciones de Input-Output …………………………………………………. Otras funciones de Lisp ………………………………………………………. ¿Cómo acceder desde Lisp a Pspal? …………………………………… 104 105 106 110 111 112 113 114 116 CAPITULO 10: LAS FUNCIONES KNOW Patrones ………………………………………………………………………………. Bases de Conocimiento ………………………………………………………. Reglas …………………………………………………………………………………. Redes Semánticas ………………………………………………………………. Frames …………………………………………………………………………………. 118 120 123 127 130 Manual del Usuario PSPS IV ii Indice de Contenenidos. Búsqueda …………………………………………………………………………….. 135 CAPITULO 11: CORRIGIENDO ERRORES EN UN PROGRAMA Errores de Compilación ………………………………………………………. 139 Errores de Ejecución …………………………………………………………… 143 Sentencias y bloques de Debugging ………………………………….. 146 La Ventana del Debuger …………………………………………………….. 151 Dynamic Dialog Tools. DDT ……………………………………………….. 152 Ventan del Listener …………………………………………………………….. 156 APENDICES Apéndice Apéndice Apéndice Apéndice Apéndice A: B: C: D: E: Limitaciones del Lenguaje PSPS ………………………. Manejo de las direcciones de memoria ……………. La Ventana del Listener ……………………………………. La Traza del Sistema ……………………………………….. Uso del Sistema PSPS ………………………………………. Manual del Usuario PSPS IV 158 159 161 170 176 iii INTRODUCCION § § § § § Manual del Usuario PSPS IV Bienvenido al PSPS IV ¿Para quien es este programa? Algo de Historia Necesidades ¿Cómo esta organizado el Manual? Bienvenido al PSPS IV ¡ Bienvenido al PSPS IV ! PSPS (Programa Simulador de Pequeños Sistemas) es un software de simulación orientado a la simulación de pequeños sistemas. PSPS es a la vez un lenguaje y un programa. Lenguaje porque proporciona unos signos concretos para construir un modelo de la realidad y programa porque permite la evolución de dicho modelo en el ordenador. Es un lenguaje de bloques, transacciones y procesadores. El comportamiento de un modelo se representa por secuencias de bloques, que procesan las transacciones que fluyen entre ellos. Al mismo tiempo las transacciones mandadas por los bloques, entran y salen de los procesadores. Los bloques y procesadores mantienen estadísticas de diferentes tipos, que pueden ser consultados en cualquier momento de la simulación. ¿Para Quien es el PSPS? PSPS es un sistema de notable flexibilidad y, especialmente, fácil de usar. Esta pensado para introducir a decisores en la construcción y explotación de pequeños (o medios) modelos de simulación. Por tanto si es Vd. un potencial decisor, PSPS puede convertirse en su herramienta de trabajo para comprender mejor el problema y ayudarle en la toma de decisiones, respondiendo a preguntas del tipo ¿Qué pasa si …? Algo de Historia PSPS debe sus inicios a William Sharpe, premio Nóbel y Profesor de la Universidad de Stanforf. Antes de su bien merecida fama, Sharpe desarrollo el primer prototipo del PSPS y lo cedió al IESE para su uso. A partir de allí, PSPS evolucionó gracias a los esfuerzos de un grupo de profesores, especialmente de Jaume Ribera que, bajo la supervisión de Josep Riverola, acuñó el nombre de PSPS (Programa Simulador de Pequeños Sistemas) y construyó el PSPS I, escrito en Basic y funcionando sobre un Data General Nova-840 en tiempo compartido. Más tarde, y siempre bajo la supervisión de Josep Riverola, los alumnos de la ETSIIT de la Universitat Politécnica de Cataluña implementaron el PSPS II en Fortran sobre un HP-1000. El mismo grupo implantó PSPS III sobre el PC, usando para ello el entonces recién nacido Turbo Pascal, sobre MS-DOS. Oscar Mañanes convirtió el sistema a Windows, usando Delphi, y manteniendo la misma denominación, ya que el sistema era idéntico en funcionalidad al original. Finalmente, y tras una época de uso intensivo en la construcción de modelos de tamaño medio, nació PSPS IV, que incorpora la experiencia de este trabajo. Manual del Usuario PSPS IV 2 Necesidades Para instalar el PSPS IV necesita: • • • • Windows 95, Windows 98, Windows 2000, Windows NT 4.0 o Windows XP. 32 MB RAM. 12 MB de disco. Procesador Pentium 2 a 400MHz o AMD K6-2 a 450 MHz. ¿Cómo esta organizado el Manual? Este Manual incluye lo siguiente • Capítulo 0: Conceptos Fundamentales del PSPS. Este capítulo describe los conceptos fundamentales que hay que manejar para diseñar un modelo en PSPS. • Capítulo 1: Estructura General del Lenguaje PSPS. Este capítulo contiene la descripción de las secciones de un programa PSPS. • Capítulo 2: Elementos Básicos del Lenguaje PSPS. En este capítulo describiremos en detalle los elementos básicos del lenguaje como identificadores, operadores y la forma de operar con los números del PSPS. • Capítulo 3: Definició n de Constantes. Este capítulo enumera y describe las diferentes constantes predefinidas del PSPS. • Capítulo 4: Definición de Variables. Este capítulo contiene la definición de las variables predefinidas que contiene el PSPS. • Capítulo 5: El lenguaje de Programación Pspal. En este capítulo se describe el Lenguaje de Programación Pspal embebido en el PSPS. • Capítulo 6: Definición de Funciones y Macros. Este capítulo describe la manera de definir funciones y macros del usuario que permiten dotar de gran generalidad a los modelos. También se listan las funciones predefinidas en el PSPS IV. Manual del Usuario PSPS IV 3 • Capítulo 7: El lenguaje de Bloques. Inicializando el PSPS. El capítulo contiene la descripción detallada y ejemplos de los bloques de la sección Data del PSPS. • Capítulo 8: El lenguaje de Bloques. Describiendo el sistema de Simulación. El capítulo contiene la descripción detallada de los bloques de la sección System del PSPS. • Capítulo 9: El Lenguaje Lisp. El capítulo contiene la descripción de las funciones de Lisp que pueden utilizarse en el PSPS. • Capítulo 10: Las funciones Know. El capítulo describe las funciones de conocimiento definidas en el PSPS. • Capítulo 11: Corrigiendo Errores. Lista los errores más frecuentes con los que nos podemos encontrar a la hora de construir un modelo de simulación utilizando el PSPS. • Apéndices o Apéndice A: Limitaciones del Lenguaje PSPS Lista las limitaciones del PSPS en cuanto al número de bloques o sentencias que pueden utilizarse. o Apéndice B: Manejo de las Direcciones de Memoria Contiene una descripción detallada del uso de los operadores de ampersand & y caret ^. o Apéndice C: La Ventana del Listener Contiene una descripción detallada de las distintas opciones de los menús de la Ventana, especialmente de las opciones de Debug o Apéndice D: La Traza de un sistema Contiene la descripción detallada del Output en la Ventan del Listener de las opciones de Trazado del PSPS. Manual del Usuario PSPS IV 4 o Apéndice E: Uso del Sistema PSPS Breve descripción de los distintos menús y botones de la barra de herramientas de la Ventana Principal del PSPS. Manual del Usuario PSPS IV 5 CAPITULO 0: Conceptos Fundamentales del PSPS. Transacciones Procesadores Bloques Acontecimientos § El Reloj Físico y el Reloj Maestro de la simulación § § § § Manual del Usuario PSPS IV Capítulo 0: Conceptos Fundamentales del PSPS. En el mundo real hablamos de stocks, almacenes, camiones pero en el PSPS trataremos con transacciones, procesadores… . En este capítulo introduciremos algunos de los conceptos fundamentales que maneja el PSPS para simular sistemas. Transacciones Las transacciones son las entidades móviles del sistema, circulan por él y su estado va cambiando a lo largo del tiempo. El estado de una transacción viene dado por los atributos de la misma. El valor de los atributos de una transacción puede ser consultado por el usuario en cualquier momento de la simulación. Dos transacciones se diferencian entre si únicamente por sus atributos. Cada transacción dispone de un máximo de 40 atributos que permitirán al usuario definir las características que diferencian unas transacciones de otras. Los cinco primeros atributos de una transacción tienen asociados los siguientes valores: At[- 1] bloque del que procede la transacción. At[0] instante de tiempo en el que la transacción abandonará el bloque en el que se encuentra detenida. At[1] instante de tiempo en el que la transacción ha sido generada. At[2] número correlativo de nacimiento. At[3] bloque generador de la transacción. Algunos ejemplos de transacciones son los coches que llegan a una gasolinera, las personas que esperan ante una ventanilla para ser atendidos o las llamadas telefónicas que llegan a una centralita. Procesadores Los procesadores son las entidades permanentes del sistema. Las transacciones intentan acceder a ellos para recibir un servicio. Entenderemos por servicio cualquier cosa que tarde algún tiempo en obtenerse. En una gasolinera el empleado que se encarga del surtidor estará representado por un procesador, porque es un elemento permanente del sistema y proporciona un servicio, rellenar el depósito de los clientes empleando cierto tiempo para ello. Manual del Usuario PSPS IV 6 Capítulo 0: Conceptos Fundamentales del PSPS. Bloques Hasta ahora disponemos de las transacciones o elementos móviles y de los procesadores o puntos de servicio. Pero las transacciones deben de realizar una serie de actividades programadas por el usuario. Los bloques son las herramientas que permiten construir procesos completos que identifican el “plan de vida” de una transacción. Los bloques nos permiten definir una serie de instrucciones que le digan a la transacción, por ejemplo a que procesador deben acudir, que tipo de servicio debe solicitar o que debe hacer en caso de encontrarlo saturado. Acontecimientos En un modelo PSPS el tiempo no transcurre de forma continua (como sucede en la vida real) sino que avanza a saltos. Por tanto el estado de un sistema no varia de forma continua, solo sufre cambios en determinados instantes de tiempo. Las actividades que desencadenan las transacciones en su recorrido a través de los bloques son la causa de que el sistema evolucione. De estas actividades solo nos interesa algunos instantes clave como su comienzo y su final, momentos en que se altera el estado del sistema. Decimos que se produce un acontecimiento cuando se desarrolla una actividad que no consume tiempo y que cambia instantáneamente el estado del sistema. Imaginemos un vehículo que llega a una estación de servicio en el instante 0, encuentra el surtidor vacío y comienza a ser atendido. El modelo estaría formado por una transacción (vehículo) que accede a un procesador (surtidor de gasolina) y se encuentra en un bloque de demora en el instante 0. Para el sistema se producen dos acontecimiento: Acontecimiento 1: La transacción ocupa el bloque de demora. Acontecimiento 2: La transacción abandona el bloque de demora. En el momento en que ocurre el primer acontecimiento el sistema calcula el instante de ocurre ncia del segundo acontecimiento. Diremos que el segundo acontecimiento es un acontecimiento pendiente de ocurrir. Manual del Usuario PSPS IV 7 Capítulo 0: Conceptos Fundamentales del PSPS. El Reloj Físico y el Reloj Maestro de la simulación El Reloj Maestro de la simulación es el reloj interno que controla toda la actividad del sistema modelado. El Reloj Maestro avanza a saltos, de acontecimiento en acontecimiento. El tiempo entre acontecimientos sucesivos no interesa y se elimina. Cuando el sistema no puede mover más transacciones en el instante de tiempo en que se encuentra el Reloj Maestro, este da un salto y se adelanta de forma automática hasta el instante de tiempo en el que se produce el siguiente acontecimiento. Si no se indica lo contrario el funcionamiento del Reloj Maestro es independiente del Reloj Físico del ordenador. Es importante tener en cuenta que PSPS no se preocupa de las unidades en que se mide el tiempo. Las unidades del Reloj Maestro deben de ser elegidas por el usuario en función del modelo. Manual del Usuario PSPS IV 8 CAPITULO 1: Estructura General del Lenguaje PSPS § § § § § § § Manual del Usuario PSPS IV Sección Constant Sección Labels Sección Variables Sección Macros Sección Data Sección OnDebug Sección System Capítulo 1: Estructura General de un Programa PSPS Un programa PSPS consta de siete secciones, de las cuales las seis primeras son opcionales. Las secciones, si se usan, deben aparecer en el orden que se indica. • Definición de constantes, o sección CONSTANTS. En esta sección se declaran las constantes, que luego pueden usarse en el resto del programa. • Definición de etiquetas, o sección LABELS. En esta sección se declaran los identificadores que podremos emplear como referencia posteriormente en la sección SYSTEM. • Definición de variables, o sección VARIABLES. En esta sección se definen variables, proporcionando su nombre y atributos. Existen dos tipos básicos de variables, escalares y Arrays. Las variables se pueden utilizar libremente en el resto del programa, tanto para intervenir en cálculos, como para almacenar valores intermedios. Todas las variables declaradas en esta sección son variables globales, es decir visibles desde cualquier parte del programa. • Definición de funciones, o sección MACROS. En esta sección se definen las funciones y las macros del programa. • Definición de funciones de Debug, o sección ONDEBUG. En ella se definen una sola función de usuario que se puede ejecutar desde el debugger. • Definición de datos, o sección DATA. En ella se inicializan las variables y parámetros del sistema que así lo requieren. • Definición de bloques, o sección SYSTEM. En esta sección se definen los bloques que forman el modelo de simulación. Cada uno de los elementos de las secciones DATA y SYSTEM posee una serie de parámetros que deben especificarse adecuadamente. En general, todos los parámetros se dan por medio de Sentencias Pspal. Es importante destacar que, en las secciones DATA y SYSTEM, todo parámetro en el que pueda escribirse un número, puede contener también una sentencia Pspal que devuelva un valor, incluyendo una función definida por el usuario o cualquier EAG (Expresión Algebraica Generalizada). El programa debe terminar siempre EndSystem seguida de un punto y coma. con la palabra clave Sección Constants La sección de constantes, en caso de que aparezca, debe ser la primera sección de un programa PSPS. Su comienzo se indica por Manual del Usuario PSPS IV 9 Capítulo 1: Estructura General de un Programa PSPS la aparición de la palabra clave CONSTANTS, y su final por el comienzo de la siguiente sección. Tras la palabra CONSTANTS siguen las declaraciones de las constantes del usuario. Formato: = ; El valor de la constante debe ser un entero en el rango permitido o una expresión aritmética simple entre constantes ya definidas. Nótese que cada declaración de constante contiene el signo "=" y termina por un punto y coma ";". Ejemplos: - Definicio nes validas VELOCIDAD = 3000; ACELERA = 0; TIEMPO = 3; ESPACIO = VELOCIDAD*TIEMPO; NUEVO = ON; La definición de ESPACIO es validad ya que ambas constantes VELOCIDAD y TIEMPO han sido definidas con anterioridad. - Definiciones inválidas VELOCIDAD = 0.3; ERROR!! El valor que se asigna al identificador debe ser un entero. En todos los contextos, la utilización de un identificador de una constante es idéntica a la utilización de su valor numérico. Por ejemplo son válidas las operaciones: TRUE * FIFO; con resultado –1000, PI + OFF + NO; con resultado 31416, PRINTER + CONSOLE + FALSE; dando como resultado 1. Se aconseja al lector el uso del identificador de la constante adecuado en cada contexto para mejorar la legibilidad del programa, aunque algunos de ellos sean completamente equivalentes (por ejemplo FALSE, OFF y CONSOLE). El lenguaje PSPS tiene una serie de Constantes Predefinidas que pueden ser utilizadas sin necesidad de definirlas: Manual del Usuario PSPS IV 10 Capítulo 1: Estructura General de un Programa PSPS - Constantes clásicas. Constantes de disciplina de espera en cola. Constantes lógicas. Constantes de Input- Output. Constantes de Gráficos. Constantes estadísticas. Constantes de color. Todas estas constates se describen en detalle en el Capítulo 3 de este manual. Sección Labels En esta sección se declaran las etiquetas, que luego pueden ser usadas en la sección SYSTEM como identificadores de un bloque, para poder dirigir transacciones hacia ellos, desde cualquier parte. Estas etiquetas siguen las mismas convenciones, en lo referente a caracteres admitidos, que cualquier otro identificador de una constante o una variable. Las etiquetas se declaran al aparecer su identificador seguido de un punto y coma, dentro de la sección LABELS. Sección Variables La definición de variables globales, variables conocidas por todo el programa, se realiza en esta sección, que debe seguir a la definición de Labels. La sección de definición de variables se inicia con la aparición de la palabra clave VARIABLES y termina con la aparición de la sección siguiente. Hay dos tipos principales de variables: Variables Escalares y Variables Arrays. Todas las variables de un programa deben declararse, aunque algunas de ellas estén implícitamente declaradas en el lenguaje (Variables Predefinidas), la descripción de cada una de estas variables aparece en el Capítulo4 de este manual. Sección Macros La sección MACROS permite definir funciones, con gran generalidad y usando el lenguaje Pspal. También permite la Manual del Usuario PSPS IV 11 Capítulo 1: Estructura General de un Programa PSPS definición de macros, que pueden contener tanto expresiones de bloques PSPS como sentencias Pspal. Ambas construcciones se llaman usando su nombre y sus argumentos, en el caso de tenerlos. Pero el tratamiento de las funciones y las macros es totalmente diferente. Las funciones definidas por el usuario se comportan como cualquier otra función interna del PSPS. Las funciones, en el momento de su compilación, pasan a enriquecer los operadores de cálculo de Pspal. Se compilan y en tiempo de ejecución se llaman como subrutinas independientes, comunicadas entre si por el paso de argumentos y por el uso de variables globales. Las macros en cambio se expanden automáticamente en tiempo de compilación, sustituyendo los argumentos proporcionados en su llamada por los parámetros indicados en su definición. Por tanto, las macros producen sustitución de código en el momento de la compilación, código que desaparece como tal, al quedar expandido en línea. Las macros pueden considerarse abreviaciones para construcciones repetitivas que ayudan a mejorar la legibilidad del programa PSPS. En este sentido, son verdaderas extensiones del lenguaje, ya que implantan nuevos bloques, cuyo comportamiento se define en términos de los bloques ya existentes, de las funciones declaradas (incluyendo las del usuario) y de los elementos básicos del lenguaje. Un conjunto de macros permiten definir un lenguaje especial, definiendo nuevos tipos de bloques, para la simulación de un cierto tipo de problemas. Todo el cuerpo de la macro se expandirá en el lugar de su llamada, por lo que puede dar lugar a efectos insospechados, capturando variables del contexto. En la jerga se dice que las macros del PSPS no son "higiénicas" pues pueden provocar efectos laterales no previstos. Las macros son muy útiles pero deben usarse con extremado cuidado, porque su uso puede hacer el programa muy difícil de poner en marcha, debido a los errores sutiles que producen. La sintaxis de la llamada es diferente para ambos casos y se precisara en las secciones correspondientes. Sección Data La sección Data contiene sentencias de inicialización del PSPS. Estas sentencias se ejecutan una sola vez, antes de empezar la simulación. Por tanto, permiten definir fácilmente el contexto en el que se va a realizar la simulación. La sección Data admite bloques de: Manual del Usuario PSPS IV 12 Capítulo 1: Estructura General de un Programa PSPS • • • • • • • • • • • Definición de tamaño: FACILITY, STOCK, SWITCH, GRAPHS e HISTO. Declaración de objetos: TABLE, SCREEN, GANTT. Duración de la simulación: TIME, ITEM. Inicialización de valores de variables: VARS, RESET. Debugging: LOOP, TRACE, DEBUG Mando de la simulación: REPORT Inicialización por programa: INITIAL. Sentencias de OutPut: DUMP. Simulación continua: STEP. Generación de números Aleatorios: RANDOMIZE. Definición de Distribuciones de Probabilidad: DISTRIBUTION. Todos estos bloques se describen en detalle en el Capít ulo 7 de este manual. Sección OnDebug En esta sección se puede escribir una única sentencia Pspal. Este fragmento de código se puede ejecutar en cualquier momento que la simulación este detenida mediante el botón UserFunction de la Ventana de Control de la simulación o de la ventana del Debugger. La sentencia Pspal suele ser la llamada a una función definida previamente en la sección Macros. Esta sección se suele utilizar para definir tablas informe que muestran el valor de las variables más representativas del modelo. Sección System La sección SYSTEM es la única obligatoria en todo programa PSPS. Contiene las especificaciones para la simulación en forma de bloques por los que circulan las transacciones. Clasificaremos los bloques en nueve categorías, de acuerdo con su función: • Control de transacciones y avance de reloj. Bloques GENERATE, DEGENERATE, TERMINATE, SPLIT, ASSEMBLE, SYNCRO, SSYNCRO, ADVANCE y WAITFOR, SGROUP, GROUP, GRAB, JOIN. SELJOIN y UNGROUP. • Ocupación de procesadores y switches. Bloques ENTER, MENTER, GET, MGET, LEAVE, QUEUE, SWITCH, GATE, QGATE y GATEGROUP. • Cálculo y modificación de variables. Bloques ASSIGN y COMPUTE. Manual del Usuario PSPS IV 13 Capítulo 1: Estructura General de un Programa PSPS • Definición de secuencia. FREORDER y SREORDER • Elaboración de estadísticas. Bloques TABULATE ,TTAB. y SIMRESET. • Input, Output y Debugging. Bloques STOP, DUMP, PRINT, TRACE y DEBUG. Bloques multimedia y gráficos. Bloques DISPLAY, PLAY y DRAWXY. • • Bloques TRANSFER, YIELD, Simulación continua: Bloque INTEGRATE. Todos estos bloques se describen en detalle en el Capítulo8 de este manual. Manual del Usuario PSPS IV 14 CAPITULO 2: Elementos Básicos del Lenguaje PSPS § § § § § § Manual del Usuario PSPS IV Alfabeto Básico Ficheros como comentarios activos Números Identificadores Strings Operadores Capítulo 2: Elementos Básicos del Lenguaje PSPS Alfabeto Básico El alfabeto básico esta formado por las letras a – z minúsculas y A – Z mayúsculas, los dígitos 0 – 9 y los caracteres especiales que se muestran en la Tabla 1. Tabla 1. Alfabeto Básico. Letras Dígitos Caracteres Especiales a – z minúsculas A – Z mayúsculas 0- 9 + - * / < > ( ) [ ]{ } , ; .: = # @ $ ^ El formato de escritura es libre, y no se hace distinción de las líneas de escritura. Una línea es lógicamente la estricta continuación de la anterior, pero el retorno de carro actúa de separador, con lo que una palabra no puede estar partida entre dos líneas. Los blancos actúan de separadores y por lo tanto no pueden aparecer embebidos en identificadores u operadores. El símbolo @ indica el principio y final de un comentario. La primera aparición de @ abre el comentario, y la segunda lo cierra. También, todo texto comprendido entre { } es considerado un comentario. El lenguaje no distingue letras mayúsculas de minúsculas, excepto en las series de caracteres usadas en sentencias de Output. Por tanto, el tipo de letra puede elegirse en la forma adecuada para mejorar la legibilidad del programa. Ficheros como comentarios activos Cuando queremos añadir a nuestro modelo datos contenidos en otro fichero lo que debemos hacer es emplear un comentario activo. Un comentario activo es un comentario como los que se emplean para facilitar la lectura de los programas pero que por contener determinados caracteres especiales se convierten en parte del programa y realizan alguna función. En este caso el comentario activo se emplea para añadir el texto contenido en un fichero y su formato es el mismo que el comentario pero precedido de un símbolo $, veámoslo con un ejemplo: Manual del Usuario PSPS IV 15 Capítulo 2: Elementos Básicos del Lenguaje PSPS Ejemplo: @$c:\PSPS-III\Examples\Example1.pss @ { $c:\PSPS-III\Examples\Example1.pss } Estas dos sentencias incluirían el contenido del fichero Examples1.pss en el lugar del programa en el que hemos escrito la sentencia. Números Un número es una sucesión de dígitos opcionalmente precedidos por un signo. Los números que maneja internamente el sistema son siempre reales, aunque todos los números deben ser escritos como enteros, es decir, sin punto decimal y en el rango [2147483648, +2147483648]. Esta particularidad es debida a que el sistema de entrada solo reconoce números enteros, pero internamente los cálculos se realizan entre números reales. Si queremos que, por ejemplo, el valor que se almacene en una variable sea 0.0001 la única forma de hacerlo, si el valor no proviene de un cálculo realizado por el sistema, es: X = 1/10000 siendo X una variable cualquiera definida anteriormente. Identificadores Los identificadores creados por el usuario son nombres que representan algún elemento del modelo como variables, constantes, etiquetas, funciones o macros. Un identificador puede tener tantos caracteres de longitud como se desee, pero sólo los treinta y dos primeros caracteres son significativos. Todo identificador debe empezar por una letra. En general, es aconsejable no usar caracteres numéricos en un identificador, ya que en muchos casos estos tienen un significado especial. En el sistema hay una serie de identificadores predefinidos. Sus nombres son palabras reservadas y por tanto debe evitarse la declaración de identificadores cuyo nombre coincida con alguno de ellos. Los identificadores predefinidos corresponden a nombres de secciones, nombres de bloques, constantes, funciones Manual del Usuario PSPS IV 16 Capítulo 2: Elementos Básicos del Lenguaje PSPS predefinidas, predefinidas. palabras clave del lenguaje Pspal y variables Strings Una String es cualquier conjunto de caracteres que se encuentra entre comillas dobles. Toda constante puede tener como valor una String. Toda variable puede contener una String o en el caso de variables Array, un Array de strings. La única forma de modificar Strings en un programa es mediante la función Format o la función MakeStr. En realidad PSPS es incapaz de manejar variables String. Tan solo puede tratar constantes de tipo String. No reconoce el tipo String, mas que por la presencia de este en un lugar bien determinado de una sentencia. Una String esta representada por un número, el valor del puntero que da su dirección interna. Cualquier asignación de una String a una variable, asigna a la variable el número de la dirección de memoria que representa la String. El uso de la variable en un contexto en el que no se espera una String puede dar lugar a resultados variados, insospechados y la mayoría de las veces perjudiciales. Ejemplos: La sentencia X = "La del alba sería" ; es una asignación válida. Aquí, X es una variable que contendrá un número que proporciona la dirección de memoria de la String, tras la asignación. La sentencia Y = \"La", "del","alba","sería"\; inicializa un Array de Strings. Y es una variable Array que contiene 5 elementos, que serán Strings tras la inicialización. Operadores Los operadores son los elementos de un lenguaje, generalmente símbolos, que se encargan de combinar identificadores y números para generar resultados numéricos. Manual del Usuario PSPS IV 17 Capítulo 2: Elementos Básicos del Lenguaje PSPS Los operadores disponibles en el PSPS habituales en la mayoría de los lenguajes. son los operadores Operadores Algebraicos Son los operadores aritméticos habituales que nos permiten realizar operaciones numéricas. Tabla 2. Operadores Algebraicos. Operadores Algebraicos + – * / - Función Suma Resta Multiplicación División Cambio de signo Operadores Relacionales Estos operadores se utilizan para establecer una relación entre dos operandos, devuelven el valor True si la relación analizada es cierta y False en caso contrario. Tabla 3. Operadores Relacionales. Operadores Relacionales == # < <= > >= A A A A A A Relación Analizada es igual a B es distinto de B es menor que B es menor o igual que B es mayor que B es mayor o igual que B Operadores Lógicos En este caso los operadores And y Or dan el And y el Or bit a bit de los enteros obtenidos redondeado los operandos. Las habituales tablas de Verdadero Falso son ciertas para estos operadores. El operador Negación Not efectúa el complemento bit a bit del redondeo de su operando. Tabla 4. Operadores Lógicos Operadores Lógicos And Or Not Manual del Usuario PSPS IV And Bit a Bit Or Bit a Bit Operador Negación 18 Capítulo 2: Elementos Básicos del Lenguaje PSPS Operadores de Manejo de Direcciones El manejo de las direcciones de memoria en el PSPS se realiza mediante los operadores ampersand & y caret ^. & Variable: proporciona la dirección de memoria de la variable. ^ Variable : permite el acceso al contenido de una posición de memoria. Manual del Usuario PSPS IV 19 CAPITULO 3: Definición de Constantes § § § § § § § § Manual del Usuario PSPS IV Constantes Clásicas Constantes de Disciplina de Espera Constantes Lógicas Constantes de Input/Output Constantes de Gráficos Constantes Estadísticas Constantes de Color Otras Constantes Capítulo 3: Definición de Constantes Las constantes predefinidas pueden utilizarse como argumentos de las funciones, parámetros de los bloques o para realizar cálculos. Constantes Clásicas Tabla 1. Constantes Clásicas. Constantes Clásicas Identificador Valor Numérico Número Pi PI 31416 Número e E 27172 INFINITY +2147483648 Mayor entero representable Constantes de Disciplina de Espera en una Cola. Hay tres prioridades especiales que no están asociadas con atributos de transacciones y que en el PSPS están representadas por las siguientes constantes: Tabla 2. Constantes de Disciplina de Espera ante una Cola. Constantes Disciplina de Espera en Cola Identificador Valor Numérico Primero en llegar, primero en ser servido. FIFO 1000 Primero en llegar, último en ser servido. LIFO 1001 No existencia de cola organizada. NOQUEUE 1002 Agrupa las transacciones sobre la primera y salen todas juntas cuando termina la espera. REGROUP 1003 Manual del Usuario PSPS IV 20 Capítulo 3: Definición de Constantes Constantes Lógicas Tabla 3. Constantes Lógicas. Constantes Lógicas Identificador Valor Numérico TRUE FLASE -1 0 YES NO -1 0 ON OFF -1 0 WAIT NOWAIT 0 -1 Afirmación OK 0 Valor Lógico False en el lenguaje Lisp NIL 0 Valores Lógicos Cierto y Falso Estados Bivalentes Salida de bloque por Impaciencia Constantes de Input/Output. Estas constantes se utilizan para indicar el destino del Output en las sentencias y bloques de escritura Tabla 4. Constantes de Input/Output. Consta ntes Input/Output Identificador Valor Numérico FILE 2 Impresora PRINTER 1 Output en la ventana del Listener CONSOLE 0 Ficheros a los que se puede destinar el Output del bloque PRINT Manual del Usuario PSPS IV 21 Capítulo 3: Definición de Constantes Constantes de Gráficos Estas constantes se utilizan en combinación con la función FDrawCont y HDrawCont para indicar opciones de formato en un gráfico o histograma. En la siguiente tabla mostramos las distintas disponibles, su función y los argumentos necesarios. constantes Tabla 5. Constante de los Gráficos. Función FDrawCont( ) y HDrawCont( ). Constantes Gráficas Identificador Argumentos Requeridos Valor Numérico Borra todas las series de datos de un gráfico. GCLRALL ____ 1 Borra una serie de valores de un gráfico. GSERCLR Números Series 2 Dibuja los valores de una serie de forma ordenada. Ignora los que llegan desordenados. Une cada valor por medio de una línea con el valor cuya x es inmediatamente anterior. GSERORDER Números Series 3 Dibuja y une los puntos de una serie en el orden que se entregan a la función FdrawCont. GSERUNORDER Números Series 4 Define el tamaño del gráfico. GSIZE Puntos extremos de los ejes 5 Titulo del gráfico. GTITLE String 6 Número de barras en un histograma GBARS Número de Barras 7 GSERNODOTS Números Series 7 Trazo de la serie continuo. Si aparece el argumento False, el trazado discontinuo GSERSOLID (False) y Números Series 8 True: Redibujado automático Cada orden de dibujo se representara inmediatamente en la pantalla. False: Solo se pone al día el estado interno del gráfico. Cuando cambie a True se dibujara lo guardado. GUPDATE True o False 9 Suprime la representación de los puntos en un gráfico. Manual del Usuario PSPS IV 22 Capítulo 3: Definición de Constantes No dibuja la línea que une puntos consecutivos en las series, solo los puntos. GSERNOLINES Números Series 10 Titulo del Eje X GXTITLE String 11 Titulo del Eje Y GYTITLE String 12 Permite definir el color del fondo de un gráfico o diagrama. GBCOLOR Const o Función Color( ) y Números Series 13 Permite definir el color de la línea de la serie indicada GSERCOLOR Const o Función Color( ) y Números Series 14 Permite definir el color de los puntos de la serie indicada. GSERDCOLOR Const o Función Color( ) y Números Series 15 Dibuja la serie como una función escalonada continua por la izquierda. GSTEPLEFT Números Series 16 Dibuja la serie como una función escalonada continua por la derecha. GSTEPRIGHT Números Series 17 Constantes de Estadísticas Se utilizan como mnemotécnicos para acceder a diferentes campos estadísticos de Facilities, Bloques, Colas, switches o Histogramas, en las funciones STATBL, STATFAC, STATQ, STATSW y STATTAB. Tabla 6. Constates Estadísticas. Constantes Estadísticas Accede a la media. Identificador SAVERAGE Accede a la desviación tipo. SSTDEV Accede a la media temporal. STAVERAGE Accede a la desviación tipo temporal. Accede al número de Items. STSTDDEV SNUM Accede al valor máximo. SVALMAX Accede al valor mínimo. SVALMIN Manual del Usuario PSPS IV 23 Capítulo 3: Definición de Constantes Constantes de Color Son mnemotécnicas para utilizar los colores en el dibujo de gráficos. Corresponden a los colores básicos de la paleta estándar de Windows. Tabla 7. Constantes de Colores. Constantes Colores Identificador Valor CBLACK ClBlack CBLUE ClBlue Color Gris Oscuro CDKGRAY ClDkGray Color Fucsia CFUCHSIA ClFuchsia CGRAY ClGray CGREEN ClGreen CLIME ClLime CMAROON ClMarron Color Azul Oscuro CNAVY ClNavy Color Verde Aceituna COLIVE ClOlive CPURPLE ClPurple CREAM $00AAFFFF CRED ClRead CSILVER ClSilver CTEAL ClTeal CWHITE ClWhite CYELLOW ClYellow Color Negro Color Azul Color Gris Color Verde Color Verde Limón Color Marrón Color Púrpura Color Crema claro Color Rojo Color Gris Claro Color Verde Oscuro Azulado Color Blanco Color Amarillo Manual del Usuario PSPS IV 24 Capítulo 3: Definición de Constantes Otras Constantes Tabla 8. Otras Constantes. Otras Constantes Identificador Se utiliza en el bloque UNGROUP para indicar que queremos desagrupar todas las transacciones agrupadas. ALL Indica en el bloque RANDOMIZE que queremos una serie de números antitética a la anterior. ANTI Se utiliza en las funciones que hacen referencia a las transacciones para referirnos a un Switch. SWTCH Se utiliza en las funciones que hacen referencia a las transacciones para referirnos a los procesadores. FACLTY Primera dirección del espacio de memoria reservado para las variables. LOWVAR Se utiliza como argumento de la función Message para crear los botones Yes y No en el cuadro de diálogo definido por la función. YESNO Se utiliza como argumento de la función Message para crear los botones Yes, No y Ok en el cuadro de diálogo definido por la función. YESNOOK Manual del Usuario PSPS IV 25 CAPITULO 4: Definición de Variables § § § Manual del Usuario PSPS IV Variables Escalares Variables Array Variables Stats Capítulo 4: Definición de Variables Variables Escalares Una variable escalar se declara simplemente dando su nombre seguido de un punto y coma, es decir: ; Ejemp los: Variables ACELERA; b; c; d; 1ABC; ERROR !!! El identificador es inválido, porque un identificador no puede empezar por un dígito. Variables Predefinidas Tabla 1. Variables Escalares. Variables Escalares Identificador Descripción Clock CL Valor del reloj maestro de la simulación. Previous Block PB Número de bloque en el que se encontraba la transacción antes de ocupar el bloque actual. Current Block CB Número del bloque en que se encuentra actualmente la transacción. Items IT Número de items que han abandonado el sistema y han sido contabilizados por un bloque TERMINATE. Tiempo de Generación TrTime Instante de tiempo en que fue generada la transacción en curso. Es equivalente al atributo 1 de la transacción en curso. Contador de Transacciones TrCount Contador del número de transacciones generadas en el bloque GENERATE. Equivale al atributo 2 de la transacción en curso. Bloque Generador TrWhere Indica el número de bloque en el que fue generada la transacción en curso. Equivale al atributo –1 de la transacción. Variables Array Las variables array pueden clasificar en tres tipos: Arrays normales (unidimensionales y bidimensionales), Arrays Virtuales y Arrays Funcionales. Manual del Usuario PSPS IV 26 Capítulo 4: Definición de Variables Las variables array dan gran generalidad, al permitir el uso de cualquier expresión para indexar un componente particular de las mismas. Todas las variables tienen un valor numérico que se concreta en el instante de su evaluación (o de la evaluación de la sentencia que las contiene). Este valor es siempre un real. La evaluación de una expresión se produce siempre antes de iniciar el movimiento de una transacción. Arrays La declaración de una variable array es similar a la declaración de una variable escalar, pero hay que indicar también el número de elementos que lo forman. Formato: • Array unidimensionales (vector) Array ; • Array bidimensional (matriz) Array , ; Parámetros: : indica el nombre del array : puede ser cualquier valor constante mayor que cero, dentro de los límites de la implementación. A los componentes de las variables array se le asigna la memoria de forma secuencial empezando por el elemento 1 y llegando hasta el total de elementos del array. Los arrays bidimensionales se almacenan por filas, es decir se almacenan linealmente en la forma a[1,1], a[1,2],... a[1,n], a[2,1], a[2,2] ... De esta forma, el primer elemento de una fila se halla contiguo al último elemento de la fila anterior. La dirección de memoria del Array es la dirección de memoria de su primer elemento. El nombre de un array sólo puede aparecer sin subíndice en la sentencia de inicialización (ver sentencia Vars en la Sección Data). En todos los demás casos deben utilizarse sus componentes. Para seleccionar una componente de un array se debe indicar el subíndice o los subíndices, si se trata de un array Manual del Usuario PSPS IV 27 Capítulo 4: Definición de Variables bidimensional, a continuación del nombre y dentro de paréntesis cuadrados, en la forma [índices1, índice2] VArrays Las variables de tipo VArray, también pueden ser vectores o matrices. Una variable tipo VArray no tiene asignada una dirección de memoria permanentemente. Para poder utilizar una variable de tipo VArray, antes se le debe asignar una dirección, que pasa a ser la dirección de inicio (del primer elemento) del array que representa. La asignación de dirección se logra asignando al nombre del VArray la dirección de memoria (mediante el operador &) de otra variable o de un elemento de un array. Una variable VArray se declara de la misma forma que una variable array, pero con la palabra clave VArray sustituyendo a la palabra array. VArray ; VArray , ; FArrays Un FArray es un array unidimensional cuyos subíndices pueden tomar cualquier valor real. En la declaración del array no debe darse el tamaño del mismo, ya que un array de este tipo es potencialmente infinito, pudiendo contener tantos valores como quepan en la memoria del ordenador. El formato de la declaración es: FArray; Un array FArray es de hecho la implementación de una función con argumentos reales. Debido a esta característica, este tipo de arrays no ocupan espacio en la memoria de las variables, y por tanto no aparecen en los volcados de memoria de variables. Un array FArray se llena en la forma habitual, asignando un valor a cada posición del mismo, solo que en este caso cada posición viene indexada por un real. Cuando se usan los valores de un FArray, el valor del índice se utiliza para encontrar el valor asociado en una asignación previa. Si no hay una asignación previa para el valor del índice, distinguimos tres casos de asignación: Manual del Usuario PSPS IV 28 Capítulo 4: Definición de Variables • Hay un intervalo declarado que contiene al índice dado. En este caso, el valor del FArray (de la función) se obtiene por una interpolación lineal en el intervalo que contiene al índice. La formula de esta interpolación, dados los puntos (x0,y0), (x1 ,y1), es y = y1 *(x-x0)/(x1 -x0) + y0 *(x1 -x)/(x 1-x0 ) • El índice es menor que el menor índice asignado. El valor resultante es el valor del FArray ( de la función) de menor índice de entre los asignados. • El índice es mayor que el mayor índice asignado. El valor resultante es el valor del FArray ( de la función) de mayor índice de entre los asignados. Variables Predefinidas Tabla 2. Variables Array. Variables Array Identificador Descripción Block Array 200 BL[ ] Número de transacciones entradas en cada bloque. Facility Size Array 100 FS[ ] Capacidad o tamaño de cada procesador. El tamaño por defecto de un procesador es 1. Facility Content Array 100 FC[ ] Indica el número de transacciones que hay en cada procesador. Facility Max Array 100 FM[ ] Número máximo de transacciones que ha habido en un procesador. Facility Accepting Array 100 FA[ ] Estado del procesador para aceptar transacciones. Si el estado es True, acepta transacciones; si es False no acepta transacciones. Queue Array 100 QU[ ] Tamaño de la cola de cada procesador Switch Array 50 SW[ ] Estado de los Switches. El estado puede ser On u Off. Atributos Array 20 AT[ ] Valor de los atributos de la transacción en curso. Variables Array 500 VA[ ] Este array variables”. 1 Memory Array MEM[ ] es la “memoria de las Representa a la memoria del PSPS, incluyendo las variables predefinidas. Este Array se superpone con las variables predefinidas de acuerdo al orden en que aparecen en esta tabla. Todas las variables declaradas se identifican con porciones de este array, en orden alfabético. Por tanto el array Va[ ] proporciona una forma alternativa de acceder a las variables declaradas. Así VA[1] es la primera variable, en orden alfabético, de todas las variables declaradas. 1 Manual del Usuario PSPS IV 29 Capítulo 4: Definición de Variables Variables Stats Toda variable PSPS puede declararse Stat. Una variable Stat es una variable como otra cualquiera y puede usarse exactamente de la misma forma. La única diferencia es que el sistema calcula automáticamente estadísticas de su valor, estadísticas que pueden ser consultadas posteriormente. Ejemplo: X Stat; XY Stat Array 2,5; Las estadísticas disponibles para este tipo de variables, son las mismas que para el contenido de una Facility o procesador, es decir, valor extremo, media temporal ponderada, desviación tipo temporal ponderada, media simple y desviación tipo simple. Para consultar el valor de una variable Stat se utiliza el menú Display/StatVars de la barra de herramientas. Manual del Usuario PSPS IV 30 CAPITULO 5: El lenguaje de Programación Pspal. § § § Manual del Usuario PSPS IV Sentencias Pspal con valor Sentencias Pspal Simples Sentencias Pspal Compuestas Capítulo 5: El Lenguaje de Programación Pspal El Pspal es un lenguaje algebraico de programación embebido el PSPS. Este lenguaje, similar al Pascal, permite realizar cálculos que la lógica de los bloques no pueda proporcionar eficientemente. El lenguaje Pspal comparte los elementos básicos con el PSPS, por lo que las variables, constantes y funciones declaradas en las secciones correspondientes pueden usarse en la construcción de expresiones algebraicas. Podemos distinguir tres tipos de sentencias Pspal, las Sentencias Pspal con valor, las Sentencias Simples y las Sentencias Compuestas. Sentencias Pspal con Valor (SPVs) Las Sentencias Pspal con Valor (SPVs) son sentencias Pspal que devuelven un valor. Por ejemplo las expresiones algebraicas o las funciones son sentencias Pspal que devuelven un valor numérico. También veremos más adelante que las funciones en línea, que son sentencias Pspal compuestas, devuelven un valor mediante la sentencia Return. Expresiones Algebraicas Generalizadas (EAGs). Una EAG es una fórmula que se construye a partir de los elementos básicos del lenguaje como identificadores, números y operadores. Los identificadores pueden, a su vez corresponder a constantes, variables y funciones que, o bien están declaradas implícitamente en el lenguaje, o que han sido definidas con anterioridad por parte del usuario en la sección correspondiente. Las EAGs se evalúan internamente como núme ros reales, es decir, dentro de una expresión los cálculos se efectúan con los reales equivalentes de los valores, aunque no es posible introducir directamente un número real en una expresión. El resultado de una evaluación es siempre un número real aunque los operandos sean enteros, por tanto, en general podemos decir que el PSPS realiza aritmética con números reales. La conversión de reales a enteros puede ser controlada por el usuario por medio de la función Int( ) que trunca la parte decimal de un número real para convertirlo en entero. Esta forma de operar hace que ciertas expresiones deban formularse de una manera particular. Por ejemplo Va[1] * 0.1 es una expresión invalida, porque 0.1 es un número real y un número real debe ser siempre el resultado de una evaluación. Una forma correcta de escribir esta expresión es Va[1] * 10 / 100. Manual del Usuario PSPS IV 31 Capítulo 5: El Lenguaje de Programación Pspal Usando operaciones algebraicas entre enteros se puede construir cualquier racional, por lo que estas restricciones en la escritura no son realmente restricciones en el uso. La razón fundamental de su presencia es la eficiencia de proceso. Las EAGs combinan números, identificadores y operadores para dar un resultado numérico. Veamos algunos ejemplos de expresiones válidas. 3+2*At[1], 3/max(At[1],2,Va[2]), 3/max(At[1],2,Va[2])>3+2*At[1], Dentro de cada EAG y en ausencia de paréntesis los operadores se evalúan de acuerdo con su prioridad. En una expresión se evalúan primero los operadores de prioridad más alta y el resto de los operadores se evaluaran sucesivamente en orden decreciente de prioridad. Dentro de cada prioridad los operadores se evalúan de izquierda a derecha, es decir en el orden en que se encuentran en la expresión. La prioridad de los operadores viene dada por la siguiente tabla, en la que cada clase tiene mayor prioridad que las clases que la siguen, y dentro de cada clase todos los operadores tienen la misma prioridad. Tabla 1. Prioridades de los Operadores. Prioridad Operadores Clase1 *, / Clase2 + , - , - unario Clase3 Clase4 , <, = =, #, < = , > = And, Or, Not Obsérvese que de acuerdo con esta tabla, la expresión -3+2 da como resultado -1, ya que primero se evalúa el menos unario y luego la suma -3+2. Adicionalmente la expresión 3+-2 es invalida, ya que al intentar evaluar el operador + el segundo operador aun no se ha asignado. Para evitar estas situaciones recomendamos usar paréntesis para rodear el operando de un menos unario, de forma que la expresión anterior quedaría 3+(-2). La prioridad de los operadores puede alterarse mediante el uso de paréntesis. Una expresión entre paréntesis se evalúa como una unidad independiente antes de usarla en operaciones con otras Manual del Usuario PSPS IV 32 Capítulo 5: El Lenguaje de Programación Pspal expresiones. Así en la expresión anterior 3 + (-2) se evaluaría primero el menos unario y la expresión devolvería el valor 1. Cuando aparecen funciones en alguna EAG, como en los ejemplos anteriores, hay que tener en cuenta que se evalúan primero los argumentos de la función, luego la función y el resultado se utiliza en la expresión que la contiene. Por ejemplo en la siguiente expresión Not 3 * Cond (3 + 2 * At[1], Va[10], Va[3]), se evalúan primero los argumentos de la función Cond ( ), con los resultados obtenidos se evalúa la función y según la tabla de prioridades anterior el último operador que se evalúa será el operador Not. Sentencias Pspal Simples Las sentencias simples son las sentencias más sencillas y básicas del lenguaje Pspal. La combinación de estas sentencias nos permitirá definir las sentencias compuestas que describiremos en la siguiente sección. Sentencias de Asignación. Estas sentencias, como su nombre indica, se encargan de asignar un valor a una variable. El formato general de las sentencias de asignación es Variable = Las variables pueden ser escalares o subindexadas, pero todas las variables deben estar declaradas implícita o explícitamente. En el caso de las variables subindexadas los subíndices pueden venir dados por cualquier sentencia Pspal. Ejemplos: Sw[1]= Constante1+Constante2, Esta sentencia asigna a la variable de tipo Array Sw[ ] el resultado de la evaluación de la SPV Constante1+Constante2. La variable Sw [ ] esta definida implícitamente por el sistema y los identificadores Constante1 y Constante2 deben ser definidos por el usuario en la sección correspondiente. Manual del Usuario PSPS IV 33 Capítulo 5: El Lenguaje de Programación Pspal Sw[1]= (Va[1] > 0), Esta sentencias asigna el resultado de la evaluación de la sentencia Va[1] > 0 al primer elemento de la variable Array Sw[ ]. Si Va[1] es positiva, la sentencia asigna el valor True (el valor –1) a la variable Sw[1], en caso contrario asigna False (el valor 0). Sentencias de Control. Las sentencias de control permiten escribir con facilidad la lógica de un programa. La Sentencia If. If Then [Else ] La parte de la sentencia que aparece entre paréntesis cuadrados [ ] puede omitirse. Aquí, como en todo el lenguaje Pspal, toda puede ser una sentencia simple o compuesta, dando así lugar a construcciones recursivas de gran riqueza. Cuando se ejecuta una sentencia If, la primera EAG se evalúa y si el resultado no es cero (no es False) se ejecuta la sentencia Pspal que sigue a la palabra Then. En caso contrario (el resultado de la evaluación ha sido False) se ejecuta la sentencia que sigue a la palabra Else, si está presente, o continua con la ejecución de la próxima sentencia en secuencia, si no aparece la palabra Else. Veamos un ejemplo de una sentencia If muy sencilla If (a[2]*x+a[1]*x*x > 0) Then Sqrt(x) Else x Como vimos en el caso de las sentencias simples todas las variables utilizadas en las SPVs y sentencias Pspal deben estar definidas internamente o haber sido definidas por el usuario en las sección correspondiente. Podemos observar que en este ejemplo hemos utilizado como SPV la función Sqrt ( ), que es una función predefinida del PSPS. Esta sentencia evaluará la expresión a[2]*x+a[1]*x*x si es mayor que cero calcula la raíz cuadrada de la variable x. En caso contrario, es decir si la expresión evaluada es menor o igual que cero, devuelve el valor de la variable x. La Sentencia While. While Do Manual del Usuario PSPS IV 34 Capítulo 5: El Lenguaje de Programación Pspal Mientras la condición expresada por la sentencia Pspal con valor, evaluada según las convenciones anteriores, es cierta, se ejecuta la sentencia Pspal que sigue al Do. While es por tanto una sentencia de iteración que ejecuta iterativamente la sentencia Pspal hasta que la condición sea falsa, es decir la sentencia Pspal se ejecuta hasta que la SPV devuelve el valor cero. Ejemplos: While a[i]>x Do i=i+1, mientras que las componentes del vector a[ ] sean mayores que x aumentamos el subíndice i en una unidad. Cuando una de las componentes del vector a[ ] sea negativa o cero la ejecución de la sentencia se detendrá y el resto de las componentes del vector no serán analizadas. While a[i]# x Do i=i-1, mientras que las componentes del vector a[ ] sean distintas que x disminuimos el subíndice i en una unidad. La Sentencia Return. Return Devuelve el valor de a l sentencia Pspal con valor y termina la ejecución de la sentencia compuesta en la que se halla. Por ejemplo For i = 1 To 100 Do If a[i] == x Then Return i esta sentencia comprueba para las 100 primeras coordenadas del vector a[ ] si la componente i-esima del vector es igual a X; la primera vez que esto es cierto la sentencia devuelve el índice i, en caso contrario no devuelve ningún valor. La Sentencia For. For = To | DownTo Do ; Parámetros: : debe ser una sección Variables. variable previamente definida en la : es la sentencia que se ejecutará repetidamente pudiendo ser cualquier tipo de sentencia Pspal, y constituye el cuerpo del For. Manual del Usuario PSPS IV 35 Capítulo 5: El Lenguaje de Programación Pspal Las dos serán los valores inicial y final del bucle. La variable se inicializa al valor de la sentencia Pspal con valor que se halla después del signo de asignación, =. Una vez ejecutado el cuerpo del For, y antes de iniciar un nuevo bucle, se modifica su valor de acuerdo con el tipo de partícula usada. Si se usa la forma To, el valor inicial debe ser siempre menor o igual que el final, ya que el bucle se ejecuta recorriendo valores crecientes de la . Para ello, se incrementa el valor de la variable en 1 unidad, antes de empezar un nuevo bucle. Si el valor supera al valor final, el bucle no se ejecuta y la ejecución prosigue a la siguiente sentencia. En caso contrario se evalúa la sentencia que sigue al Do, y que forma el cuerpo del For. Si se usa la forma DownTo , la ejecución del bucle se realiza para valores decrecientes de la variable (siempre restándole una unidad) hasta que la variable sea menor o igual que el valor final del bucle. La sentencia For i = sentencia1 To sentencia2 Do sentencia3 es totalmente idéntica al bucle i = sentencia1, While i <= sentencia2 Do Begin sentencia3, i=i+1 End Nótese que si el valor inicial de sentencia2 es menor que el de sentencia1 el bucle no se ejecuta nunca, aunque si se producen los efectos laterales de la evaluación de sentencia1 y sentencia2, si los tienen. De la misma forma For i = sentencia1 DownTo sentencia2 Do sentencia3 es idéntico al bucle i = sentencia1, While i >= sentencia2 Do Begin sentencia3 i=i- 1 End Igual que antes si el valor de ‘sentencia1’ es menor que el de ‘sentencia2’ el bucle no se ejecuta nunca, pero si se producirán los efectos laterales de la evaluación de ‘sentencia1’ y ‘sentencia2’, en el caso de que existan. Ejemplo: Supongamos que queremos saber si alguno de los atributos de la transacción actual es nulo. Lo que haremos es mediante un bucle For recorrer los 20 primeros atributos de la transacción. En el caso Manual del Usuario PSPS IV 36 Capítulo 5: El Lenguaje de Programación Pspal de que alguno sea igual a cero la función Write se encargará de escribir “Atributo Nulo” y el índice en el que nos encontramos. 1 For i = 0 To 20 Do Begin If At[counter]=0 Then Write ("AtributoNulo",i), Return i End; La Sentencia Pause. Pause [] Al ejecutar esta sentencia la simulación se detiene. La detención se muestra en la ventana de control de la simulación, ya que el fondo del campo número de ítems procesados, aparece de color amarillo. En el mismo campo aparece el número de la pausa, si se ha especificado. Si no se ha indicado, aparece el valor cero. Figura 1. Ventana de Control de la Simulación. Pulsando el botón Continue, de la ventana de control, la ejecución continua inmediatamente después de la instrucción Pause. La sentencia Pause es muy útil para debugging, ya que permite realizar la ejecución con rapidez hasta alcanzar la situación en la que se produce el error. La pausa se puede aprovechar para preparar las herramientas de debugging, que se usaran tras la reanudación de la simulación. Es normal usar la construcción If Cl >= valor then Pause para detener la ejecución al llegar el reloj de la simulación a un instante de tiempo determinado. 1 Write, sentencia de Input/Output del lenguaje Pspal. Manual del Usuario PSPS IV 37 Capítulo 5: El Lenguaje de Programación Pspal Sentencias de Input/Output. La Sentencia Write Write( ) La sentencia Write provoca la impresión de resultados sobre el dispositivo de salida. Si se trata del dispositivo CONSOLE los resultados se escriben sobre una ventana denominada Listener. La escritura se produce aunque el Listener este cerrado, y aparecerá en cuanto esta ventana se abra. El argumento es una colección de variable s, constantes, sentencias Pspal con valor y strings de caracteres constantes, todos ellos separados por comas. Recuérdese que una string de caracteres (cadena o string) es un conjunto de caracteres encerrados entre comillas dobles. Por ejemplo, son series de caracteres: "Esto es una serie de caracteres..." “ " (es la serie o cadena nula). Dentro de una serie de caracteres el PSPS distingue mayúsculas de minúsculas. Las constantes String se transcriben literalmente en el dispositivo de salida. La escritura de la en el Listener se produce en el orden de su aparición en la lista. Los valores de las constantes y variables numéricas que aparecen en la se presentan en un formato standard, con un ancho de campo de 8 caracteres y dos decimales, justificado a la derecha y rellenado con blancos en cabeza. Si el valor de la constante o variable no cabe en esta representación, se cambia a notación flotante con un ancho de campo de 18 caracteres y en notación exponencial, en la forma: bsd.ddddddddddEsdd donde b es un blanco, s es el signo si negativo o un blanco si el valor es positivo, d son dígitos y E es la indicación (que se escribe) de que sigue la potencia de 10 por la que hay que multiplicar el número para obtener su verdadero valor, precedida de un signo s. Si la lista de escritura no cabe en una línea, se continua en la línea siguiente y así hasta completar la escritura de todos los argumentos de la . Al final se inserta un retorno de carro. En caso necesario la pantalla hace scroll. Como vimos, en el PSPS no hay variables de tipo String, entonces las siguientes sentencias Manual del Usuario PSPS IV 38 Capítulo 5: El Lenguaje de Programación Pspal y = "La del alba seria", Write(y) provocan la escritura de un número, que es la dirección de memoria de la constante string asignada a la variable y. A no ser que una expresión se halle en un contexto donde el lenguaje espere una string, no será posible manejar en la forma adecuada una variable que tenga asignada un valor string. La Sentencia WriteStr WriteStr( | variable | EAG) Esta sentencia escribe una String que no viene dada por una constante. El argumento de la sentencia se interpreta siempre como una String. Por tanto WriteStr crea un contexto en el que el valor numérico de una variable o el valor de la EAG se interpreta como la dirección de una string. Si el usuario quiere construir una string por medio de la función Format asignarla a una variable y/o imprimir esta, debe usar la sentencia WriteStr. El efecto de esta sentencia es presentar la string en el dispositivo de salida, que suele ser habitualmente el Listener. Ejemplos: WriteStr (Format("%1d",3)), esta sentencia crea mediante la función Format la string “3” y la imprime dando como resultado la aparición de un 3 en el dispositivo de salida. x = 10, WriteStr (Format("El valor hexa de %3d es %3x", x, x)), mediante la función Format crea la string "El valor hexa de 10 es A" y la imprime en el dispositivo de salida. La Sentencia PrintR PrintR( | variable | EAG) Esta sentencia realiza la escritura del valor de una variable o de una String sobre una tabla de output. La escritura se realiza en la tabla y casilla en curso. Una tabla y casilla se puede poner en curso utilizándolas como argumentos de la función GotoXY 2 . La propia instrucción PrintR 2 Función GotoXY(nTabla, nFila, nColumna): Esta función nos permite posicionarnos en la nFila de la nColumna de la nTabla. Manual del Usuario PSPS IV 39 Capítulo 5: El Lenguaje de Programación Pspal avanza de la casilla en curso a la próxima posición en la fila en curso. Si la fila se agota, la casilla pasa a la siguiente fila. Por tanto se puede escribir toda una tabla por filas, sin usar más que una vez la función GotoXY. La sentencia PrintR puede hacer output de strings o de números, que reconoce automáticamente, con un algoritmo de muy baja probabilidad de fallo. Sentencias Pspal Compuestas Una sentencia compuesta es un grupo de sentencias Pspal que comienzan con la palabra clave Begin y terminan con la palabra clave End. Las sentencias comprendidas entre estas dos palabras se ejecutan en la secuencia en la que se encuentran. Begin y End actúan como un paréntesis, agrupando las sentencias que se encuentran entre ellas como una sentencia única. Cada sentencia Pspal se separa de la siguiente mediante una coma 3 . La partícula End actúa también como separador, por lo que no es necesario insertar una coma cuando la próxima sentencia sea la partícula End. Una sentencia Pspal compuesta puede aparecer en cualquier lugar en el que el sistema espere una sentencia Pspal. Un ejemplo importante de sentencias compuestas son las funciones en línea. Funciones en Línea. Podemos definir una función en línea como cualquier sentencia Pspal compuesta que retorna un valor por medio de la sentencia Return. Ejemplo: Begin If x>0 Then x = Sqrt(x) Else x = 0, Return x End; es una función en línea que devuelve en el punto donde esta escrita el valor de la raíz de un número si este es positivo, y cero en caso contrario. 3 Nótese la diferencia con otros lenguajes en los que se utiliza el punto y coma como separador entre sentencias. En el PSPS el punto y coma esta reservado para separar definiciones de bloques en la sección System. Manual del Usuario PSPS IV 40 Capítulo 5: El Lenguaje de Programación Pspal Las funciones en línea son utilizadas por el usuario para definir sus propias funciones que podrán ser utilizadas a lo largo de todo el modelo de simulación. En este caso la función en línea debe ser definida en la sección Macros. Pero las funciones en línea también pueden utilizarse dentro de una EAG. Un ejemplo de una EAG que contiene a una función en línea podría ser la siguiente X * (1 + Y) * Begin If X > 0 Then X = Sqrt(X) Else X = 0, Return X End; El tercer operando de la expresión dependerá del signo de la variable X. Manual del Usuario PSPS IV 41 CAPITULO 6: Definición de Funciones y Macros. § § § Manual del Usuario PSPS IV Definición de Funciones Funciones Predefinidas Definición de Macros Capítulo 6: Definición de Funciones y Macros Definición de funciones. Las funciones creadas por el usuario deben definirse en la sección Macros y la estructura general para la definición de una función es la siguiente: : Function ({argumentos}) [Locals {Variables};] Las funciones no tienen que tener argumentos, por tanto la lista de argumentos puede estar vacía, pero los paréntesis deben aparecer siempre en la definición de la función. Si la función tiene argumentos, los valores que se den a los argumentos en la llamada de la función son los que se utilizarán para calcular la función en línea que constituye el cuerpo de la función. Una función creada por el usuario se llama citando su nombre proporcionando a continuación, y entre paréntesis, los valores de los argumentos de la misma. Si la función no tiene argumentos no es necesario incluir los paréntesis en la llamada a la función. Es importante tener en cuenta que todos los argumentos de una función se pasan por valor. Esto significa que en el momento de la llamada a la función, se evalúan los parámetros proporcionados y el valor se sustituye por los argumentos en la definición de la función. Los argumentos de una función deben ser siempre variables simples, no pueden ser variables de tipo array. Veamos algunos ejemplos de definición de funciones Ejemplo 1: PiReal: Function ( ) Return Pi/10000; Es una función muy sencilla, no tiene argumentos y la función en línea que constituye su cuerpo, se limita devolver el valor real del número π. La constante Pi esta definida como el número entero 31416, y para obtener el valor real aproximado del número Pi debemos expresarlo como un cociente de enteros. Ejemplo 2: Cuadrado: Function (x) Return x * x; Manual del Usuario PSPS IV 42 Capítulo 6: Definición de Funciones y Macros Esta función se encarga de devolver el cuadrado de una variable. La variable, cuyo cuadrado queremos calcular, se pasa como argumento de la función. Las funciones definidas por el usuario pueden ser utilizadas en la definición de otra función. Pero todas las funciones que se utilizan en una definición deben haber sido definidas con anterioridad. Ejemplo 3: AreaCirculo : Function (Radio) Return PiReal * Cuadrado(Radio); La función AreaCirculo calcula el área de un circulo a partir del radio del mismo Así la sentencia AreaCirculo(3) calcularía el área de un circulo de radio 3. La función usa las dos funciones definidas anteriormente. La palabra clave Locals que puede aparecer en la definición de una función, permite definir variables locales, que solo se pueden usar dentro de la función en línea. Las variables locales son de gran utilidad como variables auxiliares, acumuladores, índices y otras variables temporales. De esta forma no se producen confusiones en las llamadas de funciones anidadas por la utilización de la misma variable global como variable auxiliar en una función llamante y una función llamada. Las variables locales consiguen independizar la función del contexto en el que ha sido definida, facilitando de esta manera la reutilización de las funciones en contextos diferentes. La memoria para las variables locales se asigna en el momento de ejecutar la función, y por tanto, el valor de una variable local desaparece al terminar la ejecución de la función que contiene su declaración. Solo se pueden declarar variables locales tipo simple, no se pueden definir variables locales de tipo array, ni Stat. Las variables locales se inicializan a cero. Las variables locales se inicializan a cero al llamar a la función y oscurecen cualquier otra declaración de la variable con el mismo nombre que exista en el contexto en el que esta siendo utilizada la función. Veamos que quiere decir esto en el siguiente ejemplo Ejemplo 4: Supongamos que queremos definir una función que calcule una solución de la ecuación de segundo grado Una forma de hacerlo seria Manual del Usuario PSPS IV 43 Capítulo 6: Definición de Funciones y Macros Solución: Function(a,b,c) Locals disc; Begin disc = b*b - 4*a*c, If disc > 0 Then Return (-b+sqrt(disc))/2*a Else return -infinity End; Donde la variable local disc se encarga de guardar el valor del discriminante de la función. Supongamos que ahora llamamos a la función desde un contexto en el que también esta declarada una variable global llamada "disc", de la siguiente manera y = solución(3,2,1) En este caso todo funcionara correctamente porque al llamar a la función Solución, la variable local disc, oscurece el valor de la variable global, y la as ignación que realiza la función afectará únicamente a la variable local, no a la variable global. El desastre amenazaría si no se hubiera definido una variable local, porque la asignación interna a la función, modificaría la variable global. Como pasar un array a una función. Hemos visto que los argumentos de una función solo pueden ser variables simples, pero puede haber situaciones en las que nos interese que las funciones utilicen elementos de una variable de tipo array. Para utilizar un array en una función debemos pasar como argumento la dirección de memoria del primer elemento del array. Esto lo podemos hacer de dos maneras: utilizando Arrays Virtuales (VArrays) o bien mediante la aritmética de direcciones. Ejemplo 5: Arrays Virtuales. Supongamos que queremos calcular la media de los elementos de un vector numérico. Para ello definimos una función de dos argumentos. El primer argumento de la función será la dirección de memoria del vector, y el segundo argumento será el tamaño del vector. Suponemos que en el contexto en el que esta definida la función, se ha declarado, un VArray de nombre ‘Vector’. Promedio: Function(dirarray, Num) Locals i, Auxsuma; Begin Auxsuma = 0, Vector = dirarray, For i=1 To Num do Auxsuma=Auxsuma+Vector[i], Return Auxsuma/Num End; Manual del Usuario PSPS IV 44 Capítulo 6: Definición de Funciones y Macros La función asigna al VArray Vector la dirección de memoria que se pasa como primer argumento de la función. A partir de este momento podemos acceder a cada una de los componentes del vector en la forma habitual1 . Por supuesto, vale más que la dirección dirarray corresponda a la dirección de un vector, porque si no se machacaría el contenido de la memoria en las número siguientes posiciones a partir de esa dirección. Este procedimiento tiene un inconveniente, y es que requie re la definición por parte del usuario de una variable global de tipo VArray. Para hacer la función completamente autocontenida, e independiente del contexto en el que está definida, podemos utilizar la aritmética de direcciones como se muestra en el siguiente ejemplo Ejemplo 6: Aritmética de Direcciones. Promedio: Function(diraray, Num) Locals i, Auxsuma; Begin Auxsuma = 0, For i=1 To Num Do Auxsuma=Auxsuma+^(dirarray)[i], Return Auxsuma/Num End; La función espera la dirección del vector, que se le debe pasar como argumento. El operador ^, seguido de una dirección de memoria, permite el acceso al contenido de esa dirección de memoria. Por tanto, su uso permitirá acceder a los elementos del vector. La sintaxis para acceder a los elementos del vector debe respetarse escrupulosamente. No es lo mismo ^dirarray[i], que ^(diararray)[i]. En el primer caso se devolverá el valor de la variable cuya dirección este contenida en dirarray[i]. En el segundo caso, se devuelve el elemento i-esimo del vector deseado. En los ejemplos que hemos visto hasta ahora, las funciones devolvían un único valor, mediante la sentencia Return. El uso de la aritmética de direcciones nos permitirá devolver varios valores. Como devolver valores por medio de los argumentos de la función. Para devolver un valor por medio de los argumentos de una función debemos pasar la dirección de la variable a modificar, como argumento de la función. Después, mediante la aritmética de direcciones, podemos acceder a esta variable y escribir sobre ella. 1 Recordamos que los Arrays Virtuales no tienen asignado un espacio de memoria permanente y por eso es necesario asignarles una dirección de memoria antes de utilizar una variable de este tipo. Manual del Usuario PSPS IV 45 Capítulo 6: Definición de Funciones y Macros Ejemplo 7: Supongamos que queremos definir una función que cambie de coordenadas polares a cartesianas. Esta función debe devolver dos valores x e y, calculados a partir del radio r y del ángulo alfa. Como la función no puede devolver un array, y no es posible devolver como valor de la función ambos valores, podemos pasar la dirección de la variable ‘Y’ como argumento de la función y modificar su valor mediante el operador ^ desde dentro de la función. En este caso, el valor de la variable X se devuelve mediante la sentencia Return. Polar:Function(r,alfa,dirY) Begin ^dirY = r*sin(alfa), Return r*cos(alfa) End; Otra forma es pasar a la función, como argumentos, las direcciones de ambos resultados y devolver mediante la sentencia Return un valor que indique si se ha tenido éxito o no. En nuestro caso, elegimos pasar la dirección de un vector. La función modifica entonces los elementos del vector, mediante el uso del operador ^. Polar:Function(r,alfa,dirxy) Begin ^(dirxy)[1] = r*cos(alfa), ^(dirxy)[2] = r*sin(alfa), Return True End; Todos los procedimientos de esta sección son muy delicados y deben usarse con extrema prudencia. No hay forma de controlar el uso del operador ^, por lo que cualquier posición de memoria está accesible al incauto, tanto en lectura como, y esto es lo malo, en escritura. Toda la carga de la exactitud del proceso recae sobre el usuario, ya que el compilador puede hacer muy poco para comprobar el uso de las direcciones. Si se comete un error en el cálculo de una dirección, la función puede escribir en zonas imprevistas de la memoria, dando lugar a errores, que hacen muy difícil poner el programa a punto. Funciones Predefinidas Hay un cierto numero de funciones definidas implícitamente en el PSPS IV que pueden utilizarse libremente en el cálculo de expresiones, para ello basta citar su nombre y a continuación entre paréntesis los argumentos de la función. Es importante recordar que las funciones se ‘llaman por valor’, lo que implica que los argumentos se evalúan antes de llamar a la Manual del Usuario PSPS IV 46 Capítulo 6: Definición de Funciones y Macros función. De esta forma a la función se le proporcionan directamente los valores numéricos de los argumentos, en el caso de que vengan dados por expresiones Pspal. A continuación describiremos los distintos tipos de funciones que el sistema tiene predefinidos. Funciones para la generación de números aleatorios. Tabla 1. Funciones para la Generación de Números Aleatorios. Función Argumentos Descripción --- Proporciona un numero real al azar entre 0 y 100. (minVal, maxVal) Proporciona un numero real extraído al azar en el intervalo dado por minVal y maxVal - 1. (mean, number) Proporciona un valor aleatorio real extraído de una distribución Erlang. El primer argumento indica la media de la distribución y el segundo el numero de variables Exponenciales que se suman para dar lugar a la Erlang2. (mean) Proporciona un valor aleatorio real extraído de una distribución Exponencial de media el argumento de la función. Normal (media, sigma) Proporciona un valor real extraído de una distribución Normal de media el primer argumento y desviación tipo el segundo argumento. Uniform (minVal, maxVal) Proporciona un valor real muestreado de una distribución Uniforme en el rango dado por los argumentos de la función. LNormal (a, b) Proporciona una muestra de una distribución Logarítmico-Normal de parámetros (a, b). (alfa, beta) Proporciona una muestra de una distribución Beta concentrada en el intervalo [0, 1]. Los argumentos de la función son los parámetros de la distribución Beta. Rand Random Erlang Exponential Beta 2 Un valor del segundo argumento igual a 1 proporciona muestras de una distribución Exponencial. Otros valores van dando distribuciones cada vez mas simétricas y parecidas a la distribución Normal. Manual del Usuario PSPS IV 47 Capítulo 6: Definición de Funciones y Macros Funciones Matemáticas Tabla 2. Funciones Matemáticas. Función Argumentos Descripción (x) Logaritmo Neperiano: obtiene el logaritmo natural y devuelve su valor como un numero real. (x) Exponencial: devuelve ex como un real. Sin ( x )3 Seno: devuelve el seno del argumento como un número real. Cos ( x )4 Coseno: devuelve el coseno del argumento como un número real. Sqrt (x) Raíz Cuadrada : calcula la raíz cuadrada de su argumento y la devuelve como un valor real. Abs (x) Valor Absoluto: devuelve el valor absoluto de su argumento. Int (x) Parte Entera: trunca el valor del argumento x a un entero. Inc (x) Incremento: incrementa el valor del argumento en una unidad. Dec (x) Decremento: disminuye el valor del argumento en una unidad. Mod (x, n) Modulo: redondea los argumentos x y n, a dos enteros (a y b) y luego devuelve a modulo b, o lo que es lo mismo el resto de la división entera a/b como un entero. Count ( x )5 Contador: devuelve números consecutivos obtenidos de la stream x. Ln Exp Sort (&Array, NumElemts, RecordLength, KeyPosition) Ordenar : ordena el array cuya dirección se indica en el primer argumento, según la columna indicada en el ultimo argumento en orden creciente. El segundo argumento indica el numero de filas del array a ordenar y el tercer argumento el numero de columnas. 3 El argumento debe venir expresado en radianes. El argumento debe venir expresado en radianes. 5 Este argumento debe ser una constante menor que MaxFa. MaxFa es una constante interna del sistema, con valor igual a 200, que define el número máximo de Facilities. 4 Manual del Usuario PSPS IV 48 Capítulo 6: Definición de Funciones y Macros Cond (Condición, IfValor, ElseValor) Condicional: Implementa una expresión condicional en dos vías. Si el primer argumento de la función es distinto de cero, devuelve el valor del segundo argumento, IfValor. Si el segundo argumento es cero, devuelve el valor del tercer argumento, ElseValor. Max (x1, …, x n) Máximo: devuelve el valor máximo entre los valores de los argumentos suministrados. ArgMax (x1, …, xn) Argumento Máximo: devuelve el numero del argumento con valor máximo entre todos los argumentos suministrados. Min (x1, …, xn) Mínimo: devuelve el valor mínimo entre los valores de los argumentos suministrados. ArgMin (x1, …, xn) Argumento Mínimo: devuelve el numero del argumento con valor mínimo entre todos los argumentos suministrados. Choice (x, a 1, …, an) Elegir: devuelve el valor del x-esimo argumento de la lista a 1, …, a n. Funciones Estadísticas. Estas funciones son de gran utilidad para la construcción de informes finales, ya que nos permiten acceder a las estadísticas, que el sistema mantiene de forma automática, sobre los diferentes elementos de la simulación como procesadores, o Switches. Manual del Usuario PSPS IV 49 Capítulo 6: Definición de Funciones y Macros Tabla 3. Funciones Estadísticas. Función Argumentos Descripción STATBL (n, nStat)6 Accede a las estadísticas del n-esimo bloque. STATFAC (n, nStat) Accede a las estadísticas del procesador número n. STATQ (n, nStat) Accede a las estadísticas del procesador que representa una cola ante el procesador número n. STATSW (n, nStat) Accede a las estadísticas del Switch número n. STATAB (n, nStat) Acced e a las estadísticas del Histograma número n. STATVAR (dirección, nStat) Accede a las estadísticas de las variables definidas como Stat. El primer argumento de la función debe ser la dirección de memoria de una variable estadística. Estas estadísticas las mantiene el sistema de forma automática y pueden ser consultadas en cualquier momento de la simulación mediante la opción Display de la barra de menús de la Ventana Principal del PSPS IV. Función de Gantt. Bar(Numero diagrama, Fila, Tinicial, Tfinal, Color7). Esta función se encarga de dibujar una barra en el diagrama de Gantt indicado por el primer argumento, en la fila indicada por el segundo argumento de la función. Las filas de un diagrama de Gantt se empiezan a numerar a partir de la fila cero. La barra se extiende desde el tiempo ‘Tinicial’ hasta el tiempo ‘Tfinal’. La barra se colorea con el color indicado en el último argumento de la función. Pueden conseguirse efectos de superposición de barras organizándolas en secuencia. Si dos barras se superponen, la que se pinto en último lugar queda delante de la pintada anteriormente. Se pueden conseguir otros efectos interesantes utilizando filas fraccionarias. De hecho pintar en un diagrama de Gantt no esta limitado a alinear las barras en filas. El parámetro fila es la coordenada vertical del vértice superior izquierdo de la barra, por lo que una barra se puede apoyar en cualquier punto del diagrama. En cualquier caso, la altura de la barra siempre es la misma, e igual a 1. 6 Los posibles valores que puede tomar el argumento nStat vienen dados por las constantes estadísticas que se definen en el Capítulo 3. 7 Color: este argumento se define utilizando cualquiera de las constantes de color predefinidas del PSPS IV. Manual del Usuario PSPS IV 50 Capítulo 6: Definición de Funciones y Macros Funciones de Dibujo. Las funciones de Dibujo nos permiten características de un gráfico en el PSPS IV. definir las distintas • FDrawXY(numero gráfico, numero serie, x,y). Es la función fundamental para dibujar un punto en un gráfico. En el gráfico indicado, para la serie indicada dibuja el punto (x,y) de acuerdo con las opciones del gráfico. Las opciones del gráfico se indican por medio de la función FDrawCont. • FDrawCont(numero gráfico, constante de función, ...). El formato de esta función es variable dependiendo de la constante de funcionalidad que se especifica. En general esta función especifica una característica del gráfico indicado por el primer argumento de la función. El formato de la función depende de la constante utilizada como segundo argumento. Las constantes que pueden ser utilizadas se definen con detalle en el Capítulo 3 del manual. Los formatos de la función según la constante utilizada se muestran en la siguiente tabla: Tabla 4. Formatos de la función FDrawCont ( ) en función de la constante utilizada. Formato Constantes Sin argumentos adicionales FDrawCont(Num Graf, Constant) GCLRALL, Con argumentos adicionales • Propiedades Serie FDrawCont(NumGraf, Constant, Num Series8) GSERCLR GSERORDER, GSERUNORDER GSERNODOTS, GSERSOLID, GSERNOLINES, GSTEPRIGHT GSETPLEFT • Strings de Títulos FDrawCont(Num Graf, Constant, String) GTITLE, GXTITLE, GYTITLE • Asignación de Colores FDrawCont(Num Graf, Constant, Color9) GBCOLOR FDrawCont(NumGraf, Constant, Num Serie, Color9) GSERCOLOR GSERDCOLOR 8 Números de las series del gráfico que poseen la propiedad indicada separadas por comas. 9 El Color puede indicarse mediante las constantes de color definidas en la siguiente sección o mediante la función Color ( ) o ColorNum( ). Manual del Usuario PSPS IV 51 Capítulo 6: Definición de Funciones y Macros • Puesta al día de un gráfico FDrawCont(Num Graf, Constant, Val Logico) GUPDATE • Definición tamaño gráfico FDrawCont(Num Graf, Constant, X 0, Y0, X1, Y 1) GSIZE • HDrawCont(numeroHistograma,constante, otros argumentos) Esta función nos permite especificar diferentes características de un histograma. El formato de esta función depende de la constante utilizada. Los formatos se muestran en la siguiente tabla: Tabla 5. Formatos de la función HDrawCont ( ) en función de la constante utilizada. Formato Constantes Sin argumentos adicionales HDrawCont(Num Histo, Constant) GCLRALL HdrawCont(NumHisto, Constant, X 0,X1,numslots, False) HDrawCont(NumHisto, Constant, Num) GSIZE HDrawCont(NumHisto, Constant, Color) GBCOLOR HDrawCont(Num Histo, Constant, String) GTITLE, GXTITLE, GYTITLE Con argumentos adicionales • Tamaño • Numero de Barras Color de fondo • GBARS • Strings de Títulos • Color(contenidoRojo, contenidoVerde, contenidoAzul). Esta función define un color combinando las cantidades de Rojo, Verde y Azul, que se indican en los argumentos de la función. Los valores de las coordenadas oscilan entre 0 y 255. El valor 0 representa la ausencia del color indicado, y el valor 255 la presencia del color a nivel de saturación. La comp osición es aditiva, por lo que Color(255, 255, 255) == CWhite (el color blanco) y Color(0,0,0) == CBlack (color negro) • ColorNum(numero). Esta función asigna el color indicado por el parámetro argumento de la función. Funciones de Input/Output. • Gotoxy(nTabla, ncol,nfila) Función de tres argumentos que nos permite posicionarnos en una tabla de resultados. La función selecciona de la tabla, nTabla la celda cuya columna es Manual del Usuario PSPS IV 52 Capítulo 6: Definición de Funciones y Macros ncol y cuyo número de fila es nfila. Las tablas empiezan en la fila y columna 0, normalmente estas columnas se reservan para los títulos. Generalmente este es el paso previo a editar esa celda. El valor que devuelve esta función es irrelevante. • FWrite(s1,...,sn) Función de un número variable de argumentos. La función provoca la escritura de sus argumentos en el dispositivo de salida. Los argumentos se interpretan como números, y deben ser de este tipo. Por defecto, el dispositivo de salida es el listener. Se puede reasignar el dispositivo de salida en el cuadro de diálogo del menú Run/Options. Esta función solo se incluye por compatibilidad. Su funcionalidad ha quedado superada por las expresiones del lenguaje Write, WriteStr y PrintR. • Format(StringFormato, x1, x2...) Función con un número variable de argumentos. Devuelve una String que es el resultado de aplicar las instrucciones de formato en la string StrinFormato, a la lista de argumentos que la siguen. Con esta función es posible especificar un formato de salida de datos y crear Strings para presentar datos de manera uniforme y coherente. Su funcionamiento y los parámetros a emplear son parecidos a los que se emplean en el lenguaje Pascal. Esta función excluye únicamente la posibilidad de convertir en una String las direcciones de punteros, puesto que es una adaptación al entorno PSPS de la función que emplea en lenguaje Pascal. • MakeStr(StringFormato, x 1, x2...) Función con un número variable de argumentos. Similar a la función Format, la única diferencia es que esta función no reutiliza la string de forma definida, se crea una nueva cada vez que hacemos una llamada a la función. En ambas funciones los argumentos x1 ,x2 ,... son Strings o números que van a escribirse de acuerdo con las instrucciones contenidas en la String StringFormato. El argumento StringFormato aparece siempre entre comillas dobles y contiene dos tipos de objetos: caracteres normales y especificadores de formato. Los caracteres normales se copian tal cual en la String resultado y los especificadores de formato utilizan la lista de argumentos x1 ,x2 ,...y los incluyen en la String resultado siguiendo las especificaciones. Un especificador de formato tiene la siguiente estructura % [índice :] [- ] [anchura] [.precisión] tipo donde [índice :]: argumento opcional que especifica el índice; Manual del Usuario PSPS IV 53 Capítulo 6: Definición de Funciones y Macros [-] : indicador opcional de justificación a la izquierda; [anchura] : argumento opcional que especifica la anchura del campo; [. precisión] : argumento opcional que especifica la precisión; Tipo: un argumento obligatorio que indica el tipo. En la siguiente tabla se resumen los posibles valores del argumento Tipo. Los caracteres de conversión que aparecen en la tabla pueden especificarse en mayúsculas o en minúsculas; ambos producen los mismos resultados. Tabla 6. Especificadores de Formato Tipo Argumento Descripción d Decimal Valor entero El valor se convierte a una String de dígitos decimales. Si la StringFormato contiene un especificador de precisión, indica que la String resultante debe contener por lo menos el número especificado de dígitos; si el valor tiene menos dígitos, la String resultante se rellena a la izquierda con ceros. e Cientifico Valor real El valor se convierte a una String de la forma -d.ddd...E+ddd. La string resultante empieza con un signo menos si el número es negativo. Un dígito precede siempre al punto decimal. El número total de dígitos en la String resultante (incluyendo el que esta antes del punto decimal) viene dado por el especificador de precisión. Si éste no está presente, se asume una precisión por defecto de 15 dígitos. La E, el carácter exponente en la String resultante, es seguido siempre por un signo más o menos y, al menos, tres dígitos. f Fijo Valor real El valor se convierte a una String de la forma -ddd.ddd... La String resultante empieza con un signo menos si el número es negativo. El número de dígitos después del punto decimal viene dado por el especificador de precisión en la StringFormato. Si no está presente, se toma una precisión por defecto de 2 dígitos decimales. g General Valor real El valor se convierte a la String decimal más corta posible usando ambos formatos, el formato científico y el fijo. El número de dígitos significativos en la String resultante viene dado por la especificador de precisión de la String de Formato. Si no está presente se asume una precisión de 15 dígitos. Los ceros no significativos se eliminan de la String resultante, y el punto decimal aparece únicamente si es necesario. La String Manual del Usuario PSPS IV 54 Capítulo 6: Definición de Funciones y Macros resultante emplea formato fijo si el número de dígitos a la izquierda del punto decimal es menor o igual que la precisión especificada y si el valor es mayor igual que 0,00001. En cualquier otro caso la String resultante usa el formato científico. n Numero Valor real El valor se convierte a una String de la forma -d,ddd,ddd.ddd... Este formato es similar al de tipo fijo salvo porque incluye separadores de millares. m Money Valor real El valor se convierte a una String que representa una cantidad de dinero. La conversión y representación de las cantidades viene controlada por el sistema anfitrión. Si la String de formato incluye un especificador de precisión, este será el número de decimales que se empleen, si no, se tomará el valor que tenga por defecto el sistema String Si la StrinFormato incluye un especificador de precisión se usará como tamaño máximo de la String resultante. Si el argumento es una String mayor que el tamaño máximo, se truncará al tamaño máximo. Valor entero El valor se convierte a una String de dígitos hexadecimales. Si la StringFormato contiene un especificador de precisión, indica que la String resultante debe contener por lo menos el número especificado de dígitos; si el valor tiene menos dígitos, la String resultante se completa con ceros a la izquierda s String x Hexadecimal Ejemplos: Format ("El día %d de Abril", 10); Dará como resultado "El día 10 de Abril" Format ("Es %e veces más rico" ,100000); Dará como resultado "Es 1E+005 veces más rico" Format ("Es %.3f veces más viejo" ,1/1000); Dará como resultado "Es 0.001 veces más viejo" Format ("Tiene %g productos", 1000); Dará como resultado "Tiene 1000 productos" Format ("Tiene %n razones" ,10000); Dará como resultado "Tiene 10.000 razones" Format ("Tengo unas %m", 10000); Dará como resultado "Tengo unas 10,000 Ptas" Format ("Su %s era %s", "nombre", resultado "Su nombre era Pablo" Manual del Usuario PSPS IV "Pablo"); Dará como 55 Capítulo 6: Definición de Funciones y Macros Funciones para la elaboración de Estadísticas Tabla 7. Funciones para la elaboración de Estadísticas. Función FTabulate FTab HFrequency Argumentos (nHisto, Val) Descripción Esta función obtiene estadísticas de una muestra discreta. En el Histograma de Frecuencias que calcula se obtienen las frecuencias para cada intervalo en porcentaje de ocurrencias. (nHisto, Val) Esta función considera las observaciones como parte de una trayectoria aleatoria en el tiempo y obtiene las estadísticas de esta trayectoria. En el Histograma que define se muestra el porcentaje de tiempo durante el que la variable ha tenido un valor dentro del intervalo correspondiente del histograma. (nHisto, &Array) Esta función guarda las frecuencias del Histograma nHisto en el array de dirección &Array. Funciones para la definición de una distribución de Probabilidad Tabla 8. Funciones para la definición de una distribución de Probabilidad. Función Argumentos Descripción FDistribution (NumFun, Num, &xArray, &fArray) Esta función permite definir una distribución de probabilidad a partir de las probabilidades de Num puntos. El primer argumento identifica la función de distribución definida, el segundo argumento indica el número de puntos que definen la distribución, el tercero la dirección de memoria del array en el que se almacenan los puntos y el cuarto argumento la dirección de memoria del array que guarda las probabilidades de los números. (n) Devuelve el valor muestral de la nesima distribución definida por el usuario mediante la función FDistribution o el bloque DISTRIBUTION de la sección Data. Sample Manual del Usuario PSPS IV 56 Capítulo 6: Definición de Funciones y Macros Funciones para el tratamiento de Transacciones. Tabla 9. Funciones para el tratamiento de Transacciones. Función Argumentos Descripción (Num Bl) Crea una copia de la transacción en curso y la envía al bloque indicado por el único argumento de la función. (NextBl,numAt,At1,..., Atn) Crea una transacción cuyos atributo a partir del atributo número numAt vienen dados por los valores At1, ..., Atn y la envía al bloque NextBl. La función devuelve la direccion de la transaccion. TransFisrt (FACLTY, Num, &ArrayAt, LastAt) Devuelve la dirección de memoria de la primera transacción que se encuentra en el procesador numero Num y asigna al Array ArrayAt los valores de los LastAt primeros atributos de la transacción. Si la lista de transacciones esta vacía la función devuelve el valor cero. TransNext (&Trans, &ArrayAt, LastAt) Devuelve la dirección de memoria de la transacción siguiente a la transacción cuya dirección de memoria viene dada en el primer argumento de la función y asigna al Array ArrayAt los LasAt primeros atributos de la transacción. TransJoin (FACLTY, NumFa, &Trans) Selecciona la transacción con dirección de memoria &Trans y la une a las transacciones del procesador numero NumFa. TransFree (&Trans) Libera el espacio de memoria que ocupaba la transacción con dirección &Trans (FACLTY, NumFa, &Trans) Elimina la transacción con dirección de memoria &Trans del procesador indicado por el segundo argumento de la función. La función devuelve la dirección de memoria de la transacción eliminada. TransCopy TransCreate TransRemove Manual del Usuario PSPS IV 57 Capítulo 6: Definición de Funciones y Macros Otras Funciones. Tabla 10. Otras Funciones. Función FSwitch Dt Argumentos Descripción (Numero de Switch, Estado) Permite modificar el estado de un Switch. El primer argumento indica el numero del Switch a modificar, y el segundo argumento el estado al que debe pasar el Switch. --- Devuelve el intervalo de integración definido por el bloque STEP en la sección Data. Define un cuadro de diálogo. El primer argumento es el mensaje que queremos que aparezca y el segundo argumento los botones que queremos definir en el cuadro de diálogo. Message (“Mensaje”, Botones)10 AtTestTr (i) Devuelve el valor del Atributo i-ésimo de la transacción que esta siendo testada en ese momento. Se utiliza en el bloque GRAB. IsStatVar (&Variable) Comprueba si la variable a la que apunta la dirección de memoria dada como argumento de la función ha sido definida como una variable de tipo Stat. (nTabla) Lee de la Tabla número n el valor de la celda en la que nos encontramos. RealTime --- Refresh --- Esta función almacena la hora del Reloj Físico del Ordenador. TEvent --- Devuelve el instante de tiempo en el que se producirá el próximo evento. (Argument) Permite modificar el funcionamiento del Reloj de simulación. Si el valor del argumento es True, el Reloj de simulación es independiente del Reloj Físico del ordenador. Si el valor del argumento es False, entonces el tiempo de simulación pasara de forma física. Una unidad de tiempo del modelo coincidirá con un segundo del Reloj Físico del Ordenador. FRead TimeMode Se encarga de poner al día los displays abiertos, que reflejaran el verdadero estado de la simulación. 10 La constante YESNO define dos botones, ‘Yes’ y ‘No’, en un cuadro de dialogo. La constante YESNOOK define tres botones, Yes, No y OK, en un cuadro de dialogo. Manual del Usuario PSPS IV 58 Capítulo 6: Definición de Funciones y Macros Definición de Macros. Al igual que las funciones la definición de una Macro debe aparecer en la sección Macros. La estructura general de la definición de una macro es: : Macro({argumentos}) End; Una macro permite definir un nuevo tipo de bloque PSPS. Esta definición puede contener argumentos cuyos valores se determinan en el momento de la compilación. Estos valores se reemplazaran en la macro literalmente, en un proceso conocido como expansión de la macro. La expansión es simplemente la sustitución literal de los valores por los argumentos, seguida de la eliminación de todo aquello que no esta contenido dentro del segmento de código expandido. La llamada a la macro es diferente de la llamada a una función. Una macro debe aparecer aislada en una sentencia PSPS, como cualquier bloque normal. Por tanto se llama como un bloque, citando su nombre y a continuación los argumentos, separados por comas, en la forma arg1,arg2,....,argn; En la definición de una Macro debemos tener en cuenta las siguiente reglas, que son cruciales para evitar efectos secundarios: 1. Todas las bifurcaciones dentro de una macro deben hacerse usando el formato de bifurcación relativa: Cb + o * + . No debe usarse un Label o etiqueta, a no ser que la macro se use una sola vez. En caso contrario, si la macro usa (y se expande) más de una vez, se tendría un mismo Label definido varias veces y esto daría lugar a un error de compilación. 2. Si se necesitan variables auxiliares, hay que extremar el cuidado al usar variables globales para este propósito. La razón es que el nombre de la variable será el mismo para todas las expansiones de la macro, por lo que puede haber problemas de solapamiento, especialmente cuando una macro se interrumpe esperando un evento. Como no se pueden declarar variables locales en una macro, una forma de resolver el problema es usar funciones para todos los cálculos que requieran variables auxiliares, y declarar las variables auxiliares en la sentencia Locals de las funciones definidas. Otra forma es usar los atributos de la transacción para contener las variables auxiliares necesarias. Manual del Usuario PSPS IV 59 CAPITULO 7: El Lenguaje de Bloques. Inicializando el PSPS. § § § § § § § § § § § Manual del Usuario PSPS IV Sentencias de Definición de Tamaño Sentencias de Objetos Sentencias de Duración de la simulación Sentencias de Inicialización de las variables Sentencias de Debugging Sentenc ias de Mando de la simulación Sentencias de Inicialización por programa Sentencias de Output Sentencias de Simulación Continua Sentencias de Generación de Números Aleatorios Sentencias de Definición de Distribuciones Capítulo 7: El Lenguaje de Bloques. Inicializando el PSPS Las sentencias de inicialización de la sección Data nos permiten definir las características del contexto en el que se va a realizar la simulación. Todos los bloques definidos en esta sección se ejecutaran una sola vez antes de empezar la simulación. Sentencias de definición de tamaño. Bloque Data FACILITY Formato: FACILITY ; Descripción: Indica el número de procesador máximo que se va a usar en la simulación. El número máximo que se puede asignar a un procesador es 50. Es importante no usar números de procesadores demasiado altos, puesto que el sistema mantiene internamente espacio y datos para todos los procesadores con número menor que el máximo especificado. Por tanto, si se declara FACILITY 50, el sistema mantendrá listas para 50 procesadores, haciendo el proceso de la simulación algo más lento. Supongamos que en un modelo utilizamos dos procesadores. Uno es el número 1 y el otro el número 23, entonces debemos indicarlo en la sección Data mediante la sentencia FACILITY 23. Bloque Data STOCK Formato: STOCK [Número de procesador] 1 ; Descripción: El bloque STOCK indica que el contenido de los procesadores listados en el único parámetro del Bloque puede ser negativo. Si este bloque no se incluye en la sección Data y el contenido de algún procesador del modelo se vuelve negativo a lo largo de la simulación, el sistema enviará un mensaje de error y se detendrá la simulación. 1 Parámetro compuesto es o bien un parámetro simple (es decir, una SPV), o una lista de SPV's separadas por comas e incluidas en paréntesis cuadrados. Por ejemplo: [Fc[1], At[2] * At[1]] es un parámetro compuesto. Manual del Usuario PSPS IV 60 Capítulo 7: El Lenguaje de Bloques. Inicializando el PSPS Ejemplos: STOCK 1; Esta sentencia indica que el contenido del procesador número 1 puede tomar un valor negativo. STOCK [1,2]; Esta sentencia indica que el contenido de los procesadores número 1 y número 2 pueden tomar un valor negativo. Obsérvese que el uso de los paréntesis cuadrados [ ] en el parámetro del bloque solo es necesario cuando queremos que más de un procesador admita un contenido negativo. Bloque Data SWITCH Formato: SWITCH ; Descripción: Este bloque es análogo a al bloque FACILITY, pero para los indicadores de condiciones o switches. El número máximo que se puede asignar a un switch en la versión standard es 50. Bloque Data HISTO Formato: HISTO , , , , ; Descripción: El bloque HISTO requiere tres parámetros obligatorios, dados por sentencias SPV's. Los dos últimos son opcionales. Los Histogramas del PSPS tienen por defecto 10 intervalos y las 30 primeras observaciones en llegar a un histograma constituyen una muestra que se utiliza, al llegar las 31, para calcular la estructura de los intervalos del mismo. El primer intervalo sie mpre se reserva para las observaciones desde menos infinito al valor inicial del segundo intervalo, y lo mismo para el último, que va desde el valor final hasta más infinito. Para la definición externa de un histograma utilizaremos el bloque HISTO. Manual del Usuario PSPS IV 61 Capítulo 7: El Lenguaje de Bloques. Inicializando el PSPS Parámetros: : indica el número del histograma que queremos definir. Debe estar comprendido entre 1 y 10. : es el valor del primer punto del segundo intervalo. : es el valor izquierdo del último intervalo. : parámetro opcional que indica el número de intervalos del Histograma. Si se suprime se toman 10 intervalos. : parámetro opcional cuyo valor por defecto es False. Si es igual a True, el histograma se representara en forma acumulada. Si es False se representa de la forma habitual sin acumular. El intervalo del histograma se puede calcular por la expresión: Intervalo = (Valor final - Valor Inicial) / (número intervalos - 2) Los intervalos de un histograma son siempre abie rtos por la derecha. Ejemplo: Histo 1, 20,100; siguiente estructura inicializará el histograma número 1 con la Intervalo No 1 2 3 4 5 6 7 8 9 10 De: - inf. 20 30 40 50 60 70 80 90 100 A: ( < ) 20 30 40 50 60 70 80 90 100 + inf. Bloque Data GRAPHS Formato: GRAPHS ; Descripción: Este bloque se emplea para indicar el número máximo de gráficos que se van a dibujar y dimensionar en el sistema. No es necesario Manual del Usuario PSPS IV 62 Capítulo 7: El Lenguaje de Bloques. Inicializando el PSPS indicar de antemano el número de series que se van a dibujar en cada gráfico. Ejemplo: GRAPHS 5; Inicializa el sistema para poder dibujar 5 gráficos. Sentencias de objetos. Bloque Data TABLE Formato: TABLE , , ; de filas>,: identificador de la tabla. : indica el número de filas de la tabla. : indica el nú mero de columnas de la tabla. : parámetro compuesto que debe contener una lista de strings. Las strings serán utilizadas como nombres de las columnas, y asignadas a estas en forma secuencial empezando por la primera columna, que es la número cero. Si hay menos strings que columnas, las strings se usaran hasta agotarlos. El resto de los encabezamientos se dejaran vacíos. Si hay más strings que columnas, solo se usaran las necesarias ignorando las restantes. Ejemplo: TABLE 1, 5, 2, ["Valor", "Porcentaje"]; Crea una tabla con cinco filas y dos columnas, la primera columna con el título de Valor y la segunda con el título Porcentaje. Manual del Usuario PSPS IV 63 Capítulo 7: El Lenguaje de Bloques. Inicializando el PSPS TABLE 1, 5, 2, ["Valor"]; Crea una tabla con cinco filas y dos columnas y solo aparecerá el titulo de la primera columna. El titulo de la segunda columna se deja en blanco. Bloque Data SCREEN Formato: SCREEN , Left, Top, Width, Height; Descripción: Crea una ventana que puede usarse para presentar información multimedia o imágenes de bits. Para ello deben usarse los bloques DISPLAY o PLAY, en la sección System. La bloque define las dimensiones y la posición de la ventana, en coordenadas de pantalla. En las coordenadas de pantalla la esquina superior izquierda es el punto (0,0). Todos los datos se dan píxeles. Parámetros: : identificador de la pantalla. Left, Top: son las coordenadas (x, y) de la esquina superior izquierda de la ventana creada. Width, Height : son las dimensiones de la ventana en horizontal (x) y vertical(y). Bloque Data GANTT Formato: GANTT ,,,; Descripción: Define un diagrama de Gantt que luego se completara por medio de llamadas a la función Bar. La numeración de las filas empieza desde la fila cero. El es el momento a partir del cual se empezará a pintar el diagrama. De la misma forma, es el último tiempo que se representará en el diagrama. Manual del Usuario PSPS IV 64 Capítulo 7: El Lenguaje de Bloques. Inicializando el PSPS Sentencias de duración de la simulación. Bloque Data ITEM Formato: ITEM ; Descripción: Este bloque se usa para indicar la longitud de la simulación, en ítems procesados. Cuando la cuenta de todos los ítems terminados, realizada por los bloques TERMINATE, alcance el número de ítems especificado en el parámetro de este bloque, la simulación se detiene. Bloque Data TIME Formato: TIME ; Descripción: Define el tiempo de terminación de la simulación. Cuando el reloj interno de la simulación alcance el valor obtenido al evaluar la SPV se detendrá la simulación. Si no se indica tiempo alguno, es decir no aparece esta bloque, el tiempo de finalización será “infinity”. Sentencias de inicialización de las variables. Bloque Data VARS Formato para variables escalares: Vars = ; Descripción: Este bloque nos permite inicializar las variables que hemos definido en la sección VARIABLES. En ausencia de indicaciones el sistema inicializa a cero todas las variables definidas por el usuario en la sección VARIABLES. Pueden asignarse valores iniciales a variables tanto escalares como arrays. Manual del Usuario PSPS IV 65 Capítulo 7: El Lenguaje de Bloques. Inicializando el PSPS Parámetros: : declarada o implícita. indica el nombre de una variable : es una SPV cuyo resultado se asigna a la variable. Formato para variables array: Vars = \ \; Parámetros: : es el nombre del array (no de uno de sus elementos) : es una lista de SPV's. Se evalúan por orden y el resultado se asigna a los elementos del array en sentido creciente de su índice empezando por el índice 1. Si se deseamos inicializar un elemento concreto de un array debemos usar el formato definido para el caso de variables de tipo escalar. Ejemplos: Supongamos que hemos definido el array Números, de dimensión 5. La siguiente sentencia asigna valores iniciales a sus 4 primeros elementos: Vars Números = \ pi/1000, sqrt(1000), 2, 1\; Así, el array queda inicializado a 3, 31, 2, 1, 0. El último elemento del array será cero ya que el array es de dimensión 5 y en la bloque de inicialización hemos dado únicamente 4 valores. Si queremos inicializar un único elemento del array deberíamos hacerlo de la siguiente manera; Vars Números[2]=4; Así la posición 2 del array Números quedara inicializada con el valor 4 y le resto de los elementos del array serian iguales a cero. Bloque Data RESET Formato: RESET ; Manual del Usuario PSPS IV 66 Capítulo 7: El Lenguaje de Bloques. Inicializando el PSPS Descripción: Se evalúa la SPV y el resultado es el valor del reloj interno para el cual se inicializarán a cero todas las estadísticas. Con el valor adecuado del Tiempo de Inicialización podemos resolver el problema de las condiciones iniciales, inicialmente los sistemas se encuentran vacíos, con las que se inician todas las simulaciones y que dan lugar a un régimen transitorio que afecta a las estadísticas. Las estadísticas inicializadas mediante esta bloque incluyen los datos sobre procesadores, bloques e histogramas. Si no aparece estadísticas. este bloque no se reinicializan nunca las Sentencias de Debugging. Toda sentencia o todo bloque puede comenzar con el prefijo DEBUG , < Sentencia Pspal>; DEBUG Do ; Si esto es así, la sentencia o el bloque solo se incluirá en el código si la constante es True. Si la constante es False se omitirá el código correspondiente. Esta característica proporciona la compilación condicional de sentencias individuales. Usando diferentes constantes se puede dotar de distinta funcionalidad al programa sin inflar el código. Debe enfatizarse que las sentencias o bloques suprimidos son tratadas como comentarios, y que por tanto no pasan a formar parte del código. Ejemplo 1: For i = 1 to 10 do Debug Scod, Write("Mensaje de debugging"),... La sentencia Write se ejecutará solo cuando la variable Scod tenga el valor TRUE. Ejemplo 2: Data DEBUG Scod DO REPORT ON; ............. El bloque REPORT se ejecutará solo si la constante Scod, definida en la sección CONSTANTS del modelo, tiene el valor TRUE. Manual del Usuario PSPS IV 67 Capítulo 7: El Lenguaje de Bloques. Inicializando el PSPS Bloque Data TRACE Formato: TRACE , ; Descripción: Selecciona lo que se va a trazar o dejar de trazar y en que instante de tiempo se realizará cada operación de trazado. Abre un cuadro de diálogo de trazado, idéntico al que se abre al seleccionar el menú Interaction/Trace de la barra de menús de la Ventana Principal del PSPS IV. El cuadro de diálogo permite elegir a partir de qué momento se quiere trazar, o dejar de trazar, que es lo qué queremos trazar y si se quiere que el sistema trace de forma automática, la opción por defecto, o que sea el usuario el que lo haga avanzar manualmente, parándose el sistema cada vez que se va a ejecutar un acontecimiento. Cada opción de la traza muestra una parte del sistema, así: Facilities: Traza el movimiento de entrada y salida transacciones en los procesadores. de Transactions: indica el progreso de cada transacción por el sistema, a medida que se va produciendo la entrada de la transacción en un bloque. Blocks : informa sobre la situación de los bloques en el instante de entrada de una transacción. BasicInterpreter: se traza la máquina virtual PSPS. Todas las evaluaciones de EAGs se realizan en una máquina stack simulada. La traza se limita a las instrucciones del programa principal y no se realiza dentro de las llamadas a funciones. Interpreter: esta es una traza completa, que traza también la ejecución del código de todas las funciones. Listas Transacs: cada vez que se altera una de las listas internas del PSPS se da información sobre el estado de las listas. Es dudoso que el usuario típico de PSPS deba trazar a este nivel. Estos niveles de trazado solo son útiles para diagnosticar la operación del propio PSPS. En cualquier caso debe procederse con moderación con esta característica, ya que la cantidad de Output producida puede ser muy elevada. Manual del Usuario PSPS IV 68 Capítulo 7: El Lenguaje de Bloques. Inicializando el PSPS Bloque Data LOOP Formato: LOOP ; Descripción: El PSPS dispone de un detector que trata de evitar ciclos de transacciones que utilizan tiempo de ordenador sin hacer progresar la simulación (sin adelantar el reloj interno de la simulación). PSPS cuenta el número de bloques que visita una transacción antes de que se produzca una avance del reloj interno. Si este número de bloques es superior a un parámetro dado, el sistema infiere la presencia de un ciclo en el proceso de transacciones. El valor por defecto de este parámetro es 100. En la practica este valor es satisfactorio casi siempre. Pero si el usuario lo desea, puede cambiarlo utilizando esta sentencia. Un valor bajo del parámetro puede provocar la detección de un ciclo inexistente. Un valor alto del parámetro hace que se consuma mucho tiempo de ordenador antes de decidir que se ha entrado en un ciclo. Sentencias de mando de la simulación. Bloque Data REPORT Formato: REPORT ; Descripción: Este bloque detiene la simulación y hace aparecer la ventana de control de la simulación en un instante de reloj definido a priori. Si añadimos la sentencia Report On, en la sección Data, el sistema detendrá la simulación en el instante de tiempo –1. Es decir antes de que comience la simulación. Manual del Usuario PSPS IV 69 Capítulo 7: El Lenguaje de Bloques. Inicializando el PSPS Sentencias de inicialización por programa. Bloque Data INITIAL Formato: INITIAL ; Descripción: Este bloque sirve para realizar cálculos dentro de la sección Data y por lo tanto antes de empezar la simulación propiamente dicha. Parámetros: : es una sentencia que normalmente contendrá una o varias inicializaciones de variables y que realizará determinados cálculos para inicializar estas variables que de otra forma no sería posible inicializar a esos valores. Ejemplo: El bloque INITIAL nos permite inicializar un array de forma secuencial antes de que comience la simulación del modelo. VARIABLES .... Datos Array 100; {Definición de el datos} .... DATA .... INITIAL Begin For i = 0 To 100 Do Datos[i] = i, End; .... SYSTEM .... EndSystem; array Sentencias de Output Bloque Data DUMP Formato: DUMP ; Manual del Usuario PSPS IV 70 Capítulo 7: El Lenguaje de Bloques. Inicializando el PSPS Descripción: Cuando el reloj de la simulación alcanza el , se produce un listado completo del estado del sistema. El output producido tiene diferente extensión y contenido en función de las opciones definidas en el cuadro de dialogo Run/Options de la barra de herramientas. Sentencias de simulación continua Bloque Data STEP Formato: STEP ; Descripción: El bloque fija el incremento de tiempo que se usará para la simulación continua. Cuando se procesen bloques INTEGRATE, el tiempo interno avanzará en intervalos de duración indicada en el bloque STEP. Ejemplo: STEP 1/100; realizará la simulación continua en incrementos de tiempo de 0.01 unidades. Sentencias de Generación de Números Aleatorios. Bloque Data RANDOMIZE Formato: RANDOMIZE ; Descripción: Este bloque sirve para alterar la secuencia de números aleatorios generada por el PSPS según el valor del único parámetro del bloque. Manual del Usuario PSPS IV 71 Capítulo 7: El Lenguaje de Bloques. Inicializando el PSPS Parámetro: : acepta un valor entero que indica diferentes opciones según su valor. TRUE: indica al generador de números aleatorios que debe generar corrientes de números aleatorios independientes, empezando la generación por un valor al azar. Este valor hace que las simulaciones sean irrepetibles, ya que el valor al azar es función del momento de tiempo en que se genera usando para ello el reloj interno del ordenador. ENTERO POSITIVO : genera una corriente de números aleatorios que depende del entero suministrado. En este caso las simulaciones son repetibles. ANTI: esta constante hace que el generador de números aleatorios genere una corriente de números aleatorios idéntica a la generada anteriormente pero usa su complemento a uno. Es decir la nueva corriente de números aleatorios se obtiene restando de uno los números anteriores. Sentencias de Definición de Distribuciones de Probabilidad Bloque Data DISTRIBUTION Formato: DISTRIBUTION , , [xData], [fData]; Descripción: Este bloque define una distribución de probabilidad a partir de las probabilidades de una serie de puntos. La distribución definida es muestreable mediante la función Sample. Parámetros: : identificador de la distribución que vamos a definir : número de puntos que definen la distribución. [xData]: puntos que definen la distribución. Es un parámetro compuesto, que debe tener Npoint elementos. [fData]: probabilidades de los puntos que definen la distribución. Es un parámetro compuesto, que debe tener Npoint elementos. Manual del Usuario PSPS IV 72 CAPITULO 8: El Lenguaje de Bloques. Describiendo el Sistema de Simulación. § § § § § § § § Manual del Usuario PSPS IV Control de Transacciones y avance del reloj de simulación Ocupación de Procesadores y Switches Cálculo y modificación de Variables Definición de una secuencia Elaboración de Estadísticas Input Output y Debugging Bloques Multimedia y Gráficos Simulación Continua Capitulo 8: El Lenguaje de Bloques. Describiendo el Sistema de simulación. La sección SYSTEM es la única obligatoria en todo programa PSPS. Contiene las especificaciones para la simulación en forma de bloques por los que circulan las transacciones. Estructura General de definición de un bloque en PSPS La definición de un bloque PSPS en la Sección System tiene la siguiente forma general: : , ; : el número del bloque es una constante que lo identifica en secuencia. Si el número de bloque se omite se toma el número del bloque igual al del bloque anterior más uno. Si se utiliza un asterisco '*' en vez de un número, también se toma como número de bloque el anterior más uno. Esta última opción permite marcar algunos bloques que interesa destacar sin necesidad de asignar explícitamente un número de bloque. Tanto en el caso de usar un * o una constante deben incluirse los dos puntos. Si se omite el núme ro de bloque deben omitirse los dos puntos a continuación. La omisión del número de bloque permite intercalar fácilmente sentencias en un programa sin necesidad de renumerar los bloques existentes. Tiene sin embargo el inconveniente de que el número de blo que no queda explícito, dificultando a veces la interpretación posterior de los resultados de la simulación. Se recomienda numerar unos cuantos bloques que actúen de hitos en el programa. : es una de las palabras clave que identifican un bloque. Debe figurar siempre. : es una lista de parámetros separados por comas que especifican las características de la acción del bloque. Un parámetro puede ser simple o compuesto, y algunos de los Parámetros de la lista son opcionales. Un parámetro simple es una SPV (Sentencia PSPAL con Valor). Un parámetro compuesto es, o bien un parámetro simple, o una lista de SPV's separadas por comas e incluidas en paréntesis cuadrados. Por ejemplo: [Fc[1],Va[10],At[2]*At[1]] es un parámetro compuesto. Los parámetros compuestos se utilizan en bloques como PRINT, SINCRO o SPLIT. También puede definirse un parámetro compuesto utilizando la dirección de memoria de un array de la siguiente manera: [índice1: índice2: &Array]. Por ejemplo: [1: 3: &XX], este parámetro tomara los elementos 1, 2 y 3 de array XX. El parámetro anterior seria equivalente al parámetro compuesto [XX[1], XX[2], XX[3]] Manual del Usuario PSPS IV 73 Capitulo 8: El Lenguaje de Bloques. Describiendo el Sistema de simulación. es una SPV que indica el próximo bloque al que debe dirigirse la transacción, si las condic iones standard se dan. Puede suprimirse (debiendo suprimir también la coma que lo separa de las lista de parámetros). Si se suprime se toma como próximo bloque el bloque actual más uno. Si queremos indicar explícitamente el numero del próximo bloque debemos incluir en la definición del bloque todos los parámetros, incluidos los parámetros opcionales. Es decir, no es posible dejar huecos en la lista de Parámetros. Debemos incluirlos todos aunque sus valores sean exactamente los mismos que sus valores por defecto. Control de transacciones y avance de reloj de simulación. Bloque GENERATE. Formato: GENERATE , ; Descripción: Este bloque especificados, especificar la consecutivas y genera transacciones a intervalos de tiempo tanto fijos como aleatorios. El bloque permite distribución de tiempo entre dos generaciones un cierto número de parámetros de control. Parámetros: : es una SPV (Sentencia Pspal con valor) que se evalúa cada vez que se genera una transacción. El resultado de esta evaluación es el número de periodos de tiempo que transcurrirán hasta la aparición de una nueva transacción en el sistema generada en este bloque. : Parámetro opcional. Indica el número máximo de transacciones que se generan en este bloque. La SPV se evalúa cada vez que se genera una transacción. El valor obtenido de la SPV es el número de transacciones a generar. Si se alcanza este número de transacciones el bloque se desactiva y no genera ninguna otra transacción. Si en este parámetro se evalúa un número negativo, no hay limite en el número de transacciones a generar. Las constantes ON y OFF son útiles en este contexto. Por defecto este parámetro tomara el valor On. Manual del Usuario PSPS IV 74 Capitulo 8: El Lenguaje de Bloques. Describiendo el Sistema de simulación. Ejemplos: 1:GENERATE Erlang(10,1); Genera infinitas transacciones con un intervalo entre salidas del bloque distribuido exponencialmente con media 10 unidades de tiempo. 1:GENERATE Normal(10,2),On,3; Genera transacciones con un intervalo entre salidas del bloque Normal de media 10 y desviación estándar 2. El número de transacciones es ilimitado (el generador se mantiene en 'On' indefinidamente, porque On es una constante predeterminada cuyo valor es -1). Las transacciones generadas en este bloque se dirigirán al bloque número 3. 1:GENERATE Normal(10,2),10,2; Genera transacciones con distribución entre las salidas Normal de media 10 y desviación típica 2. Se generan diez transacciones, desactivándose el generador al generar la décima transacción. GENERATE 10,1; Se genera una única transacción en el instante en que el reloj interno marca diez. El generador se desactiva a continuación. El número de bloque y el siguiente bloque se indican implícitamente. GENERATE Cond(Rand>50,100,Cond(Rand>25,200,300)); Se generan transacciones indefinidamente con un tiempo entre generaciones de 100 con probabilidad 0.5, 200 con probabilidad 0.25 y 300 con probabilidad 0.25. Bloque DEGENERATE. Formato : DGENERATE ,, ; Descripción: Este bloque genera transacciones a intervalos de tiempo especificados, tanto fijos como aleatorios fijando el instante de la primera generación. Al igual que el bloque GENERATE , permite especificar la distribución de tiempo entre generaciones y un cierto número de parámetros de control. Parámetros: : es una SPV (sentencia Pspal con valor). El resultado de esta evaluación es el instante de generación de la primera transacción. Manual del Usuario PSPS IV 75 Capitulo 8: El Lenguaje de Bloques. Describiendo el Sistema de simulación. y son idénticos a los parámetros definidos para el bloque GENERATE . Bloque TERMINATE. Formato: TERMINATE ; Descripción: Este bloque es un sumidero de transacciones. Cuando una transacción entra en un bloque TERMINATE, desaparece inmediatamente del sistema. El bloque TERMINATE no puede llevar número de bloque siguiente explícito, ya que las transacciones nunca dejan este bloque. Parámetros: Parámetro Opcional. La SPV correspondiente a este parámetro se evalúa y la variable número de ITEMS se incrementa en su valor. Si este número supera el número máximo permitido (declarado en el bloque ITEMS, o alterado por el usuario posteriormente mediante la opción Interaction/Items de la barra de menús de la ventana principal del PSPS) la simulación se detiene. Si este parámetro no aparece en la definición del bloque la variable ITEM incrementa su valor en una unidad cada vez que llega una transacción al bloque. Ejemplo: 10:TERMINATE; transacción. Cuenta un ítem cada vez que llega una 10: TERMINATE 2; Incrementa en dos unidades el valor de la variable Item cada vez que llega una transacción. Bloque SPLIT Formato: SPLIT , ; Descripción: El bloque SPLIT crea copias idénticas de una transacción, que se dirigen a continuación a los bloques que se indican en el parámetro Manual del Usuario PSPS IV 76 Capitulo 8: El Lenguaje de Bloques. Describiendo el Sistema de simulación. compuesto1 . La transacción original sigue su camino como en el resto de los bloques. Parámetros: : la SPV se evalúa y se crean tantas copias como indica el valor que devuelve. El número de transacciones que deja el bloque por cada transacción entrada es igual a este parámetro. La transacción original cuenta dentro de las copias a obtener. : parámetro compuesto, que debe tener - 1 elementos. Las SPVs se evalúan cada vez que se intenta mover una transacción. La transacción original es la que primero se intenta mover. El resto de las transacciones se moverán por orden. Cuando una transacción se detiene se intenta mover la siguiente. Si después de la lista de aparece otro parámetro este será, como en el resto de los bloques, el bloque al que se dirigirá la transacción original una vez haya provocado el copiado. Ejemplos: 10:SPLIT 2,12,13; Se crean dos copias idénticas de la transacción. La transacción original se dirige al bloque 13. La copia, cuando sea su turno (cuando la transacción original se detenga por alguna causa), se dirigirá al bloque 12. En este caso se indica el próximo bloque explícitamente. 10:SPLIT 2,12; Se crean también dos transacciones. Como el próximo bloque no se incluye en la definición, la transacción original se dirige al bloque siguiente, el bloque 11. 10:SPLIT 3,[15,16]; Se crean tres transacciones por cada transacción que entra en este bloque. La original se dirigirá al bloque siguiente (el bloque 11), ya que no se indica el bloque explícitamente. Cuando sea su turno, la transacción segunda se dirigirá al bloque 15. De la misma forma, cuando sea el turno de la tercera copia se dirigirá al bloque 16. 10:SPLIT 3,[Va[2],At[3]]; La transacción original se dirige al bloque 11, el bloque siguiente. Cuando ésta se detenga, y le toque el turno a la primera copia, se evaluará la primera SPV del parámetro compuesto. En este caso, el próximo bloque vendrá dado por el contenido de la variable Va[2]. Cuando le llegue el turno a la segunda copia (la tercera transacción que saldrá del 1 Un Parámetro Compuesto es una lista de SPVs separadas por comas e incluidas entre paréntesis cuadrados. Por ejemplo [Fc[1], At[2], At[1]] es un parámetro compuesto. Manual del Usuario PSPS IV 77 Capitulo 8: El Lenguaje de Bloques. Describiendo el Sistema de simulación. bloque) se evalúa la segunda SPV de la lista. El valor del atributo tres de la transacción en curso será el próximo bloque. Como las copias son idénticas a la transacción original, el atributo tres tendrá el valor que tenia el atributo correspondiente de la transacción original cuando entro el bloque SPLIT. Bloque ASSEMBLE Formato: ASSEMBLE ; Descripción: Este bloque es, en algún sentido, el inverso del bloque SPLIT. El bloque retiene el número de transacciones indicado en el parámetro y cuando el número es suficiente se deja salir una única transacción idéntica a la última transacción entrada en el bloque. Parámetro: : se evalúa la SPV cada vez que llega una transacción. Si el valor del parámetro es igual o menor que el número de transacciones llegadas desde la última salida, se produce la salida de la transacción recién llegada. La cuenta de transacciones retenidas se disminuye en el valor de la SPV. Si sobran transacciones se acumulan para el próximo conteo. Ejemplos: 10:ASSEMBLE 3,12; Las dos primeras transacciones entradas desaparecerán del sistema. Cuando llegue la tercera, la cuenta se completa y la transacción en curso se deja pasar. La transacción ira al bloque 12. La cuenta de transacciones retenidas queda a cero. 10:ASSEMBLE Va[2]; Cada vez que llega una transacción se evalúa la expresión Va[2]. Supongamos que la primera y segunda transacciones llegadas encuentran Va[2] igual a 3. Por tanto, no se produce ninguna salida, y ambas transacciones desaparecen del sistema. Si al llegar la tercera transacción Va[2] tiene el valor 2, se produce el paso de la transacción en curso y el número de transacciones retenidas en el bloque queda igual a 3 – 2 = 1, con lo que la próxima transacción, si no pasa, dejará este valor en 2. Las transacciones que pasan van al bloque 11 (el bloque no se indica explícitamente). Manual del Usuario PSPS IV 78 Capitulo 8: El Lenguaje de Bloques. Describiendo el Sistema de simulación. Bloque SSYNCRO Formato: SSYNCRO , ; Descripción: El bloque retiene todas las transacciones que llegan a él. La condición para dejar salir una transacción depende ahora de la procedencia de las transacciones llegadas. Solo deja pasar una transacción cuando ha llegado una transacción de cada uno de los bloques de una lista que el usuario debe explicitar. Parámetros: : es un parámetro compuesto. El parámetro se evalúa cada vez que llega una transacción nueva al bloque, o se intenta mover una de las transacciones retenidas en el bloque. El resultado se interpreta como una lista de bloques. Si se ha retenido una transacción de cada uno de los bloques de la lista, la transacción en curso se deja pasar. En caso c ontrario, si no estaba retenida en el bloque la transacción se retiene, anotando su bloque de procedencia, y si estaba retenida, sigue así. Cuando se deja pasar una transacción, por haberse cumplido la condición, se disminuye la cuenta de transacciones retenidas(de cada uno de los bloques del parámetro). El resto de transacciones quedan para ayudar a cumplir la condición en otros casos. : las transacciones retenidas se ordenan de acuerdo con la prioridad especificada en este parámetro. La satisfacción de la condición comienza siempre viendo si la transacción en curso esta en la condición. Si lo esta se da de baja de la condición. Ahora se empieza a revisar las transacciones retenidas en el orden especificado por la prioridad hasta determinar si se cumple o no la condición. Esta situación se puede dar cuando la lista de condiciones depende del estado del sistema. Los atributos de la transacción saliente coinciden con los atributos de la transacción fusionada más antigua de acuerdo con la prioridad. Ejemplos: 10:SSYNCRO [2,3,4],Fifo,12; Cuando una transacción que llega, encuentre retenidas (incluyéndose a si misma) transacciones provenientes de los bloques 2, 3 y 4 se dejará pasar la transacción en curso. Cualquier transacción que llegue de otro bloque se retendrá y no podrá seguir nunca su camino. El orden de examen de las transacciones retenidas es FIFO. La transacción que pasa sigue al bloque 12. Manual del Usuario PSPS IV 79 Capitulo 8: El Lenguaje de Bloques. Describiendo el Sistema de simulación. 10:SSYNCRO [2,2,3,3],2; Cuando una transacción llegue podrá pasar si se encuentran retenidas (incluyéndola a ella) dos transacciones del bloque 2 y dos del 3. El orden de examen de las transacciones retenidas es creciente según el valor del atributo 2, evaluado en el instante en que llegaron. Las transacciones que pasan se dirigen al bloque 11. Bloque SYNCRO Formato: SYNCRO , , ; Descripción: Este bloque es similar en su funcionamiento al bloque SSYNCRO. La principal particularidad es que el bloque SYNCRO especifica el valor que debe tener una expresión determinada para la transacción entrante. Es posible por tanto incrementar la complejidad del mecanismo de sincronización de transacciones que suponía el bloque SSYNCRO. El parámetro especifica el orden en el que esperarán las transacciones que no puedan pasar por no darse la condición de sincronismo. El bloque retiene todas las transacciones que llegan a él. Solo deja salir una transacción cuando ha llegado una transacción que complete la lista de valores. Entonces se ha cumplido la condición de sincronismo se deja pasar la transacción y el proceso vuelve a empezar. Ejemplo: 1: SYNCRO [2,3,4],Fifo,At[3]; Para que salga una transacción deben haber entrado al menos 3 transacciones que tengan 4, 3 y 2 como valor de su tercer atributo. Bloque ADVANCE y WAITFOR Formato: ADVANCE ; WAITFOR ; Descripción: Estos dos bloques son idénticos y se encargan de retener la transacción el tiempo indicado en su primer y único parámetro. Este parámetro puede ser aleatorio y en general es distinto para Manual del Usuario PSPS IV 80 Capitulo 8: El Lenguaje de Bloques. Describiendo el Sistema de simulación. cada transacción. Por tanto las transacciones pueden adelantarse unas a otras en este bloque. Parámetro: : este parámetro es similar al primer parámetro del bloque GENERATE. Es una SPV o Sentencia Pspal con valor (que devuelve un valor) que se evalúa cada vez que se genera una transacción. El resultado de esta evaluación es el número de periodos de tiempo que transcurrirán por el reloj de simulación hasta que la transacción pueda salir de ese bloque Ejemplos: 10:WAITFOR Exponential(10); Las transacciones que entran en el bloque son demoradas de acuerdo con una distribución exponencial de media 10. 10:WAITFOR 8; Todas las transacciones se demoran un tiempo constante de 8 unidades. Bloque SGROUP Formato: SGROUP , ; Descripción: Reúne transacciones provenientes de los bloques que figuran en la lista del primer parámetro, las agrupa sobre la transacción que proviene del primer bloque en la lista, y suelta a esta, con las demás transacciones a caballo y por tanto recuperables por medio de un bloque UNGROUP. Ejemplos: SGROUP [1,3,5],Fifo; Acumula transacciones provenientes de los bloques 1, 3 y 5 y las libera como una única transacción con los atributos de la transacción proveniente del bloque 1. SGROUP [&BlArray:1:5], Fifo; Agrupa las transacciones cuyos números de bloque figuran en los elementos 1 a 5 del array cuya dirección se proporciona mediante el operador &. Manual del Usuario PSPS IV 81 Capitulo 8: El Lenguaje de Bloques. Describiendo el Sistema de simulación. Bloque GROUP Formato: GROUP , , ; Descripción: El bloque GROUP es similar al bloque SYNCRO. El bloque GROUP agrupa transacciones que cumplen una condición especificada y las pone a caballo de una de ellas, lanzando esta al mundo. Se evalúa la expresión que figura como tercer parámetro para todas las transacciones en espera en el bloque. El resultado de esta evaluación se recoge en una lista (posiblemente con valores repetidos). Cuando esta lista contiene como subconjunto a los valores de las transacciones correspondientes se colapsan en una sola, con los atributos de aquella que proporciona el primer valor de la lista, y la transacción resultante se suelta al mundo. Las transacciones son recuperables por medio de un bloque UNGROUP. Ejemplo: GROUP [3,22,0,0],Fifo, At[3]; Agrupa cuatro transacciones cuyo tercer atributo tenga uno de los valores indicados en la lista de valores. La transacción que se libera tiene los atributos de la transacción cuyo tercer atributo vale 3. Bloque GRAB Formato: GRAB , , , , , ; Descripción: Asocia las transacciones que se encuentran en un procesador o switch con la transacción activa que llega al bloque GRAB. Cada vez que llega una transacción al bloque GRAB repasa la lista de transacciones que se encuentran en el procesador o switch. La primera transacción (de las que se encuentran en el procesador o switch), para la que la condición se evalúe TRUE, se superpone a la transacción en curso y abandona el bloque. Si no hay ninguna transacción que verifique la condición, la transacción en curso se espera en el bloque GRAB según la prioridad indicada y el tiempo de impaciencia definido. A la llegada de cada transacción se testan todas las transacciones que están esperando en el bloque GRAB. Manual del Usuario PSPS IV 82 Capitulo 8: El Lenguaje de Bloques. Describiendo el Sistema de simulación. Parámetros: : las constantes FACLTY o SWTCH indican si la transacción se asocia con las transacciones de un procesador o de un Switch respectivamente : número del procesador o del Switch del que se quiere extraer una transacción. : condición que debe verificar una transacción para salir del bloque. : orden de espera de las transacciones dentro del bloque. Cuando llega una transacción nueva se evalúa la condición para todas las transacciones del bloque y sale la primera que la verifica según el orden de espera. : parámetro opcional. Es una SPV que se evalúa en el momento de la primera llegada al bloque. Si su valor es WAIT el tiempo de impaciencia se hace infinito, es decir, no se permiten las salidas por impaciencia. Si el valor es NOWAIT, el tiempo de impaciencia se hace cero, por lo que si una transacción al llegar al bloque no encuentra ninguna transacción que verifique la condición, proseguirá inmediatamente su camino por la salida de impaciencia. En cualquier otro caso se producirá una salida por impaciencia si el tiempo de espera supera el valor calculado. El sistema define el tiempo de impaciencia igual a WAIT si se omite este parámetro en la definición del bloque. : parámetro opcional. Es una expresión que indica el número de bloque al que se dirigirá la transacción si se produce una salida por impaciencia. Si el tiempo de impaciencia es WAIT, puede darse cualquier número de bloque, ya que el sistema no comprueba la validez de este hasta que no se produce la impaciencia. Por tanto es conveniente dar un bloque inexistente para prevenir, y detectar, errores. Si el parámetro no aparece en la definición del bloque el sistema asume que el parámetro es igual a Off, es decir un bloque inexistente, ya que el tiempo de impaciencia por defecto es WAIT. El bloque GRAB altera la secuencia de proceso de las transacciones que se hallan dentro de un procesador o switch. La transacción correspondiente puede hallarse en el procesador, pero estar esperando en un bloque WAITFOR. En este caso aunque se retirara la transacción del procesador, el acontecimiento asociado con el fin del WAITFOR seguiría en curso, por lo que la transacción trataría de salir del procesador cuando se produzca el fin de la espera. Los resultados pueden ser desastrosos. Se aconseja limitar el uso del bloque GRAB a un procesador que sea un deposito terminal de transacciones. Es decir, un deposito Manual del Usuario PSPS IV 83 Capitulo 8: El Lenguaje de Bloques. Describiendo el Sistema de simulación. del cual las transacciones se sacan solo si se cumple la condición del bloque GRAB. El sistema permite el acceso a los atributos de la transacción en curso utilizando el Array At[ ]. También permite acceder a los atributos de las transacciones en examen usando la función AtTestTr[i], que devuelve el valor del atributo i-esimo de la transacción que esta siendo testada. Este bloque permite usar directamente los atributos de dos transacciones. Ejemplo: GRAB FACLTY, 1,At[3]==AtTestTr[2],Fifo; Comprueba si hay una transacción en el procesador número 1 que tenga el atributo 2 igual al atributo 3 de la transacción en curso. Si no la hay, la transacción actual espera Fifo, y será considerada a la llegada de la siguiente transacción. Bloque JOIN Formato: JOIN ,; Descripción: Realiza la misma función que el bloque ASSEMBLE. Agrupa transacciones consecutivas que llegan al bloque y las suelta a caballo de la última transacción llegada al bloque. Las diferencias con el bloque ASSEMBLE son las siguientes: • • las transacciones son recuperables individualmente por medio de un bloque UNGROUP y la agrupación no se realiza por conteo de las transacciones llegadas, sino por acumulación de valores asociados con cada transacción. El conteo se inicializa a cero, y se va sumando el resultado de la expresión hasta que su valor alcanza o supera el dado. Entonces se sueltan las transacciones. Ejemplos: JOIN 3, 1; Tiene el mismo efecto que ASSEMBLE 3,1; pero con las transacciones recuperables por medio del bloque UNGROUP . JOIN Total, At[2]; Va sumando el contenido de At[2] de las transacciones llegadas, hasta que se alcanza el valor Total, soltando entonces las transacciones a caballo de la última llegada. Manual del Usuario PSPS IV 84 Capitulo 8: El Lenguaje de Bloques. Describiendo el Sistema de simulación. Bloque SELJOIN Formato: SELJOIN ,,; Descripción: Se trata de un bloque JOIN que realiza una separación de las transacciones que procesa en función de un atributo de las mismas. La acumulación depende del valor del atributo. Para cada valor del atributo se inicializa una totalización, que se incrementa a la llegada de cada transacción por la expresión incremento. Las transacciones se acumulan en función de su atributo selector, por tanto en n colecciones una para cada valor del atributo. Cuando una de ellas llega a acumular unidades, las transacciones de esta colección se agrupan entre si y se liberan. Ejemplo: SELJOIN 3,1,At[4]; Unirá entre si tres transacciones que tienen el mismo valor en su atributo 4, y las soltará al mundo. Y esto sucederá seleccionando las transacciones en función del atributo selector. Bloque UNGROUP Formato: UNGROUP ; Descripción: Desagrupa las transacciones agrupadas por uno de los bloques GRAB, JOIN, SELJOIN, SGROUP o GROUP en sus transacciones correspondientes, que saldrán consecutivamente del bloque en el orden en que fueron agrupadas. El bloque al desagrupar las transacciones devuelve +1 ya que devuelve la transacción en la que se habían agrupado y las últimas de las lista de transacciones agrupadas que esta ordenada según la prioridad indicada en el bloque que se encargo de agrupar las transacciones. Manual del Usuario PSPS IV 85 Capitulo 8: El Lenguaje de Bloques. Describiendo el Sistema de simulación. Ocupación de procesadores y switches. Bloque ENTER Formato: ENTER , , , , ; Descripción: El bloque ENTER solicita la entrada de una transacción en un procesador. Si la entrada no se consigue debido a que el procesador es incapaz de absorber el volumen de entrada que solicita la transacción, esta se espera de acuerdo con una disciplina de cola especificada en el bloque. Cuando la transacción inicia su espera, se puede calcular para ella un tiempo de impaciencia. Cuando el tiempo que la transacción lleva esperando supera al tiempo de impaciencia, la transacción sale hacia un bloque especificado por el usuario. Parámetros: : es una SPV que se evalúa cada vez que se intenta entrar en el bloque ENTER. Una misma transacción puede solicitar la entrada a procesadores distintos en distintos momentos de tiempo, dependiendo del estado del sistema. : parámetro opcional. Si se logra entrar el contenido del procesador se incrementa en el valor indicado por este parámetro. Si la capacidad restante del procesador no es suficiente para absorber este número de unidades la transacción se espera en cola. Si este parámetro no aparece en la definición del bloque el número de unidades que solicitan la entrada al procesador es igual a uno. : parámetro opcional. Es el número de un atributo, o una de las constantes de prioridad (FIFO, LIFO y NOQUEUE). Las transacciones esperan en el orden dado por este parámetro. Si se indica un atributo, este se evalúa en el momento de llegar la transacción por primera vez y el valor resultante se usa para establecer el orden de espera. En todas las disciplinas, excepto en la NOQUEUE, si una transacción no puede moverse, no se examinan las transacciones que la siguen en la cola. Por tanto, la única transacción candidato al movimiento es la primera de la cola. En la disciplina NOQUEUE, se examinan todas las transacciones en espera y si alguna se puede mover el sistema inicia su movimiento. Por tanto las transacciones, en esta Manual del Usuario PSPS IV 86 Capitulo 8: El Lenguaje de Bloques. Describiendo el Sistema de simulación. disciplina, pueden adelantarse. La disciplina de espera por defecto si este pará metro no aparece en la definición del bloque es la disciplina Fifo. : Parámetro opcional. Es una SPV que se evalúa en el momento de la primera llegada al bloque. Si su valor es WAIT el tiempo de impaciencia se hace infinito, es decir, no se permiten las salidas por impaciencia. Si el valor es NOWAIT, el tiempo de impaciencia se hace cero, por lo que si una transacción encuentra el procesador lleno, proseguirá inmediatamente su camino por la salida de impaciencia. En cualquier otro caso se producirá una salida por impaciencia si el tiempo de espera supera el valor calculado. El sistema define el tiempo de impaciencia igual a WAIT si se omite este parámetro en la definición del bloque. : Parámetro opcional. Es una expresión que indica el número de bloque al que se dirigirá la transacción si se produce una salida por impaciencia. Si el tiempo de impaciencia es WAIT, puede darse cualquier número de bloque, ya que el sistema no comprueba la validez de este hasta que no se produce la impaciencia. Por tanto es conveniente dar un bloque inexistente para prevenir, y detectar, errores. Si el parámetro no aparece en la definición del bloque el sistema asume que el parámetro es igual a Off, es decir un bloque inexistente, ya que el tiempo de impaciencia por defecto es WAIT. Ejemplos: 10:ENTER At[2],Va[2]*10,3,Wait,Off; Se intentará entrar en el procesador indicado por el valor del atributo número 2 de la transacción en curso. Si entra, el contenido del procesador se incrementara en Va[2]*10 unidades, si este número de unidades de capacidad estuviera disponible. El orden de espera será en orden creciente según los valores del atributo 3. No hay salida por impaciencia. 10:ENTER Argmin(Fc[1],Fc[2],Fc[3]),1,Fifo,Wait,Off; Se intentara entrar en el procesador que tenga menos contenido de entre los procesadores 1,2 y 3. Nótese que Argmin da un valor que coincide, en este caso, con el número del procesador. En general debe procederse como en el ejemplo siguiente. 10:ENTER Choice(Argmin(Fc[5],Fc[7],Fc[9]),5,7,9),1,Fifo,Wait,Off; Este es el caso general del anterior. La función Argmin produce el valor 1,2, o 3 en función del argumento que alcanza el mínimo. Este valor se usa para elegir el procesador. 10:ENTER 3,1,Fifo,NoWait,15; En este caso si no se puede incrementar el contenido del procesador 3 en una unidad, la transacción bifurcara inmediatamente al bloque 15. Manual del Usuario PSPS IV 87 Capitulo 8: El Lenguaje de Bloques. Describiendo el Sistema de simulación. Bloque MENTER Formato: MENTER , , ,,; Descripción: Este bloque es una versión del bloque anterior para múltiples entradas. En este bloque los primeros parámetros del bloque ENTER quedan sustituidos por parámetros compuestos. El primer parámetro indica la lista de procesadores a los que se quiere entrar simultáneamente. El segundo parámetro indica el número de unidades en que se incrementa el contenido de los procesadores indicados en el primer parámetro si se logra entrar a ellos. Si no se logra la entrada a todos ellos la transacción se comporta de la misma forma que en el bloque ENTER. Al igual que en el bloque ENTER los parámetros que definen la disciplina de espera y el tiempo de impaciencia son opcionales, asumiendo el sistema la disciplina FIFO y el tiempo de impaciencia igual a WAIT si estos parámetros no aparecen en la definición del bloque. Ejemplo: 10:MENTER [1,2,3],[2,2,2]; Se quiere entrar simultáneamente a los procesadores 1,2 y 3. Se solicita la entrada de 2 unidades en cada uno de ellos. Bloque LEAVE Formato: LEAVE , ; Descripción: Este bloque disminuye el contenido de un procesador. Es el inverso del bloque ENTER. Cuando se combina con el bloque MENTER, deben hacerse LEAVE de todos los procesadores en el citado bloque. Parámetros: : es una SPV que se evalúa cuando llega una transacción. Indica el número del procesador del que se va a disminuir el contenido. Si el contenido de un procesador se hace negativo el sistema detecta un error. : parámetro opcional. Es el número de unidades en que disminuye el contenido del procesador cada vez Manual del Usuario PSPS IV 88 Capitulo 8: El Lenguaje de Bloques. Describiendo el Sistema de simulación. que una transacción entra en este bloque. El numero de unidades por defecto, si el parámetro no aparece en la definición del bloque, es uno. Ejemplo: 11:LEAVE 1; Se disminuye el contenido del procesador número 1 en una unidad cada vez que una transacción pasa por este bloque. La transacción pasa al bloque 12, dado implícitamente. Bloque GET Formato: GET , , , , ; Descripción: El bloque GET tiene un papel parecido al del bloque LEAVE, pero la transacción espera en el procesador a que el número de unidades reclamadas este disponible en el mismo. Cuando esto se produce, las extrae y la transacción prosigue su camino. La espera puede producirse con diferentes disciplinas de espera, y puede indicarse un tiempo y una ruta de impaciencia. El parámetro es el único obligatorio el resto de los parámetros si no aparecen en la definición del bloque el sistema tomara como numero de unidades uno, como disciplina de espera Fifo y el tiempo de impaciencia será igual a WAIT, es decir infinito. Bloque MGET Formato: MGET , , , , ; Descripción: El bloque MGET es similar al bloque GET pero para el caso de varios procesadores. La transacción debe esperar a que el número de unidades solicitadas a cada uno de los procesadores este disponible en el mismo instante de tiempo. Cuando esto ocurra, el bloque extrae las unidades indicadas de cada procesador y la transacción sigue su camino. La espera puede producirse con diferentes disciplinas de espera y puede indicarse un tiempo y una ruta de impaciencia. Manual del Usuario PSPS IV 89 Capitulo 8: El Lenguaje de Bloques. Describiendo el Sistema de simulación. Parámetros: : parámetro compuesto que indica la lista de procesadores de los que queremos disminuir el contenido. < Número de unidades>: parámetro compuesto que indica el número de unidades reclamadas en cada uno de los procesadores indicados en el parámetro < Lista de procesadores>. : parámetro opcional. Indica la disciplina de espera cuando el número de unidades reclamadas no este disponible. Si este parámetro no se incluye en la definición del bloque la disciplina de espera es igual a Fifo. : parámetro opcional. Una SPV que se evalúa en el momento de la primera llegada al bloque. Si su valor es WAIT el tiempo de impaciencia se hace infinito, es decir, no se permiten las salidas por impaciencia. Si el valor es NOWAIT, el tiempo de impaciencia se hace cero, por lo que si una transacción encuentra el procesador lleno, proseguirá inmediatamente su camino por la salida de impaciencia. En cualquier otro caso se producirá una salida por impaciencia si el tiempo de espera supera el valor calculado. Si este parámetro no se incluye en la definición del bloque el tiempo de espera se hace infinito. : parámetro opcional. Expresión que indica el número de bloque al que se dirigirá la transacción si se produce una salida por impaciencia. Si este parámetro no se incluye en la definición del bloque la salida por impaciencia será Off. Ejemplo: 10: MGET [1,2], [1,1]; Se reclama 1 unidad de los procesadores 1 y 2. En caso de no estar disponibles en ambos procesadores una unidad, la transacción esperará ante el bloque según la disciplina de cola Fifo, no se produce salida por impaciencia, la transacción esperará hasta que estén disponibles las unidades solicitadas. Bloque QUEUE Formato: QUEUE , , , , ; Descripción: El bloque QUEUE se encarga de solicitar la entrada de una transacción al procesador indicado en el primer parámetro del Manual del Usuario PSPS IV 90 Capitulo 8: El Lenguaje de Bloques. Describiendo el Sistema de simulación. bloque. Si el procesador esta saturado el bloque gestiona de forma automática la cola ante el procesador. Al igual que en el bloque ENTER se puede indicar una disciplina de espera un tiempo máximo de espera. Con este bloque no es necesario definir un procesador que represente a la cola ante un procesador. Los parámetros , , , son opcionales. Si estos parámetros no aparecen en la definición del bloque el número de unidades solicitadas será igual a uno, la disciplina de espera será Fifo y el tiempo de impaciencia se hará infinito. Bloque SWITCH Formato: SWITCH , ; Descripción: Este bloque permite definir el estado de un Switch. Parámetros: : indica el número del switch que vamos a modificar. : es una SPV que se evalúa y se asigna al estado del Switch. El estado del Switch será False si el resultado es 0 y True en caso contrario. Ejemplo: 10:SWITCH 1, At[2]+At[3]; Se evalúa la expresión y se asigna al switch número 1. La transacción sigue al bloque siguiente. Bloque GATE Formato: GATE , ; Descripción: Este bloque retiene las transacciones en función del estado de uno de los Switches del sistema. Si el estado del Switch que se consulta es Off las transacciones se esperan ante el bloque según la disciplina Fifo. Cuando el Switch cambia a On, todas las Manual del Usuario PSPS IV 91 Capitulo 8: El Lenguaje de Bloques. Describiendo el Sistema de simulación. transacciones que estaban retenidas se liberan simultáneamente. Por tanto, si el Switch se volviera a poner en Off, no podría interceptar ninguna de las transacciones que estaban esperando, ya que éstas habrían pasado instantáneamente por el bloque GATE. El bloque GATE es especialmente útil cuando se trata de mantener una lista de espera, ordenada por un índice de prioridad variable en el tiempo. Parámetros: : es una SPV que se evalúa al llegar cada transacción y cuyo valor determina el número del Switch a consultar. : Parámetro opcional. Es el número de un atributo o una de las constantes de prioridad, que determinan el orden de espera ante el Switch. Aunque las transacciones se liberan todas simultáneamente, el orden de cola influye en la forma en que el sistema las moverá posteriormente, por lo que puede ser conveniente su especificación. Si no se especifica el valor de este parámetro la disciplina de espera será Fifo. Ejemplo: 10:GATE 1; Las transacciones que llegan con el switch número uno en Off (False) se esperan en cola de acuerdo con la regla Fifo. Bloque QGATE Formato: QGATE , , , , ; Descripción: El bloque QGATE es parecido al bloque ENTER pero referido al estado de un Switch (como en el bloque GATE). El estado del Switch se consulta cada vez que hay un cambio de estado en el sistema. Si el estado es On la primera transacción se deja pasar. Si no se retiene, de acuerdo con la prioridad y la impaciencia indicadas. La principal diferencia con el bloque GATE es que al soltar las transacciones una a una, alguna puede alterar el estado del sistema y atrapar de nuevo a las transacciones que la siguen en el bloque QGATE. Manual del Usuario PSPS IV 92 Capitulo 8: El Lenguaje de Bloques. Describiendo el Sistema de simulación. Parámetros: : es una SPV que se evalúa para determinar el número del switch a consultar. : parámetro opcional. Este argumento no se usa pero debe estar presente si queremos modificar la disciplina de espera y el tiempo de impaciencia. Se aconseja usar la constante 'No' para indicar su valor. : parámetro opcional. Es un parámetro idéntico al del bloque ENTER, indica la disciplina que se aplica a la cola. Puede especificarse la constante NOQUEUE, que produce efectos análogos que en el bloque ENTER. Si no se especifica este parámetro el valor de la disciplina de espera será Fifo. : parámetro opc ional. Análogo al parámetro del bloque ENTER. Si no se especifica este parámetro en la definición del bloque el tiempo de espera se hará infinito. : parámetro opcional. Análogo al parámetro del ENTER. Si no se especifica este paráme tro no hay salida por impaciencia. Ejemplo: 10:QGATE 1,No,Fifo,Wait,Off; Se seguirá el estado del switch número uno. Las transacciones en espera se ordenaran según la regla Fifo. No hay impaciencia. Bloque GATEGROUP Formato: GATEGROUP < Número de switch >, < Prioridad >; Descripción: Este bloque, al igual que el bloque GATE y el bloque QGATE, retiene transacciones en función del estado de un Switch del sistema. Si el estado del Switch que se consulta es 'Off' las transacciones esperan ante el bloque. Cuando el Switch cambia a 'On' todas las transacciones que estaban retenidas se liberan agrupadas en una única transacción. Para recuperar las transacciones originales se utiliza el bloque UNGROUP. Parámetros: : una SPV que se evalúa al llegar cada transacción y cuyo valor determina el número del Switch a consultar. Manual del Usuario PSPS IV 93 Capitulo 8: El Lenguaje de Bloques. Describiendo el Sistema de simulación. : Parámetro opcional. El número de un atributo o una de las constantes de prioridad, que determinan el orden de espera ante el Switch. Aunque las transacciones se liberan todas agrupadas en una única transacción, el orden de cola influye en la forma en que el sistema las moverá posteriormente, por lo que puede ser conveniente su especificación. Si este parámetro no aparece en la definición del bloque el orden de las transacciones será Fifo. Cálculo y modificación de variables. Bloques ASSIGN y COMPUTE Formato: COMPUTE ; ASSIGN ; Estos dos bloques son idénticos. únicamente el bloque COMPUTE. Por tanto describiremos Descripción: Este bloque tiene un solo argumento que debe ser una sentencia Pspal. El efecto del bloque es la ejecución de la sentencia Pspal cada vez que una transacción llega al bloque. El resultado de tal evaluación es el valor de la última sentencia Pspal ejecutada. Ejemplo: Cualquier sentencia Pspal es válida aquí, siempre que vaya precedida de la definición del bloque. 10:COMPUTE Begin Tiempo=0, n=0, While Tiempo<100 Do Begin Tiempo=Tiempo+ Erlang(100,1), n=n+1 End, n=n-1, End,15; Calcula una muestra de la distribución de Poisson. El punto y coma final es obligatorio, ya que termina la definición del bloque. En este caso damos explícitamente el siguiente bloque, para hacer notar esta opción. La transacción se encaminará al bloque 15, tras haber completado el proceso del bloque COMPUTE. Manual del Usuario PSPS IV 94 Capitulo 8: El Lenguaje de Bloques. Describiendo el Sistema de simulación. Definición de Secuencia. Bloque TRANSFER Formato: TRANSFER ; Descripción: Este bloque permite desviar las transacciones a otros bloques de acuerdo con condiciones lógicas definidas por el usuario. Como todas las sentencias de bloque admiten una sentencia Pspal en el número del próximo bloque, este bloque es redundante y se mantiene por compatibilidad. De acuerdo con nuestra definición de parámetros, TRANSFER no tiene ningún parámetro. Si se da una expresión para el siguiente bloque, ésta se evalúa y la transacción se encamina al bloque resultante. Si no se da una expresión, el TRANSFER actúa como un bloque nulo, y la transacción sigue en secuencia. Ejemplos: 10:TRANSFER Cond(Rand > 50, 12, 13); Con probabilidad 0.5 la transacción va al bloque 12 o al 13. 10:TRANSFER Choice(At[2], 7, 8, 22); Según el valor del atributo 2, la transacción en curso se bifurca a 7, 8, 22. Aquí TRANSFER actúa como una sentencia CASE. Bloque YIELD Formato: YIELD; Descripción: Este bloque se emplea para bloquear temporalmente la transacción en curso y dar la oportunidad de moverse a otras transacciones que deberían moverse aun en el caso de que la transacción en curso modificara el estado del sistema para bloquearlas. Las transacciones deben poder moverse porque en realidad todo sucede en un mismo instante de tiempo y el bloqueo se elimina dentro del mismo instante de tiempo, simplemente la transacción que entra en el bloque Yield da la oportunidad a las otras de "pasar delante", pasando ella a continuación, si bien debe tenerse en cuenta, que en todo este proceso el reloj de la simulación no ha avanzado. La transacción que ha alcanzado el Manual del Usuario PSPS IV 95 Capitulo 8: El Lenguaje de Bloques. Describiendo el Sistema de simulación. bloque YIELD se moverá una vez que todas las anteriores lo hayan intentado. Ejemplo: SYSTEM GATE 1,Fifo; ...... 4: GATE 1,Fifo,5; 5: YIELD; SWITCH 1,Off; ...... Si suponemos que hay transacciones esperando en ambos switches y llega una transacción al bloque 4 (segundo bloque GATE) que encuentra el Switch 1 en On y si el YIELD no estuviera inmediatamente después de que pasara la primera transacción por este bloque se pondría el switch a Off y las transacciones que esperan en el primer bloque GATE no podrían moverse aunque deberían poder hacerlo puesto que todo sucede en el mismo instante de tiempo. Bloque FREORDER Formato: FREORDER ,,; Descripción: Este bloque reorganiza la lista de transacciones pendientes de entrar en el procesador . Para ello asigna al atributo indicado el valor resultante de calcular la función en línea para cada transacción. A continuación ordena las transacciones por orden creciente de este atributo. La transacción que desencadena el cálculo no participa del mismo. Por tanto se deben tomar precauciones para que esta transacción al llegar al procesador entre en el orden adecuado. Este bloque implanta prioridades dinámicas en los bloques. Sin embargo tiene algunas limitaciones. Todas ellas se derivan de que la prioridad se calcula únicamente cada vez que llega una transacción al bloque, no en el bloque que produce las llegadas al procesador. Por tanto, cuando se sacan transacciones de la lista de transacciones pendientes sin que pase tiempo (es decir entre dos eventos) la lista de transacciones no se pone al día de forma dinámica. Por tanto, para ciertos tipos de prioridades que dependan del número de ítems en procesadores, es posible que la lista de transacciones no se reordene permanentemente de la forma deseada. Manual del Usuario PSPS IV 96 Capitulo 8: El Lenguaje de Bloques. Describiendo el Sistema de simulación. Este bloque es útil para implantar prioridades que dependan por ejemplo del tiempo de permanencia en algún segmento del sistema. Ejemplo: Supongamos que las transacciones llevan en su atributo TEntrega el tiempo de entrega deseado, y en su atributo Restante, el trabajo que aun queda por realizar en la transacción hasta el momento en que este lista para entregar. Entonces FREORDER 1, 3, (At[TEntrega]- cl ) / At[restante]; Implementa la prioridad dinámica tiempo hasta la entrega/trabajo residual, de gran interés en las operaciones. Bloque SREORDER Formato: SREORDER ,,; Descripción: Este bloque es similar al bloque FREORDER pero para el caso de una lista de transacciones pendientes de pasar por el Switch . Elaboración de Estadísticas. Bloques TABULATE y TTAB Formato: TABULATE , ; TTAB , ; Descripción: Ambos, TABULATE y TTAB, tienen exactamente el mismo número de parámetros, pero difieren en el tipo de estadísticas que mantienen. El bloque TABULATE obtiene estadísticas de una muestra discreta. Los sucesivos valores se consideran muestras de una distribución de probabilidad y de ellos se calculan estadísticas descriptivas. Manual del Usuario PSPS IV 97 Capitulo 8: El Lenguaje de Bloques. Describiendo el Sistema de simulación. El bloque TTAB considera las observaciones como formando parte de una trayectoria aleatoria, en el tiempo, y obtiene las estadísticas de esta trayectoria. Ambos bloques calculan las siguientes estadísticas: Media: en el caso del bloque TABULATE, la media es simplemente la suma de las observaciones dividido por el número de estas. En el bloque TTAB, cada observación se multiplica por el tiempo transcurrido entre observaciones, se suman los productos y se dividen por el tiempo total de observación. Así se obtiene el valor medio en el tiempo de la variable. Desviación tipo: en el caso del bloque TABULATE, el valor es la raíz cuadrada del valor medio sencillo de la suma de cuadrados. En el bloque TTAB, cada cuadrado está ponderado por el tiempo en que la variable ha mantenido el valor en cuestión. Valor máximo: el mayor alcanzado por la variable que se tabula. En caso del bloque TTAB, este valor puede haberse alcanzado durante un intervalo de tiempo de longitud cero. Valor mínimo: igual que el valor máximo pero para el menor valor. Histograma de frecuencias: Para el bloque TABULATE se obtienen las frecuencias para cada intervalo del histograma en porcentaje de ocurrencias. Para el bloque TTAB se obtiene el tiempo total y el porcentaje de tiempo durante el que la variable ha tenido un valor dentro del intervalo correspondiente del histograma. Parámetros: : es una SPV que se evalúa a la llegada de cada transacción. Indica el número del histograma en que se acumularan las observaciones. : es una SPV que se evalúa a la llegada de la transacción e indica la observación que vamos a tabular. Bloque SIMRESET Formato: SIMRESET; Descripción: Reinicializa todas las estadísticas. A diferencia del bloque RESET de la sección Data, SIMRESET es útil cuando se desea alterar los valores de algunas variables y volver a simular de forma automática, sin intervención del usuario. Esta característica es útil cuando se planean simulaciones sucesivas, para explorar el Manual del Usuario PSPS IV 98 Capitulo 8: El Lenguaje de Bloques. Describiendo el Sistema de simulación. comportamiento del sistema en el entorno de un punto o para usar procedimientos de optimización. Input Output y Debugging. Igual que en la sección DATA cualquier bloque de la sección System pude ir precedido de la palabra calve DE BUG DEBUG DO ; El bloque solo se incluirá en el código si el valor de la constante es True, es decir si es distinto de cero. Si el valor de la constante es False el bloque se tratará como un comentario, es decir no pasará a formar parte del código del programa. Bloque STOP Formato: STOP; Descripción: Este bloque se utiliza para parar el curso de la simulación, pero no instantáneamente. Para la simulación en el momento en que la transacción que está siendo procesada se detiene por cualquier motivo (por ejemplo espera en un bloque GATE o espera para ganar acceso a un procesador). Ejemplo: 3: STOP; Cuando una transacción después de pasar por este bloque se pare (por ejemplo en un bloque GATE), entonces se parará toda la simulación. Bloque DUMP Formato: DUMP; Descripción: Este bloque produce la impresión del estado de la simulación, en el formato standard de salida. Puede usarse para imprimir resultados a la llegada de una transacción. El bloque no tiene parámetros pero se puede elegir que es lo que se quiere imprimir mediante las opciones del simulador. Este cuadro de diálogo se abre al Manual del Usuario PSPS IV 99 Capitulo 8: El Lenguaje de Bloques. Describiendo el Sistema de simulación. seleccionar Opciones en el menú Run de la barra de menús del PSPS- IV. Bloque PRINT Formato: PRINT , ; Descripción: Este bloque permite la escritura de la Lista de expresiones en un fichero, esto permite exportar los ficheros de Output a otros programas. PSPS define dos ficheros auxiliares, que en el lenguaje se conocen como los fic heros 1 y 2. En general estos ficheros están asignados a dos ficheros de disco con la terminación .pr1 y .pr2. El bloque PRINT puede enviar output a cualquiera de estos ficheros (es la opción por defecto), también se pueden enviar a un gráfico o a una hoja de cálculo. Para guardarlo en un gráfico o en una hoja de cálculo hay que especificar estas opciones en el menú Run/Options de la barra de menús del PSPS. El bloque PRINT exporta además como primer elemento de la lista de resultados su propio número de bloque, lo que permite la identificación fácil del output de varios bloques PRINT. Para poder acceder a los ficheros de Ouput creados por el bloque Print es necesario guardarlos mediante el menú Interaction/Save File Output de la barra de menús del PSPS. Este menú abre el cuadro de diálogo habitual para guardar ficheros. Parámetros: : Console, Printer o File son los únicos valores validos. : es un parámetro compuesto que lista entre paréntesis cuadrados las SPV's cuyo valor hay que exportar. La lista se imprime en un registro completo terminado en un retorno de carro y con el formato standard. En este argumento no se admiten tiras de caracteres. Ejemplos: 10:PRINT File, [cl, At[1], At[3], Va[2]]; Producirá la exportación al fichero File de: el número del bloque (10 en este caso), seguido del valor del reloj, de los atributos 2 y 3 y de la variable 2, formando un registro terminado por un retorno de carro. Manual del Usuario PSPS IV 100 Capitulo 8: El Lenguaje de Bloques. Describiendo el Sistema de simulación. Bloque TRACE Formato: TRACE , ; Descripción: Este bloque provoca el inicio o finalización de la traza, al nivel que se especifique. Parámetros: : si este parámetro es ON la traza se inicia. Si es OFF se detiene. Si ya estaba en ON u OFF respectivamente, la orden se ignora. : es una SPV que se evalúa y da como resultado el nivel al que se debe desarrollar la traza. Bloques Multimedia y Gráficos. Bloque DISPLAY Formato: DISPLAY ,; Descripción: El bloque carga en la screen la imagen contenida en el fichero correspondiente y la muestra. Parámetros: : indica el número de una Screen, creada con el bloque correspondiente de la sección Data. : es un string de texto con el nombre de un fichero. El fichero debe ser del tipo .bmp o .wmf. Manual del Usuario PSPS IV 101 Capitulo 8: El Lenguaje de Bloques. Describiendo el Sistema de simulación. Bloque PLAY Formato: PLAY ,,; Descripción: Para el bloque PLAY el fichero debe ser del tipo AVI. La película existente en el fichero se carga y se proyecta en una pantalla de dimensiones dadas por los otros dos argumentos, en pixels. Bloque DRAWXY Formato: DRAWXY , [ g 1, x1, y 1, g 2, x 2, y2 , ..., g n, xn, yn]; Descripción: Este bloque sirve para dibujar gráficas de una o varias funciones en una ventana. Parámetros: : es el número de la ventana en la que dibujaremos la gráfica o gráficas y que debe ser un número comprendido entre 1 y el número de gráficos que viene definido por la variable del sistema GRAPHS a la que debemos asignar un valor en la sección de variables. [ g1, x1, y1, g2, x2, y2, ....., gn, xn, yn]: es una lista de los puntos que se van a dibujar en el gráfico. Cada punto supone 3 valores(g,x,y), el primero indica el número de serie al que pertenece el punto de entre todas las series que se representan en un mismo gráfico. El segundo representa el valor de la abscisa del punto y el tercero el valor de la ordenada. Con estos tres valores el sistema dibujará el punto y lo unirá con el último que haya dibujado de esa serie salvo que sea el primero que entonces pintará solamente el punto. Los puntos de una misma gráfica deben darse en orden creciente o decreciente de las abscis as para que el sistema dibuje la serie de manera correcta. Ejemplo: DRAWXY 1,[1,0,0, 2,1,1, 1,0.5,0.5, 2,0.5,0.5, 1,1,1, 2,0,0]; Este bloque dibuja en el gráfico número 1 dos series distintas. La Manual del Usuario PSPS IV 102 Capitulo 8: El Lenguaje de Bloques. Describiendo el Sistema de simulación. serie número 1 es una recta que une el origen de coordenadas con el punto (1,1). La serie número 2 forma un ángulo recto con la anterior y va del punto (0,1) al punto (1,0). Simulación Continua. Bloque INTEGRATE Formato: INTEGRATE ; Descripción: Este bloque permite la simulación en tiempo continuo. La función en línea debe realizar el proceso de integración, calculando las variables de estado a partir de los inputs y outputs de las ecuaciones diferenciales siendo integradas. El método de integración debe ser programado por el usuario. El bloque se limita a programar la ejecución de la función en línea que figura en su argumento, a intervalos dados en el bloque STEP de la sección Data. Para ello genera acontecimientos cada STEP unidades de tiempo, y en cada acontecimiento se ejecuta la función. Para la programación de la integración, es de gran utilidad la función Dt, que devuelve el intervalo de integración. Manual del Usuario PSPS IV 103 CAPITULO 9: El Lenguaje Lisp § § § § § § § § § Manual del Usuario PSPS IV Tipos Básicos de Datos Funciones Aritméticas Funciones de Listas Funciones Predicado Funciones Evaluadoras Funciones de Comparación Funciones de Input -Output Otras Funciones de Lisp ¿Cómo acceder desde Lisp a Pspal? Capítulo 9: El Lenguaje Lis p El PSPS tiene integrado un interprete del lenguaje Lisp que nos permitirá tratar de forma sencilla listas en cualquiera de nuestros modelos. En este Capítulo trataremos de describir los principales elementos del lenguaje y las funciones Lisp disponibles en el PSPS IV. Tipos Básicos de Datos. Átomos Son los objetos básicos del lenguaje y se representan por una secuencia de caracteres alfanuméricos. Cada átomo tiene asignado un valor que puede ser un número, un carácter o una cadena de caracteres. Los átomos pueden ser de dos tipos numéricos y no numericos. Los átomos numéricos representan un número. Un átomo no numérico es un símbolo representado por una cadena de caracteres alfanumericos que debe comenzar por una letra. TRUE y NIL son dos átomos que Lisp utiliza para representar los valores True y False. Listas Las listas se definen como una concatenación de átomos, es una manera de representar un conjunto de átomos. Diremos que un conjunto de átomos entre dos paréntesis es una lista. (1 2 3) Como hemos dicho los elementos de una lista son átomos pero también puede ser otra lista (0 (1 2 3) 4 5) o podemos definir una lista vacía ( ) que es equivalente a Nil como veremos más adelante en alguno de los ejemplos. En Lisp el nombre formal del primer elemento de una lista es Car y el resto de los elementos de la lista reciben el nombre del Cdr. El Car de una lista puede ser un átomo o una lista, pero el Cdr de una lista siempre es una lista. Veamos algunos ejemplos: Supongamos que hemos definido la lista Manual del Usuario PSPS IV 104 Capítulo 9: El Lenguaje Lisp (a b c d) el Car de esta lista será el átomo a y el Cdr será la lista (b c d). Si definimos la lista ((a b) c d e) en este caso el Car será igual a la lista (a b) y el Cdr será la lista (c d e) En la memoria Lisp las listas se almacenan asignado a cada lista una doble celda, llamada Cons, en la que la primera parte de la celda apunta al Car de la lista y la segunda al Cdr de la lista o un Nil. Funciones Aritméticas LDefNAtom(double) convierte el número Pspal argumento de la función en un átomo numérico. LDec(Numeric_Atom, Value) disminuye el valor del átomo numérico Numeric_Atom en las unidades indicadas por el segundo argumento de la función. Ejemplo 1 : X = LDefNAtom (3), LDec (x, 1), -> 2 2 LInc(nueric_atom, value) incrementa el valor del átomo numérico en las unidades indicadas por el segundo argumento de la función. LNumVal(numeric_atom) convierte el átomo numérico argumento de la función en un número manejable en PSPS. LSetNVal(Numeric_Atom, Value) asigna un valor numérico a un átomo que debe haber sido definido previamente. Ejemplo: X = LDefNAtom (“Numero”), LSetNVal ( X, 33 ) -> 33 Lista1 = LQ(“(Num1 Num2 Num3)”), LSetNVal (LCar( Lista1 ), 12) -> 12 1 - > Indica el resultado de evaluar la expresión anterior de Lisp mediante la función LPrint( ). 2 Las variables utilizadas en los ejemplos deben estar definidas en la sección Variables del modelo. Manual del Usuario PSPS IV 105 Capítulo 9: El Lenguaje Lisp Funciones de Listas A continuación describiremos algunas de las funciones elementales de Lisp que nos permitirán definir listas y realizar distintas operaciones con ellas. Funciones Constructoras LCons(List1, List2) construye una nueva lista en la que el Car de la nueva lista será List1 y el Cdr será List2. Ejemplos: Lista1 = LQ (“1“), Lista2 = LQ (“2”), LCons (Lista1, Lista2) -> (1 2) Lista1 = LQ (“(1 2)”), Lista2 = LQ(“(1 2 3)”) LCons (Lista1, Lista2) -> ((1 2) 1 2 3) LList(List) convierte el argumento de la función en una lista de forma que el argumento es el Car de la Lista definida y el Cdr es igual a Nil. Ejemplo: Lista = LQ( “(1 2 3)”), LList ( Lista ), -> ( (1 2 3) ) LAppend(List, List) devuelve una nueva lista, que será igual al resultado de la concatenación de los argumentos de la función. Los argumentos de esta función no se destruyen. Ejemplo: Lista1 = LQ(“(1 2 3)”), Lista2 = LQ(“(4 5 6)”), LAppend (Lista1, Lista2), -> (1 2 3 4 5 6) LPairList(List1, List2, Initial PairList) crea una lista de pares asociando los elementos de la primera lista con los correspondientes elementos de la segunda lista. El último argume nto de la función indica la lista de pares iniciales. Ejemplo: Lista1 = LQ( “(1 2 Lista2 = LQ( “(4 5 LPairList (Lista1, -> ((1 4) (2 5) (3 Manual del Usuario PSPS IV 3)”), 6)”), Lista2, Nil) 6)) 106 Capítulo 9: El Lenguaje Lisp Funciones Selectoras LCar(List) devuelve el Car de la lista argumento de la func ión. Ejemplos: Lista1 = LQ(“(1 2 3)”) LCar (Lista1) -> 1 Lista2 = Lq(“((1 2 3) 4)”), LCar (Lista2) -> (1 2 3) LCdr(List) devuelve el Cdr de la lista argumento de la función. Ejemplos: Lista1 = LQ(“(1 2 3)”) LCdr ( (1 2 3) ) -> (2 3) Lista2 = Lq(“((1 2 3) 4)”), LCdr ( ((1 2 3) 4) ) ->( 4 ) Lista3 = LQ (“((1 2 3))”) LCdr (Lista3) ->( )3 LCaar(List) devuelve el Car del Car de una lista. Esta función es la abreviación de la concatenación de dos funciones LCar ( ). Es decir LCaar ( ) = LCar ( LCar( )) Ejemplo: Lista1 = LQ(“((1 2) 3 4)”), LCaar (Lista1) -> 1 LCadr(List) devuelve el Car del Cdr de la lista argumento de la función. Igual que la función anterior es una abreviación de la concatenación de las funciones LCar ( ) y LCdr( ). Es decir LCadr ( ) = LCar ( LCdr ( )). Ejemplo: Lista = LQ(“(1 2 3)”), LCadr (Lista) -> 2 3 Lista vacía = Nil Manual del Usuario PSPS IV 107 Capítulo 9: El Lenguaje Lisp LLast(List) devuelve una lista con el último elemento de la lista argumento de la función. Ejemplos: Lista1 = LQ(“(1 2 3)”) LLast ( Lista1 ) ->( 3 ) Lista2 = LQ(“(1 (1 2))”), LLast ( Lista2 ) -> ( (1 2) ) LNth(List, Position) devuelve el elemento situado en la posición indicada por el segundo argumento de la función en la lista List. Ejemplo: Lista = Lq(“(1 2 (2 3))”), LNth ( Lista, 3) -> (2 3) Funciones de Asignación LSetCar(List1, List2) coloca la lista List2 como Car de la lista List1. La lista List1 queda modificada. Ejemplo Lista1 = LQ(“(1 2 3)”) Lista2 = LQ(“(A B C)”) LSetCar ( Lista1, Lista2 ) -> ( (A B C) 1 2 3 ) LSetCdr(List1, Lis t2) coloca la lista List2 como Cdr de la lista List1. La lista List1 queda modificada. Ejemplo Lista1 = LQ(“(1 2 3)”) Lista2 = LQ(“(A B C)”) LSetCdr ( Lista1, Lista2 ) -> ( ( 1 2 3 ) A B C ) LSetNth(List1, n, List2) coloca la lista List2 en la posicion n de la lista List1. La lista List1 queda modificada. Ejemplo Lista1 = LQ(“(1 2 Lista2 = LQ(“(A B LSetNth ( Lista1, -> (1 (A B C) 2 3 Manual del Usuario PSPS IV 3)”) C)”) 2, Lista2 ) ) 108 Capítulo 9: El Lenguaje Lisp Otras Funciones de Listas LAllAssoc(Key_value, List) devuelve una lista de asociació n con todos los record de la lista argumento de la función cuyo código coincide con el primer argumento de la función. LAssoc(Key, List Of Pairs) consulta una lista de la forma ( (Clave Valor) (Clave Valor) .... ) y devolverá el elemento de la lista cuya clave coincida con el argumento Key. Si hay varios devuelve el primero. Ejemplo: Lista1 = LQ(“(1 2 3 1)”), Lista2 = LQ(“( A B C D)”), ListaPares = LpairList(Lista1, Lista2, Nil), LAssoc (LQ(“1”), ListaPares), -> (1 A) LAllAssoc (Lq(“1”), ListaPares), -> ((1 A) (1 D)) LConc(List1, List2) concatena la lista List2 con la lista List1. La lista List1 queda modificada. Ejemplo: Lista1 = LQ(“(1 2 3 1)”), Lista2 = LQ(“( A B C D)”), LConc(Lista1, Lista2), -> (1 2 3 1 A B C D) LCopyList(List) crea una copia de la lista dada como argumento de la función. Es decir, hay dos direcciones de memoria que contiene la misma lista. LDefAtom(Atom_Name) convierte el argumento de la función en un átomo. LDelAssoc(Key_value, List) elimina un récord de una lista de asociación cuya clave coincida con el argumento Key_Value. Si hay varios elimina el primero. LDelete(Key_value, List) elimina de la lista List los elementos cuyo valor coincide con el del argumento Key_Value. La lista argumento de la función queda modificada. LGrow(List1, List2) añade un Cons al final de la lista List1 que apunta al Car de la lista List2. Manual del Usuario PSPS IV 109 Capítulo 9: El Lenguaje Lisp Ejemplo: Lista1 = LQ(“(1 2 3)”), Lista2 = LQ(“(A B C)”), LGrow (Lista1, Lista2), -> ( (1 2 3) A B C ) LInsert(List, record, Ke y_position) inserta en la lista el segundo argumento de la función en la posición indicada por el tercer argumento. LLength(list) devuelve el número de elementos de la lista argumento de la función. LListAt(address) devuelve la lista que se encuentra en la dirección de memoria argumento de la función. Ejemplo: Lista = LQ(“(1 2 3)”), LListAt(Lista), -> (1 2 3) LMember(Item, set_as_list) comprueba si Item es un elemento de la lista definida en el segundo argumento y devuelve el valor True, en caso contrario devolverá Nil. LQuote(String) esta función no evalúa el argumento, devuelve la string como tal. Esta función es útil cuando queremos escribir un objeto de Lisp como un valor constante en cualquier programa. LQ(String) convierte el argument o de la función en un símbolo, siempre que la string este formada por una unica cadena de caracteres entre comillas. LReverse(List) esta función invierte el orden de los elementos de la lista argumeto de la función. La lista argumento de la función no se modifica. Ejemplo: Lista = LQ(“(1 2 3)”), LReverse (Lista), -> (3 2 1) Funciones Predicado Estas funciones devuelven siempre True o Nil. Si la relación analizada es verdadera devolverán True y si es falsa devolverá Nil. LAtomt(List) devuelve True si el argumento de la función es un átomo y Nil en caso contrario. Manual del Usuario PSPS IV 110 Capítulo 9: El Lenguaje Lisp Ejemplos: Lista1 = LQ(“(1 2 3)”), LAtomp ( LCar (Lista1) ) -> T Lista2 = LQ(“((1 2) 3 4)”) LAtomp ( LCar ( Lista2 ) ) -> NIL LNullp(List) devuelve True si el argumento de la función es Nil, en caso contrario la función devuelve Nil. Ejemplos: Lista1 = LQ(“(1 2 3)”) LNullP ( LCdr( Lista1 ) ) -> Nill Lista2 = LQ(“((1 2))”) LNullP ( LCdr( Lista2 ) ) -> T LNumberp(List) devuelve True si el argumento de la función es un número, en caso contrario devolverá Nil. LListp(List) devuelve True si el argumento de la función es una lista, en caso contrario devolvera Nil. LEqv(List, List) devuelve True si los átomos de ambas listas tiene el mismo valor pero no son el mismo objeto. LEqual(List, List) devuelve True si los átomos de las dos listan tiene el mismo valor y la estructura es igual sean o no el mismo objeto. Funciones Evaluadoras LApply(Function, Argument_List, var_list) aplica la función Function a la lista de argumentos Argument_List usando para la evaluación la lista de variables var_list. La función que aparece como primer argumento puede ser cualquier función primitiva de Lisp o una función definida por el usuario. LE(string) es la abreviación de la función LEvalf LEval(Expression, Var_List) devuelve el resultado de evaluar la expresión dada como primer argumento de la función sobre la lista Var_List. LEvalf(string) es aquivalente a la función LEvalq(....., Nil). Manual del Usuario PSPS IV 111 Capítulo 9: El Lenguaje Lisp LEvalq(expression, var_list) aplica LEval al resultado de hacer el quote a una string, se le puede dar un contexto. LGet(atom, property) consulta la Lista de Propiedades 4 del átomo indicado, y devuelve el valor de la propiedad property. LGetAtoms(property) devuelve la lista de los átomo s definidos en cuya Lista de Propiedades4 esta la propiedad property. LGetTable(num) lee una string de la tabla dada argumento de la función y la transforma en una lista. como LGlobals obtiene la dirección de la lista de asociación de variables globales Lisp. LMapcar(Function, List) aplica la función definida en el primer argumento a todos los elementos de la lista suministrada, devolviendo la lista de resultados. LPutProp(atom, value, property) añade una propiedad a la Lista de Propiedades4 del átomo indicado que tendrá como identificador el tercer argumento y valor el segundo. Esta función modifica la Lista de propiedades existente, no crea una nueva. Devuelve el valor de la propiedad añadida. Ejemplo: Atomo = LDefAtom (“Casa”), LPutProperty (Atomo, Lq(“5”), Lq(“Ventanas”)), -> 5 LRemprop(atom, property) elimina una propiedad de la lista de propiedades4 del átomo Atom, cuyo identificador coincide con Property. Devuelve el valor de la propiedad eliminada. LVarVal(var_name, entorno) permite acceder a los valores de las variables definidas. Funciones de Comparación LGt(List1, List2) compara dos listas de forma lexicografica y devuelve True si la primera lista es mayor que la segunda. En caso contrario devuelve Nil. 4 Lista de Propiedades: Lisp tiene asociado a cada símbolo una estructura de datos llamada Property List. Esta lista inicialmente esta vacía. Cada entrada de la lista esta asociada a un indicador y a una lista o un átomo que llamaremos valor o propiedad. La estructura es la siguiente: ( (prop valor) (prop valor) . . . ). Manual del Usuario PSPS IV 112 Capítulo 9: El Lenguaje Lisp LLt(List1, List2) compara dos lista de forma lexicografica y devuelve True si la primera es menor que la segunda. En caso contrario devuelve Nil. Ejemplo: Lista1 = LQ(“(1 2 3)”) Lista2 = LQ(“(4 5 6)”) LLt( Lista1, Lista2 ) 5 -> T LAnd(List1, List2) devuelve Nil si alguno de sus argumentos es una lista vacía. En caso contrario devuelve la lista List2 argumento de la función. Ejemplo: Lista1 = LQ(“(1 2 3)”) Lista2 = LQ(“((1 2))”) LAnd( Lista1, LCdr ( Lista2 ) ) -> Nil 6 LOr(List1, List2) devuelve True si a lguno de los argumentos es distinto de Nil. Ejemplo: Lista1 = Lq(“(1 2 3)”) Lista2 = Lq(“((1 2))”) LOr( Lista1, LCdr ( Lista2 ) ) -> T LNot(List) devuelve True si el argumento es Nil y en caso contrario devuelve Nil. Ejemplos: LNot ( Nil ) -> T Lista1 = Lq(“(1 2 3)”) LNot ( LCar ( Lista )) -> Nil Funciones de Input - Output LPrint(List) escribe la lista, argumento de la función, entre parentesis en la ventana del Listener. Comienza con un salto de carro y termina con un espacio en blanco. 5 6 El CDR de la lista ( (1 2) ) es igual a la lista vacía ( ), es decir Nil. El CDR de la lista ( (1 2) ) es igual a la lista vacía ( ), es decir Nil. Manual del Usuario PSPS IV 113 Capítulo 9: El Lenguaje Lisp LPrint1(List) escribe la lista argumento de la función. La diferencia con la función LPrint( ) es que no deja espacio en blanco al final. LPPrint(List) imprime la lista argumento de la función con saltos de carro para una mejor lectura LOpenRdb(FileNa me) prepara una base de datos para su lectura posterior. El argumento es una string que indica el nombre del fichero de la base de datos. La función devuelve un átomo que se usará como referencia a la base de datos en el resto de las funciones. LRead(List) transforma los caracteres en datos de Lisp y devuelve la dirección de la lista. LGetRecord(FileAtom) devuelve, en forma de lista, el siguiente record de la base de datos identificada por FileAtom. Cuando intenta leer más allá del último record devuelve la lista vacía. LGetStruct(FileAtom) devuelve una lista con la estructura de campos de la base de datos identificada por FileAtom. LGetFileByName(FileAtom, Name) obtiene el valor del campo identificado con Name del record en curso del fichero FileAtom. LGetTable(UsertTableNum) lee una string de la tabla dada como argumento de la función y la transforma en una lista LEOfDb(FileAtom) si el fichero se ha agotado, es decir si la última llamada a la función LGetRecord ha intentado leer más allá del fin del fichero, devuelve el valor True. En caso contrario devuelve False. LCloseDb(FileAtom) esta función cierra la base de datos que hemos abierto con la función LOpenRdb y elimina la asociación entre la variable especificada y la base de datos. Otras Funciones de Lisp LFreeSpace función sin argumentos, que devuelve el número de celdas libres en la memoria Lisp. LFullGc esta función se encarga de reciclar las celdas de memoria que no van a volver a ser utilizadas por el programa, para que puedan ser reutilizadas posteriormente. Hace la “recolección de basura” de todos los átomos que no estén protegidos mediante la función LProtect. Manual del Usuario PSPS IV 114 Capítulo 9: El Lenguaje Lisp LGc Garbage Collecting. Esta función se encarga de liberar la memoria eliminando de la memoria todas las listas que no se necesitan. Es responsabilidad del usuario preservar las variables que contiene listas en uso mediante la función LStatic. También las variables globales del PSPS cuyo identificador es de la forma Lispxxx contienen listas que hay que preservar siempre. LGenSym esta función genera un símbolo garantizando que es único. Esta función es de gran utilidad para asociar una variable a un símbolo Lisp. Ejemplo: X = LGenSym, Atomo = LdefAtom (“Casa”), LPutProp(Atomo, LQ(“5”), X), LGet(Atomo, X), -> 5 LNoise esta función activa la escritura del mensaje de las funciones LGc y LStats cuando hemos utilizado la función LSilence. LPointer(&psps_variable) crea un átomo que contiene la dirección de la variable PSPS indicada en el argumento de la función. LProtect(List) declara la lista del argumento con carácter reservado, lo que significa que no se elimina en el primer uso del GC. LSetq(variable, value, var_list) el primer argumento de esta función es un símbolo que no será evaluado. El segundo argume nto es asignado como el valor de la variable primer argumento de la función utilizando el entorno var_list. LSort(list, Key_position) ordena la lista según la posición indicada por el segundo argumento. LStatic(List) declara el argumento de la función con carácter permanente, es decir siempre estará protegida contra el Gc. Si el valor de la variable cambia, la nueva lista no se preservara a no ser que se vuelva a poner como argumento de la función LStatic. LStats muestra las estadísticas de ocupación de memoria del sistema. LSilence esta función desactiva el mensaje que mandan al Listener las funciones LGc y LStats. LShow(List) convierte el argumento de la función en una string. El argumento de esta función es una variable Pspal que contiene la dirección de una lista. Manual del Usuario PSPS IV 115 Capítulo 9: El Lenguaje Lisp LUnStatic(List) elimina de la lista protegida la lista dada como argumento de la función que habia sido protegida mediante la función LStatic. LTrace(Boolean) si el argumento es igual a True se realiza la traza de las sentencias de Lisp ejecutadas. LSTrace(Boolean) si el argumento es igual a True se realiza la traza del sistema de las sentencia de Lisp ejecutada. ¿Cómo acceder desde Lisp a Pspal? Existen tres funciones de Lisp que nos permitirán ejecutar cualquier funció n Pspal y devolver los resultados en formato Lisp. Como el resultado de una función Pspal no es más que un número sin interpretación, se necesitan tres funciones. Una para trasladar a Lisp un resultado numérico, otra para enviar a Lisp una lista y una última función para enviar un valor booleano. PspsNum devuelve átomos numéricos, PspsList devuelve punteros a listas (es decir listas LISP) y PspsBool devuelve T o Nil (los valores booleanos correspondientes a los de Pspal: True o False) Formato: (PspsNum …) (PspsList …) (PspsBool …) Argumentos: …: son expresiones Lisp, que se evaluaran antes de aplicarles la función Pspal. El resultado de la evaluación se interpreta de las siguiente manera según sea: - Un número Lisp (un átomo numérico). El valor numérico del átomo se usara en la llamada a la función Pspal. - Una lista Lisp. Se pasa a la función Pspal la dirección de la lista - Un átomo. El átomo se toma como nombre de una variable Pspal, cuyo contenido se usará como argumento. Por este medio se pueden pasar valores Pspal cualesquiera, incluyendo listas. Nótese que esta característica impide el uso de otros Manual del Usuario PSPS IV 116 Capítulo 9: El Lenguaje Lisp átomos como argumentos, ya que siempre se interpretan como nombres de variables. es una expresión que debe evaluarse a un átomo no numérico. Suele ser una expresión quoted, en la forma 'Nombre. El resultado de la aplicación de una de estas funciones se transformará en una átomo numérico para PspsNum , en una lista para PspsList o en un valor booleano LISP (T o Nil) para PspsBool. Manual del Usuario PSPS IV 117 CAPITULO 10: Las Funciones Know § § § § § § Manual del Usuario PSPS IV Patrones (Patterns) Bases de Conocimiento (Knowledge Bases) Reglas (Rules) Redes Semánticas (Associative NetWorks) Frames Búsqueda (Search) Capitulo 10. Las Funciones de Conocimiento Las funciones de conocimiento disponibles en el PSPS se agrupan en distintos paquetes que describiremos en detalle en este capítulo con ayuda de sencillos ejemplos. Las funciones que presentamos son una adaptación al PSPS de los paquetes desarrollados por Kreutzer en su libro Programming For Artificial Intelligence1. Allí están presentadas en Scheme, una variedad de Lisp. Nosotros las hemos traducido y adaptado al contexto del PSPS. Patrones (Patterns) Definiremos un patrón como una lista formada por elementos básicos (átomos y listas LISP) y una serie de elementos propios de los Patrones que describiremos a continuación. Los Patrones se utilizan para ver si una lista encaja con una determinada estructura, y obtener información de la lista comparándola con el patrón. El resultado de este tipo de comparaciones suele ser un valor booleano, True si el patrón definido es semejante (encaja con) la lista y False en caso contrario. También puede que devuelva una lista de asociación, con pares de la forma . Llamaremos un encaje a la operación de poner en correspondencia una lista cualquiera, que llamaremos lista objetivo, con un patrón determinado. Un elemento de la lista objetivo es un átomo o una sublista de la misma. Diremos que un patrón encaja con un/os símbolo/s cuando la operación de encaje devuelve el valor True. La operación de encajar en PSPS la efectúa la función KMatch, que describiremos más adelante. Elementos 'especiales' de un patrón. '? En un encaje, asocia la posición del patrón en la que se encuentra a cualquier elemento correspondiente de la lista objetivo. '?+ En un encaje, asocia la posición del patrón en la que se encuentra a uno o varios elementos correspondientes de la lista objetivo. '(?Var) En un encaje, asocia la posición del patrón en la que se encuentra, a cualquier elemento, y guarda el valor del elemento correspondiente en la variable Var, y devuelve una AList que contiene la asociación (Var Valor). 1 Kreutzer, W., McKenzie, B. Programming for Artificial Intelligence: Methods, Tools and Applications. Addison Wesley, 1991. Manual del Usuario PSPS IV 118 Capitulo 10. Las Funciones de Conocimiento '(?+Var) En un encaje asocia la posición del patrón en la que se encuentra a una secuencia de elementos de la lista objetivo y devuelve una AList formada por la asociación (Var Valor) en la que Valor será una lista con la secuencia de elementos simples. '(<-?Var) Indica que el encaje debe de ser sustituido por el valor de la variable Var que en este momento debe tener asociado un valor como resultado de una asignación anterior. '(?Var(función Fn)); ' ( <- ? Var (función Fn )); y '(?+Var(función Fn)) La función Fn es una función LISP (aunque se puede usar las funciones psps por medio del mecanismo de comunicación). Estos elementos son similares a los descritos anteriormente, la única diferencia es que cuando realizamos un encaje la función Fn se incluye en la condición de encaje, es decir, la función Fn debe devolver el valor True. La función tiene un solo argumento, que el sistema le pasa en forma de la AList que contienen la asociación (Var Value). Funciones de Encaje PSPS KGetAssVal (unaPatVar, anAList) devuelve el valor asociado a una variable en la AList dada como segundo argumento de la función. KMatch (unPatron, aListObj, anAList) encaja un patrón con una lista y devuelve el valor True si coinciden el patrón y la lista objetivo o Nil en caso contrario. Si el patrón contiene variables, la función devolverá una AList con los pares de la forma (Variable Valor). Ejemplos 2 : Kmatch(LE(“(PATTERN ‘Numero 'Impar '?)”), LQ(“(Numero Impar 13)”)); -> T Esta sentencia devolverá el valor True, ya que el patrón definido en el primer parámetro de la función coincide con los elementos de la lista objetivo. Los dos primeros elementos de dic ha lista coinciden con los del patrón y el tercer elemento puede ser cualquier elemento, con lo que se produce el encaje. KMatch(LE(“(PATTERN Impar 13)”), Nil); 'Numero 'Impar '(? X))”), LQ(“(Numero ->( ( X 13) ). KMatch(LE(“(PATTERN Impar 13 !)”), Nil); 'Numero 'Impar '(?+ X))”),LQ(“(Numero ->((X (13 !))). 2 -> Indica el resultado de evaluar la expresión anterior mediante la función LPrint() Manual del Usuario PSPS IV 119 Capitulo 10. Las Funciones de Conocimiento Kmatch (LE(“(PATTERN 'Numero 'Impar ,LQ(“(Numero Impar 13 !)”), Nil); '(? X) '(? Y))”) ->((X 13) (Y !)) Formatos de Lisp (PATTERN patronElements) Define un patrón. Para definir un patrón se deben entregar una serie de átomos o listas a la función PATTERN, y evaluarla. Esto se consigue en PSPS usando la función LE en la forma LE(“(PATTERN patronElements)”). Los argumentos pueden ser cualquiera de los elementos validos, es decir strings, números, listas y los elementos especiales que hemos descrito antes. Knowledge Bases (KBs). Las KBs se utilizan para almacenar hechos. Cada hecho viene dado por una proposición, si se trata de una KB de afirmaciones, o por un patrón si la KB es utilizada para almacenar patrones. Las funciones disponibles en PSPS para la edición y manejo de estas bases de conocimiento son las siguientes: Funciones PSPS KMakeKB(aListOfFacts) define una base de datos formada por la secuencia de hechos dados como argumentos de la función, que como hemos dicho antes puede ser una secuencia de proposiciones en forma de listas (en una KB de Assertions) o una colección de patrones. Ejemplo 3 : KMakeKB(LQ("(1 2 3)"),LQ("(uno dos tres)"),LQ("(esto son numeros)")) ->((1 2 3) (UNO DOS TRES) (ESTO SON NUMEROS)) KKnownFactP(aFact, aKB) la función devolverá el valor True si el primer argumento pertenece a la KB indicada, en caso contrario devolverá Nil. 3 -> Indica el resultado de evaluar la expresión anterior mediante la función LPrint(). Manual del Usuario PSPS IV 120 Capitulo 10. Las Funciones de Conocimiento Ejemplo 4 : KBase = KMakeKB(LQ( "(1 2 3)"),LQ("(uno dos tres)"),LQ("(I II III)")), KKnownFactP (LQ("( I II III)"), KBase), -> T KAddFact(aKB, aFact) añade un nuevo ítem dado como segundo argumento, a la KB indicada en el primer argumento de la función. Ejemplo: KBase = KMakeKB(LQ( "(1 2 3)"),LQ("(uno dos tres)"),LQ("(I II III)")), KAddFact (Kbase, LQ("( 4 5 6)")), -> ( (1 2 3) (unos dos tres) (I II III) (4 5 6) ) KRemoveFact(aKB, aFact) elimina el ítem indicado de la KB dada como primer argumento de la función. Ejemplo: KBase = KMakeKB(LQ( "(1 2 3)"),LQ("(uno dos tres)"),LQ("(I II III)")), KRemoveFact (Kbase, LQ("(I II III)")), -> ( (1 2 3) (unos dos tres) ) KPrintKB(aKB) muestra la mediante la función KMakeKB. KB, probablemente construida Ejemplo 5 : KBase = KMakeKB(LQ( "(1 2 3)"),LQ("(uno dos tres)"),LQ("(I II III)")), KprintKB(KBase) -> ((1 2 3) (uno dos tres) (I II III)) KEmptyRetrievedList(aRetrievedList) comprueba si la lista devuelta por alguna de las funciones KRetrievedByPattern, RetrievedByString, KRetrievedAllByPAttern, y KretrievedAllByString es igual a la lista nula. KCurrentRetrievedElement(aRetrievedList) devuelve el primer elemento de una lista de contenidos, aRetrievedList, que se obtiene mediante las funciones KRetrievedByPattern, RetrievedByString, KRetrievedAllByPAttern, y KretrievedAllByString. Un elemento de una lista de contenidos es una lista de dos elementos: un Hecho y una Alista, obtenida de los procesos de comparación de los Patrones con variables. KRestOfRetrievedList(aRetrievedList) devuelve el resto de los elementos de la lista de contenidos, argumento de la función. 4 Las variables utilizadas en los ejemplos deben estar definidas en la sección Variables del modelo. Las variables contendrán la dirección de memoria que apunta al objeto definido. 5 En este ejemplo la función KPrintKB sustituye al uso de la función LPrint( ). Manual del Usuario PSPS IV 121 Capitulo 10. Las Funciones de Conocimiento KGetFact(aRetrievedElement), KGetAList(aRetrievedElement) estas dos funciones sirven para obtener cada uno de los dos componentes de un elemento de una lista de contenidos. KRetrievedByPattern(aKB,unPatron,aSelectorLispFn, anAList) procesa el patrón dado y lo compara con el contenido de la KB, elemento por elemento y de forma secuencial. Esta función se detiene cuando encuentra el primer elemento de la base de datos que encaja con el patrón definido en el segundo argumento de la función. La función devuelve el ítem de la KB que encaja con el patrón. Ejemplo: KBase = KMakeKB (LQ( "(1 2 3)"), LQ("(I II III)"),LQ("(1 2 4)")), KRetrieveByPatter (KBase, LE("(PATTERN '1 '2 '?)"), Nil, Nil), -> ( ((1 2 3)) ) KRetrievedByFact(aKB, aFact, aSelectorLispFn, anAList) se encarga de comparar los ítems de la lista aFact con los patrones definidos en la KB. Todos los patrones almacenados serán comprobados en secuencia. La función devuelve una lista con la primera coincidencia y su correspondiente AList, en el caso de que el patrón definido contenga variables. KRetrievedAllByPattern(aKB,unPatron,aSelectorLispFn,anAList) devuelve una lista de todos los elementos de la KB que coinciden con la estructura del patrón dado. Ejemplo: KBase = KMakeKB (LQ( "(1 2 3)"), LQ("(I II III)"),LQ("(1 2 4)")), KRetrieveAllByPatter (KBase, LE("(PATTERN '1 '2 '?)"), Nil, Nil), -> ( ((1 2 3)) ((1 2 4)) ) KRetrievedAllByFact(aKB, aFAct, aSelectorLispFn, anAList) es similar a la función KRetrievedByString, la diferencia es que no se detiene al encontrar la primera equivalencia y devuelve la lista completa de coincidencias. Formatos de Lisp (MAKEKB initialHechos) Define una KB formada por la lista de ítems dados, que como en el caso de la función del PSPS KMakeKB puede ser una colección de proposiciones o una colección de patrones. Manual del Usuario PSPS IV 122 Capitulo 10. Las Funciones de Conocimiento Rules En esta sección definiremos dos tipos de KBs. La KB que llamaremos Memoria de Reglas, Production Memory (PM), se encargará de almacenar las reglas que definamos y la KB Memoria de Trabajo, Working Memory (WM), que se encargará de almacenar las proposiciones iniciales, y los resultados de la aplicación de las reglas. Su contenido se puede modificar mediante las sentencias 'Asserts' y 'Retracts' de las reglas. La reglas almacenadas en la PM están formadas por dos partes. La parte primera de una regla, las Condiciones, esta formada por una secuencia de proposiciones, patrones o negaciones de patrones. La segunda parte de una regla son las conclusiones. Cada conclusión esta formada por una secuencia arbitraria de acciones que pueden incluir 'Asserts', 'Retract' y otras operaciones entre elementos de la WM. Las funciones disponibles en el PSPS para la definición de reglas son las siguientes: Funciones PSPS KMakeWM(aListOfFacts) crea una KB que utilizaremos como Working Memory que almacenara la serie de Hechos dados como argumentos de la función. KMakePM(aListOfRules) crea una KB que utilizaremos como Production Memory para almacenar las reglas que definamos. Ejemplo: Regla1 = KRule (Lq("Regla1"), KConditions(LQ("(Goal eat)"), LQ("(Monkey on floor)")), KConclusions( KRetract(LQ("(goal climb)")))), Regla2 = KRule (Lq("Regla2"), KConditions(LQ("(Goal climb)"), LQ("(Monkey on floor)")), KConclusions( KRetract(LQ("(MOnkey on floor)")))), KMakePM(Regla1, Regla2) -> ((REGLA1 ((GOAL EAT) (MONKEY ON FLOOR)) ((RETRACT (GOAL CLIMB)))) (REGLA2 ((GOAL CLIMB) (MONKEY ON FLOOR)) ((RETRACT (MONKEY ON FLOOR))))) KRule(Name, Conditions, Conclusions) define una nueva regla. Una regla tiene tres componentes, el nombre, las condiciones que se deben cumplir y las conclusiones que son las acciones que se lleva a cabo en el caso de que se verifiquen las condiciones anteriores. KConditions(aListOfConditions ) la lista de condiciones debe ser una lista de proposiciones y patrones. Esta lista también puede Manual del Usuario PSPS IV 123 Capitulo 10. Las Funciones de Conocimiento contener la negación de patrones que se consigue mediante la función KNegate ( ). KConclusions(aListOfConclusions) esta parte de una Regla define las acciones que se llevaran a cabo sobre la WM en el caso de verificarse las condiciones de la regla, puede contener un número cualquiera de ASSERTION, RETRACS y llamadas a los procedimientos EXECUTE y RETURN. KPrintWM(aWM) muestra la KB creada mediante la función KMakeWM. KPrintPM(aPM) muestra la KB creada mediante la función KMakePM. Ejemplo 6 : Regla1 = KRule (Lq("Regla1"), KConditions(LQ("(Goal eat)"), LQ("(Monkey on floor)")), KConclusions( KRetract(LQ("(goal climb)")))), Regla2 = KRule (Lq("Regla2"), KConditions(LQ("(Goal climb)"), LQ("(Monkey on floor)")), KConclusions( KRetract(LQ("(MOnkey on floor)")))), BaseReglas = KMakePM(Regla1, Regla2), KprintPM (BaseReglas), -> + + + Rule: REGLA1 Conditions: (GOAL EAT) (MONKEY ON FLOOR) Conclusions: RETRACT:(GOAL CLIMB) + + + Rule: REGLA2 Conditions: (GOAL CLIMB) (MONKEY ON FLOOR) Conclusions: RETRACT:(MONKEY ON FLOOR) KFireRule(aRule, aWM, VerboseFlag) este procedimiento nos permite ejecutar una regla sin necesidad de añadirla a la PM. La función devuelve la nueva WM pero no modifica la WM que tenemos guardada. KPrintRule(aRule) muestra la regla cuyo nombre aparece en el argumento de la función. En este ejemplo la función KPrintPM no tiene que ser evaluada mediante la función LPrint( ). 6 Manual del Usuario PSPS IV 124 Capitulo 10. Las Funciones de Conocimiento KNegate(unPatron) operador de negación. Se utiliza en la definición de condiciones de reglas. KAssert(aFact) tiene como argumento un hecho, que añadirá a la WM. Si ya esta en WM no se realiza operación alguna. KRetract(aFact) podemos decir que se trata de la función inversa de la anterior. Esta función elimina de la WM el hecho dado como argumento de la función. El argumento de esta función debe ser un hecho conocido para la WM, ya que en caso contrario no se altera la WM. KExecute(aLispProc, aParameterLis) procedimiento que usado en las conclusiones de una Regla ejecuta una función Lisp. KReturnP(aLispProc, aParameterList) procedimiento que detiene el proceso de las reglas devolviendo el valor de la función ejecutada como resultado del procedimiento KForwardChainer. KForwardChainer(aPM, aWM, VerboseFlag) procedimiento de deducción lógica por Encadenamiento Directo. Esta función define un mecanismo de inferencia que toma las reglas en el orden que aparecen en la base de datos y las aplica repetidamente hasta que no se pueden aplicar más reglas, o alguna regla detiene el proceso por medio de la función RETURN. Típicamente esto sucede cuando se alcanza una cierta conclusión. Formatos de Lisp (MAKEWM InitialHechos) Define una WM a partir de la secuencia de Hechos dados como argumentos de la función. (MAKEPM InitialRules) Define una PM a partir de las reglas dadas como argumento de la función. (RULE aName aConditionList aConclusionList) Define una nueva regla a la que se le asigna un nombre y se definen las condiciones y conclusiones. (CONDITIONS anyNumberOfItems ) Define la lista de condiciones de una Regla. (-| aFact) Operador de negación del hecho que aparece como argumento. Se utiliza en la definición de condiciones de reglas. (CONCLUSIONS anyNumberofAsserts) Define las conclusiones de una Regla y puede contener cualquier número de ASSERTs RETRACTs o llamadas a procedimientos EXECUTE y RETURN. Manual del Usuario PSPS IV 125 Capitulo 10. Las Funciones de Conocimiento (ASSERT aFact) Añade aFact a la WM. Típicamente aparece entre las conclusiones de una regla y añade el hecho a la WM en caso de verificarse la condición de la regla. (RETRACT aFact) Es un elemento de la lista de conclusiones de una regla que elimina aFact de la WM. (EXECUTE (function fn) parameters) Procedimiento que ejecuta la función fn con los parámetros indicados. (RETURN (function fn) parameters ) Procedimiento que ejecuta la función fn A diferencia del procedimiento EXECUTE este para el proceso de la reglas devolviendo el valor de la función como resultado del ForwardChainer. Ejemplo: El ejemplo muestra un fragmento de una base de reglas BaseReglas = LE(“(MakePM (RULE '1-GiveGoal {---Prepara el goal---} (CONDITIONS (-| (PATTERN 'goal '?))) (CONCLUSIONS (ASSERT '(goal eat)))) (RULE '2-Eat (CONDITIONS '(goal eat) '(monkey on box)) (CONCLUSIONS (EXECUTE (lambda(x)(print x)) '(Eating bannana...delicious!)) (RETURN (lambda(x) (print x)) 'HungerOK))) (RULE '3-Eat (CONDITIONS '(goal eat) '(monkey on floor)) (CONCLUSIONS (RETRACT '(goal eat)) (ASSERT '(goal climb)))) (RULE '4-Climb (CONDITIONS '(goal climb) '(monkey on box)) (CONCLUSIONS (RETRACT '(goal climb)) (ASSERT '(goal eat)))) (RULE '5-Climb (CONDITIONS '(goal climb) '(monkey on floor) (PATTERN 'monkey (PATTERN 'box (PATTERN 'bannanas (CONCLUSIONS (RETRACT '(monkey (ASSERT '(monkey Manual del Usuario PSPS IV 'at '(? x)) 'at '(<-? x)) 'at '(<-? x))) on floor)) on box))))”) 126 Capitulo 10. Las Funciones de Conocimiento Associative Networks Un AN es una red de asociaciones formada por Nodos y Arcos. Los Nodos representan Conceptos que se relacionan con otros conceptos mediante vínculos (Links) que corresponden a los arcos. Los Links pueden ser de dos tipos AKOLinks que define clases o subclases de objetos y Links ordinarios que definen un tipo de relación binaria entre dos conceptos de la red. Las funciones disponibles en PSPS para el tratamiento de este tipo de redes son las siguientes: Funciones PSPS KAKO(aConceptList) definido previamente. define una subclase de un concepto KMakeAN(aConceptList) función que se utiliza para definir una AN, los argumentos de la función son una secuencia de conceptos iniciales de la red. KLink(aLinkName, aConceptName, aCertaintyFactor) define una clase de asociación binaria entre conceptos. El primer argumento es una etiqueta que indica el nombre del Link; el segundo es el concepto al que el Link esta unido y por último, el tercer argumento es un número real entre cero y uno que indica la cantidad de 'incertidumbre' asociada con la relación. El valor por defecto de este factor es 1. KAddLink(anAN, aConceptSymbol, aLinkSymbol) añade un Link al concepto dado por el segundo argumento, dentro de la AN dada como primer argumento de la función. Ejemplo 7 : KAddLink ( Base, LQ("Vida"), KLink(LQ("tiene"), Lq("Peligro"), 1)) -> ((CRIATURA ((TIENE VIDA))) (ANIMAL ((AKO (CRIATURA)))) (HUMANO ((AKO (CRIATURA)) (ES MORTAL) (LEGUSTA DINERO 0,50))) (MARIA ((AKO (HUMANO)))) (LEON ((AKO (ANIMAL)) (TIENE FUERZA))) (MORTAL) (FUERZA) (DINERO) (VIDA ((TIENE PELIGRO)))) KRemoveLink(anAN, aConceptSymbol, aLinkSymbol) elimina un Link del concepto dado por el segundo argumento, dentro de la AN dada como primer argumento de la función 7 En este ejemplo y los que siguen en esta sección utilizaremos la red de asociación definida mediante los formatos de Lisp en las paginas siguientes. Manual del Usuario PSPS IV 127 Capitulo 10. Las Funciones de Conocimiento KAddAKOLink(anAN, aConceptSymbol, superSymbol) añade un Link del tipo AKO al concepto dado por el segundo argumento la AN dada como primer argumento de la función. KRemoveAKOLink(anAN, aConceptSymbol, superSymbol) elimina un Link del tipo AKO definido en la red y concepto dada como primer argumento de la función. KConcept(aConceptName, aSlotList) se utiliza para definir un Concepto. Un concept esta formado por una etiqueta, el nombre del concepto y una lista de links que pueden ser de cualquiera de los tipos descritos anteriormente. KPrintAN(anAN) muestra una AN definida mediante la función KMakeAN. Ejemplo: KPrintAN(Base), -> *******Associative Network********* CRIATURA: (LINK (TIENE VIDA)) ANIMAL: (AKO (CRIATURA)) HUMANO: (AKO (CRIATURA))(LINK (ES MORTAL))(LINK (LEGUSTA DINERO 0,50)) MARIA: (AKO (HUMANO)) LEON: (AKO (ANIMAL))(LINK (TIENE FUERZA)) MORTAL: FUERZA: DINERO: KAddConcept(anAN, aConcept) devuelve una nueva AN como resultado de añadir un concepto. Si queremos que le cambio se mantenga debemos asociar el resultado de esta función a la correspondiente variable que representa a la AN modificada. KRemoveConcept(anAN, aConceptSymbol) devuelve una nueva AN resultado de eliminar el concepto dado como segundo argumento de la función. KFindAllConcepts(anAN) devuelve una lista de todos Conceptos contenidos en la AN argumento de la función. los KFindAllLinkNames(anAN) devuelve una lista con las etiquetas de todos los Links definidos en la AN argumento de la función. KFindConcept(anAN, aConceptSymbol) busca especifico en la AN indicada. un concepto KGetAKOSlot (anAN, aConceptSymbol) devuelve el SLOT que define el concepto aConceptSymbol en la red anAN como un AKO. Manual del Usuario PSPS IV 128 Capitulo 10. Las Funciones de Conocimiento Ejemplo: KGetAKOSlot(Base, Lq("Humano"))), -> (AKO (CRIATURA)) KGetAKOLinks(anAN, aConceptSymbol) devuelve una lista de las superclases, es decir de los Links definidos como AKO. KGetAKOChain(anAN, aConceptSymbol) recorre los Links definidos como AKOLinks y devuelve una lista con todos los superconceptos a los que el segundo argumento de la función esta conectado. Ejemplo: KGetAKOChain(Base, LQ("Leon"))), -> (LEON ANIMAL CRIATURA) KGetLinkSymbolSlots(anAN, aConceptSymbol, aLinkSymbol) devuelve una lista de todos los Links simples, es decir no definidos como AKOLink, unidos a un nodo o concepto dado. KFindAllLinkedConcepts(anAN,aConceptSymbol1, aLinkSymbol, aThresHoldValue) devuelve una lista de los conceptos unidos directamente o heredados, mediante el link aLinkSymbol, al concepto argumento de la función. KFindAllLinks(anAN,aConceptSymbol1,aConceptSymbol2, aThresHoldValue) devuelve una lista de todas las uniones posibles entre dos nodos dados, es decir entre dos conceptos argumentos de la función. KLinkedP(anAN,aConceptSymbol1,aConceptSymbol2, aThresHoldValue) comprueba si existe unión entre dos conceptos. Esta función puede estar cuantificada por un umbral de verosimilitud, de manera que el los Links entre los dos conceptos deben tener al menos la verosimilitud indicada por el ultimo argumento de la función. Formatos de Lisp (AKO conceptFrameNames) Define una subclase del concepto dado como argumento de la función. (LINK aLinkName aConceptName [acertaintyFactor]) Define un Link simple, es equivalente a la función KLink ( ). (CONCEPT aConceptName Links) Define un concepto, similar a la función KConcept( ). (MAKEAN concepts) Define una AN a partir de una lista de conceptos. Manual del Usuario PSPS IV 129 Capitulo 10. Las Funciones de Conocimiento Ejemplo: Base = LEvalf ( "(MakeAN (CONCEPT 'Criatura (LINK 'Tiene 'Vida)) (CONCEPT 'Animal (AKO 'Criatura)) (CONCEPT 'Humano (AKO 'Criatura) (LINK 'es 'Mortal) (LINK 'legusta 'dinero 0.5)) (CONCEPT 'Maria (AKO 'Humano)) (CONCEPT 'Leon (AKO 'Animal) (LINK 'Tiene 'Fuerza)) (CONCEPT 'Mortal) (CONCEPT 'Fuerza) (CONCEPT 'Dinero)) "), Frames Un Frame permite la representación de objetos o de clases de objetos. Un Frame esta formado por una colección de Slots, cada uno de estos Slots. Los Slots pueden ser de dos tipos los simples y los del tipo AKO. Los Slots simples se completan con diferentes tipos de valores que llamaremos Facets y también pueden incluir procedimientos. Los Slots del tipo AKO contiene una lista de Frames y hacen que el Frame definido herede las propiedades de los frames contenidos en esta lista. Las Facets también pueden ser del tipo VALUE o DEFAULT o contener los procedimientos IF-NEEDED, IF-ADDED, o IF-REMOVED Funciones PSPS KAddFacet(anFN, aFrameName, aSlotName, aFacet) esta función nos permite añadir un Facet a un Slot de un Frame definido dentro de una red de Frames. Ejemplo: Red = KMakeFN ( KFRAME ( LQ("Fabricado"), KSLOT (Lq("Proveedor"), KDEFAULT (LQ("Fabricado!")))), KFRAME ( LQ("MateriaPrima"), KSLOT (Lq("Proveedor"), KDEFAULT (LQ("NoTieneFijo")))) ), KAddAFacet (Frames, LQ("MateriaPrima"), LQ("Stock"), KDefault (LQ("50"))), -> ((FABRICADO ((PROVEEDOR ((DEFAULT FABRICADO!))))) (MATERIAPRIMA ((PROVEEDOR ((DEFAULT NOTIENEFIJO))) (((DEFAULT 50)))))) ) (STOCK KAddFrame(aFN, aFrame) esta función permite añadir un nuevo Frame a la red de Frames dada como primer argumento de la función. Manual del Usuario PSPS IV 130 Capitulo 10. Las Funciones de Conocimiento KAddSlot(anFN, aFrameName, aSlot) nos permite añadir un Slot a un Frame que se encuentra en una red de Frames. KAddAValue(anFN, aFrameName, aSlotName, aValue) nos permite añadir un Facet de tipo Value a un Slot de un Frame definido en una red de Frames. Si el slot no esta definido la función lo creara. KAKO (aListOfFrames) define un Fra me del tipo AKO que heredara las propiedades de la lista de Frames argumento de la función. KCreateValue(anFN, aFrameName, aSlotName, aValue) define un facet de tipo Value en un Slot de un Frame de una red de Frames. KDefault(aValue) se utiliza para definir un tipo de Facet que define el valor de una propiedad en los casos en los que no se conozca un valor especifico, es decir que no se ha definido una facet del tipo VALUE. KFacetType(aFacet) devuelve el tipo del Facet argumento de la función. KFirstFrame(anFN) devuelve el primer Frame de la red de Frames argumento de la función. Ejemplo: Red = KMakeFN(KFRAME (LQ("Fabricado"), KSLOT (LQ("Proveedor"), KDEFAULT (LQ("Fabricado!")))), KFRAME (LQ("MateriaPrima"), KSLOT (LQ("Proveedor"), KDEFAULT (LQ("NoTieneFijo")))) ), KFirstFrame (Red), -> (FABRICADO ((PROVEEDOR ((DEFAULT FABRICADO!))))) KFirstSlot(aSlotList) devuelve el primer Slot de la lista de Slots argumento de la función. KFisrtFacet(aList) devuelve el primer Facet de la lista argumento de la función. KFrame(aFrameName, slot1, ..., slotn) define un Frame de nombre aFrameName y formado por los Slots dados como argumento de la función. KFrameL(aFrameName, atListOfSlots) define un Frame a partir de la lista de Slots dada como segundo argumento de la función. KFrameName(aFrame) devuelve el nombre del Frame argumento de la función que ha sido definido mediante la función KF rame ( ). Manual del Usuario PSPS IV 131 Capitulo 10. Las Funciones de Conocimiento Ejemplo: Frame1 = KFrame ( Lq("Fabricado"), KSlot( LQ("Slot1"), KDefault( LQ("3"))), KSlot( LQ("Slot2"), KDefault(LQ("5")))), KFrameName (Frame1), -> Fabricado KGetAValue(anFN, aFrameName, aSlotName) esta función devuelve el valor correspondiente al slot y el Frame indicados en los argumentos de la función. Para ello primero buscara los Facets de tipo Value, si no existe entonces buscara uno del tipo Default, por ultimo activara el procedimiento If-Needed. Si el valor no se puede encontrar, entonces la función devuelve la string 'NotKown'. KGetFacet(aSlot, aFacetName) función de acceso que permite obtener la Facet dada por el segundo argumento dentro del slot dado por el primer argumento de la función. KGetFacets(aSlot) función de acceso que permite obtener los Facets del Slot argumento de la función. KGetFrame(anFN, aFrameName) función de acceso que permite obtener la Frame dada por el segundo argumento dentro de la red indicada por el primer argumento de la función. Ejemplo: Red = KMakeFN(KFRAME ( LQ("Fabricado"), KSLOT (Lq("Proveedor"), KDEFAULT (LQ("Fabricado!")))), KFRAME ( LQ("MateriaPrima"), KSLOT (Lq("Proveedor"), KDEFAULT (LQ("NoTieneFijo")))) ), KGetFrame (Red, LQ("MateriaPrima")), -> (MATERIAPRIMA ((PROVEEDOR ((DEFAULT NoTieneFijo))))) KGetFrameName(aFrame) función de acceso que obtener el nombre de la Frame argumento de la función. permite KGetFrameNames(anFN) función de acceso que permite obtener los nombres de las Frames de la red argumento de la función. KGetNumValue(aSlot) caso especial de la función KGetFacet que nos permite obtener un Facet de tipo VALUE numérico. La función devuelve un número Pspal. KGetSlot(anFN, aSlotName) función de acceso que permite obtener el Slot dada por el segundo argumento dentro de la red de frames indicada por el primer argumento de la función. kGetSlots(aFrame) función de acceso que nos permite obtener todos los Slots de la Frame argumento de la función Manual del Usuario PSPS IV 132 Capitulo 10. Las Funciones de Conocimiento KGetValue(aSlot) caso especial de la función KGetFacet que nos permite obtener un Facet de tipo VALUE. KGetValues(aFacet) nos permite obtener todas las Facets de tipo VALUE. KIfAdded(aDemonLispProc) define un procedimiento que se activara cuando se añada el valor de un Slot o se modif ique. KIfNeeded(aDemonLispProc) define un procedimiento que se activara cuando no este definido ni un Value ni un Default en el Slot correspondiente. KIfRemoved(aDemonLispProc) define un procedimiento que se activara cuando de elimine el valor de un Slot. KMakeFN(anyNumberOfFrames) define una red de Frames que contendrá los Frames dados como argumentos de la función. Ejemplo: KMakeFN (KFRAME (LQ("Fabricado"), KSLOT(Lq("Proveedor"), KDefault(LQ("Fabricado!"))))) -> ((FABRICADO ((PROVEEDOR ((DEFAULT FABRICADO!)))))) KMergeFNs(anFN1, anFN2) combina en la red de frames anFN1 las Frames, slots y values de las dos redes argumentos de la función. Si un elemento esta en ambas redes se combinan los subelementos, si no esta se añade al resultado. KPrintFN(anFn) muestra la estructura de la red de Frames argumento de la función. KRemoveAValue(anFN, aFrameName, aSlotName) nos permite eliminar un facet de tipo Value de un Slot de un Frame definido en una red de Frames. KRemoveFacet(anFN, aFrameName, aSlotName, aFacetType) nos permite eliminar un Facet de un Slot de un frame definido en una red de Frames. Ejemplo: Red = KMakeFN(KFRAME ( LQ("Fabricado"), KSLOT (Lq("Proveedor"), KDEFAULT (LQ("Fabricado!")))), KFRAME ( LQ("MateriaPrima"), KSLOT (Lq("Proveedor"), KDEFAULT (LQ("NoTieneFijo")))) ), KRemoveFacet(Red, LQ("Fabricado"), LQ("Proveedor"), LQ("Default")), -> ((MATERIAPRIMA ((PROVEEDOR ((DEFAULT NOTIENEFIJO))))) (FABRICADO ((PROVEEDOR)))) KRemoveFrame(anFN, aFrameName) elimina un Frame de la red de Frames indicada en el primer argumento de la función. Manual del Usuario PSPS IV 133 Capitulo 10. Las Funciones de Conocimiento KRemoveSlot(anFN, aFrameName, aSlotName) elimina un slot de un Frame definido en una red de Frames. KRestOfFrames(anFN) devuelve la lista de Frames de la red argume nto de la función salvo el primero. KRestOfFacets(aList) devuelve el CDR de la lista de FACETS argumento de la función. KRestOfSlots(aSlotList) devuelve la lista de Slots de la red argumento de la función salvo el primero. KSetAValue(anFN, aFrameName, aSlotName, aValue) asigna el valor aValue a la facet VALUE del Slot indicado en la Frame aFrameName de la red anFN. Si alguno de los elementos Frame, Slot o la Facet VALUE no existieran la función los crea. KSetValue(aSlot, aValue) reemplaza el contenido de la Facet VALUE del slot por el valor dado en el segundo argumento de la función. KSetFacet(aSlot, aFacet) añade en el Slot aSlot la Facet dada como segundo argumento de la función. KSetNumValue(aSlot, aNumber) reemplaza el contenido de la Facet VALUE del slot por el valor dado en el segundo argumento de la función que debe ser un número PSPS. KSetSlot(aFrame, aSlot) añade en la Frame aFrame el Slot dado en el segundo argumento de la función. La función no comprueba si existe un slot con ese nombre. KSlot(aSlotName, Facet1, …, Facetn) define un Slot de tipo simple a partir de la lista de Facets dada por los argumentos de la función. KSlotL(aSlotName, aListOfFacets) define un Slot de tipo simple a partir de la lista de Facets dada como segundo argumento de la función. KSlotName(aSlot) devuelve el nombre del Slot argumento de la función. KValue(aValue) se utiliza para definir un tipo de Facet que define el valor de una propiedad representada por un slot. Formatos de Lisp (VALUE aValue) Define un tipo de Facet que define el valor de una propiedad representada por un slot. Manual del Usuario PSPS IV 134 Capitulo 10. Las Funciones de Conocimiento (DEFAULT aValue) Define un tipo de Facet que define el valor de una propiedad en los casos en los que no se conozca un valor especifico. (IF -NEEDED (Function aDemon)) Define un procedimiento que se activara cuando no este definido ni un Value ni un Default en el Slot correspondiente. (IF -ADDED (Function aDemon)) Define un procedimiento que se activara cuando se añada el valor de un Slot o se modifique. (IF -REMOVED (Function aDemon)) Define un procedimiento que se activara cuando de elimine el valor de un Slot. (AKO anyNumberOfFrames) Define un slot del tipo AKO. (SLOT aSlotName anyNumberOfHechos) Define un slot de tipo simple. (FRAME aFrameName anyNumberOfSlots) Define un Frame. (MAKEFN anyNumberOfFrames) Define un red de Frames. Search Una búsqueda puede conceptualizarse como la exploración de un espacio de estados. En el que un estado resume la situación de la búsqueda en cada momento. No importa como se ha llegado a ese estado, sino tan solo el estar en dicho estado. Las funciones que definiremos en esta sección del capitulo nos van a permitir definir Problemas de Búsqueda. Un Problema de Búsqueda tiene las siguientes componentes: Predicado: que será cierto para todos los estados, y solo aquellos, que constituyan una solución. Función de calidad de estado: que evaluada para cada estado se usa para proporcionar una indicación de la plausibilidad de que el estado pueda conducir a la situación deseada. Función de sucesores: que indica los estados sucesores hacia los que puede evolucionar la búsqueda. Predicado de igualdad: que determina cuando dos estados son iguales para la búsqueda. Esta función se utiliza para no volver a explorar un estado ya explorado. Estado Inicia l: en el que empieza la búsqueda. Manual del Usuario PSPS IV 135 Capitulo 10. Las Funciones de Conocimiento Función de escritura del estado: que imprime el estado de forma entendible para el usuario. Indicadores: que determinan las propiedades de la búsqueda. Hay dos indicadores TraceFlag y AnnouncedFlag. TraceFlag indica si hay que escribir información de trazado cada vez que la búsqueda elige un camino o hace BackTrack; y AnnouncedFlag que determina la cantidad de OutPut que se produce al terminar la búsqueda. Funciones PSPS KMakeSearchproblem(aState, GoalFN, EvalFN, Actions, genFN) define un problema de búsqueda. Define el estado inicial, la función solución, la función de evaluación y la función de sucesores que indica el estado siguiente a cada estado. Ejemplo: Search = KMakeSearchproblem(Llist(LdefNAtom(0)), LispFDestino,LispFValor, Nil, LispFExpnasion); Esta sentencia define un Problema de Búsqueda en el que el estado inicial es la lista (0) y las funciones LispFDestino, LispFValor y LispFExpansion son funciones definidas por el usuario para representar a la función solución, la función de evaluación y la función de sucesores respectivamente. KMakeActionlist(item1, item2, ...) define una lista de acciones con los argumentos de la función. KSetPrintState(aSearchProblem, aValue) define la función de impresión de estados que permitirá imprimir los estados de forma legible para el usuario KSetSameState(aSearchProblem, aFunction) define la función de igualdad de estados, que determina cuando dos estados son iguales. Ejemplo: KsetSameState(Search, LispMismo); Esta sentencia define para el problema Search, previamente definido, la función de igualdad mediante la función del usuario LispMismo. La función LispMismo se encargara de testar durante el proceso de búsqueda si dos estados son iguales. KSetAnnounceFlag(aSearc hProblem) activa el indicador de impresión de resultados, AnnounceFlag, al terminar la búsqueda. Manual del Usuario PSPS IV 136 Capitulo 10. Las Funciones de Conocimiento KResetAnnounceFlag(aSearchProblem) desactiva el indicador de impresión de resultados, AnnounceFlag. KSetTraceFlag(aSearchProblem) activa el indicador impresión de trazado, TraceFlag durante la búsqueda. de KResetTraceFlag(aSearchProblem) desactiva el indicador de impresión de trazado TraceFlag. KPrintSearchProblem(aSearchProblem) imprime el problema de búsqueda definido por aSearchProblem de forma legible para el usuario. KFirstElement(aState) si el estado argumento de la función tiene estructura de lista, esta función es equivalente al Car de la lista. KRestOfElements(aState) si el estado argumento de la función tiene estructura de lista, esta función es equivalente al Cdr de la lista. KEmptyStateP(aState) predicado que devuelve True si la lista que representa los estados es la lista vacía y False en caso contrario. KFindSymbolinSlot(aSlNumber,aState) la función devuelve el elemento almacenado en el Slot número aSlNumber. KFillSlot(aSlotNumber, aSymbol,aState) crea un nuevo estado reemplazando el valor del Slot indicado en el primer argumento por el símbolo dado en el segundo. Una vez definido el problema de búsqueda el paquete proporciona varios procedimientos de búsqueda mediante las siguientes funciones: KDfSearch(aSearchProblem, limit) Depth Search o Búsqueda en Profundidad. En cada estado se elige el próximo expandiéndose inmediatamente, este procedimiento continua así hasta llegar a un estado solución o haberse agotado las opciones o superado el limite de profundidad dado por el segundo argumento de la función. En este caso vuelve atrás (BackTraking) para elegir otro estado en la ultima expansión que tiene alternativas. Esta función no realiza ningún tipo de ordenación automática entre las diferentes alternativas, las toma simplemente en el orden de aparición en el cálculo. KHillSearch(aSearchProblem, Limit) esta función de búsqueda hace uso de una función de evolución que debe ser proporcionada por el usuario y se toma como una estimación de la distancia desde el estado en curso hasta la solución. Sigue una trayectoria de exploración similar a la de la Búsqueda en profundidad, siempre que los valores proporcionados por la función de evolución sean Manual del Usuario PSPS IV 137 Capitulo 10. Las Funciones de Conocimiento crecientes. Si en algún momento la función deja de crecer la trayectoria en curso se abandona y se retrocede hasta la alternativa anterior. KGradSearch(aSearchProblem,limit) esta función de búsqueda es una variación de la anterior. En cada iteración se enumeran la lista de las posibles continuaciones y se ordena de acuerdo con los valores de la función de evaluación suministrada. Manual del Usuario PSPS IV 138 CAPITULO 11: Corrigiendo Errores en un programa. § § § § § § Manual del Usuario PSPS IV Errores de Compilació n Errores de Ejecución Sentencias y Bloques de Debugging La Ventana del Debugger Dynamic Dialog Tools DDT Ventana del Listener Capítulo 11: Corrigiendo Errores en un programa. Errores de Compilación. Errores de sintaxis en la escritura de sentencias o bloques, la falta de un punto y coma al final de una sentencia o la falta de un símbolo } que cierra un comentario, son algunos de los errores de compilación más frecuentes. Cuando se produce un error de este tipo, el sistema envía un mensaje, indicando que se trata de un error de compilación, la posición del error y una breve descripción del error. En PSPS la descripción del error se da desde la óptica del compilador. Un error es una sorpresa que el compilador ha tenido, al tratar de interpretar una expresión. Por esto, a veces la descripción del error no es fácil de interpretar, desde el punto de vista del usuario. Veamos a continuación algunos ejemplos de los errores de compilación más frecuentes. Ejemplo 1: Utilización de una variable no definida Supongamos que ejecutamos este sencillo programa System GENERATE 1; COMPUTE Y = 1 + 1; TERMINATE; EndSystem; Al ejecutarlo, el sistema envía el siguiente mensaje de error “Variable no Declarada” y marca en la Ventana de Texto la Variable no declarada, como se observa en la figura siguiente. ¿La solución?. ¡Declarar la variable! Figura 1. Mensaje de Error. Manual del Usuario PSPS IV 139 Capítulo 11: Corrigiendo Errores en un programa. Ejemplo 2: Falta de un punto y coma. También es frecuente olvidar el punto y coma, que debe seguir a cada declaración de un bloque. En este caso, dependiendo del lugar en el que falte el punto y coma, el sistema produce diferentes mensajes de error. Si en ejemplo anterior omitimos el punto y coma después del bloque COMPUTE, el mensaje que envía el sistema será “Una expresión termina en un carácter o símbolo invalido” y marcará el bloque TERMINATE 1. Figura 2. Mensaje de Error. De nuevo, la solución es simplemente poner el punto y coma en el sitio adecuado. Ejemplo 3: Nombre incorrecto de un bloque o sentencia. Si en nuestro programa no escribimos correctamente el nombre de algún bloque o sentencia el compilador envía un mensaje de error. Este tipo de error puede evitarse utilizando el Programig Help. El Programming Help es un asistente que permite consultar de forma rápida los argumentos de una función, los parámetros de un bloque, el nombre correcto de una constante, de una variable o de una sentencia. Aquí tenemos un ejemplo del efecto del punto de vista en los mensajes de error. Desde el punto de vista del compilador, al no encontrar el punto y coma que cierra el bloque, el compilador sigue adelante, tratando de interpretar el sentido de lo que sigue. Al encontrar la palabra TERMINATE, que no debería estar ahí, se lleva una sorpresa e informa de que la expresión anterior termina con un símbolo invalido (el símbolo TERMINATE). Desde el punto de vista del usuario, el mensaje de error más sencillo seria "Falta un punto y coma para cerrar un bloque". A lo mejor, en una de las futuras versiones de PSPS nos decidimos a cambia el punto de vista. Por el momento, pedimos al lector ¡que trate de comprender al pobre compilador! 1 Manual del Usuario PSPS IV 140 Capítulo 11: Corrigiendo Errores en un programa. Ejemplo 4: Orden de las secciones. Este error es difícil de cometer, ya que al abrir una nueva ventana de texto el sistema muestra las cabeceras de las distintas secciones, precisamente para prevenir este error. Pero en caso de que ocurriera 2 el mensaje variaría dependiendo de cómo se haya alterado el orden de las secciones. Algunos ejemplos son: “Falta un nombre de bloque” o "Se espera el nombre de una función y no se halla”. Si por ejemplo colocamos la sección Variables después de la sección Data. Data Report On; Variables Y; System GENERATE 1; COMPUTE Y = 2+1; TERMINATE; EndSystem; se produce el error de la figura 4. El sistema espera una definición de bloque de DATA después de la cabecera Data, y hasta el inicio de la sección System. En su lugar encuentra la palabra Variables, que en ese lugar es desconocida, porque no es un nombre de un bloque. Figura 4. Mensaje de Error. Igual que en el resto de los casos, el mensaje indica la posición del error y lo señala en la Ventana de Texto. 2 y sucede a menudo, ¡Vaya si sucede!. Es imposible hacer un sistema a prueba de tontos, ¡porque la experiencia demuestra que los tontos son muy inteligentes! Manual del Usuario PSPS IV 141 Capítulo 11: Corrigiendo Errores en un programa. Ejemplo 5: Números Recordemos que el sistema de entrada de PSPS solo reconoce números enteros. Por tanto, si inicializamos una constante o variable, con una expresión que contenga valores no enteros, el sistema envía un mensaje de error de compilación. En las figuras 5 y 6 vemos los mensajes de error. En la figura 5 hemos asignado un valo r no entero a una constante, mientras que en la figura 6 hemos inicializado el valor de una variable (en la sección Data) con una expresión que contiene un valor no entero. Figura 5. Mensaje de Error. El mismo mensaje de error se obtendría al tratar de inicializar con un valor no entero una variable en un bloque COMPUTE. Figura 6. Mensaje de Error. Ejemplo 6: Si la cabecera de la primera sección de nuestro programa PSPS no es una de las palabras claves que definen las diferentes secciones del programa, o la hemos olvidado, el sistema envía el siguiente mensaje de error. Manual del Usuario PSPS IV 142 Capítulo 11: Corrigiendo Errores en un programa. Figura 7. Mensaje de Error. Este error es muy frecuente en aplicaciones multifichero. El sistema inicia la compilación desde la ventana activa, si no se le indica lo contrario. El error aparece si se inicia la compilación desde una ventana que no es la ventana básica del programa, es decir, la primera ventana no contenida en un include. Para asegurar que la ventana en curso es la ventana básica, es conveniente usar el primer botón de la barra de botones de acceso rápido . Al pulsarlo, el sistema toma nota de básica es la que está activa en ese momento. mostrará en el campo de edición, a la derecha botones. La ventana se mantendrá como independencia de la ventana que se halle activa, cierre, o se vuelva a cambiar. que la ventana Su nombre se de la barra de principal con mientras no se Errores de Ejecución En esta sección mostraremos los errores más frecuentes de este tipo. Y en las secciones siguientes mostraremos los distintos bloques, sentencias y herramientas de Debugging que posee PSPS, y que nos ayudaran a detectar y corregir estos errores. Ejemplo 1: Recordemos que el plan de vida habitual de una transacción es nacimiento, recorrido y muerte. Por tanto, la secuencia de bloques de la sección System suele terminar con un bloque TERMINATE. También que hay casos en los que las transacciones se quedan de forma permanente en el sistema. En este caso, el último bloque de la secuencia no será un bloque TERMINATE. Por tanto, hay que especificar el bloque al que queremos redirigir las transacciones. ¿Qué ocurriría en un ejemplo de de este tipo si no indicáramos este bloque?. El sistema detiene la ejecución del modelo y envía el siguiente mensaje de error Manual del Usuario PSPS IV 143 Capítulo 11: Corrigiendo Errores en un programa. Figura 8. Mensaje de Error. Al llegar la transacción al último bloque del modelo, se dirigirá al bloque Cb+1, pero ese bloque no existe. El mensaje indica el bloque en el que se produce el error. Este mismo tipo de error aparecerá siempre que intentemos dirigir la transacción a un bloque que no existe. Ejemplo 2: Otro error que hace que el sistema se detenga durante la ejecución de un programa, es la generación de un valor negativo en un bloque WAITFOR. Esto puede ocurrir, por ejemplo, en el caso de que el tie mpo de espera para el bloque siga una distribución Normal. Esta distribución siempre tiene una probabilidad positiva, aunque a lo mejor muy pequeña, de proporcionar valores negativos. Figura 9. Mensaje de Error. Ejemplo 3: Contenido de un procesador negativo. El contenido de un procesador debe ser normalmente positivo 3 . Supongamos que mediante un bloque LEAVE solicitamos la salida de más unidades de las disponibles en un procesador. En ese momento, el contenido del procesador se vuelve negativo, la ejecución del programa se detiene y el sistema envía un mensaje de error. 3 sin embargo, ver más abajo. Manual del Usuario PSPS IV 144 Capítulo 11: Corrigiendo Errores en un programa. Figura 10. Mensaje de Error. Supongamos que el contenido de un procesador representa el Stock de un almacén y que este Stock puede ser negativo, significando unidades pendientes de servir. ¿Cómo modelamos este caso?. PSPS dispone del bloque STOCK [número de procesador/es] en la sección Data. Este bloque indica que el contenido del procesador, o procesadores, indicados puede ser negativo, evitando de esta forma que el sistema se detenga en este caso. Ejemplo 4: Demasiadas Transacciones en el Sistema. PSPS no es capaz de mover infinitas transacciones, el número máximo de transacciones que pueden encontrarse vivas al mismo tiempo es igual a 400. En caso de que este número se supere, el sistema envía un mensaje de error y detiene la ejecución del programa. Figura 11. Mensaje de Error. Este es el mensaje de error más frecuente en las primeras pruebas de un modelo que contenga algún tipo de coordinación entre transacciones. Típicamente, sucede que un bloque retiene transacciones de forma anómala. Curiosamente, este error es una herramienta de depuración de primera categoría. La mayoría de modelos son muy sensibles a pequeños errores de lógica, que permiten el bloqueo de las transacciones. Un modelo está correcto en un 80%, cuando las transacciones fluyen si acumularse. Capacidades mal definidas, switches que no se ponen en ON, envío de transacciones a bloques equivocados (especialmente en construcciones del tipo Cb+j) o condiciones de coordinación entre transacciones que nunca se cumplen, son los típicos culpables de la situación. Una ojeada a la tabla de bloques mostrará los bloques dónde se acumulan las transacciones, y debe ser el primer paso para resolver el problema. Suelen ser muy pocos, uno por cada Manual del Usuario PSPS IV 145 Capítulo 11: Corrigiendo Errores en un programa. proceso independiente a lo sumo. A continuación, el uso del DDT (ver siguientes secciones) permite observar el flujo de las transacciones y detectar la causa de la acumulación. Sentencias y Bloques de Debugging. En esta sección describiremos las sentencias y bloques PSPS, que son de utilidad para depurar los errores de ejecución de un programa. Sentencia Write y Bloque DEBUG. Cuando los resultados devueltos por el programa no son los esperados, una de las formas más sencillas de analizar el funcionamiento del mismo es escribir los valores de algunas variables, en distintos puntos del programa. La sentencia Write ( ) provoca la impresión de resultados sobre el dispositivo de salida, que por defecto suele ser la Ventana del Listener. Esta sentencia nos permite escribir Strings y variables numéricas. Así una sentencia como: Write (“Variable de Estado”, Estado) escribe el valor de la variable Estado en la ventana del Listener, precedida por la string indicada. Estado debe ser una variable cuyo valor nos resulte fácil de calcular fuera del modelo. De esta manera sabremos si los cálculos que realiza el sistema son correctos. Otro ejemplo es: Write (“Instante de Tiempo”, Cl, “Transacción número”, At[2]) La sentencia presenta el tiempo de paso de la transacción por el bloque o función que contiene la sentencia Write, comprobando así si las transacciones entran en determinados bloques o funciones. La sentencia Write la podemos combinar con el bloque DEBUG cuya estructura es la siguiente: DEBUG DO ; El bloque DEBUG proporciona una compilación condicional de sentencias y bloques, en función del valor de la constante suministrada como primer argumento del bloque. El bloque se incluirá en el código compilado, solo si el valor de la constante es igual a True. De esta forma podemos instrumentar exhaustivamente un programa, y una vez depurado, eliminar todas Manual del Usuario PSPS IV 146 Capítulo 11: Corrigiendo Errores en un programa. las sentencias de depuración simplemente asignando un valor a una constante. Nótese que hay una gran diferencia entre usar sentencias if o bloques Debug para instrumentar código. Las primeras, aunque no se ejecuten, forman parte del código objeto compilado, y hacen ir más lento al programa. Las segundas desaparecen en tiempo de compilación. Así el bloque DEBUG Escribe DO Write (“Sentencia de Debugging”); escribirá en la Ventana del Listener la String “Sentencia de Debugging” solo cuando el valor de la constante Escribe, previamente definida en la sección correspondiente, sea igual a True. En caso contrario la sentencia será tratada como un comentario y no pasará a formar parte del código. Funciones de Debug. Sección OnDebug. En un programa PSPS, y después de la sección Data, podemos incluir una sección ONDEBUG. En esta sección se puede escribir una única sentencia Pspal. Este fragmento de código se puede ejecutar directamente en cualquier momento en que la simulación este detenida, pulsando el botón UserFunction de la Ventana de Control de la Simulación o de la Ventana del Debugger. El código suele constar de una llamada a una función, definida anteriormente en la sección Macros. Este procedimiento se suele utilizar para definir tablas informe, que muestran el valor de las variables más representativas del modelo, quizá combinados con cálculos de comprobación. Típicamente, se detiene el sistema en un valor del reloj, por medio de la sentencia Pspal Pause 4 número_de_pausa, o por un bloque STOP. Desde la pausa se puede usar el código de la sección ONDEBUG para comprobar el estado de la simulación en ese instante de tiempo . El bloque STOP. Supongamos que queremos detener la simulación exactamente en el momento en el que una transacción se detiene en un bloque WAITFOR, para en ese instante comprobar el estado de la simulación. El bloque STOP se encarga de detener el curso de la simulación. El bloque STOP no detiene la simulación en momento en que se produce una entrada en él de una transacción. 4 La ejecución de la sección DATA no se puede detener, por lo que se recomienda que si hay que testar un fragmento importante de código de la sección Initial, se incluya en la sección System y se ejecute al paso de la primera transacción. Manual del Usuario PSPS IV 147 Capítulo 11: Corrigiendo Errores en un programa. La parada se produce en el momento en que la transacción que esta siendo procesada, se detiene, por alguna causa, después de haber accedido a este bloque. Por ejemplo se puede detener ante un bloque ENTER, esperando acceder a un procesador. Esta forma de proceder, se debe a que el bloque debe dejar el sistema en condiciones de continuar, al pulsar el botón Continue. Y el estado interno del sistema no se preserva adecuadamente, si se para drásticamente la ejecución a la entrada de un bloque. El bloque STOP no tiene ningún parámetro y el paso de una transacción se realiza siempre de forma instantánea. El bloque DUMP El bloque DUMP es un bloque sin parámetros que se encarga de producir la impresión del estado de la simulación, en el formato estándar de salida. Este bloque es de gran utilidad para imprimir el estado detallado de la simulación a la llegada de una transacción. Al no tener parámetros las opciones de escritura del bloque DUMP se fijan en la pestaña Parameters del menú Run, en la Ventana Principal de PSPS. Figura 12. Menú Run / Opciones. El bloque DUMP puede producir cantidades ingentes de output, por lo que recomienda prudencia en el uso de las opciones. Desde el menú Debug del Listener, se pueden obtener OutPuts parecidos a los de este bloque, pero, eso si, sólo si la simulación está detenida Manual del Usuario PSPS IV 148 Capítulo 11: Corrigiendo Errores en un programa. El bloque TRACE Este bloque provoca el inicio, o la finalización, de la traza de un sistema, al nivel de detalle que se especifica en el segundo parámetro del bloque. TRACE , ; Si el valor del primer parámetro es On, se inicia la traza; si el valor es Off se detiene la traza. La traza también se puede poner en marcha mediante la opción Trace del menú Interaction de la Ventana Principal del PSPS. La traza del modelo se realiza de forma diferente si el bloque TRACE se halla en la sección Data o en la sección System de nuestro modelo. Si el bloque está en la sección Data, la traza se realiza desde el instante inicial. En cambio si definimos el bloque TRACE en la sección System, el inicio o fin de la traza se realiza cuando la primera transacción pasa por ese bloque. La traza del sistema aparece en la Ventana del Listener que, como hemos visto, es el dispositivo de salida por defecto. Otra forma de definir la traza de un modelo es mediante la opción Trace del menú Interaction. El cuadro de diálogo permite elegir a partir de qué momento se quiere trazar (o dejar de trazar), que es lo que queremos trazar y si se quiere que el sistema trace de forma automática (la opción por defecto) o que sea el usuario el que lo haga avanzar manualmente, parándose el sistema cada vez que se va a ejecutar un acontecimiento (avanzar el reloj). Figura 13. Cuadro de Dialogo del menú Interaction/Trace. Ejemplo: Supongamos que hemos definido un sencillo modelo que representa una cola ante 10 servidores. Las llegadas al sistema Manual del Usuario PSPS IV 149 Capítulo 11: Corrigiendo Errores en un programa. siguen una distribución Normal y el tiempo de servicio es constante para todos. He aquí el modelo Data VARS fs[1] = 10; TIME 350; RESET 100; Report On; System GENERATE Normal(8/20,1/20); TRACE On,1; QUEUE 1; WAITFOR 4; LEAVE 1; TERMINATE; Endsystem; Hemos incluido el bloque TRACE en la sección System. El primer parámetro igual a On indica que la traza se iniciara cuando la primera transacción acceda a dicho bloque. Si el lector ejecuta este modelo, vera que en la Ventana del Listener aparece la siguiente información: Figura 14. Ventana del Listener. Traza del Modelo. Como el nivel de traza seleccionado es igual a 1, el sistema traza la entrada y salida de las transacciones a los procesadores del modelo. Como puede verse en la traza, lo primero que hace la transacción es solicitar la entrada al procesador que representa a la cola. Después solicita la entrada al procesador número 1. Una vez que accede al procesador número 1, la transacción abandona el procesador cola. En cada entrada o salida, la traza muestra la capacidad del procesador, el contenido y el número de unidades que entran o salen del mismo. Para más información acerca de los niveles de traza, y el output producido, el lector debe consultar el Apéndice D de este manual. Manual del Usuario PSPS IV 150 Capítulo 11: Corrigiendo Errores en un programa. La Ventana del Debugger. programa Paso a Paso. Ejecutando un La Ventana del Debugger permite por un lado observar el valor de variables seleccionadas del modelo, y por otro lado, ejecutar paso a paso el programa. El Debugger puede activarse desde la Ventana de Control de la simulación, mediante el botón o mediante la opción Interaction/Debugger de la barra de menús de la Ventana Principal. La Ventana del Debugger se muestra en la Figura 15. Figura 15. Ventana del Debugger. El campo Var permite seleccionar las variables que queremos trazar. Podemos seleccionar cualquiera de las variables definidas por el usuario o las variables que el sistema mantiene de forma automática. En el caso de tratarse de variables de tipo Array deben indicarse los índices de las mismas, en los campos que aparecen a continuación, campos i y j. El botón hace que se muestren en la tabla inferior las variables seleccionadas. El menú Edit de la barra de menús permite borrar de la tabla una variable, o eliminar de la misma todas las variables seleccionadas. Una vez que hemos indicado las variables a trazar, podemos simular el modelo de formas diferentes, de acuerdo con las alternativas de uso que proporciona el Debugger. A continuación describimos los botones que dan acceso a las distintas alternativas: Step Pspal Sentence: en este caso la ejecución del programa avanza hasta la siguiente sentencia Pspal. Este modo de ejecutar el modelo es de interés cuando queremos observar, paso a paso, los valores que toman las variables durante la ejecución de una función Pspal. Manual del Usuario PSPS IV 151 Capítulo 11: Corrigiendo Errores en un programa. Step Trhu functions: La simulación avanza sin detenerse en las distintas sentencias de las funciones. To Next Return: la ejecución del programa se detiene cuando la transacción en curso encuentra una sentencia Return, es decir cuando finaliza la ejecución de una función. Step a Block: en este caso, la ejecución del modelo se detiene cada vez que la transacción se dirige a un bloque nuevo. Esta es una de las opciones más útiles, porque además de observar el valor de las variables, podemos observar el movimiento de la transacciones. Si seleccionamos como variable a observar At[2], podemos saber que transacción se encuentra en movimiento. Step to Next Store Instructions: la ejecución del modelo avanza hasta la siguiente instrucción almacenada. Step To Event: en este caso la ejecución del modelo avanza hasta el siguiente evento almacenado. Dynamic Dialog Tools DDT. Observando correcto movimiento de las transacciones. el Ya hemos dicho que el primer paso para depurar un modelo es comprobar el correcto movimiento de las transacciones por entre los bloques del sistema. Si el modelo es sencillo, por ejemplo una cola ante un servidor, el movimiento de las transacciones también es sencillo y fácil de seguir. Para casos más complejos, PSPS dispone del DDT, una herramienta que permite observar de forma gráfica el movimiento de las transacción por entre los bloques. No muestra los valores de las variables o el estado de la simulación, sino únicamente el flujo de las transacciones. Pero ya hemos dicho que en el 80% de las veces, esto es todo lo que se necesita para poner a punto un modelo. Como la mayoría de las herramientas de este tipo, un botón en la Ventana de Control de la simulación permite activarla . La primera ventana que nos muestra el sistema es la ventana DDTDialog en la que debemos fijar las opciones del DDT. La principal opción es el modo de ejecutar el modelo, que puede ser automático o manual. En el segundo caso el sistema se detiene cada vez que se para una transacción, y espera a que el usuario pulse Continue (en la Ventana de Control) para seguir adelante. También podemos fijar en esta ventana la velocidad de movimiento de las transacciones, que debe ser la adecuada para poder seguir visualmente el proceso. Algunos tanteos ayudan a Manual del Usuario PSPS IV 152 Capítulo 11: Corrigiendo Errores en un programa. hallar las asignaciones correctas, que dependen de la velocidad de cada ordenador. Una vez definidas las características del DDT, aparece una tabla que permite seleccionar los bloques y los procesadores que queremos observar. Figura 16. Ventana DDTDialog. Seleccionando el DDT y las opciones indicadas anteriormente, el sistema mostrara la siguiente ventana Figura 17. Ventana del DDT Mediante el menú Llenar seleccionamos los bloques y procesadores que queremos observar. El botón obtiene de la ventana de la izquierda, items uno a uno, y los coloca en la ventana de la derecha, como items seleccionados. El botón selecciona todos los items que figuran en la ventana de la izquierda. Proponemos al lector que se detenga aquí, e introduzca el siguiente ejemplo en una ventana de texto, lo compile y lo ejecute usando el DDT en modo Auto y a una velocidad media, para observar el movimiento de las transacciones. Manual del Usuario PSPS IV 153 Capítulo 11: Corrigiendo Errores en un programa. System GENERATE Exponential(3); QUEUE 1; WAITFOR Normal(3,1); LEAVE 1; TERMINATE; endsystem; El ejemplo modela una cola ante un servidor, por el uso del bloque QUEUE. Lector, si ya ha acabado sus exploraciones, siga leyendo. Figura 18. Cuadros de Dialogo del DDT. Para observar el modelo del ejemplo, seleccionaremos todos los bloques, ya que son pocos, y no tendría sentido eliminar alguno de ellos. En otros casos se recomienda seleccionar partes consistentes del sistema. Cuando el sistema está compuesto de varios procesos deben seleccionarse procesos completos. En nuestro ejemplo, y después de la selección, tendríamos la siguiente tabla Figura 19. Ventana del DDT. La primera parte de la Tabla muestra los bloques del modelo, Cuando se ponga en marcha el reloj de simulación, unas bolitas rojas representaran a las transacciones, y el movimiento de las bolitas mostrara el movimiento de las transacciones por entre los Manual del Usuario PSPS IV 154 Capítulo 11: Corrigiendo Errores en un programa. bloques del modelo. La segunda parte de la tabla muestra los procesadores. Aquí, unas bolitas azules representarán el contenido de los procesadores que, como ya sabemos, no tiene porque coincidir con el número de transacciones. La manera de poner en marcha la simulación es siempre la habitual, mediante el botón CONTINUE de la Ventana de Control de la Simulación. La opcion Stop del menú DDT , nos permitira detener el funcionamiento del DDT . Las opciones ResumeAuto y ResumeManual reanudan el funcionamiento del DDT en forma automatica o manual. Figura 20. DDT de una Cola con un Único Servidor En la figura 20 podemos ver que hay tres transacciones esperando, en el bloque QUEUE, a que el procesador número uno quede libre. Como no hay nadie en el procesador 1, el lector puede pensar que esta vacío. Pero recordemos que en PSPS, hasta que la transacción que se esta moviendo no se detiene, o desaparece del sistema (como ocurrirá en nuestro ejemplo), las transacciones que se encuentran paradas no se ponen en marcha. Las bolitas azules indican que en este momento hay tres unidades en el procesador que representa la cola, el procesador número uno. En este caso coincide con el número de transacciones que se encuentran esperando ante el bloque QUEUE, porque las transacciones solicitan la entrada de una unidad al procesador. Si, por ejemplo, las transacción solicitaran la entrada de dos unidades al procesador, tendríamos la siguiente situación Manual del Usuario PSPS IV 155 Capítulo 11: Corrigiendo Errores en un programa. Figura 21. Ventana DDT. En este caso, en el procesador que representa a la cola ante el servidor hay 6 bolitas, es decir 2 unidades por cada una de las transacciones que se encuentran esperando. 5 Para utilizar el DDT debemos anticipar cual debe ser el recorrido de las transacciones. En modelos más complicados, se recomienda utilizar el modo manual. En este modo, la transacción en curso se mueve hasta que es detenida por alguna causa. Cada vez que se detiene la transacción, DDT detiene la simulación. Para mover otra transacción basta pulsar el botón Continue de la Ventana de Control de Simulación. Ventana del Listener. Estado de la Simulación. Como hemos visto ya, la ventana del Listener es el dispositivo de salida por defecto de las funciones y bloques de PSPS. También dispone de una barra de menús, que permite acceder a ciertas características del estado de la simulación. Los menús más útiles son Display y Debug. El menú Display permite listar algunas de las características del programa, típicamente resultados de la compilació n. Se incluyen las constantes y variables declaradas, los bloques, switches y el propio código generado, en el lenguaje de maquina de la maquina virtual Pspal. La opción más importante, aunque desafortunadamente algo avanzada, es la opción Stack. Esta es probablemente la herramienta más útil para corregir errores de ejecución de que dispone el lector avanzado. Presenta la situación 5 Para que el modelo funcione correctamente hemos realizado cambios en el. La capacidad del procesador debe ser igual a 2, en caso contrario ninguna transacción podría acceder a el y el bloque LEAVE se encarga de disminuir el contenido del procesador en dos unidades, ya que si no fuera así únicamente la primera transacción podría acceder al procesador. Manual del Usuario PSPS IV 156 Capítulo 11: Corrigiendo Errores en un programa. de la maquina virtual en el momento en que se ha producido el error, incluyendo un fragmento de código alrededor del punto de interrupción, que está señalado con un asterisco. También se muestra la situación del stack de ejecución y los valores de las variables locales, en caso de que las haya. Para más detalles, debe consultar el Apéndice C. Si el lector va a acometer simulaciones complicadas, la familiaridad con esta herramienta es una condición necesaria. Figura 22. Ventana del Listener. En el menú Debug, se hallan opciones que muestran diferentes aspectos del estado de la simulación, en forma parecida a la del bloque DUMP. Se pueden obtener todo tipo de datos, incluyendo los procesadores con contenido distinto de cero, las variables definidas por el usuario con valor distinto de cero, el contenido de los bloques y las listas de acontecimientos pendientes y de transacciones paradas. Manual del Usuario PSPS IV 157 PSPS Programa Simulador de Pequeños Sistemas Manual del Usuario PSPS IV (Apendices) Version 1.4 Book Version 2. CopyRight © Josep Riverola. Catacatel IESE – May 2003. APENCICE A: Limitaciones del Lenguaje PSPS Manual del Usuario PSPS IV Apendice A: Limitaciones del Lenguaje PSPS Limitaciones del Lenguaje PSPS IV. Tabla 1. Limitaciones del Lenguaje PSPS IV. Número Máximo Bloques Atributos de una Transacción Facilities Switches Histogramas Gráficos Funciones definidas por el usuario Ficheros declarables 200 40 50 50 50 20 50 20 Tabla 2. Limitaciones del Lenguaje Pspal. Número Máximo Instrucciones en memoria programada Labels definibles Posiciones de memoria disponibles para la definición de variables Variables Constantes Sentencias Pspal Strings en el sistema Argumentos para una función Variables locales en una función Manual del Usuario PSPS IV 5000 50 5000 200 100 2000 100 10 50 158 APENDICE B: Manejo de las direcciones de memoria. Manual del Usuario PSPS IV Apendice B: Manejo de las direcciones de memoria En PSPS es posible realizar indirecciones y por tanto manejar direcciones de memoria realizando operaciones sobre ellas. Para obtener la dirección de una variable se emplea el ampersand &, así el nombre de la variable precedido por & nos proporciona la dirección de la variable. En el caso de que la variable sea una variable tipo array la dirección del array coincide con la dirección del primer elemento. El proceso contrario se consigue empleando un caret ^; la presencia de un signo ^ antes de una variable que contenga la dirección de una posición de memoria nos dará acceso al contenido de esa posición de memoria y no a la dirección (el número) almacenada en la variable. Veamos algunos eje mplos: Ejemplo 1: X = &TransEnCurso; Asigna a la variable X la dirección de la posición de memoria de la variable TransEnCurso, no el valor contenido en esa posición de memoria. Y = ^X; Asigna a la variable Y el contenido de la posición de memoria cuya dirección está almacenada en la variable X; Las dos sentencias anteriores concatenadas serian equivalentes a asignar el valor de la variable TransEnCurso a la variable Y. El caret ^ también se puede emplear de una forma un poco más elaborada para acceder a los elementos de un array. Si a continuación del símbolo ^ se coloca entre paréntesis una sentencia Pspal con valor, el valor que devuelva se empleará como la dirección origen del array,dirección del primer elemento, de tal forma que si a continuación entre corchetes indicamos un índice recuperaremos el valor almacenado en la posición del array a la que apunta el índice. Este sistema es muy útil para acceder a elementos de un array desde subrutinas puesto que si pasamos como parámetro a la subrutina la dirección del array podremos acceder a todos los elementos. Existe otra forma de conseguir esto mismo y es mediante el empleo de una variable VArray a cuyo identificador asignaremos la dirección de memoria que corresponde al primer elemento del array, que hemos podido pasar como parámetro, pudiendo a partir de este momento acceder a los elementos del array original por medio del VArray. Manual del Usuario PSPS IV 159 Apendice B: Manejo de las direcciones de memoria Ejemplo 2: ^ (X)[3]; Esta sentencia nos permite acceder al tercer elemento de un array cuya dirección de memoria viene dada por el valor de la variable X. Otra manera de acceder a los elementos de un array es mediante las variables VArray. A la variable VArray previamente definida se le asigna la dirección de memoria del array mediante el operador & o en el caso de una función podemos pasar la dirección de memoria como un argumento y accederemos a los elementos del array de la siguiente manera: VX= &X; VX[3]; Estas dos sentencias nos permiten acceder al tercer elemento del Array X. También podemos acceder al contenido de la tercera posicion mediante la sentencia: ^(X+2); donde la variable x debe contener la dirección de memoria del array a cuyos elementos queremos acceder, es decir X contiene la dirección de memoria del primer elemento del array. Manual del Usuario PSPS IV 160 Apéndice C: Las Ventana del Listener § § § Manual del Usuario PSPS IV La Barra de Menús Las Instrucciones de la Máquina El estado del Sistema. Menú Debug Apéndice C. La Ventana del Listener La Ventana del Listener es, por defecto, el dispositivo de salida de funciones y bloques del PSPS. Además de permitirnos observar el Output del modelo, en la Ventana del Listener podemos comprobar el estado de la simulación mediante las opciones de Debug que describiremos en detalle en este Apéndice. En primer lugar describiremos brevemente las distintas opciones de los menús de la Ventana y en las siguientes secciones del Apéndice profundizaremos en las opciones de Debugger. La Barra de Menús La barra de Menús de la Ventana del Listener cuenta con cinco menús que describiremos a continuación. Figura 1. Ventana ListenerBase Menú Files El menú Files cuenta con la opción Save que nos permite guardar en un fichero el Output existente en la Ventana del Listener. Menú Edit El menú Edit contiene las opciones de edición habituales Cut: corta el texto seleccionado y lo guarda en el portapapeles. Copy: copia el texto seleccionado y lo guarda en el portapapeles. Paste: copia el contenido del portapapeles en Manual del Usuario PSPS IV 161 Apéndice C. La Ventana del Listener la posición actual del cursor en la ventana del Listener. Clear: borra el contenido de la Ventana del Listener. Find: abre el cuadro de dialogo habitual para la búsqueda de una string en la Ventana del Listener. Menú Display Las distintas opciones del menú Display nos permiten listar los elementos del modelo que hemos simula do y el código que genera cada uno de ellos. Constants: enumera las constantes definidas mostrando el nombre y el valor de las mismas. Symbol: enumera definidas mostrando dirección de memoria, ocupa en la memo ria y las variables el nombre, la la posición que el tipo. Functions: enumera las funciones definidas mostrando para cada una de ellas el nombre, el número de argumentos y la dirección. Label: enumera las etiquetas definidas mostrando el nombre y el número de bloque que representa. Si el valor de una etiqueta es 0, indica que no ha sido utilizada para marcar ningún bloque del modelo. Block: lista los bloques definidos en el modelo. Stack: muestra el contexto de ejecución, las instrucciones que rodean al punto en el que esta detenida la simulación. Code/Block: muestra el código generado por los bloques de la sección System. Code/Data: muestra el código generado por los bloques de la sección Data. Code/Macros: muestra el código generado por las macros o funciones, definidas en la sección Macros. Code/Debug: muestra el código generado desde la última sentencia de Debug en adelante. Si no hay sentencias de Debug muestra el código generado desde la primera sentencia. Manual del Usuario PSPS IV 162 Apéndice C. La Ventana del Listener Code/From: muestra el código generado por el modelo empezando en la instrucción cuyo número debe ser indicado por el usuario. Continue: la opción Code escribe un máximo de 150 instrucciones. Si el número de instrucciones generadas por un bloque o función es mayor que 150 se activa la opción Continue que escribirá en la Ventana del Listener otras 150 instrucciones o el resto de las instrucciones desde el punto en el que se había detenido. Menú Debug Show Call Stack: muestra el stack de llamadas a funciones o macros. Show State: muestra el estado de la simulación. Lista el reloj de simulación, los procesadores utilizados con capacidad distinta de cero, los switches con ocupación mayor que cero, las variables distintas de cero, los histogramas que tiene preparado el sistema, una lista de los bloques con las transacciones que han entrado y las que han salido del bloque y por ultimo la lista de acontecimientos pendientes (L.A.P) y la lista de transacciones paradas (L.T.P), transacciones que estan detenidas en algún bloque a la espera de que cambie el estado del sistema. Ambas listas muestran los valores de los 10 primeros atributos de las transacciones. Same NoTransations: es similar a la opción anterior pero en este caso no aparecen la lista de acontecimientos pendientes ni la de transacciones paradas. Same NoVars: similar a Show State pero en este caso no lista las variables. Show Transactions in Blocks: lista los diferentes bloques del modelo con las estadísticas correspondientes, las transacciones pendientes y los acontecimientos pendientes. Show Transactions in Facs: muestra la lista de los procesadores definidos y la lista de acontecimientos pendientes. Show Transactions in Sw: muestra la lista de los switches con ocupación mayor que cero, la lista de transacciones detenidas por el estado de un switch y la lista de acontecimientos pendientes. Manual del Usuario PSPS IV 163 Apéndice C. La Ventana del Listener Menú Lisp En el menú Lisp están disponibles las siguientes opciones: Check( ): comprueba los niveles de paréntesis de una expresión numerándolos. Normal Trace: si esta marcada esta opción el sistema realiza la traza de la sentencia ejecutada. System Trace: si esta marcada esta opción se realiza la traza del sistema de la sentencia ejecutada. DefineGlobalvars: define la variable seleccionada como una variable global. Create Global From Address: define una variable global con la dirección de memo ria seleccionada. Import Global From PSPS: importa una variable del PSPS y la define como global. Las variables deben ser simples no se pueden importar variables array. List GlobalVars: muestra la lista de las variables globales. Show Atoms: muestra la lista de los átomos creados por el usuario. Show System Atoms: muestra la lista de los átomos disponibles en el sistema. Show Numerical Atoms: numéricos del sistema. muestra la lista de los átomos Show List Structure: muestra la estructura interna de la lista correspondiente a la dirección indicada. Structure Of Last Evals: muestra la estructura de la última evaluación. Statistics: muestra las estadísticas de ocupación del sistema. Gc: Garbagge Collecting. Se encarga de reciclar las celdas de memoria que no van a volver a ser utilizadas por el programa. Recupera las celdas de todos los átomos que no han sido protegidos mediante la función LProtect. Silence: desactiva el mensaje que mandan a la Ventana del Listener las funciones LG y LStats. Manual del Usuario PSPS IV 164 Apéndice C. La Ventana del Listener Las Instrucciones de la Máquina. Menú Display. En esta sección describiremos las distintas instrucciones de máquina que aparecen al listar el código generado por los distintos elementos del modelo en el menú Display de la Ventana del Listener. Las instrucciones de máquina suelen constar de dos partes. La primera es el comando que indica la operación que se va a realizar. La segunda parte de la instrucción es el argumento que indica donde hallar o almacenar los datos que se van a manipular. Las instrucciones de má quina trabajan sobre un stack, en concreto sobre el último y/o penúltimo elemento del Stack. Antes de definir los distintos tipos de instrucciones definiremos dos operaciones básicas POP y PUSH. POP: Elimina el último elemento del stack y sube al anterior. El argumento de esta instrucción es ignorado. PUSH: Empuja el stack y pone el argumento, cuya dirección se indica, en el top de este. Instrucciones Inmediatas Este tipo de instrucciones carga el argumento que aparece en la instrucción en el lugar indicado. Tabla 1. Instrucciones Inmediatas Instrucción Descripción LIT Load Inmediato Carga el argumento de la instrucción en el stack de memoria. LIS Load Inmediato Carga el argumento de la instrucción en el stack. El argumento es una string. JMP Jump Salta a la dirección indicada por el argumento de la instrucción. JPC Jump On Cero Si el valor del top del stack es cero salta a la dirección indicada. En caso contrario sigue en secuencia. BOS Begin of Sentence El argumento de esta instrucción es el número de sentencia, indica el número de sentencia Pspal en Debugging EOS End Of Sentence El argumento de esta instrucción es el número de sentencia Pspal, sirve para el Debug. Manual del Usuario PSPS IV 165 Apéndice C. La Ventana del Listener Instrucciones Normales Las instrucciones Normales manejan el elemento al que apunta la dirección argumento de la instrucción. Tabla 2. Instrucciones Normales. Instrucción Descripción LOD Load Carga en el top del stack lo que encuentra en la dirección argumento de la instrucción. STO Store Almacena en memoria, en la dirección indicada en la instrucción el top del stack. BOF Begin of Function Indica el inicio de una función JSR Jumb Subrutina El argumentos se descompone en dos argumentos de 8 bites, que indican el número de argumentos y el número de función. El número de función se asigna internamente en tiempo de compilación. Instrucciones Indirectas Las instrucciones Indirectas acceden a la dirección de memoria indicada en la instrucción, y lo toman como una dirección de memoria de donde extraer los datos propiamente dichos. Tabla 3. Instrucciones Indirectas. Instrucción Descripción LOI Load Indirecto Carga en el top del stack el dato cuya dirección se encuentra en la dirección indicada por el argumento. STI Store Indirecto Toma los datos como una dirección de memoria en la que se encuentra la dirección en la que se almacenara el top del stack LOM Load Múltiple Esta instrucción toma tres datos del stack que indican una dirección, d, un número inicial, i, y un número final, j. La instrucción carga en el stack el contenido de las direcciones de memoria d+i hasta d+j. OPR Operación Aritmética El argumento indica la operación a realizar, las operaciones que corresponden a cada argumento se indican en la tabla 4. La instrucción opera con los dos últimos números del stack y deja su resultado en el Top del stack. Los dos datos desaparecen del stack. Manual del Usuario PSPS IV 166 Apéndice C. La Ventana del Listener Tabla 4. Operaciones argumento de la instrucción OPR. Valor Argumento Operación 1 2 3 4 5 6 7 8 9 10 11 12 13 14 Menos Unitario + * / AND OR Eql Neq Lss Geq Gtr Leq Not Instrucciones de Input / Output Tabla 5. Instrucciones de In/Out. Instrucción Descripción SIO Escribe la string a la que apunta el top del stack en la stream de salida. SRO Escribe en la posición en curso de una tabla lo que hay en el top del stack. NIO Escribe en la stream de salida el número que hay en el top del stack Otras Instrucciones Tabla 6. Otras Instrucciones de Máquina. Instrucción Descripción EDI Crea el Error 71 que indica el índice invalido en un Array ERT Crea el Error Falta Return en una función (en tiempo de ejecución) RET Retorna de la rutina. EOS Manual del Usuario PSPS IV End Of Simulation Termina el programa Pspal y detiene la simulación ordenadamente. 167 Apéndice C. La Ventana del Listener STP Stop Aborta la simulación NOP Non operation Operación nula. LAB Label Etiqueta . El argumento es la etiqueta de la expresión Pspal usada en debugging PAU Pause Pausa La opción Code del Menú Display muestra el código de la máquina para los distintos ele mentos del modelo. Mostramos a continuación un fragmento del Output que se obtiene. La opción Code/Block lista para cada bloque del modelo las instrucciones de má quina. El sistema trata de identificar la variable Pspal a partir de su dirección y lo muestra en el listado. El símbolo ? a continuación de los argumentos de la instrucción indica que el sistema no esta seguro de que la operación se realiza sobre la variable indicada. Figura 2. Ventana del Listener. Menú Display/Code/Block. El estado del s istema. Menú Debug: Ejemplo. Las opciones del menú Debug nos permiten comprobar en cualquier momento en que la simulación este detenida, el estado del sistema que estamos simulando. En esta sección describiremos el Output con la ayuda de un sencillo ejemp lo el output generado por las opciones de este menú. Manual del Usuario PSPS IV 168 Apéndice C. La Ventana del Listener Cuadro 1. Ejemplo Data FACILITY 2; SWITCH 0; REPORT On; System 1:GENERATE Uniform(12,24); 2:ENTER 1; 3:ENTER 2; 4:LEAVE 1; 5:WAITFOR Uniform(12, 20); 6:LEAVE 2; 7:TERMINATE 1; EndSystem; Podemos comprobar el número de transacciones que se encuentran en el sistema, las que han entrado y salido de cada bloque, el estado de los switches o el contenido de los procesadores. Utilizando el modelo del cuadro anterior y mediante la opción ShowState del menú Debug obtenemos el output que se muestra en la figura 3. Figura 3. Menú Debug/ShowState. Las últimas líneas muestran la lista de acontecimientos pendientes en la que podemos observar cual será el próximo evento. En nuestro ejemplo el próximo evento es la generación de una transacción en el bloque 1 en el instante 18.38. Para cada una de las transacciones que se encuentran en la lista de acontecimientos pendientes se muestran los valores de sus 11 primeros atributos que nos permitirán ver de qué bloque provienen las transacciones, o el instante de tiempo en que saldrán del bloque en el que se encuentran detenidas. Manual del Usuario PSPS IV 169 Apéndice D: La Traza de un Sistema § § § Manual del Usuario PSPS IV Trazando los Procesadores Trazando las Transacciones Trazando la Lista de Transacciones Apéndice D. La Traza de un Sistema. Como vimos en el Capítulo 11 de este manual, la traza del sistema puede activarse mediante el uso del Bloque TRACE, tanto en la sección Data como en la sección System, o mediante la opción Trace del menú Interactions, de la Barra de menús de la Ventana Principal del PSPS. Figura 1. Ventana Principal PSPS. Menú Interaction Si se utiliza el bloque TRACE las opciones de trazado deben especificarse en los parámetros de dicho bloque. Si se utiliza el Menú Interactions las opciones se deben seleccionar en el cuadro de diá logo. En ambos casos la traza del sistema aparece en la Ventana del Listener. En las secciones siguientes analizaremos en detalle el output de la traza en la Ventana del Listener. La opción Trace del menú nos permite seleccionar los elementos del modelo que queremos trazar por ejemplo los procesadores o la lista de transacciones. El bloque TRACE permite fijar en su segundo parámetro niveles de trazado. En las siguientes secciones utilizaremos el siguiente ejemplo para explicar en detalle el Output de la Traza Cuadro 1. Ejemplo. Data VARS Fs[1] = 10; TIME 350; RESET 100; REPORT ON; ITEM 1; System GENERATE Normal(8/20, 1/20); SWITCH 1,on; QUEUE 1; WAITFOR 4; LEAVE 1; switch 1, off; TERMINATE; Endsystem; Manual del Usuario PSPS IV 170 Apéndice D. La Traza de un Sistema. Cuadro de Dialogo Trace Parameters En esta sección describiremos en detalle las opciones del cuadro de dialogo TRACE Parameter. Figure 2. Menú Interactions/Trace. Ventana TRACE Parameter. Las opciones de Tracing nos permiten seleccionar los elementos que queremos trazar, marcando la opción deseada. A diferencia del bloque TRACE en el que tenemos que definir un nivel de traza aquí podemos seleccionar la traza de cualquiera de los componentes del sistema . Si seleccionamos la opción Trace All se marcaran automáticamente todas las opciones y la traza será completa, de todos los componentes del modelo. Trace Step nos permite seleccionar la modalidad de la traza. La opción Auto realiza la traza de forma automática, y puede ser consultada en la Ventana del Listener cuando la simulación se detenga. La opción Manual nos permite consultar la traza cada vez que se ejecuta un acontecimiento, ya que el sistema se detiene y debe ser el usuario el que lo haga funcionar manualmente mediante el botón Continue del la Ventana de Control de la simulación. El instante de comienzo de la traza del sistema es por defecto el instante cero pero esta ventana nos permite fijar el instante de tiempo en que queremos que comience la traza del sistema. La opción Stop Tracing nos permite detener la traza del sistema de un bloque TRACE sin necesidad de cambiar el código del modelo. Por último la opción Debug Switch es similar al Tracing Facilities pero para el caso de los procesadores de tipo Switch. El output de todas las opciones y la forma de interpretarlo lo describiremos en detalle en las siguientes secciones. Manual del Usuario PSPS IV 171 Apéndice D. La Traza de un Sistema. Bloque TRACE TRACE , ; El primer parámetro del bloque TRACE puede tomar los valores On y Off que indican el inicio o el fin de la traza, respectivamente. El segundo parámetro indica el nivel de la traza. Nivel 1, procesadores Nivel 2, procesadores y transacciones Nivel 3, procesadores, transacciones y bloques. Nivel 4, procesadores, transacciones, bloques y el Interprete. Nivel 5 o superior, procesadores, transacciones, bloques, interprete y lista de transacciones. Como vimos en el capitulo 11, la traza del modelo se realiza forma diferente si el bloque se encuentra en la sección Data o la sección System. Si el bloque esta en la sección Data la traza realiza desde el instante inicial y si esta en la sección System inicia cuando la transacción accede al bloque. de en se se El bloque TRACE puede combinarse con las opciones del cuadro de dialogo TRACE Parameters. Mediante la opción Time del cuadro de dialogo podremos modificar el nivel de Traza en un instante concreto, sin modificar el código del modelo. Trazando los Procesadores. Tracing Facilities Tracing Facilities escribe en la Ventana del Listener la entrada y salida de las transacciones a los procesadores. Veamos la traza generada por nuestro ejemplo Figure 3. Traza del Sistema. Opción Facilities Manual del Usuario PSPS IV 172 Apéndice D. La Traza de un Sistema. Como hemos activado la traza del sistema mediante la opción Trace del menú Interaction y no hemos modificado la opción Starting Time , la traza comienza a realizarse desde el instante 0. Cuando la transacción en curso intenta acceder a un procesador, la traza nos indica si es posible entrar en el procesador dando número del procesador, la capacidad, el contenido actual del mismo y el número de unidades que solicitan la entrada. En caso de que la capacidad del procesador estuviera saturada, la traza escribiría la frase “NO PUEDO METER EN EL PROCESADOR” indicando a continuación los datos del procesador. Otra acción que enumera la traza es la salida de un procesador, indicando el número del procesador que es abandonado, la capacidad y el contenido del mismo y el número de unidades en que disminuye el contenido del procesador. Trazando las Transacciones. La opción Transactions lista en la ventana del Listener el paso de las transacciones por los bloques del sistema. Para cada bloque aparece el instante de tiempo en el que la transacción accede a dicho bloque. En le caso del bloque GENERATE es el instante en el que una transacción es generada. A continuación aparece el número de bloque, el tipo de bloque y después se listan los 40 primeros atributos de la transacción en curso. Con esta opción podemos observar el orden en que las transacciones recorren los bloques del modelo. Figure 4. Traza del Sistema. Opción Transactions Manual del Usuario PSPS IV 173 Apéndice D. La Traza de un Sistema. Trazando los Bloques. Los datos que muestra la traza con esta opción son muy similares a los que podemos obtener mediante la tabla de bloques del Menú Display/Block de la Ventana Principal del PSPS. La diferencia es que mediante la traza podemos observar el estado de los bloques a en cada instante de la simulación. Además mediante la traza obtenemos información adicional sobre el stack. Figure 5. Traza del Sistema. Opción Blocks Vemos para cada bloque el número de transacciones que han entrado (T. In) el número de transacciones que han salido (T.Sa.) y el número máximo de transacciones que ha habido hasta ese momento en el sistema (Max), Tranzando la Lista de Transacciones. Tracing List Transactions se encarga de mostrar la Listas de Transacciones Paradas (L.T.P). Son las transacciones que están detenidas en algún bloque porque las condiciones del sistema no les permiten moverse. Normalmente suele tratarse de transacciones que esperan a que un Switch cambie de estado o a que un procesador quede libre. También muestra la lista de Acontecimientos Pendientes (L.A.P), en la que aparece el instante de tiempo en el que se producirá un acontecimiento. Manual del Usuario PSPS IV 174 Apéndice D. La Traza de un Sistema. Figure 6. Traza del sistema. Opción Transactions List. Manual del Usuario PSPS IV 175 APENDICE E: Uso del Sistema PSPS. § § § § § § § Manual del Usuario PSPS IV Menu File Menu Edit Menu Display Menu Window Menu Run Menu Interaction Menu Help Apendice E: Uso del Sistema PSPS En este apéndice se muestra información acerca de las distintas opciones de los menús de la Ventana Principal del PSPS IV. Menu File New C rea una nueva ventana de texto preparada para la edición de un programa. El sistema sitúa en la ventana las cabeceras de las diferentes secciones de un programa PSPS para ayudar al usuario a conservar el orden necesario entre secciones. La ventana es efímera, de forma que al salir del PSPS si no se ha guardado se pierde. Open Presenta el cuadro de diálogo habitual en la apertura de ficheros. Permite elegir el fichero que se quiere abrir. Se puede restringir la visualización de los ficheros de acuerdo con su terminación. En concreto el sistema permite visualizar los ficheros psps (*.pss) o los ficheros de texto (*.txt), además de la opción habitual de ver todos los ficheros (all files). Close Cierra una ventana de texto. En caso de que el contenido no haya sido guardado en un fichero, el sistema pregunta si se quiere guardar. Si la respuesta es positiva, se abre el cuadro de diálogo para guardar un fichero. En caso contrario la ventana de texto se cierra y su contenido se pierde irremediablemente. Save Guarda el contenido de la ventana de texto en el fichero asociado cuyo nombre se muestra en el título de la ventana. El fichero se guarda con el mismo nombre. Si el fichero en la ventana ha sid o modificado, y por tanto se presume no idéntico con el guardado, el sistema abre un cuadro de diálogo para preguntar al usuario si esta seguro de la sustitución que va a efectuar. Si la respuesta es 'No' se cancela la operación. Si la respuesta es 'Sí' se completa la sustitución perdiéndose el fichero existente en el disco. Si la ventana no se ha guardado nunca, se abre el cuadro de diálogo habitual para guardar ficheros. Save All Realiza la operación de guardar sobre todas las ventanas que se encuentre abiertas en ese momento. Siempre pide confirmación de la operación que se va a realizar para cada una de las ventanas. Manual del Usuario PSPS IV 176 Apendice E: Uso del Sistema PSPS Save As… Abre una ventana en la que se debe escribir el nombre del fichero en el que se desea guardar la ventana en curso. La forma de operar es la standard de Windows. Por lo tanto se puede marcar un fichero en la ventana de diálogo para indicar que se quiere utilizar este nombre, lo que provocara su sobrescritura. Close All Cierra todas las ventanas de texto que esten abiertas en ese momento. Si han sido modificadas pide confirmación de la operación para cada una de las ventanas. Print Imprime el texto de la ventana en la impresora del sistema. El formato de impresión es muy simple. Para realizar impresiones más sofisticadas, quizá con formatos elaborados, puede guardarse la ventana en un fichero y abrirse el fichero en un procesador de texto. AutoRun Esta opción nos permite ejecutar automáticamente el modelo de simulación guardado en el fichero AutoRun sin necesidad de abrir el fichero ni de compilarlo. La opción AutoRun oculta la ventana principal del PSPS y muestra únicamente la ventana de control de la simulación y los resultados de la simulación. Exit Sale del PSPS. En todos los casos pide confirmación de la operación Menu Edit Undo Proporciona hasta 200 niveles de Undo, restaurando el estado de la ventana al momento anterior del último cambio. Cut Corta el texto seleccionado y lo pone en el portapapeles Copy Copia el texto seleccionado y lo pone en el portapapeles. Paste Pega el contenido del portapales en la posición actual del cursor. Select All Selecciona todo el texto de la ventana activa. Manual del Usuario PSPS IV 177 Apendice E: Uso del Sistema PSPS Find Abre el cuadro de diálogo standard para buscar un String en la ventana de texto activa. Find In Files Abre el cuadro de diálogo de búsqueda de un string, para buscar un string en los ficheros de texto del directorio de la ventana de texto activa. Replace Abre el cuadro de diálogo standard para buscar y reemplazar un String en la ventana de texto activa. Check ( ) Comprueba los niveles de paréntesis de la expresión seleccionada. Comment Convierte el texto seleccionado en un comentario encerrandolo entre corchetes { } UnComment Elimina los símbolos { } que abren y cierran el comentario seleccionado. Indent Modifica la alineación del texto seleccionado desplazándolo hacia la derecha. Outdent Modifica la alineación del texto seleccionado desplazándolo hacia la izquierda. To Uppercase Cambia los mayúsculas. caracteres de texto seleccionados a de texto seleccionados a To Lowercase Cambia los minúsculas. caracteres Menu Display Variables Permite visualizar en forma de tabla los valores de las variables del modelo que hemos simulado y la dirección de memoria de las mismas. Manual del Usuario PSPS IV 178 Apendice E: Uso del Sistema PSPS Local Vars Permite visualizar en forma de tabla los valores de las variables locales del modelo que hemos simulado y la dirección de memoria de las mismas. Blocks Muestra las distintas estadísticas disponibles para los bloques de nuestro modelo de simulación. Para cada bloque nos indica el tipo de bloque, el número de transacciones que han entrado, el número de las que han salido, las transacciones que están en ese momento en el bloque (stock), el número máximo de transacciones que ha habido en el bloque, y la esperanza de capacidad de cada bloque en el tiempo. Facilities Muestra una tabla de los procesadores que han sido usados en la simulación. En la tabla aparece el núme ro de procesador, la capacidad, las transacciones en curso al terminar la simulación, el número máximo, el número medio de transacciones en el tiempo y la desviación tipo de la ocupación durante la simulación. Switches Muestra una tabla de los Switches utilizados en la simulación, en la que aparece la ocupación media del Switch y la desviación tipo de la ocupación. Stat Variables Muestra las estadísticas de las variables que han sido declaradas Stat. Las estadísticas disponibles son: el valor máximo, la media temporal ponderada, la desviación tipo temporal ponderada, la media simple y la desviación tipo simple. Tables Muestra los Histogramas de Frecuencias creados por un bloque TABULATE. Current Transactions Muestra en forma de tabla los valores de los 40 primeros atributos de la transacción en curso. All Muestra las tablas de los bloques, los procesadores, los switches, las variables Stat y los Histogramas, si hemos definido alguno en nuestro modelo. Refresh Actualiza los valores de las tablas del menú Display que se encuentren abiertas en ese momento. Manual del Usuario PSPS IV 179 Apendice E: Uso del Sistema PSPS Menu Window Close All Cierra todas las tablas, histogramas o gráficos definidas en la simulación y que tenemos abiertas. Results: Cierra todas las ventanas que muestran los resultados de la simulación. Graphs: Cierra las ventanas de los gráficos de la simulación que se encuentren abiertas. Tables: Cierra las ventanas de los histogramas de la simulación. User Tables: Cierra las tabla creadas por el usuario que se encuentra abiertas. Gantt Diagrams:Cierra las ventanas que contienen los diagramas de Gantt. Cascade Organiza las ventanas que estén abiertas en forma de cascada, es decir superpuestas unas con otras. Tile Organiza las ventanas que estén abiertas en forma de pila, es decir una debajo de otra sin que se superpongan. Arrange Icons Ordena los iconos de las ventanas al pie de la ventana principal del PSPS. Minimize All Este menú minimiza todas las ventanas que estén abiertas en ese momento. Programming Help Muestra una ventana en la que aparece un asistente para implementar un programa PSPS. Esta ventan es de gran utilidad ya que permite consultar de forma rápida los argumentos de una función, el nombre correcto de una constante o los parametros de un bloque. Menu Run Set As Main Cuando tenemos varias ventanas de texto abiertas, nos permite fijar una de ellas como ventan principal. Diremos entonces que la ventana es la ventana principal de nuestro modelo de simulación y será la ventana sobre la que actuaran el resto de las funciones del menú Run . Manual del Usuario PSPS IV 180 Apendice E: Uso del Sistema PSPS Compile Compila el fichero de texto que hemos definido como principal. Detecta si hay errores de compilación que hacen que no se pueda ejecutar el modelo. Si hay algún error aparece un mensaje indicando donde se encuentra y el tipo de error. Run Compila automáticamente la ventana de texto principal y si no hay errores de compilación muestra el cuadro de control de la simulación y pasa a ejecutar el programa. Si hay algún error de compilación aparecerá un cuadro de diálogo indicándonos el tipo y la posición del error. Simulate Simula el modelo que tenemos en la ventana de texto principal. Continue Permite continuar la simulación después de haberla parado mediante el botón Stop. También pone en marcha el reloj de la simulación si el programa tiene la sentencia Report. La sentencia Report para la simulación en el instante indicado. Si la constante de la sentencia Report es negativa, la simulación se parara antes de comenzar. En este caso haciendo clic en el botón Continue se pondrá en marcha el reloj de simulación y comenzará la simulación. Stop Para el reloj de simulación. Options Abre una ventana que nos muestra las distintas opciones para las sentencias de Output y las sentencias de Debugging. Abort Detiene la simulación y aparece un cuadro de diálogo que nos indica que la simulación ha sido detenida por el usuario. Si detenemos el reloj de simulación con el comando Abort, no se puede volver a poner en marcha con el comando Continue. Hay que inicializar el modelo, es decir hay que volver a compilarlo. Menu Interaction Trace Muestra el cuadro de diálogo en el que seleccionaremos las opciones de trazado del sistema. DDT Abre el cuadro de diálogo del DDT. El DDT muestra de forma gráfica el movimiento de las transacciones por los distintos bloques del sistema. Manual del Usuario PSPS IV 181 Apendice E: Uso del Sistema PSPS Show Listener Muestra la ventana del Listener. Esta ventana dispone de una barra de menu que nos permite consultar el Output de la simulación, las variables utilizadas o el estado actual de la simulación mediante las opciones del menu Debug. También dispone de un interprete de Lisp para el tratamiento de listas. Debugger Muestra una ventana de Debugger, en la que podemos realizar una ejecucion paso a paso del modelo y ver el estado de las distintas variables, procesadores o Switches del modelo. Items Muestra un cuadro de diálogo que nos permite modificar el número de items a procesar. Este cuadro de diálogo se utiliza para indicar la longitud de la simulación según el número de Items procesados. Time Muestra un cuadro de diálogo que nos permite modificar el tiempo de finalización de la simulación. Cuando el reloj interno alcance el valor fijado en este cuadro la simulación se detendrá. Reset Statistic Este menú realiza la misma función que la sentencia Reset de la sección Data. Reset reinicializa las estadísticas del modelo que estamos simulando. Las estadísticas inicializadas incluyen los datos sobre procesadores, bloques e Histogramas. Inspect Muestra las tablas de las variables y los procesadores. Nos permite cambiar el valor de las variables y los parámetros de los procesadores. Save File OutPut Guarda los ficheros de Output creados por el modelo. Abre el cuadro de diálogo habitual para guardar un fichero. Si no guardamos los ficheros de Output mediante esta opción no podremos acceder a ellos. Reset Time Mode Este menú permite restablecer el funcionamiento del reloj de simulación a la forma habitual, es decir independiente del reloj físico del ordenador, si ha sido modificada mediante la función TimeMode. Menu Help About Muestra información acerca de la versión y del Copyright del PSPS que estamos utilizando. Help PSPS Muestra la ayuda on-line del PSPS. Manual del Usuario PSPS IV 182 CopyRight © Josep Riverola. Catedra Alcatel IESE – May 2003