Vous êtes sur la page 1sur 5

Laboratório de Sistemas e Sinais

Máquinas de Estados
Luı́s Caldas de Oliveira
Março 2009

As máquinas de estados são sequenciais: começam num estado inicial, e reagem aos valores de entrada transi-
tando sequencialmente entre estados. A realização de máquinas de estados em software é razoavelmente simples.
Neste laboratório, exploraremos a sua construção e progrediremos até à realização de uma implementação que faça
a composição de duas máquinas de estados.

1 Introdução
1.1 Cadeias de caracteres em Matlab
As máquinas de estados operam sobre sequências de sı́mbolos de um alfabeto. Por vezes esse alfabeto é
numérico mas, no caso mais geral, é um conjunto de elementos com nomes arbitrários. Por exemplo, a entrada
para uma máquina que funcione como um gravador de chamadas será:

Entradas = {toca, atende, fimdasaudacão, fimdamensagem, nulo}


Cada elemento do conjunto anterior pode ser representado em Matlab como uma cadeia de caracteres (help
strings). As cadeias de caracteres são delimitadas por plicas. Por exemplo:

>> x = ’toca’;

A própria cadeia de caracteres é uma matriz de caracteres, sendo assim é possı́vel indexar os caracteres indivi-
duais

>> x (1:3)

ans =

toc

Podem-se juntar cadeias de caracteres tal como matrizes normais,

>> y = ’o’;
>> z = ’sino’;
>> [x, y, z]
ans =
tocaosino

Isto pode não ser necessariamente o que é pretendido. Pode-se querer construir uma matriz de cadeias de
caracteres em que cada elemento é ele próprio uma cadeia de caracteres (em vez de um só caracter). Esse objecto
pode ser representado em Matlab como um cell array,

>> c = {’toca’, ’atende’, ’fim da saudação’, ’fim da mensagem’, ’nulo’}

Notar as chavetas em vez dos parenteses rectos habituais. Um cell array em Matlab é uma matriz em que os
seus elementos são objectos Matlab arbitrários (tais como cadeias de caracteres e matrizes). Os cell arrays podem
ser indexados tal como os vectores normais

1
>> c(1)

ans =

’toca’

Pretende-se muitas vezes testar uma cadeia de caracteres para saber se é igual a outra cadeia. O operador ==
não pode ser usado na comparação de cadeias de caracteres ou em células de um cell array,

>> c = ’toca’;
>> if (c == ’atende’) result = 1; end
??? Error using ==> ==
Array dimensions must match for binary array op.

>> c = {’toca’, ’atende’, ’fim da saudação’, ’fim da mensagem’, ’nulo’}


??? Error using ==> ==
Function ’==’ not defined for cariables of class ’cell’

As cadeias de caracteres devem ser comparadas usando strcmp ou switch (ver a ajuda on-line destes
comandos).

>> c = {’toca’, ’atende’, ’fim da saudação’, ’fim da mensagem’, ’nulo’}

1.2 Ficheiros de comandos


Em Matlab podem-se guardar programas em ficheiros que se mandam executar a partir da linha de comandos.
A um ficheiro de comandos deste tipo dá-se o nome de m-file, e tem um nome na forma comando.m em que
comando é o nome do comando a introduzir na linha de comandos para executar o programa.
Pode-se usar um qualquer editor de texto para criar e editar uma m-file mas o Matlab inclui ele próprio um
editor. Para chamar esse editor selecciona-se New e M-file do menu File do Matlab.
Para executar o programa, o Matlab precisa de saber onde encontrar o novo ficheiro de comandos. O modo
mais simples de resolver isto é guardar o ficheiro na directoria corrente do Matlab. Por exemplo, se os ficheiros de
comandos estão na directoria

D:\home\lco

poderá utilizá-los fazendo

>> cd D:\home\lco
>> pwd

ans =

D:\home\lco

O comando cd faz com que o Matlab altere a directoria de trabalho. O comando pwd retorna a directoria de
trabalho actual (a mnemónica é present working directory).
O Matlab pode procurar a presença de m-files numa sequência de directorias usando o comando path. Por
exemplo, em vez de mudar a directoria corrente, poderı́amos ter usado o seguinte,

>> path(path, ’D:\home\lco’);

Este comando indica ao Matlab que deverá procurar os ficheiros de comandos onde já procurava anteriormente
(o primeiro argumento path) e na nova directoria.
Supondo que se cria um ficheiro ola.m contendo,

% OLA - diz olá.


disp(’Olá’)

2
A primeira linha é um comentário. O comando disp imprime o seu argumento no ecrã sem mostrar o nome
da variável. Se se escrever o seguinte na linha de comandos,
>> ola
Olá
Nos nomes dos comandos podem-se trocar as letras minúsculas por maiúsculas, ou seja, OLA e ola são a
mesma coisa. O comentário no inı́cio do ficheiro é usado pelo comando help do Matlab.
>> help ola
OLA - diz olá.
O comando ola anterior corresponde a um programa e não a uma função, pois não existe valor de retorno.
Para definir uma função é necessário incluir o comando function no ficheiro. Por exemplo, se o ficheiro
reverse.m contiver:
function result = reverse(argument)
% REVERSE - retorna o array passado como argumento invertido
result = argument (length(argument):-1:1);
podemos fazer
>> reverse(’olá’)

ans =

