2.2. CAMILA: uma pequena introdução

CAMILA é uma linguagem formal de especificação funcional orientada por modelos algébricos [Jon86] que serve de suporte a um ambiente de prototipagem com o mesmo nome [ABNO97] e que tem as suas origens em duas linguegens de especificação formal: o VDM [Jon86] e o Z [Spi89].

Uma especificação CAMILA é um conjunto de componentes de software. Cada um destes é um modelo composto por um tipo abstracto de dados e por definições de funções e de estado [BA95].

A estrutura geral de um modelo é a seguinte:

          Modelo → MODEL identificador
                    DefTipo
                    DefFunc
                    DefEstado
                    ENDMODEL

DefTipo, a definição de tipo tem a seguinte forma:

           DefTipo → TYPE
                          (id = Tipo)*
                          ENDTYPE

Os tipos básicos do CAMILA são apresentados na tabela seguinte, Tabela 2-1.

Tabela 2-1. Tipos Abstractos de Dados e CAMILA

Tipos Abstractos Notação CAMILA
ConjuntosX-set
ListasX-seq
Funções FinitasX → Y
Relações BináriasX ↔ Y
União DisjuntaX | Y
tuplosT = X : A; Y : B
InteirosINT
StringsSTR
TokensSYM
UniversoANY

Para além destes tipos, o CAMILA tem mais alguns tipos primitivos que não têm uma correspondência matemática directa mas que são inerentes ao seu ambiente de programação.

Na definição seguinte apresenta-se a forma genérica da definição de uma função em CAMILA.

Definição: uma função em CAMILA

          DefFunc  → FHeader FPreCond FState FBody
          FHeader  → FUNC fid (ParamLst) : typeid
          FPreCond → PRE CondExp
          FState   → STATE exp
          FBody    → RETURNS Exp

Por fim, a definição de um estado faz-se como se mostra a seguir.

Definição: um estado em CAMILA

          DefEstado → STATE sid : typeid

Para exemplificar estes conceitos apresenta-se o exemplo seguinte:


Exemplo 2-2. Especificação do modelo Stack

Pretende-se especificar o modelo da stack tradicional.

A declaração dos tipos e do estado são:

; ---------- SORTS --------------------
TYPE
   X = ANY;
   Stack = X-list;
ENDTYPE

; ---------- STATE --------------------
STATE  S : Stack;

As funções normais sobre uma stack especificam-se, então, da seguinte maneira:

; ---------- FUNCTIONS ----------------
FUNC push(x:X,s:Stack):Stack
RETURN cons(x,s);
  
FUNC top(s:Stack):X
PRE s != <>
RETURN head(s);

FUNC pop(s:Stack):Stack
PRE s != <>
RETURN tail(s);

Como se pode ver esta versão é puramente funcional, não tem efeitos laterais. As mesmas funções mas agora com os efeitos laterais que provocam alterações no estado, especificam-se da seguinte maneira:

; ---------- EVENTS -------------------
FUNC INIT():
STATE S <- <>;
  
FUNC PUSH(x:X):
STATE S <- push(x,S);
  
FUNC POP():X 
PRE  S != <>
RETURN head(S)
STATE S <- tail(S);
  
FUNC TOP():X
PRE  S != <>
RETURN head(S);


A cada tipo CAMILA está associada uma colecção de funções básicas que permitem manusear os valores desse tipo (construir, seleccionar, converter, transformar). Além disso, também estão pré-definidas as conectivas proposicionais e os quantifiadores. Para exemplificar estes operadores, apresentam-se duas tabelas com um resumo das duas colecções de operadores mais usadas ao longo da tese: os operadores para funções finitas e para sequências. Em cada tabela apresenta-se a sintaxe CAMILA e uma breve descrição informal.

Tabela 2-2. Funções Finitas: X → Y

CAMILADescrição
dom(f)Domínio
ran(f)Contra-domínio
f[x]Aplicação
f/sRestrição de domínio
f\sSubtracção de domínios

Tabela 2-3. Sequências: X-seq

CAMILADescrição
hd(s)Head
tl(s)Tail
nth(i,s)Selecção do i-ésimo elemento
s^rConcatenação
< x : s >Inserção de um elemento à cabeça
elems(s)Conjunto dos elementos
inds(s)Domínio

As especificações CAMILA podem ser animadas no ambiente de prototipagem designado pelo mesmo nome, CAMILA. Desta maneira, é possível verificar a adequação da especificação ao problema que se está a resolver.