Universidade Federal de Minas Gerais Instituto de Ci^encias Exatas Departamento de Ci^encia da Computaca~o Laboratorio de Linguagens de Programac~ao Machna: A Linguagem de Especicac~ao de ASM by Fabio Tirelo Roberto da Silva Bigonha Marcelo de Almeida Maia Vladimir Oliveira di Iorio LLP 008/99 Caixa Postal, 702 30.161-970 { Belo Horizonte Minas Gerais { Brazil August, 1999 Resumo Este texto contem a denic~ao da Linguagem de Programac~ao Machna, que e uma linguagem baseada no paradigma de Programac~ao Algebrica, derivado do modelo de Maquinas de Estado Abstratas (ASM). Nesta denic~ao, apresentamos a sem^antica informal de Machna, descrevendo os aspectos sem^anticos da linguagem por meio de linguagem natural e exemplos de utilizaca~o das construc~oes da linguagem. Ao nal, apresentamos varios exemplos de programas escritos em Machna. Sumario 1 A Linguagem Machna 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 1.10 1.11 1.12 1.13 1.14 1.15 1.16 1.17 1.18 1.19 1.20 1.21 Introduc~ao . . . . . . . . . . . . . . . . . . . Comentarios . . . . . . . . . . . . . . . . . . Literais . . . . . . . . . . . . . . . . . . . . Palavras Reservadas . . . . . . . . . . . . . Identicadores . . . . . . . . . . . . . . . . Notac~ao Para Sintaxe . . . . . . . . . . . . Uma Especicac~ao em Machna . . . . . . . Modulos . . . . . . . . . . . . . . . . . . . . Agentes . . . . . . . . . . . . . . . . . . . . Termino da Execuc~ao . . . . . . . . . . . . Mecanismos de Visibilidade . . . . . . . . . Declarac~ao de Tipos . . . . . . . . . . . . . 1.12.1 Enumerac~oes . . . . . . . . . . . . . 1.12.2 Uni~oes Disjuntas . . . . . . . . . . . 1.12.3 Tipo ? . . . . . . . . . . . . . . . . . 1.12.4 Intervalos . . . . . . . . . . . . . . . 1.12.5 Tuplas . . . . . . . . . . . . . . . . . 1.12.6 Conjuntos . . . . . . . . . . . . . . . 1.12.7 Listas . . . . . . . . . . . . . . . . . 1.12.8 Tipos Funcionais . . . . . . . . . . . 1.12.9 Tipos Agentes . . . . . . . . . . . . 1.12.10Denic~oes de Tipos . . . . . . . . . . Regras de Visibilidade para Tipos . . . . . Regras para Deduc~ao de Tipos . . . . . . . Equival^encia de Tipos . . . . . . . . . . . . Compatibilidade de Tipos . . . . . . . . . . Declarac~ao de Func~oes . . . . . . . . . . . . Declarac~ao de Func~oes Externas . . . . . . Denic~ao das Regras de Inicializac~ao . . . . Declarac~ao de Abstrac~oes de Regras . . . . Sec~ao de Denic~ao de Regras de Transic~ao . 1.21.1 Regras Basicas . . . . . . . . . . . . i . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1 1 1 2 2 2 2 3 4 5 6 7 7 8 8 8 8 8 8 9 9 9 9 10 11 11 12 12 13 14 14 14 1.21.2 Regra forall . . . . . . . . . . . . . . . . . . . . 1.21.3 Regra choose . . . . . . . . . . . . . . . . . . . 1.21.4 Regras Para Criac~ao e Eliminac~ao de Agentes . 1.21.5 Regra Para Parada . . . . . . . . . . . . . . . . 1.21.6 Regra let . . . . . . . . . . . . . . . . . . . . . 1.21.7 Regra case . . . . . . . . . . . . . . . . . . . . 1.21.8 Regra with . . . . . . . . . . . . . . . . . . . . 1.21.9 Regra de Chamada a Ac~oes . . . . . . . . . . . 1.22 Invariante da Execuc~ao . . . . . . . . . . . . . . . . . 1.23 Sintaxe de Express~oes . . . . . . . . . . . . . . . . . . 1.23.1 Operadores de Machna . . . . . . . . . . . . . 1.23.2 Valores Booleanos . . . . . . . . . . . . . . . . 1.23.3 Caracteres . . . . . . . . . . . . . . . . . . . . . 1.23.4 Numeros Inteiros . . . . . . . . . . . . . . . . . 1.23.5 Numeros Reais . . . . . . . . . . . . . . . . . . 1.23.6 Cadeias de Caracteres . . . . . . . . . . . . . . 1.23.7 Aplicac~ao de Func~oes . . . . . . . . . . . . . . 1.23.8 Listas . . . . . . . . . . . . . . . . . . . . . . . 1.23.9 Conjuntos . . . . . . . . . . . . . . . . . . . . . 1.23.10Tuplas . . . . . . . . . . . . . . . . . . . . . . . 1.23.11Mapeamentos . . . . . . . . . . . . . . . . . . . 1.23.12Convers~ao de Tipos . . . . . . . . . . . . . . . 1.23.13Condicionais e Let . . . . . . . . . . . . . . . . 1.23.14Express~oes Especiais . . . . . . . . . . . . . . . 1.23.15Gramatica das Express~oes . . . . . . . . . . . . 1.24 Manipulac~ao de Arquivos . . . . . . . . . . . . . . . . 2 Exemplos 2.1 2.2 2.3 2.4 Pesquisa Binaria . . . . . . . . . . . . . . . . Ordenac~ao por Selec~ao . . . . . . . . . . . . . Numeros Primos . . . . . . . . . . . . . . . . Especicac~ao da Sem^antica de Tiny . . . . . 2.4.1 Modulo de Globais (Globals) . . . . . 2.4.2 Modulo de Operac~oes (Operations) . 2.4.3 Modulo de Express~oes (Expressions) 2.4.4 Modulo de Comandos (Comandos) . . 2.4.5 Modulo principal (Tiny) . . . . . . . . 2.4.6 Disparo do Agente de Execuc~ao . . . . 2.5 Jantar dos Filosofos . . . . . . . . . . . . . . ii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 16 16 17 17 18 18 19 19 19 19 20 20 20 21 21 22 22 22 23 23 24 25 25 26 26 29 29 30 30 31 31 32 33 34 35 35 36 Cap tulo 1 A Linguagem Machna 1.1 Introduc~ao Neste captulo, apresentamos a linguagem Machna, que e baseada na metodologia de Maquinas de Estado Abstratas (ASM), com suporte a modularidade, tipos e construc~oes de alto nvel. Um programa em Machna tem o estilo de Programac~ao Algebrica, isto e, o estado da computac~ao e descrito por uma algebra e existe uma regra de transica~o que promove a mudanca de estados. Desta forma, a escrita de um programa algebrico consiste em denir: um vocabulario, que e o conjunto de smbolos da especicac~ao, isto e, o conjunto dos identicadores e operadores conhecidos; uma algebra inicial, que e a interpretac~ao inicial do vocabulario; uma regra de transic~ao, que promove a transic~ao de estados (algebras). 1.2 Comentarios Comentarios em Machna podem ser de dois tipos: um texto que se inicia com /* e termina com */, podendo haver aninhamento; um texto que se inicia com // e vai ate o m da linha. 1.3 Literais Os literais de Machna s~ao: caracteres do conjunto ASCII, representados por um smbolo entre apostrofos, p.ex. '5' e ou por um codigo denotando caracteres especiais, como '\n', '\0', etc. numeros inteiros { numeros inteiros podem ser escritos em decimal (sequ^encia de dgitos), octal (0 seguido de sequ^encia de dgitos de 0 a 7) ou em hexadecimal (0x seguido de sequ^encia de dgitos ou letras de A a F ou a a f). Os numeros inteiros est~ao no intervalo [-2147483648,2147483647]. numeros de ponto utuante { sequ^encia de dgitos, seguida por uma parte fracionaria opcional, seguida por uma parte de expoente opcional; a parte fracionaria consiste em um ponto (".") seguido por uma sequ^encia de dgitos; a parte do expoente consiste em 'a', 1 ou E, seguido por um sinal opcional (+ ou -), seguido por uma sequ^encia de dgitos. Numeros de ponto utuante t^em valor maximo 1.79769313486231570E+308 e valor mnimo 4.94065645841246544E-324, seguindo o padr~ao IEEE 754 para ponto utuante. cadeias de caracteres { sequ^encia de caracteres entre aspas, como por exemplo, "string", "isto e\' um teste", "fim de linha\n", etc.; e 1.4 Palavras Reservadas As palavras reservadas de Machna s~ao: action choose dynamic external in list of self transition algebra create else false init machina or set true and default elseif forall interleaved module otherwise static type as derived end if is nil public stop with case do enum import let not satisfying then 1.5 Identicadores Identicadores em Machna s~ao divididos em dois tipos: identicadores de tipos e modulos { formados por uma ou mais letras, onde a primeira e maiuscula; identicadores de variaveis { formado por uma ou mais letras, onde a primeira e minuscula; podem ser decoradas, isto e, terminadas, com numeros; 1.6 Notac~ao Para Sintaxe Para descric~ao da gramatica, utilizaremos a BNF estendida [?], ou XBNF. As construc~oes utilizadas s~ao semelhantes a BNF, com as seguintes extens~oes: j Opc~oes f X g Zero ou mais ocorr^encias de X [X] Zero ou uma ocorr^encia de X Os caracteres que representam meta-smbolos, se utilizados na gramatica, ser~ao escritos em aspas, como por exemplo \f". 1.7 Uma Especicac~ao em Machna Uma especicac~ao em Machna consiste em uma coleca~o de um ou mais modulos, denominados modulos de programa, ou somente modulos. Associado a uma especicac~ao, pode haver uma ou mais \denic~oes de maquina", na qual denimos e disparamos os agentes que executam as regras dos modulos. 2 1.8 Modulos Um modulo especica um nome para o programa de um agente, a regra que este agente executa, e sua algebra subjacente, isto e, smbolos, universos e interpretac~ao dos smbolos. Um modulo tem a forma: module nome-modulo import: elementos importados algebra: algebra subjacente { tipos, funco~es, ac~oes, inicializac~oes transition: regra de transic~ao end Uma denic~ao de maquina especica o seu nome e possui uma sec~ao de inicializac~oes, onde s~ao os agentes criados e disparados. Cada denica~o possui a seguinte forma: machina nome-maquina end declarac~oes do ambiente de execuca~o inicializac~oes { criac~ao dos agentes Modulos possuem tr^es partes: Importaco~es { dene os modulos que ser~ao importados (Sec~ao 1.11); A lgebra { dene a algebra subjacente ao modelo, contendo os sorts ou tipos, as func~oes, as ac~oes e as regras de inicializac~ao; Regra de transic~ao { dene a regra de transic~ao do modulo, isto e, o programa dos agentes. A sec~ao de algebra e divida nas seguintes subseco~es: Denic~ao de tipos { dene tipos (sorts) de dados que ser~ao utilizados na especicac~ao (Sec~ao 1.12); Func~oes { agrupa as denic~oes de func~oes por classe, podendo ser estatica, din^amica e derivada. Por exemplo, uma declarac~ao da forma static f := ... g := ... h := ... dynamic a := ... b := ... dene f, g e h como func~oes estaticas, e a e b como din^amicas (Sec~ao 1.17); Func~oes externas { dene os cabecalhos das func~oes externas (Sec~ao 1.18); Aco~es { dene as transic~oes parametrizadas, que s~ao abstrac~oes de regras de transic~ao (Sec~ao 1.20); Inicializac~oes { regra de inicializac~ao de func~oes din^amicas e denic~ao de func~oes estaticas (Sec~ao 1.19); 3 A sintaxe de um modulo e a seguinte: module module-body import-part algebra-part transition-part invariant-part module-import imported-list imported-element algebra-section type-section type-pdecl function-section class-modier function-pdecl external-section external-pdecl action-section action-pdecl init-section ::= ::= ::= ::= ::= ::= ::= ::= ::= ::= module module-name module-body end [import-part] [algebra-part] [transition-part] [invariant-part] import: module-import f , module-import g algebra: f algebra-section g [interleaved] transition: transition-rule invariant: expression module-name [imported-list] ( imported-element f , imported-element g ) id j type-name type-section function-section external-section action-section init-section ::= type type-pdecl f ; type-pdecl g ::= [public] type-declaration ::= class-modier function-pdecl f ; function-pdecl g ::= static j dynamic j derived ::= [public] function-declaration ::= external external-pdecl f ; external-pdecl g ::= [public] external-declaration ::= action action-pdecl f ; action-pdecl g ::= [public] action-declaration ::= init transition-rule j j j j 1.9 Agentes A cada modulo pode ser associado um conjunto de agentes, que executam a sua regra. Agentes s~ao criados por meio de uma regra especial de nome create, como sera visto na Sec~ao 1.21. A regra de transic~ao de um modulo declarada como interleaved e executada repetidamente de forma entremeada com a de outras regras. Apos cada transic~ao, o controle volta para o modulo maquina, que pode livremente escalar o proximo agente a prosseguir em execuc~ao. Transic~oes que n~ao s~ao declaradas como interleaved s~ao executadas repetidamente ate o seu termino. Agentes podem ser referenciados, de dentro de um programa, por meio de func~oes, assim como qualquer valor. Para isto, s~ao denidos em Machna o tipo Agent e o construtor de tipos agent of M, onde M e um nome de modulo. O tipo agent of M e o conjunto de agentes que executam a regra do modulo M. Mais detalhes sobre este tipo ser~ao mostrados na Sec~ao 1.12.9. Todo agente possui uma func~ao especial de nome self 2 agent of M, que retorna a sua identicac~ao, onde M e o modulo que contem a regra que o agente executa. Desta forma, representamos informac~oes locais a um agente. Uma maquina deve denir a criac~ao dos agentes que iniciar~ao a execuc~ao. Considere, por exemplo, a denica~o dos modulos e a criac~ao dos agentes dada por: machina D module C module B module A create a : agent of A decls of C decls of B decls of A create b : agent of B transition: transition: transition: create c : agent of C rule of C rule of B rule of A end end end end A relac~ao entre os agentes denidos na machina D e os modulos A, B e C pode ser vista na Figura 1.1. 4 decls-A a rule-A decls-B b rule-B decls-C c rule-C Figura 1.1: Exemplo de espaco de declarac~oes e regras e acesso de agentes. Na Sec~ao 1.11, mostraremos como estender este modelo para lidar com o compartilhamento de declarac~oes entre modulos. 1.10 Termino da Execuc~ao A execuc~ao termina com a execuc~ao do comando stop, ou quando a guarda principal n~ao for verdadeira. Por exemplo, a execuc~ao da especicac~ao abaixo so terminara com a execuc~ao do comando stop. module A ... transition: if cond-parada then stop else ... end end Se todas as guardas do programa avaliarem em falso, ent~ao a execuc~ao terminara. Entretanto, se houver alguma chamada a func~ao externa nas guardas, a execuc~ao cara suspensa, esperando que a func~ao externa seja modicada e alguma guarda se torne verdadeira. module B external f : Int; dynamic g(x : Int) transition: if f = 10 then g(10) := 0 else g(10) := 1 end end : Int; Quando a regra for executada a primeira vez, se o valor da funca~o externa f for 10, o valor de g no ponto 10 sera atualizado para 0. Enquanto o valor de f n~ao mudar, a regra g(10) := 0 5 sera executada, o que n~ao causara mudanca alguma no estado. Neste caso, a execuc~ao n~ao sera abortada, pois n~ao sabemos se no proximo estado, o valor da func~ao externa sera diferente de 10. 1.11 Mecanismos de Visibilidade Um modulo pode importar os elementos (declarac~oes de func~oes, tipos e ac~oes) de outros modulos. Toda declarac~ao e privada a um modulo, isto e, visvel somente dentro do modulo no qual foi feita. Um elemento so n~ao e privado a um modulo se for explicitamente declarado como publico, por meio do modicador de visibilidade public. Os elementos publicos de um modulo M1 tornam-se visveis dentro de outro modulo M2, quando M1 for importado em M2. Isto e feito na parte de importac~oes do modulo M2, de uma das seguintes maneiras: import: import: M1 M1(a,b) Torna visveis todos os elementos publicos de M1 Torna visveis somente os elementos publicos a e b de M1 Da primeira maneira, todos os elementos publicos de M1 s~ao visveis dentro de M2. Um elemento a, p ublico de M1 e acessado em M2 da forma M1.a. Da segunda maneira, os elementos a e b de M1 s~ ao diretamente visveis em M2, n~ao sendo necessaria a qualicac~ao do modulo para acessar a ou b, isto e, estes identicadores podem ser acessados diretamente em M2, sem a necessidade de especicar o modulo a que pertencem. Por exemplo, considere os modulos abaixo: module X public a; b ... end module Y import: X; public m,n; ... X.a ... end module Z import: ... ... end X, Y(n); X.a ... n ... O modulo X dene um elemento de nome a, que e visvel a partir de outros modulos, enquanto a declarac~ao de b e visvel somente dentro de X, isto e, e privada a este modulo. A linha import X, no m odulo Y, importa todos os elementos publicos de X, o que signica que o elemento a, em X, e visvel dentro de Y, sob o nome de X.A. Da mesma maneira, a e visvel no modulo Z, sendo necessaria a qualicac~ao do modulo, assim como no modulo Y. Entretanto, como a importac~ao do modulo Y em Z explicitou quais identicadores s~ao visveis, podemos utilizar o nome n em Z diretamente, sem a necessidade de escrever Y.n. Alem disso, observe que o nome m, denido como publico em Y tambem e visvel em Z, mas requer completa qualicac~ao, pois n~ao foi explicitado na importac~ao. E importante ressaltar, ainda, que a clausula import n~ao causa a duplicac~ao de declarac~oes; ela apenas torna as declarac~oes publicas de um modulo visveis a outros modulos. Na Figura 1.2, ilustramos como os agentes que executam a regra denida em um modulo acessam as declarac~oes visveis do exemplo abaixo. module A module B module C D public ax; public bx; public cx; machina create a ay; by; cy; create b transition: transition: transition: create c rule of A rule of B rule of C end end end end 6 : : : agent of agent of agent of A B C ax a rule-A b rule-B c rule-C ay bx by cx cy Figura 1.2: Exemplo de Visibilidade entre Modulos. Linhas pontilhadas ligando agentes a declarac~oes signicam que o agente pode acessar a declarac~ao e linhas n~ao-tracejadas ligando agentes a regras mostra qual regra de transic~ao o agente esta executando. 1.12 Declarac~ao de Tipos Os tipos (ou sorts) primitivos de Machna s~ao Bool, Char, Int, Real e String, Set, List, ?. Os tipos estruturados, isto e, formados por meio de geradores de tipos s~ao: enumeraca~o de valores; tupla de elementos; conjunto de um dado tipo; lista de um dado tipo; tipo funcional (n~ao permitindo func~oes de ordem mais alta); uni~ao disjunta; Um nome de tipo e uma sequ^encia de letras, onde a primeira letra e maiuscula. O tipo () (null) e utilizado em denic~oes de tipos recursivos. 1.12.1 Enumerac~oes Tipos enumerados s~ao denidos por meio de enumerac~ao de identicadores, como no exemplo abaixo: RGBColor is enum f red, green, blue g: Enumerac~oes diferentes devem denir identicadores diferentes. Isto signica que n~ao e permitida uma sequ^encia de declarac~oes da forma: ... enum A is f enum B is f ... g a, b, c a, e, i, o, u g pois o identicador a esta sendo denido em duas enumerac~oes diferentes. 7 1.12.2 Uni~oes Disjuntas Uma uni~ao disjunta e feita em Machna utilizando o operador \j". Por exemplo, o tipo Numero abaixo e a uni~ao disjunta entre Int e Real: is Numero : Int | Real Observac~ao: em uma uni~ao disjunta, os tipos componentes n~ao podem ser equivalentes. 1.12.3 Tipo ? O tipo ? e denido como a uni~ao disjunta de todos os tipos possveis, com o valor default igual a undef. Isto signica que, se x e do tipo ?, ent~ao x pode receber valores de quaisquer tipos. O tipo ? so possui as operac~oes de atribuic~ao e comparac~ao por = ou !=. Convers~ao para o tipo real do valor armazenado deve ser feita via comandos ou express~oes with e is. 1.12.4 Intervalos Uma denic~ao de intervalo e feita como no exemplo: UmACem is 1..100 As express~oes que determinam os limites inferior e superior do intervalo devem ser manifestas e seus tipos devem ser iguais e discretos. 1.12.5 Tuplas As tuplas devem ser rotuladas. Pode-se utilizar a tupla vazia, (), em denic~oes de tipos recursivos. Por exemplo, considere a declarac~ao: Tree is : () | (info:Info;left,right:Tree) 1.12.6 Conjuntos O construtor de tipos \set of" e utilizado para denotar o tipo conjunto de elementos de um mesmo tipo. Por exemplo is set of Intset Int e um tipo cujos elementos s~ao conjuntos de numeros inteiros. O tipo pre-denido Set e denido como Set is set of ?: Isto signica que Set e um conjunto generico, onde seus elementos n~ao precisam de ser do mesmo tipo. As regras para utilizac~ao do tipo Set s~ao vistas na Sec~ao 1.23.9. 1.12.7 Listas O construtor de tipos \list of" e utilizado para denotar o tipo lista de elementos de um mesmo tipo. Por exemplo, Intlist is list of Int e um tipo cujos elementos s~ao listas de inteiros. Assim como em conjuntos, o tipo pre-denido List e denido como: List is list of ?: Desta forma, List representa uma lista generica, onde seus elementos n~ao precisam de ser do mesmo tipo. As regras para utilizac~ao do tipo List s~ao vistas na Sec~ao 1.23.8. 8 1.12.8 Tipos Funcionais O tipo funcional, cujo construtor e \->", e um tipo cujos valores s~ao func~oes entre domnios dados. Por exemplo, o tipo Transition denido abaixo e uma func~ao de State Element em State: Transition is : (State,Element) -> State N~ao e permitida a denic~ao de func~oes de ordem mais alta. 1.12.9 Tipos Agentes O construtor de tipos agent of M e utilizado para denotar o tipo dos agentes que executam a regra do modulo M. Existe tambem o tipo pre-denido Agent, que representa agentes de quaisquer tipos. As operac~oes que podem ser feitas sobre agentes s~ao a criac~ao (Sec~ao 1.21.4), a eliminac~ao (Sec~ao 1.21.4), a atribuic~ao, a passagem como par^ametro, o retorno de func~ao e a comparac~ao por igualdade e diferenca. 1.12.10 Denic~oes de Tipos Para permitir a escrita de tipos mutuamente recursivos, Machna permite que, na declarac~ao de um tipo, possam aparecer nomes de tipos que ainda n~ao foram declarados. Entretanto, na denic~ao de uma func~ao, os tipos utilizados devem estar completamente denidos. Em uma denic~ao de tipos, pode haver tambem uma clausula default, que permite estabelecer o valor default para inicializac~ao automatica de func~oes do tipo dado. Uma sec~ao de declarac~ao de tipos tem a seguinte sintaxe: type-declaration ::= type-id is type-expression [default expression] type-expression ::= () j ? j type-name j [public] enum \f"id f , id g \g" j type-expression \j" type-expression j expression .. expression j [public] ( tuple-element f ; tuple-element g ) j set of type-expression j list of type-expression j le of type-expression j agent of type-expression j type-expression -> type-expression tuple-element ::= [public] id f , id g [: type-expression] type-name ::= Bool j Char j Int j Real j String j List j Set j Agent j InputStream j OutputStream j type-id 1.13 Regras de Visibilidade para Tipos Quando um tipo declarado como publico e importado, o seu nome se torna visvel no ponto de importac~ao, mas n~ao a sua estrutura. Entretanto, para os tipos tupla e enumerac~ao, pode ser necessaria a exportac~ao da estrutura. Para isso, Machna dene as seguintes regras para exportac~ao de estrutura: Para exportar os elementos de uma enumerac~ao, escreve-se a palavra-chave public antes da palavra enum. Por exemplo, no codigo abaixo, s~ao visveis externamente os nomes de A, B, x, y, z, ao passo que os nomes a, b e c n~ao s~ao visveis, pois pertencem a uma enumerac~ao n~ao-publica. 9 type public A is enum fa,b,cg; public B is public enum fx,y,zg; Para exportar um campo de uma tupla, escreve-se a palavra chave public antes do nome do campo. A palavra chave public antes de uma lista de identicadores separados por vrgula torna publico todos os identicadores da lista. Para tornar publicos todos os campos da tupla, pode-se utilizar o modicador public antes da express~ao de tipo. Por exemplo, no codigo abaixo, s~ao visveis externamente os identicadores A, B, C, b, e, f, m, n e p, ao passo que os nomes x, y, z, a, c e d s~ao privados ao modulo. type public A is (x:Int;y,z:Real); public B is (a:Int; public b:Real; public C is public (m,n:A; p:B) c,d:Bool; public e,f:Char); 1.14 Regras para Deduc~ao de Tipos Machna possui as seguintes convenc~oes para deduc~ao de tipos: nomes de tipos s~ao uma sequ^encia de letras, sendo que a primeira letra e sempre maiuscula; nomes de func~oes, que aparecem em declarac~oes com especicac~ao de tipos, s~ao uma sequ^encia de letras, onde o primeiro caractere e sempre uma letra minuscula; se o tipo de um identicador for explicitado na declarac~ao, como em a:X, ent~ao o tipo do identicador e o tipo dado e o nome do identicador n~ao pode conter decoraca~o; se o tipo n~ao for explicitado na declaraca~o, ent~ao as seguintes regras s~ao utilizadas para determinac~ao do tipo: { nomes de func~oes e variaveis que cont^em decorac~oes (numeros no nal) possuem o mesmo tipo da func~ao ou variavel sem a decorac~ao; por exemplo, os identicadores x1 e x2 t^em o mesmo tipo de x; { se o tipo do identicador sem decorac~ao n~ao foi declarado, capitaliza-se a primeira letra do nome do identicador; se houver algum tipo com este nome, ent~ao este e o tipo do identicador; { caso contrario, o tipo do identicador sera ?. Por exemplo, considere a sequ^encia de declarac~oes abaixo: ... A ...; // Declara ca ~o do tipo A X ...; // Declara ca ~o do tipo X Y Int; // Declara ca ~o do tipo Y a,b,c:X; // Todas possuem o tipo X x; // O tipo de x e X y := 1; // O tipo de y e Int z; // O tipo de z e ? ... is is is 10 1.15 Equival^encia de Tipos Em Machna, tudo que diz respeito a tipos e decidido em tempo de compilac~ao, de modo que, a menos das express~oes de convers~ao, os objetos n~ao levam para a execuc~ao informac~oes sobre os seus tipos. A disciplina de tipos de Machna e a equival^encia estrutural, denida da seguinte maneira: Dois tipos A e B s~ao equivalentes se e somente se uma das seguintes condic~oes abaixo se aplicarem: A e B s~ao nomes de tipos id^enticos; A e B s~ao nomes de tipos distintos, mas cada um e a refer^encia recursiva para a denic~ao de tipo reexivo que ocorre exatametne na mesma posic~ao correspondente nas suas estruturas de tipos; A e B s~ao o tipo ? de uni~ao disjunta de todos os tipos; A e B s~ao nomes de tipos distintos, cujas denic~oes visveis s~ao, respectivamente, as cadeias mais longas AisA1 isA2 is:::isAn e B isB1 isB2 is:::isBm , tal que Ai , para 1 i n, Bj , 1 j n s~ao nomes de tipos, e An e Bm s~ao os primeiros e unicos nomes repetidos em suas respectivas cadeias; B e uma express~ao de tipos e A e um nome de tipos, cuja denic~ao visvel e tal que Aisd ou AisA1 isA2 is:::isAn isd, onde Ai , para 1 i n, s~ao nomes de tipos, e a express~ao de tipos d e equivalente a express~ao de tipos B ; A e uma express~ao de tipos e B e um nome de tipos, cuja denic~ao visvel e tal que B isd ou B isB1 isB2 is:::isBn isd, onde Bi , para 1 i n, s~ao nomes de tipos, e a express~ao de tipos d e equivalente a express~ao de tipos A; A e B s~ao domnios de listas, A e da forma list of A1 e B e da forma list of B1 , e A1 e equivalente a B1 ; A e B s~ao o tipo polimorco de listas vazias; A e B s~ao domnios de tuplas, A e da forma (A1 ; :::; An ), B e da forma (B1 ; :::; Bn ) e, para 1 i n, Ai e equivalente a Bi ; nomes de campos n~ao s~ao relevantes para a determinac~ao da equival^encia; A e B s~ao uni~oes disjuntas, A e da forma A1 j:::jAn , B e da forma B1 j:::jBn e, para 1 i n, Ai e equivalente a Bi ; A e B s~ao tipos funcionais, A e da forma A1 ->A2 , B e da forma B1 ->B2 , A1 e equivalente a B1 e A2 e equivalente a B2 . 1.16 Compatibilidade de Tipos Dizemos que um tipo A e compatvel com um tipo B , se uma express~ao do tipo A puder ser usada em um lugar onde e esperada uma express~ao do tipo B . Por exemplo, se denimos que x e do tipo A e y e do tipo B , a atribuic~ao x := y so e possvel se A for compatvel com B . A regra de compatibilidade de Machna e a seguinte: um tipo A e compatvel com um tipo B se e somente se A e B forem equivalentes ou B e uma uni~ao disjunta de tipos, da qual A e um dos componentes. Por exemplo, nos casos abaixo, A e sempre compatvel com B : A A A is is is (a,b:Int); B ...; B ... ...; B ?; is is is (x,y:Int); j A j ...; 11 Os casos especiais de compatibilidade s~ao relativos aos tipos genericos. Supondo que T e um tipo qualquer e M e um nome de modulo, as regras de compatibilidade para estes tipos s~ao as seguintes: O tipo list of T e compatvel com List; O tipo set of T e compatvel com Set; O tipo agent of M e compatvel com Agent. 1.17 Declarac~ao de Func~oes As func~oes em Machna podem ser: estaticas { s~ao as que n~ao podem sofrer atualizac~oes e nem acessar func~oes din^amicas ou externas; din^amicas { s~ao as que podem sofrer atualizac~oes; derivadas { s~ao func~oes que n~ao podem sofre atualizac~oes, mas podem acessar func~oes din^amicas ou externas; externas { s~ao func~oes denidas e atualizadas no ambiente externo. A classe da func~ao depende da sec~ao onde ela foi declarada. Por exemplo, uma func~ao estatica deve ser declarada na sec~ao static. O corpo de uma func~ao estatica ou derivada pode ser denido tanto na sec~ao de declarac~oes quanto na seca~o init (Sec~ao 1.19). O ambiente de avaliac~ao do corpo de func~oes estaticas e formado pelas outras func~oes estaticas ja denidas e pelos seus par^ametros. Func~oes externas ou din^amicas n~ao podem ser chamadas a partir do corpo de uma func~ao estatica. O nome da func~ao pode servir para determinar o tipo de retorno da func~ao, caso ele n~ao seja explicitado, como mostrado na Seca~o 1.14. Da mesma forma, o nome de um par^ametro pode servir para determinar o seu tipo. Quando o tipo de algum elemento n~ao e especicado e o compilador n~ao conseguir deduzi-lo a partir de sua denic~ao, o seu tipo sera \?". Abaixo, mostramos a sintaxe de denic~ao de func~oes e relac~oes: function-declaration ::= declared-element [: type-expression] [:= expression] declared-element ::= id f , id g j id ( parameters ) parameters ::= parameter f , parameter g parameter ::= id : type-expression j type-expression j id 1.18 Declarac~ao de Func~oes Externas Uma func~ao externa e uma func~ao denida externamente. Como o seu valor e denido pelo ambiente externo, elas n~ao possuem um corpo para ser avaliado. Desta forma, a denic~ao de uma func~ao externa contem somente a especicac~ao do sua assinatura. A sintaxe para declarac~ao de func~oes externas e dada por: external-declaration ::= declared-element [: type-expression] Machna permite que se escreva um programa em outra linguagem, como C, que avalie uma func~ao externa e retorne o valor para a especicac~ao. Para isso, denimos o protocolo de comunicac~ao de func~oes externas abaixo: 12 Protocolo de Comunicac~ao de Func~oes Externas Func~oes externas podem ser func~oes escritas em C, tais que, dados os argumentos, ela retorna o valor desejado. Desta maneira, e denido um protocolo para a passagem de par^ametros e o valor de retorno das func~oes, de modo que possamos obter precis~ao na avaliac~ao das func~oes externas. O protocolo e seguinte: para cada par^ametro da func~ao externa, existe um par^ametro na func~ao escrita em C; a ordem dos par^ametros nas duas func~oes deve ser a mesma; os tipos dos par^ametros e de retorno na func~ao escrita em C devem seguir o tipo do cabecalho denido para a func~ao externa, seguindo a seguinte equival^encia: { Bool, Char e enumerac~oes equivalem ao tipo char de C; { Int equivale ao tipo int de C; { Real equivale ao tipo double de C; { String equivale ao tipo char* de C; { um tipo tupla equivale a uma estrutura de C, de modo que os campos da tupla seguem este protocolo de equival^encias com os campos da estrutura na implementac~ao em C; { um tipo lista e recebido e retornado como um arranjo em C, cujo tipo dos elementos correspondem segundo este protocolo. Por exemplo, os cabecalhos de func~oes externas abaixo s~ao equivalentes aos cabecalhos de func~oes em C dados em seguida. /* Em Mach na */ type T is (Int, external Bool) f(x:Int):Int; g(x,y:Int;c:Char):Bool; h(a:Int;b:T):T; : ... x := f(10) ... ... y := g(a,b,c) ... ... z := h(1,d) ... transition /* Em C */ typedef int f(int struct x); ... * equivT; char g(int x, int y, char c); equivT h(int a, equivT b); ... x = f(10) ... ... y = g(a,b,c) ... ... z = (1,d) ... 1.19 Denic~ao das Regras de Inicializac~ao A sec~ao init e utilizada para denic~ao de valores iniciais de func~oes e disparo de agentes. E da forma init regra 13 e tem o efeito de executar a regra denida. Esta regra e executada da mesma forma que qualquer regra, e os valores retornados por func~oes chamadas e o valor que denido na declarac~ao da func~ao ou o valor default do tipo de retorno da funca~o. Na sec~ao init, pode-se utilizar tambem a regra create para criar os agentes que ir~ao executar a regra de transic~ao do modulo. A sintaxe e dada por: init-part ::= init transition-rule 1.20 Declarac~ao de Abstrac~oes de Regras Uma abstrac~ao de regras de transic~ao e semelhante a um procedimento de uma linguagem imperativa como Pascal. Chamaremos este tipo de abstrac~ao de ac~ao. Uma ac~ao pode ser parametrizada. Abaixo mostramos a sintaxe de uma aca~o: action-declaration ::= id [(parameters)] := transition-rule end As regras para deduc~ao dos tipos dos par^ametros de uma transic~ao e id^entica a deduc~ao dos tipos dos par^ametros de uma func~ao. Qualquer inconsist^encia de tipos causara um erro de compilac~ao. 1.21 Sec~ao de Denic~ao de Regras de Transic~ao A sec~ao de denic~ao de regras pode aparecer somente em modulos de programas, o que signica que n~ao pode aparecer em um modulo Machna. As regras em Machna s~ao as regras denidas no Lipari Guide, acrescidas de outras regras, criadas com o objetivo de tornar a especicac~ao mais simples e legvel. Abaixo, mostramos a sintaxe para as regras de transica~o: transition-rule ::= basic-rule j forall-rule j choose-rule j create-rule j destroy-rule j stop-rule j let-rule j case-rule j with-rule j action-call-rule 1.21.1 Regras Basicas As regras basicas s~ao as regras de atualizac~ao, bloco e condicional. A sintaxe e dada por: basic-rule ::= id [(arguments)] := expression j transition-rule f , transition-rule g j if expression then transition-rule f elseif-part g [else-part] end elseif-part ::= elseif expression then transition-rule else-part ::= else transition-rule arguments ::= expression f , expression g 14 A regra de atualizac~ao e formada por um identicador, que deve ser um nome de func~ao declarada como din^amica, uma tupla, que s~ao os argumentos para a determinac~ao do endereco da atualizac~ao, e uma express~ao, cujo valor sera atribudo ao endereco formado pelo identicador e pela tupla. Na atualizac~ao, uma func~ao din^amica so pode receber func~oes denidas por meio de mapeamento explcito, isto e, sem corpo para ser avaliado. Func~oes estaticas e derivadas n~ao podem ser atualizadas. Exemplos de atualizac~oes s~ao: ... x,y : Int; f,g : Int -> Int; ... x := y, f(x) := 10, g := f ... A regra bloco e composta por uma sequ^encia de regras, separadas por vrgula, que devem ser executadas simultaneamente. Uma regra condicional tem o efeito de executar a regra, cuja guarda seja a primeira guarda a avaliar em verdadeiro, na sequ^encia dada. As express~oes que formam as guardas devem ter o tipo Bool. 1.21.2 Regra forall Uma regra forall tem a forma forall e1; e2; :::; ek do regra end onde os elementos ei s~ao da forma a:A, onde A e um tipo escalar, ou a:sa, onde sa e um conjunto, ou ainda, da forma a, desde que o tipo de a possa ser deduzido do contexto. O seu efeito e criar diversas inst^ancias de regra, uma para cada valor possvel de e1 ; e2 ; :::; ek nos domnios dados. Por exemplo, considere o trecho de codigo abaixo: type Num = 1..3; dynamic f(Int,Int):Int; transition: forall x:Num,y:Num do f(x,y) := x + y end end Este codigo e equivalente ao codigo abaixo: type Num = 1..3; dynamic f(Int,Int):Int; transition: f(1,1) f(1,2) f(1,3) f(2,1) f(2,2) f(2,3) f(3,1) f(3,2) f(3,3) end := := := := := := := := := 2, 3, 4, 3, 4, 5, 4, 5, 6 15 E importante ressaltar que os identicadores denidos em um forall s~ao meta-variaveis, que n~ao podem, desta maneira, ser lados esquerdos de atualizaco~es. A sintaxe da regra forall e: forall-rule typed-pars-seq id-seq set-expression ::= ::= ::= ::= forall typed-pars-seq do transition-rule end element-seq f , element-seq g id j id : type-expression j id : set-expression expression 1.21.3 Regra choose A regra choose tem a forma: choose e1; e2; :::; ek satisfying g do regra end onde e1 ; e2 ; :::; ek s~ao da mesma forma que na regra forall. O seu efeito e escolher aleatoriamente elementos dos domnios dados que satisfacam a guarda g e executar a regra dada, associando os nomes de identicadores em e1 ; e2 ; :::; ek aos elementos escolhidos. choose-rule ::= choose type-pars-seq [satisfying expression] do transition-rule end typed-pars-seq ::= element-seq f , element-seq g id-seq ::= id j id : type-expression j id : set-expression 1.21.4 Regras Para Criac~ao e Eliminac~ao de Agentes Para a criac~ao de um agente, utilizamos a regra create, que tem a forma: create a1 ; a2; :::; an do regra end onde ai e da forma a:T, ou a, ou T, onde a e um identicador e T e um tipo agente, da forma agent of M. O efeito desta regra e criar um agente que executara a regra do modulo M. Apos a criac~ao, este agente e referenciado pela variavel a, e a regra de transic~ao regra e executada, interpretando esta variavel como o novo agente. Se o nome do modulo n~ao for explicitado, o compilador tentara inferi-lo pelo contexto; se n~ao for possvel, ocorrera um erro de compilaca~o. Para a eliminac~ao de um agente, utilizamos a regra destroy, que tem a forma: destroy id onde id e um nome de func~ao ou variavel, de um tipo agente. O seu efeito e encerrar a execuc~ao do agente referenciado por id. Por exemplo, o codigo abaixo cria um agente x que executa a regra associada ao modulo X, executando as regras de inicializac~ao dadas: create do x:X numagentes := numagentes + 1, ready(x) := end true O codigo abaixo encerra a execuc~ao de todos os agentes que executam a regra do modulo X e encerra a sua propria execuca~o. forall x : agent of X do destroy x end, destroy self 16 E interessante notar que destroy self e equivalente a regra stop. A sintaxe para as regras create e destroy e dada por: create-rule destroy-rule typed-pars-seq id-seq ::= ::= ::= ::= create typed-pars-seq do transition-rule end destroy id element-seq f , element-seq g id j id : type-expression 1.21.5 Regra Para Parada De acordo como o modelo ASM, a regra de transic~ao de um agente e executada repetidamente. A regra para parada da maquina e a regra stop. Quando executada, esta regra faz com que a regra do modulo do agente n~ao seja executada novamente, para que o agente encerre sua execuca~o. Isto signica que, quando o stop for executado, o passo em que ele for executado e terminado, para, a partir deste momento, a execuc~ao da maquina realmente terminar. Por exemplo, no estado nal da execuc~ao abaixo, o valor de a e 20: module C dynamic a := 0; transition: if a < 10 then a := a + 10 else a := a + 10, stop end end A sintaxe da regra stop e: stop-rule ::= stop 1.21.6 Regra let Uma regra let e utilizada para fazer declarac~oes que sejam locais a uma regra. Tem a seguinte sintaxe: let-rule ::= let declaration-in-let f ; declaration-in-let g in transition-rule end declaration-in-let ::= id = expression Por exemplo, o trecho de codigo ... let a b c x = = = = head(L); head(tail(L)); head(tail(tail(L))); a + b + c in g(10) end := x * (a + 1) * (b + c) ... 17 declara os identicadores a, b, c e x, cujo escopo e a regra g(10) := x * (a + 1) * (b + c) E importante ressaltar que os identicadores denidos em uma regra let s~ao meta-variaveis que representam right values, n~ao podendo ser, desta maneira, alvos de atribuic~oes. 1.21.7 Regra case Uma regra case e uma regra condicional, na qual todas as guardas s~ao da forma expression = valor manifesto A sintaxe para esta regra e dada por: case-rule ::= case expression of f case-rule-atom g [case-rule-otherwise] end case-rule-atom ::= expression -> transition-rule case-rule-otherwise ::= otherwise -> transition-rule Por exemplo, a regra abaixo e equivalente a regra mostrada acima: case head(s) * head(tail(s)) 1 -> ... 4 -> ... 9 -> ... 16 -> ... 25 -> ... -> ... of otherwise end 1.21.8 Regra with Uma regra with e uma forma de case, na qual, ao inves de compararmos o valor de uma express~ao com express~oes manifestas, comparamos o seu tipo com nomes de tipo. A sintaxe para esta regra e a seguinte: with-rule ::= with expression as f with-rule-atom g [with-rule-otherwise] end with-rule-atom ::= [id :] type-expression -> transition-rule with-rule-otherwise ::= otherwise -> transition-rule Por exemplo, a regra abaixo utiliza o tipo do primeiro elemento de uma lista para determinar a ac~ao a ser tomada: list : List; ... head(list) i:Int -> transition rules for integer head b:Bool -> transition rules for boolean head s:String -> transition rules for string head -> transition rules for other cases with as otherwise end 18 1.21.9 Regra de Chamada a Ac~oes Uma regra de chamada a ac~ao e equivalente a uma chamada de procedimentos em uma linguagem imperativa, com a excec~ao de que a sua execuca~o gera um conjunto de atualizac~oes que e tratado como o conjunto de atualizac~oes de uma regra comum. Os par^ametros de uma ac~ao, que forem atualizados, ser~ao tratados como sin^onimos para os argumentos no ponto de chamada. Demais argumentos s~ao avaliados e substitudos pelos par^ametros formais da declarac~ao da ac~ao. A utilizac~ao de ac~oes permite escrevermos denic~oes menores e mais legveis, utilizando abstrac~oes de regras. A sintaxe de chamadas a aco~es e: action-call-rule ::= id [(arguments)] arguments ::= expression f , expression g Por exemplo, a regra abaixo e uma chamada a uma transic~ao: ... action ... end t(x:Int) // declara a a c~ ao t ... // Rules... t(1), t(2), t(3) // chama a a c~ ao t... ... 1.22 Invariante da Execuc~ao Em um modulo, pode-se denir uma condic~ao que deve ser satisfeita toda vez que a sua regra de transic~ao for executada. Chamamos esta condic~ao de invariante. Para denirmos o invariante da regra de transic~ao, denimos uma sec~ao invariant, que contem a express~ao booleana do invariante. A sua forma e invariant: express~ao-booleana O invariante deve ser testado antes e depois de cada passo. Se em algum momento ele n~ao for satisfeito, ocorre um erro de execuc~ao. Em um modulo Machna, pode haver tambem uma sec~ao de invariante, semelhante a um modulo qualquer. Entretanto, os elementos que podem aparecer na express~ao do invariante s~ao somente os literais booleanos, true e false, os operadores logicos, and, or, not e xor, e invariantes de modulos, referenciados como M.invariant, onde M e um nome de modulo. Este invariante vale para a execuc~ao de todo os modulos criados a partir do modulo Machna, sendo igualmente testado antes e depois da execuc~ao de cada passo, independente de qual agente sera executado. 1.23 Sintaxe de Express~oes As express~oes de Machna s~ao as seguintes: express~oes sobre os tipos basicos, listas, conjuntos, tuplas, mapeamentos, convers~ao de tipos, condicionais, let e outras express~oes. 1.23.1 Operadores de Machna Os operadores de Machna s~ao mostrados na tabela abaixo. A ordem de apresentac~ao mostra a preced^encia dos operadores, sendo que os de preced^encia mais alta est~ao na primeira linha e os de preced^encia mais baixa est~ao no m. 19 - (un ario) * / % + = != < > <= >= preced^encia mais alta and or xor in :: -> preced^encia mais baixa 1.23.2 Valores Booleanos As express~oes com o tipo Bool s~ao: os literais true e false; qualquer aplicac~ao de func~ao (ver Sec~ao 1.23.7), ou operac~ao binaria, como por exemplo, a aplicac~ao dos operadores relacionais, cujo tipo de retorno seja equivalente ao tipo Bool; a operac~ao unaria de negac~ao logica, utilizando o operador pre-xado not; as operac~oes binarias que utilizam os operadores logicos and (conjunc~ao), or (disjunc~ao) e xor (or exclusivo). Exemplos de express~oes booleanas s~ao: e. f(x) = 21, y * a > 5 and cond, b and c xor d or 1.23.3 Caracteres As express~oes com o tipo Char s~ao: os literais caracteres, que representam os caracteres da tabela ASCII; qualquer aplicac~ao de func~ao (ver Sec~ao 1.23.7), cujo tipo de retorno seja equivalente ao tipo Char; as func~oes pre-denidas sobre o tipo Char, dadas abaixo: ord(Char):Int chr(Int):Char { Retorna o codigo ASCII do caractere; { Retorna o caractere com o codigo ASCII dado. Exemplos de express~oes com o tipo Char s~ao: `a', `1', '\n', chr(13), ord(`\n'). 1.23.4 Numeros Inteiros As express~oes com o tipo Int s~ao: os literais inteiros, que representam os numeros inteiros, com valor mnimo -2147483648 e maximo 2147483647. Estes literais podem ser representados na forma decimal (sequ^encia de um ou mais dgitos de 0 a 9), octal (sequ^encia de 1 ou mais dgitos de 0 a 7, precedida sempre por um 0) ou hexadecimal (sequ^encia de 1 ou mais dgitos de 0 a 9 ou letras de A a Z, precedida sempre por 0x); a operac~ao unaria de negac~ao, utilizando o operador -; as operac~oes binarias de adic~ao (+), subtrac~ao (-), multiplicac~ao (*), divis~ao (/) e resto da divis~ao (%); 20 qualquer aplicac~ao de func~ao (ver Seca~o 1.23.7), cujo tipo de retorno seja equivalente ao tipo Int; as func~oes pre-denidas sobre o tipo Int, dadas abaixo: { valor absoluto de um numero inteiro; max(Int,Int):Int { m aximo entre dois inteiros; min(Int,Int):Int { mnimo entre dois inteiros; sqr(Int):Int { quadrado de um n umero inteiro. abs(Int):Int Exemplos de express~ao com numeros inteiros s~ao: max(a,b) - sqr(min(x,y) + 1). x + 1, x * 2 + y * 5 - 10 % v, abs(x) + 1.23.5 Numeros Reais As express~oes com o tipo Real s~ao: os literais reais, que representam numeros de ponto utuante do padr~ao IEEE 754, com 1.79769313486231570E+308 como valor maximo e 4.94065645841246544E-324 como valor mnimo; a operac~ao unaria de negac~ao, utilizando o operador -; as operac~oes binarias de adic~ao (+), subtraca~o (-), multiplicac~ao (*) e divis~ao (/); qualquer aplicac~ao de func~ao (ver Seca~o 1.23.7), cujo tipo de retorno seja equivalente ao tipo Real; as func~oes pre-denidas sobre o tipo Real, dadas abaixo: abs(Real):Real { valor absoluto de um n umero real; max(Real,Real):Real { m aximo entre dois numeros reais; min(Real,Real):Real { mnimo entre dois n umeros reais; sqr(Real):Real { quadrado de um n umero real; sqrt(Real):Real { raiz quadrada de um n umero real. 1.23.6 Cadeias de Caracteres As express~oes sobre o tipo String s~ao: os literais cadeias de caracteres, que s~ao sequ^encias de zero ou mais caracteres, envolvidas por aspas; o padr~ao de cadeias de caracteres de Machna e de cadeias de caracteres terminadas com nulo; a operac~ao binaria de concatenac~ao, utilizando o operador +; qualquer aplicac~ao de func~ao (ver Sec~ao 1.23.7), cujo tipo de retorno seja equivalente ao tipo String; a func~ao pre-denida length(String):Int, que retorna o comprimento da cadeia de caracteres. Exemplos de express~oes com cadeias de caracteres s~ao: 21 "string\n", length(``abcd"+ nome). 1.23.7 Aplicac~ao de Func~oes A aplicac~ao de func~ao tem a forma geral nome de func~ao(argumentos) onde argumentos e uma lista de express~oes, cujo comprimento e igual a aridade da func~ao da aplicac~ao. Se a aridade da func~ao for igual a zero, ent~ao n~ao se utilizam os par^enteses, somente o nome da func~ao. Os tipos dos argumentos devem ser equivalentes aos tipos esperados como par^ametros. Exemplos de aplicac~oes de func~ao: x, f(1,2,true), f(x,g(y+1,h)), chr(0). 1.23.8 Listas Machna possui dois tipos de listas: listas genericas e listas de elementos de um tipo especco. Uma lista vazia e dada pelo literal nil. Sobre listas, est~ao denidas as seguintes operac~oes: x::list concat(list1, list2) head(list) tail(list) lenght(list) retorna uma lista cuja cabeca e x e cuja cauda e list retorna a concatenac~ao das listas list1 e list2 retorna o elemento na cabeca de list retorna a cauda de list retorna o comprimento de list Em tempo de compilac~ao, s~ao feitos testes para consist^encia e infer^encia de tipos. As regras para consist^encia de tipos s~ao as seguintes: 1. na operac~ao x::list, se x possuir o tipo X, ent~ao list deve ser do tipo list of X ou List; 2. na operac~ao cat(list1, list2), list1 e list2 devem ser listas do mesmo tipo, a menos que uma delas seja do tipo List; se o tipo de uma delas for List, ent~ao o resultado e do tipo List; 3. se list for do tipo list of X, ent~ao head(list) e do tipo X; se list for do tipo List, ent~ao head(list) ser a do tipo \?"; 4. a express~ao tail(list) tem o mesmo tipo de list. Um agregado lista e da forma [t1 ; t2 ; :::; tn ]: Se todos as express~oes forem do mesmo tipo X, ent~ao o tipo da express~ao toda e list of X; caso contrario, o tipo sera List. 1.23.9 Conjuntos Assim como listas, conjuntos podem ser genericos ou de um tipo especco. As operac~oes envolvendo conjuntos s~ao: s1 + s2 s1 - s2 s1 * s2 x s s(x) s1 relop s2 card(s) in uni~ao diferenca intersec~ao pertin^encia pertin^encia inclus~ao (<=), igualdade (=), etc. cardinalidade do conjunto 22 Um agregado conjunto e da forma ft1 ; t2 ; :::; tn g: Se todos as express~oes forem do mesmo tipo X, ent~ao o tipo da express~ao toda e set of X; caso contrario, o tipo sera Set. Conjuntos podem ser utilizados em regras da seguinte maneira: Regra de atualizac~ao: e s(t) := true s := s + f s(t) := false s := s - ftg t g Regra forall: se s e do tipo set of X, ent~ao a construc~ao forall x:s do regra end instancia regra substituindo x com cada valor pertencente a s, executando todas as inst^ancias em paralelo; Regra choose: se s e do tipo set of X, ent~ao a construc~ao choose x:s do regra end escolhe aleatoriamente um elemento e pertencente ao conjunto s e executa regra, associando x a e. 1.23.10 Tuplas Uma tupla de Machna e uma sequ^encia de tamanho xo, cujos elementos podem ser de quaisquer tipos. Uma express~ao da forma T(t1, t2, t3) cria uma tupla do tipo T, formada pelos elementos t1, t2 e t3. O acesso aos elementos de uma tupla e feito sempre pelo seus rotulos, como no exemplo abaixo: ... type is Pair (x,y:Int); p1, p2 : Pair; ... p1 := Pair(1,2), p2.x := p1.y ... 1.23.11 Mapeamentos Um mapeamento e um conjunto de associac~oes de valores de um domnio a valores de um contradomnio. Por exemplo, considere o fragmento de codigo abaixo: static f f := f1 g -> 2, 2 -> 3, 3 -> 4 e uma func~ao de inteiros para inteiros, tal que: f(1) = 2, f(2) = 3, f(3) = 4 O valor da aplicac~ao de f a algum outro valor, que n~ao especicado no conjunto, e o valor default do contradomnio. 23 O operador -> cria um par que pode ser inserido em algum conjunto. Um mapeamento e semelhante a um conjunto de pares, isto e, uma relaca~o, com a diferenca que, se x e um conjunto de pares e y e um mapeamento, ent~ao e possvel que, para quaisquer a, b e c, (a; b) 2 x e (a; c) 2 x. Entretanto, (a; b) 2 y e (a; c) 2 y so e possvel se b = c. As operac~oes que podem ser realizadas sobre mapeamentos s~ao a aplicac~ao de func~ao, da forma f (a1 ; :::; an ), a atualizac~ao de func~oes din^amicas, da forma f (a1 ; :::; an ) := b e a comparac~ao por = (igualdade) e != (diferen ca). 1.23.12 Convers~ao de Tipos As express~oes abaixo realizam a convers~ao de tipos, para os casos em que e necessario, como por exemplo, utilizac~ao de valores do tipo ?. Os dois tipos de express~oes que t^em essa nalidade s~ao as express~oes with e is e a convers~ao explcita de tipos. A express~ao with tem a forma: with e as e1 : T1 e2 : T2 -> -> b1 b2 en : Tn -> bn ... otherwise end -> bn+1 Se as express~oes b1 ; b2 ; :::; bn ; bn+1 tiverem o mesmo tipo X, ent~ao o tipo da express~ao e X. Caso contrario e ?. A clausula otherwise e obrigatoria, a menos que as clausulas de coerc~ao sejam exaustivas. Assim, se o tipo de e for ?, esta clausula e obrigatoria. O valor desta express~ao e obtido, comparando-se o tipo de e com os tipos das clausulas as. Se a i-esima clausula casar com o tipo de e, ent~ao, associamos ei ao valor de e e retornamos o valor de bi . Se nenhuma clausula casar com o tipo de e, ent~ao o valor retornado e o valor de bn+1 . Por exemplo, considere o fragmento de codigo: ... dynamic x : List; // Os elementos de ... with head(x) as a:Int -> 1 + a b:Bool -> if b then 1 else 0 end c:Real -> round(c) otherwise -> 4 end x podem ser de qualquer tipo ... No exemplo abaixo, a clausula otherwise n~ao e necessaria, pois as clausulas as s~ao exaustivas. ... type X is Bool | Int dynamic x : X; ... with x as | Real; a:Int -> 1 b:Bool -> 2 c:Real -> 3 end 24 ... O operador binario is e um operador de inspec~ao de tipos, que recebe como argumentos uma express~ao e um nome de tipo e retorna verdadeiro se o tipo da express~ao for igual ao tipo dado. Um exemplo da utilizac~ao do operador is esta no codigo abaixo: ... type X is Bool | Int dynamic x : X; ... if x is Int then ... elseif x is Bool then ... else ... end | Real; ... O casting explcito de tipos e uma express~ao da forma (T )e. O seu efeito e fazer a convers~ao explcita de e para um valor do tipo T . Se a convers~ao n~ao puder ser feita, ocorrera um erro de execuca~o. 1.23.13 Condicionais e Let Nesta categoria se enquadram as expresss~oes condicionais if e case e a express~ao let. A estrutura destas express~oes e equivalente as regras de transic~ao de mesmos nomes, com algumas diferencas: a parte else da express~ao if e obrigatoria; a clausula otherwise da express~ao case e obrigatoria, a menos que as clausulas sejam exaustivas, como por exemplo, se cobrirem todos os elementos de uma enumerac~ao; se os tipos das express~oes resultantes de cada parte do if e do case s~ao o mesmo tipo X , ent~ao o tipo da express~ao toda e X ; caso contrario e ?. 1.23.14 Express~oes Especiais A express~ao default retorna o valor default do tipo esperado. Para cada tipo existe um valor default pre-denido. A express~ao self retorna a identicac~ao ao agente que estiver executando a regra. Exemplos: algebra: static default default default default fg list of default default transition a b c d e f : : : : : := Int := // x := 0 Bool := // x := false Real := // x := 0.0 Set := // x := Int := // x := nil // f := undef, pois undef e o default de ? : ... hungry(self) := true, // Atualiza as fun c~ oes locais ao agente 25 thinking(self) := false ... 1.23.15 Gramatica das Express~oes A sintaxe das express~oes e: expression ::= literal j unop expression j expression binop expression j mod-function-call j agregate j if-expression j case-expression j let-expression j with-expression j expression . expression j [module-name .] id [(arguments)] j j j literal ::= unop binop ::= ::= agregate ::= if-expression if-expr-elseif if-expr-else let-expression case-expression case-expr-atom case-expr-default with-expression with-expr-atom with-expr-default ::= ::= ::= ::= ::= ::= ::= ::= ::= ::= j j j j self default (expression) false j true j char-literal j integer-literal oat-literal j string-literal j nil ; j not j (type-name) j = j % j + j ; j = j ! = j < j > j <= j >= and j or j xor j :: j in j is \["expression f , expression g\]" \f"expression f , expression g \g" type-name ( expression f , expression g ) if expression then expression f if-expr-elseif g if-expr-else end elseif expression then expression else expression let declaration-in-let f ; declaration-in-let g in expression end case expression of f case-expr-atom g [case-expr-default] end expression ! expression otherwise ! expression with term f with-expr-atom g [with-expr-default] end [id :] type-name ! expression otherwise ! expression 1.24 Manipulac~ao de Arquivos Para manipulac~ao de arquivos, existem os tipos pre-denidos InputStream, OutputStream e o construtor de tipos le of, que recebe como argumento um tipo. O tipo pre-denido InputStream representa um arquivo texto para leitura com caracteres de leiaute. As operac~oes (ac~oes) que podem ser feitas sobre este tipo s~ao: { ac~ao pre-denida que abre, para leitura, o arquivo de para este arquivo no par^ametro input; close(InputStream input) { a c~ao pre-denida, que fecha o arquivo referenciado por input; readInt(InputStream input, Int i) { l^ e um valor inteiro do arquivo input e coloca o resultado em i; open(InputStream input, String s) nome s, colocando uma refer^encia 26 readChar(InputStream input, Char c) em c; readReal(InputStream input, Real r) coloca o resultado em r; { l^e um caractere do arquivo input e coloca o resultado { l^e um numero ponto-utuante do arquivo readString(InputStream input, String s) coloca o resultado em s. input e { l^e uma cadeia de caracteres do arquivo input e O tipo pre-denido OutputStream e analogo ao tipo OutputStream, e representa um arquivo texto, para escrita, com caracteres de leiaute. As operac~oes (ac~oes) que podem ser feitas sobre este tipo s~ao: open(OutputStream output, String s) { a c~ao pre-denida que abre, para escrita, de nome s, colocando uma refer^encia para este arquivo no par^ametro output; o arquivo { aca~o pre-denida, que fecha o arquivo referenciado por output; writeInt(OutputStream output, Int i) { escreve o valor de i no arquivo output; writeChar(OutputStream output, Char c) { escreve o valor de c no arquivo output; writeReal(OutputStream output, Real r) { escreve o valor de r no arquivo output; writeString(OutputStream output, String s) { escreve o valor de s no arquivo output; close(OutputStream output) Uma express~ao de tipo leofT , onde T e um tipo, cria um tipo que representa arquivos, cujos elementos s~ao do tipo T . Estes arquivos s~ao binarios, com acesso sequencial ou direto. As operac~oes (ac~oes) que podem ser feitas s~ao: le of T tFile, String s, Bool readOnly) { ac~ao pre-denida que abre, para leitura ou para escrita, o arquivo de nome s, colocando uma refer^encia para este arquivo no par^ametro tFile; o arquivo sera de leitura de o par^ametro readOnly for verdadeiro, caso contrario, sera de escrita; close(le of T tFile) { a ca~o pre-denida, que fecha o arquivo referenciado por tFile; read(le of T tFile, T t) { l^ e um valor do tipo T, do arquivo referenciado por tFile, e coloca este valor em t; write(le of T tFile, T t) { escreve o valor de tipo t, no arquivo referenciado por tFile; open( Sobre todos os arquivos s~ao denidas as func~oes eof e status. A func~ao eof(f:File):Bool recebe como argumento um arquivo de qualquer tipo e retorna true, se o arquivo estiver no m, ou false, caso contrario. A func~ao status(f:File):Int retorna o status do arquivo como um numero inteiro, de acordo com a tabela abaixo: 0 1 2 3 arquivo fechado arquivo aberto erro de leitura no arquivo erro de escrita no arquivo A menos da funca~o status, qualquer operac~ao sobre um arquivo fechado gera um erro de execuc~ao. E importante salientar que, por causa do modelo algebrico, qualquer operac~ao de leitura em arquivos so e percebida no proximo estado. Da mesma forma, qualquer chamada a status em um mesmo estado retorna o mesmo valor, que e o status do arquivo no passo anterior. Assim como qualquer ac~ao de Machna, a ordem de execuc~ao de duas operac~oes sobre arquivos, no mesmo, estado n~ao e garantida. Por exemplo, considere o codigo abaixo: 27 ... f : InputStream; g : OutputStream; ... transition: readInt(f,a), readInt(f,a), readInt(f,b), writeInt(g,x), writeInt(g,y), end Ser~ao lidos tr^es valores do arquivo f e escrito dois valores no arquivo g. Entretanto, n~ao ha como determinar qual sera o valor de a e qual sera o valor de b, pois isto dependera da ordem em que o compilador escolher executar este codigo. Da mesma forma, n~ao e possvel determinar qual valor sera escrito antes em g, se o valor de x ou se o valor de y. 28 Cap tulo 2 Exemplos 2.1 Pesquisa Binaria Os modulos abaixo especicam um agente que realiza a pesquisa binaria. module PesqBin algebra: static n : Int := 100; type Index is 1..n; Array is Index -> Int; external key : Int; array; dynamic k, pos, inf, sup : Int; encontrado : Bool; array1; init array1 := array k := key, pos := (n+1)/2, inf := 1, sup := n encontrado := : mean = (inf+sup)/2 false transition let in if not encontrado and inf < sup then if array1(mean) = k then encontrado := true, elseif array1(mean) < k then inf := mean + 1 else sup := mean - 1 end end end end machina PesquisaBinaria create PesqBin end 29 pos := mean 2.2 Ordenac~ao por Selec~ao O modulo abaixo especica a ordenac~ao por seleca~o. module Selecao algebra: static n : Int := 100; type Index Array is 1..n; is Index -> external Int; n : Int; array; dynamic modo, i, k, j : array1; Int; init array1 := array, modo := 1, i := 1, k := 1, j := 1 : modo = 1 i < n k := i, j := i + 1, modo := 2 modo = 2 j := j + 1, j > n modo := 3 f(j) < f(k) k := j transition if and then elseif then if then elseif then end else modo = 3 then i := i + 1, modo := 1, if k != i then f(k) := f(i), f(i) := f(k) end end end machina OrdenacaoPorSelecao create ops : Selecao end 2.3 Numeros Primos O programa abaixo especica um algoritmo para busca de numeros primos. machina MarcaPrimos algebra: type Num is 2..1000; dynamic primo : Num -> Bool; init forall n:Num do primo(n) transition: := true end 30 forall num1,num2 do if num2 < num1 and num1%num2 = 0 then primo(num1) := false end end end O programa abaixo e equivalente ao anterior, mas utiliza outros recursos de Machna: machina algebra: type MarcaPrimos is is set of default f2..1000g; dynamic primo : Numset; transition: forall num1,num2 do if num2 < num1 and num1%num2 = 0 then primo(num1) := false end end end Num 2..1000; Numset Num machina DeterminaPrimos create mp : MarcaPrimos end 2.4 Especicac~ao da Sem^antica de Tiny Tiny e uma linguagem imperativa de pequeno porte que contem somente comandos e express~oes. A denic~ao de Tiny sera feita em cinco modulos: 1. Modulo principal (Tiny) { contem a regra principal da especicac~ao e as rotinas de inicializac~ao; 2. Modulo de Express~oes (Expressions) { contem as regras de avaliac~ao de express~oes; 3. Modulo de Comandos (Commands) { contem as regras de execuc~ao de comandos; 4. Modulo de Operac~oes (Operations) { contem as regras de operac~ao na pilha. 5. Modulo de Globais (Globals) { contem as declarac~oes dos principais tipos e func~oes da especicac~ao de Tiny. 2.4.1 Modulo de Globais (Globals) module Globals algebra: type public Undefined is public enum fundefinedg; public Id is String; public Program is List; public Input is list of Int; 31 public Output is list of Int; public Value is Bool | Int; public Memory is Id ! (Value | Undefined) default undefined; public KeyWord is ftadd, tassign, tcond, texchange, tequals tnot, toutput, tread, public Opstack is List; external p:Program; i:Input; dynamic public program := p, input public memory; public error := false end := i, output := nil, opstack := nil; 2.4.2 Modulo de Operaco~es (Operations) module Operations import: Globals(program,output,input,opstack,error,memory); algebra: action treatOutput := if head(program) is x:Int then output := concat(output, [x]), program := tail(program), opstack := tail(opstack) else error end end; := true treatAssign opstack := tail(tail(opstack)), memory((String)head(tail(opstack))) := (Globals.Value)head(program) ; treatExchange := opstack := tail(opstack), program := head(tail(program))::head(program)::tail(tail(program)) ; treatAdd := end end let in hp = head(program); htp = head(tail(program)); if is and is then hp Int htp Int program := ((Int)x + (Int)y)::tail(tail(program)), opstack := tail(opstack) else error end end end; := true treatNot := 32 g twhile ; if is not then head(program) Bool program := ( ((Bool)b))::tail(program), opstack := tail(opstack) else error := true end end; treatCond := if head(program) is Bool then if (Bool) head(program) then program := head(tail(program))::tail(tail(tail(program))) else program := tail(tail(program)) end, opstack := tail(opstack) else error := true end end; treatEquals := let in hp = head(program); htp = head(tail(program)); if is and is then hp Int htp Int program := ((Int)x = (Int)y)::tail(tail(program)), opstack := tail(opstack) else error := true end end end; public treatValue := if head(opstack) is Globals.KeyWord then case (Globals.KeyWord) head(opstack) of Globals.toutput -> treatOutput; Globals.tassign -> treatAssign; Globals.texchange -> treatExchange; Globals.tadd -> treatAdd; Globals.tnot -> treatNot; Globals.tcond -> treatCond; Globals.equals -> treatEquals end end else error end end := true 2.4.3 Modulo de Express~oes (Expressions) module Expressions import: 33 Globals(program,output,input,opstack,error,memory); algebra: action public readMemory := let id = (String) head(program) in if memory(id) = undef then error := true else program := memory(s) :: tail(program) end end end; public treatNot := program := tail(program), opstack := Globals.tnot::opstack ; treatEquals := program := tail(program), opstack := Globals.tequals::opstack ; treatAdd := program := tail(program), opstack := Globals.texchange::Globals.tadd::opstack ; treatRead := input = nil error := true end public end public end public if else then program := head(input)::tail(program), input := tail(input) end end end 2.4.4 Modulo de Comandos (Comandos) module Commands import: Globals(program,output,input,opstack,error,memory); algebra: action public treatAssign := program := tail(tail(program)), opstack := Globals.tassign::head(tail(program))::opstack ; treatOutput := program := tail(program), opstack := Globals.toutput::opstack ; treatConditional := program := tail(program), end public end public 34 opstack := Globals.tcond::opstack end; public let in treatWhile := second = head(tail(program)); third = head(tail(tail(program))); whileExp = second; whileCom = Globals.twhile::second::third::nil; whileTrue = third::whileCom::nil; whileCont = tail(tail(tail(program))); program := whileExp::whileTrue::nil::whileCont, opstack := Globals.tcond::opstack end end end 2.4.5 Modulo principal (Tiny) module Tiny import: Commands, Expressions, Operations, Globals(program,output,input,opstack,error,memory); : flatProgram := program := concat((List) head(program), tail(program)) algebra action end transition: if program != nil and not with head(program) as error then l:List -> flatProgram; s:String -> Expressions.readMemory; p:Globals.KeyWord -> p Globals.tnot -> Expressions.treatNot; Globals.tequals -> Expressions.treatEquals; Globals.tadd -> Expressions.treatAdd; Globals.tread -> Expressions.treatRead; Globals.tassign -> Commands.treatAssign; Globals.toutput -> Commands.treatOutput; Globals.tcond -> Commands.treatConditional; Globals.twhile -> Commands.treatWhile; ; x:Globals.Value -> Operations.treatValue case of end end end end 2.4.6 Disparo do Agente de Execuc~ao machina TinySemantics create tny : Tiny end 35 2.5 Jantar dos Filosofos Este e um exemplo de especicac~ao com varios agentes, onde todos executam o mesmo programa, de maneira concorrente. Para explicitar a concorr^encia, deniremos a regra de transic~ao como intercalada (interleaved). module DinPh algebra: static n : Int := 5; type PhId is 1..n; dynamic initialized, thinking, hungry, eating : leftFork, rightFork : PhId -> Bool; myId : DinPh -> PhId; : inicializado(self) thinking(self) := , initialized(self) := DinPh -> Bool; transition if not then true true else if thinking(self) then thinking(self) := false, hungry(self) := true elseif hungry(self) then if not leftFork(myId(self)) and not rightFork(myId(self)) then eating(self) := true, hungry(self) := false, leftFork(myId(self)) := true, rightFork(myId(self)) := true end else eating(self) := false, hungry(self) := true end end end O modulo Machna que dispara os agentes e dado abaixo: machina DiningPhilosophers create5 DinPh end 36