álo
O valor retornado são os caracteres da cadeia passada como argumento em ordem inversa.
Uma função pode ter qualquer número de argumentos e valores de retorno. Para definir uma função com dois
argumentos e dois valores de retorno pode-se usar
function [res1, res2] = fun(arg1, arg2)
os valores de res1 e res2 são atribuı́do dentro do ficheiro. Para usar esta função podemos atribuir os valores
de retorno a duas variáveis diferentes,
[r1, r2] = fun(a1, a2)
Os nomes dos argumentos e das variáveis de retorno são arbitrários

2 Trabalho para os alunos


1. Considere o seguinte cell array

cellarray = {’a’, ’b’, ’a’, ’a’, ’b’}


(a) Execute a seguinte sequência de comandos:
n = 0
for e = cellarray
if strcmp(e,’a’) n = n + 1;
end
end
(b) Em seguida, defina uma função conta que conte as ocorrências do caracter a em qualquer argumento.
(c) Quantas ocorrências do caracter a existem em x e em y? Por que são diferentes?
>> x = [’a’, ’b’, ’c’, ’a’, ’aa’]
>> y = {’a’, ’b’, ’c’, ’a’, ’aa’}
(d) Modifique o comando anterior para que receba dois argumentos em que o primeiro é o caracter cujo
número de ocorrências se pretende contar no segundo argumento.

3
{0}/0 {1}/1

{1}/0
0 1
{0}/1

Entradas = {0, 1, nulo}


Saı́das = {0, 1, nulo}

Figura 1: Máquina de estados.

2. A função input pode ser usada para pedir interactivamente dados ao utilizador.

(a) Crie e execute um ficheiro de comandos Matlab com o seguinte conteúdo:


% Cumprimenta o utilizador
while 1
resp = input(’Como te chamas? ’, ’s’);
if (strcmp(resp, ’sair’)|strcmp(resp, ’’))
break;
end
disp([’Olá ’ resp])
end
(b) Escreva um programa que pede ao utilizador uma cadeia de caracteres e que usa a função conta para
devolver o número de ocorrências de a nessa cadeia.

3. Considere a máquina de estados da figura 1.

(a) Construa uma m-file contendo uma definição da sua função de actualizacão. Verifique se corresponde
ao diagrama apresentado.
% The next result is 0 or 1.
function [proximo, saida] = actualiza(estado, entrada)
%
switch estado
case ’0’
switch entrada
case ’0’
proximo = ’0’;
saida = ’0’;
case ’1’
proximo = ’1’;
saida = ’0’;
otherwise
proximo = estado;
saida = ’nulo’;
end
case ’1’
switch entrada
case ’0’
proximo = ’0’;
saida = ’1’;
case ’1’
proximo = ’1’;
saida = ’1’;

4
otherwise
proximo = estado;
saida = ’nulo’;
end
end
(b) Em seguida, crie um programa que solicite ao utilizador uma entrada e, se esta estiver no alfabeto da
máquina, que reaja ao seu valor, voltando a solicitar uma nova entrada. Se a entrada não pertencer ao
alfabeto da máquina, o programa deverá assumir que a entrada é nulo e não deverá mudar de estado
(stutter). Verifique que a sua função de actualização tem em consideração a entrada nulo.

4. Projecte um animal de estimação virtual1 , neste caso um gato, construindo uma máquina de estados, escre-
vendo uma função actualizacão, e escrevendo um programa para executar repetidamente essa função. O
gato virtual deverá ter o seguinte comportamento:

O gato começa por estar feliz. Se lhe fizerem festas ele ronrona. Se lhe derem comida ele
vomita. Com o passar do tempo, ele fica com fome e roça-se nas pernas das pessoas. Se lhe derem
comida quando está com fome ele ronrona e fica feliz. Se lhe fizerem festas quando tem fome, ele
morde. Se o tempo passar enquanto ele está com fome, ele morre.

(a) Crie uma função de actualização para o seu gato virtual em que as palavras em itálico na descrição
anterior devem ser elementos ou do espaço de estados ou dos alfabetos de entrada ou de saı́da. Apre-
sente os alfabetos de entrada e de saı́da e bem como o diagrama da transição de estados. Escreva um
programa para executar a máquina de estados até que o utilizador escreva sair.
(b) Construa uma máquina de estados que produza entradas para o seu gato virtual de modo que o gato
nunca morra. Essa máquina de estados deverá gerar saı́das tempo e comida de tal maneira que o gato
nunca alcança o estado de morre.
Repare que esta máquina de estados não tem entradas particularmente significativas. O alfabeto de
entrada poderá ser

Entradas = {1, nulo}

onde uma entrada de 1 significa que a máquina deverá produzir uma saı́da não-nula, e uma entrada
nulo deverá produzir uma saı́da nula.
(c) Escreva um programa onde sua máquina de estados alimentadora seja composta em cascata com sua
máquina de estados do gato virtual, e verifique que o gato não morre. A máquina de estados deve
permitir a passagem do tempo (produzindo um número infinito de saı́das tempo) mas deve ser tão
simples quanto possı́vel.
Um dos objectivos principais deste exercı́cio é o de mostrar que as máquinas de estado sistematica-
mente construı́das podem ser compostas com facilidade.
A máquina de estados alimentadora pode ser considerada um controlador em cadeia aberta porque
controla o animal de estimação virtual sem observar a sua saı́da. No entanto, na maioria dos sistemas
práticos, não é possı́vel projectar um controlador em cadeia aberta. O laboratório seguinte explorará os
controladores em cadeia fechada.

1 Este
problema inspirou-se no jogo Tamagotchi feito por Bandai em Japão. Tamagotchi pode ser traduzido por “pequeno ovo” foi extrema-
mente popular no final dos anos 90 e tinha um comportamento consideravelmente mais complexo do que o descrito neste exercı́cio.

Vous aimerez peut-être aussi