Guião para a Décima Aula Prática de IPL

Delfim F. Marado Torres

19 de Maio de 1999

COMANDOS

Agradeço comentários, sugestões ou correccões. O meu endereço de correio electrónico é < delfim@mat.ua.pt > . Desde já obrigado.

Objectivos da aula

Resolução do problema COMANDOS proposto no CeNPL'99.

Controlo à Distância

Um aparelho usado para controlar à distância o funcionamento de uma aparelhagem electrónica de som, com sintonizador AM/FM, leitor de CDs e leitor de cassetes, aceita comandos para: ligar e desligar (ON/OFF) a aparelhagem; escolher a modalidade que se pretende ouvir (entre os 3 dispositivos existentes). Após aceitar um comando, o controlador à distância envia-o para o aparelho (processo esse que é irrelevante neste contexto) e continua a aceitar novos comandos.
O comando para desligar a aparelhagem pode ser emitido em qualquer momento, após se ter ligado o equipamento.
Só faz sentido seleccionar um modo de funcionamento depois de se ter ligado a aparelhagem.
Além disso, só são úteis as sequências de comandos que verifiquem as seguintes indicações: no caso de se escolher o sintonizador, deve indicar-se a seguir a banda (AM ou FM) e a frequência do canal a ouvir; se a escolha for o leitor de CDs, indicar-se-á apenas o número da pista; finalmente, optando-se pelo leitor de cassetes, indicar-se-á a operação desejada (FF, RW, Play), ou Stop depois de uma das outras.
Note que a introdução de uma sequência inválida de comandos faz com que a aparelhagem seja imediatamente (logo que se detecte o erro) desligada.

Tarefa

A sua tarefa é escrever um programa Prolog que dada uma sequência de comandos indique, caso a sequência seja válida, o estado em que o aparelho fica a funcionar.
Para resolver o problema, considere que o controlador à distância pode ser encarado como uma Máquina de Transição de Estados, e então implemente o autómato determinista que modela o sistema.

Os Dados

Para representar cada comando é usado o seguinte alfabeto (conjunto de símbolos terminais):

        { on, off,
          sint, lcd, lcasset,
          am, fm, freq, pista, ff, rw, play, stop }

Os Resultados

O programa deve ser chamado através do seguinte predicado:

       simulaControlador( Cmds,Estado ).

em que se supõe instanciado Cmds, com uma das sequências definidas em comandos/1; os resultados virão em Estado.

Exemplos:

?- simulaControlador([on],E).

E = 'ligado, espera comandos' ;
no

?- simulaControlador([on,freq,off],E).

E = 'desligado apos erro, sequencia cmds inutil' ;
no

?- simulaControlador([on,lcasset,rw],E).

E = 'leitor de cassetes a puxar a fita para tras' ;
no

?- simulaControlador([on,lcasset,stop],E).

E = 'desligado apos erro, sequencia cmds inutil' ;
no

Uma solução

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Solucao para o problema COMANDOS proposto no CeNPL'99
% Realizado em 19/Maio/1999 por Delfim F. Marado Torres
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Descricao da 'aparelhagem'
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

simbolosEntrada([on,off,sint,lcd,lcasset,am,fm,freq,pista,ff,rw,play,stop]).

estadoInicial(0).

delta(0,on,1).
delta(1,sint,2).
delta(2,am,3).
delta(2,fm,4).
delta(3,freq,'5a').
delta(4,freq,'5b').
delta(1,lcd,6).
delta(6,pista,7).
delta(1,lcasset,8).
delta(8,ff,9).
delta(8,rw,10).
delta(8,play,11).
delta(E,stop,8) :-
  member(E,[9,10,11]).
delta('0e',off,'0e').
delta(_,off,0).
delta('0e',on,1).
delta(_,C,'0e') :-
  simbolosEntrada(L),
  member(C,L).

descreveEstado(0,'aparelho desligado').
descreveEstado(1,'ligado, espera comandos').
descreveEstado(2,'sintonizador escolhido, espera seleccao da banda').
descreveEstado(3,'banda AM escolhida, espera seleccao da frequencia').
descreveEstado(4,'banda FM escolhida, espera seleccao da frequencia').
descreveEstado('5a','a ouvir radio, banda AM').
descreveEstado('5b','a ouvir radio, banda FM').
descreveEstado(6,'leitor de CDs escolhido, espera seleccao da pista').
descreveEstado(7,'a ouvir CD').
descreveEstado(8,'leitor de cassetes escolhido,
                  espera seleccao da operacao desejada').
descreveEstado(9,'leitor de cassetes a puxar a fita para a frente').
descreveEstado(10,'leitor de cassetes a puxar a fita para tras').
descreveEstado(11,'a ouvir cassete').
descreveEstado('0e','desligado apos erro, sequencia cmds inutil').

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% simulaControlador(Cmds,Estado)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

simulaControlador(Cmds,DescricaoEstado) :-
  estadoInicial(EI),
  simula(Cmds,EI,DescricaoEstado).

simula([],EstCor,Descricao) :-
  descreveEstado(EstCor,Descricao).
simula([C|R],EstCor,Descricao) :-
  delta(EstCor,C,ProxEst),!,        % usamos o cut, pois trata-se
  simula(R,ProxEst,Descricao).      % de um automato determinista