Pages: [1] 2   Go Down
Print
Author Topic: modifica automa erlang  (Read 2889 times)
0 Members e 1 Utente non registrato stanno visualizzando questa discussione.
rox
Forumista
***
Offline Offline

Posts: 633


« on: 13-09-2014, 19:06:43 »

Salve a tutti,
ho fatto questo programma per che simula un automa scritto in erlang.
Il programma è questo:
Code:
-module(automa_stringhe).
-compile(export_all).


%%questa è la funzione start che ci porterà allo stato UNO!
start() -> uno().

%%lettera che ci permette di fare la transizione: A
letteraA(Pid)->Pid! letteraA.

%%lettera che ci permette di fare la transizione: B
letteraB(Pid)->Pid! letteraB.

%%ecco lo stato UNO!!se ci arriva la lettera "a" allora andremo allo stato 2,altrimenti daremo un errore! :)
uno()->
    io:format("siamo nello stato 1!!~n "),
    receive
        letteraA->
            due();
        _->
            io:format("errore dammi la A! ~n"),
            uno()
end.

due()->
    io:format("siamo nello stato 2!! ~n"),
    receive
        letteraA->
            tre();
        _->
            io:format("errore! ~n"),
            due()
end.


tre()->
    io:format("siamo nello stato 3!!~n"),
    receive
        letteraB->
            due();
        _->
            io:format("errore! ~n"),
            tre()
end.



Il programma funziona alla perfezione, ma vorrei modificare il programma in maniera tale che ciascuno stato mi dica anche quale stringa abbiamo costruito mentre abbiamo percorso l'automa! per esempio, quando entro per la prima volta sullo stato 1, mi dovrebbe restituire la stringa nulla, appena passo allo stato 2 la stringa "a", quando passo allo stato 3 mi dovrebbe restituire la stringa "aa" e così via!
Ho provato a modificare il programma in questo modo:

Code:
-module(automa_stringhe).
-compile(export_all).


%%questa è la funzione start che ci porterà allo stato UNO!
start() -> uno(" ").

%%lettera che ci permette di fare la transizione: A
letteraA(Pid)->Pid! letteraA.

%%lettera che ci permette di fare la transizione: B
letteraB(Pid)->Pid! letteraB.

%%ecco lo stato UNO!!se ci arriva la lettera "a" allora andremo allo stato 2,altrimenti daremo un errore! :)
uno(Stringa)->
    io:format("siamo nello stato 1!!La stringa vale:~s ~n ",Stringa),
    receive
        letteraA->
            due(string:concat(Stringa,"a"));
        _->
            io:format("errore dammi la A! ~n"),
            uno(Stringa)
end.



Gli altri stati ovviamente saranno modificati di conseguenza.
l'errore che mi dà è questo :
Code:
Error in process <0.45.0> with exit value: {badarg,[{io,format,[<0.25.0>,"siamo nello stato 1!!~s ~n "," "],[]},{automa_stringhe,uno,1,
[{file,"automa_stringhe.erl"},{line,20}]}]}

In sostanza il problema principale è come concatenare 2 stringhe e far stampare la stringa concatenata da io:format, ma mi dà problemi ... Qualcuno saprebbe dirmi dove sbaglio?  testate testate grazie in anticipo 
Logged

Una macchina è in grado di lavorare come cinquanta uomini comuni, ma nessuna macchina può svolgere il lavoro di un uomo straordinario.
Franco Barbanera
Moderator
Forumista Eroico
*****
Offline Offline

Posts: 3.079



WWW
« Reply #1 on: 14-09-2014, 09:07:06 »

 
Quote
quale stringa abbiamo costruito
Un automa non costruisce stringhe, le riconosce.

FB
Logged
rox
Forumista
***
Offline Offline

Posts: 633


« Reply #2 on: 14-09-2014, 10:55:14 »

effettivamente ha ragione professore  cry
quindi per poter far questo io dovrei aggiungere a queste funzioni, un "manager" che, ogni volta che viene richiamato:
1) dovrebbe prendere una lettera della stringa
2) in base alla stringa presa richiamare uno dei processi che mi simulano le transizioni da uno stato all'altro(es. se stiamo prendendo la lettera a, il manager chiamerà il processo letteraA(Pid))

Il manager immagino possa avere la seguente struttura(scrivo una sorta di pseudocodice tanto per capire se il mio approccio è corretto):
Code:
manager(Pid,Stringa_da_validare, indice_lettera)
c=Stringa_da_validare.charAt(indice_lettera)
if c==a
{
      automa_stringhe:letteraA(Pid)
}
if c==b
{
      automa_stringhe:letteraB(Pid)
}
else io:format("errore la stringa non è riconosciuta dall'automa")
sarebbe corretta un'implementazione del  genere? ovviamente in questo modo da terminale noi dovremmo dare in input al manager l'indice i! Per le altre cose, direi che dà comunque un errore se chiama una lettera su uno stato errato, no?(  per esempio, dà errore se richiamiamo il processo letteraB quando siamo sullo stato 1 ). Quindi questa modifica dovrebbe risolvere tutto, no? Lei cosa ne pensa prof? 
Logged

Una macchina è in grado di lavorare come cinquanta uomini comuni, ma nessuna macchina può svolgere il lavoro di un uomo straordinario.
Franco Barbanera
Moderator
Forumista Eroico
*****
Offline Offline

Posts: 3.079



WWW
« Reply #3 on: 14-09-2014, 13:30:11 »

"indice_lettera" !?!?
Che roba e'!!!


FB
Logged
rox
Forumista
***
Offline Offline

Posts: 633


« Reply #4 on: 14-09-2014, 15:03:09 »

Indice_lettera è l'indice che mantiene la lettera corrente che faremo scansionare al manager...
In definitiva il manager l'ho scritto e sarebbe questo :
Code:
manager(Pid,Stringa,Indice)->
C=lists:nth(Indice,Stringa),
if C=:=97 ->
    letteraA(Pid),
    Indice2=Indice+1,
    manager(Pid,Stringa,Indice2);
   C=:=98->
    letteraB(Pid),
    Indice2=Indice+1,
    manager(Pid,Stringa,Indice2);
    true->
    io:format("LA STRINGA NON VIENE RICONOSCIUTA DALL'AUTOMA! \n")

end.

A quanto pare funziona bene a parte 2 cose:
1) si blocca quando arriva alla fine della stringa (non riesco a concatenare gli if tra di loro ...  testate)
2) non capisco perchè quando la stringa non la accetta compare subito la stringa LA STRINGA NON VIENE RICONOSCIUTA DALL'AUTOMA! e poi percorre tutti gli stati dell'automa come se non ci fosse quella stringa... mi spiego meglio con un esempio. Consideriamo di voler scannerizzare la stringa aababam ( stringa non accettata dall'automa). In questo caso noi andremo ad avere sul terminale questo:
Code:
Automa=spawn(automa_stringhe,start,[]).     
siamo nello stato 1!!
 <0.83.0>
31> automa_stringhe:manager(Automa,"aababam",1).
LA STRINGA NON VIENE RICONOSCIUTA DALL'AUTOMA!
siamo nello stato 2!!
siamo nello stato 3!!
siamo nello stato 2!!
ok
siamo nello stato 3!!
siamo nello stato 2!!
siamo nello stato 3!!

se invece dò in input una stringa riconosciuta dall'automa, tutto viene eseguito alla perfezione (a parte l'errore sulla funzione nth  testate). Ovvero supponiamo di voler dare in input la stringa "aabab". Questa stringa viene riconosciuta dall'automa. Nel terminale accade questo infatti:
Code:
Automa=spawn(automa_stringhe,start,[]).     
siamo nello stato 1!!
 <0.87.0>
34> automa_stringhe:manager(Automa,"aababa",1).
siamo nello stato 2!!
siamo nello stato 3!!
siamo nello stato 2!!
siamo nello stato 3!!
siamo nello stato 2!!
siamo nello stato 3!!
** exception error: no function clause matching lists:nth(1,[]) (lists.erl, line 168)
     in function  automa_stringhe:manager/3 (automa_stringhe.erl, line 77)

e infatti in questo caso, se leggiamo dall'alto verso il basso, sono esattamente gli stati visitati dall'automa. 
Spero di aver espresso in modo chiaro come voglio implementare in generale un automa. Sembrerebbe funzionare, per lei questa implementazione andrebbe bene se scritta in un compito, professore? 
Logged

Una macchina è in grado di lavorare come cinquanta uomini comuni, ma nessuna macchina può svolgere il lavoro di un uomo straordinario.
Franco Barbanera
Moderator
Forumista Eroico
*****
Offline Offline

Posts: 3.079



WWW
« Reply #5 on: 15-09-2014, 08:35:27 »

Indipendentemente che funzioni o non funzioni,
stai gestendo una stringa nello stesso modo in cui la gestiresti in
un linguaggio imperativo (con un array ed un indice).
Erlang e' funzionale e devi gestire la stringa come una lista!
Poi, quando diventerai bravo a scrivere programmi funzionali e ti accorgessi
che un programma Erlang potrebbe essere piu' efficente gestendo
una stringa con gli indici, potrai pure farlo.
Ora no!
Se mi scrivi un programma Erlang con gli indici in un compito,
io boccio te, i tuoi figli, i tuoi nipoti e i figli dei tuoi nipoti fino alla
settima generazione!!!

Un salutone
FB
Logged
rox
Forumista
***
Offline Offline

Posts: 633


« Reply #6 on: 15-09-2014, 14:32:20 »

ok prof...
Ho modificato il manager in maniera tale da essere ricorsivo.  
Posto tutto il codice corretto senza errori:

Code:
-module(automa_stringhe).
-compile(export_all).


%%questa è la funzione start che ci porterà allo stato UNO!
start() -> uno().

%%lettera che ci permette di fare la transizione: A
letteraA(Pid)->Pid! letteraA.

%%lettera che ci permette di fare la transizione: B
letteraB(Pid)->Pid! letteraB.

%%ecco lo stato UNO!!se ci arriva la lettera "a" allora andremo allo stato 2,altrimenti daremo un errore! :)
uno()->
    io:format("siamo nello stato 1!!~n "),
    receive
        letteraA->
            due();
        _->
            io:format("ERRORE stringa non riconosciuta! ~n"),
            uno()
end.

due()->
    io:format("siamo nello stato 2!! ~n"),
    receive
        letteraA->
            tre();
        _->
            io:format("ERRORE stringa non riconosciuta! ~n"),
            due()
end.


tre()->
    io:format("siamo nello stato 3!!~n"),
    receive
        letteraB->
            due();
        _->
            io:format("ERRORE stringa non riconosciuta! ~n"),
            tre()
end.

manager3(Pid,Stringa)->
L=string:len(Stringa),
if L=:=0-> %%vuol dire che la stringa è finita! quindi diamo H=[] così capiamo che siamo alla fine della stringa!! e andiamo nell'else più esterno!!(quello alla fine della funzione! )
H=[],
T=[];
true->    %% la stringa è lunga ALMENO 2!! quindi posso fare l'assegnamento! :)
[H|T]=Stringa
end,
if H=/=[]->
    C=H,
    if C=:=97 ->
        letteraA(Pid),
        manager3(Pid,T);
       C=:=98->
        letteraB(Pid),
        manager3(Pid,T);
        true->
        io:format("LA STRINGA NON VIENE RICONOSCIUTA DALL'AUTOMA!Prima di capirlo siamo passati da questi stati: \n")
    end;
true->
    io:format("siamo arrivati alla fine della stringa!... STRINGA ACCETTATA!! ecco da quali stati siamo passati:\n ")

end.


questo è quello che scrivo da terminale per eseguirlo correttamente:
Code:
8> Automa=spawn(automa_stringhe,start,[]).  
siamo nello stato 1!!
 <0.48.0>
9> automa_stringhe:manager3(Automa,"aababn").
LA STRINGA NON VIENE RICONOSCIUTA DALL'AUTOMA!Prima di capirlo siamo passati da questi stati:
siamo nello stato 2!!
siamo nello stato 3!!
siamo nello stato 2!!
ok
siamo nello stato 3!!
siamo nello stato 2!!

è possibile notare:
1)se la stringa è stata accettata o meno dall'automa;
2)gli stati che ci hanno permesso di capire se la stringa è accettata o meno!

In questo modo adesso dovrebbe essere corretto, giusto professore?  
« Last Edit: 16-09-2014, 11:16:24 by rox » Logged

Una macchina è in grado di lavorare come cinquanta uomini comuni, ma nessuna macchina può svolgere il lavoro di un uomo straordinario.
Franco Barbanera
Moderator
Forumista Eroico
*****
Offline Offline

Posts: 3.079



WWW
« Reply #7 on: 15-09-2014, 17:15:22 »

Quote
la stringa è lunga ALMENO 2!! quindi posso fare l'assegnamento! Smiley

In Erlang non si fanno assegnamenti!!!!

Inoltre non si controlla se una stringa e' lunga 0, ma se e' vuota!!!
Logged
Franco Barbanera
Moderator
Forumista Eroico
*****
Offline Offline

Posts: 3.079



WWW
« Reply #8 on: 15-09-2014, 17:16:34 »

Forse non ho letto con la dovuta attenzione, ma quale sarebbe il linguaggio che riconoscerebbe il tuo automa?
Logged
Franco Barbanera
Moderator
Forumista Eroico
*****
Offline Offline

Posts: 3.079



WWW
« Reply #9 on: 15-09-2014, 17:25:32 »

A funzionare pare funzioni.
Qual e' il vantaggio pero' di utilizzare i processi nel tuo programma?

Magari si potrebbe scrivere il manager in modo che possa creare un processo automa
per ogni stringa che riceve, in modo che piu' stringhe possano venire processate virtualmente
in parallelo.
Sullo schermo potrebbe comparire lo stato di avanzamento di ogni stringa attualmente in
fase di elaborazione.


FB
« Last Edit: 15-09-2014, 19:15:39 by Franco Barbanera » Logged
rox
Forumista
***
Offline Offline

Posts: 633


« Reply #10 on: 15-09-2014, 19:33:41 »

Qual e' il vantaggio pero' di utilizzare i processi nel tuo programma?

Magari si potrebbe scrivere il manager in modo che possa creare un processo automa
per ogni stringa che riceve, in modo che piu' stringhe possano venire processate virtualmente in parallelo.

vantaggi nn saprei se ce ne siano sinceramente, cercavo solamente di capire se l'idea che mi era venuta in mente potesse essere considerata corretta o meno da lei . per quanto riguarda il processare più stringhe contemporaneamente ci si potrebbe pensare, ma sinceramente al momento io cercavo il modo per me più semplice per implementare un automa in erlang  se per lei un' implementazione simile va bene, allora vedrò di utilizzare questa architettura nei compiti 
Logged

Una macchina è in grado di lavorare come cinquanta uomini comuni, ma nessuna macchina può svolgere il lavoro di un uomo straordinario.
Franco Barbanera
Moderator
Forumista Eroico
*****
Offline Offline

Posts: 3.079



WWW
« Reply #11 on: 15-09-2014, 20:16:20 »

Dipende da quel che richiede il compito....

Salutoni
FB
Logged
rox
Forumista
***
Offline Offline

Posts: 633


« Reply #12 on: 16-09-2014, 00:19:36 »

in pratica il manager dovrebbe essere fatto così ?  ...(manager3 è il manager visto prima che lavora su un singolo automa!)

Code:
manager4(Stringa)->
Automa=spawn(automa_stringhe,start,[]),
manager3(Automa,Stringa),
io:format("andiamo a considerare la stringa ~p",[Stringa]).

era questo che lei intendeva facessi?  
« Last Edit: 16-09-2014, 11:17:47 by rox » Logged

Una macchina è in grado di lavorare come cinquanta uomini comuni, ma nessuna macchina può svolgere il lavoro di un uomo straordinario.
Franco Barbanera
Moderator
Forumista Eroico
*****
Offline Offline

Posts: 3.079



WWW
« Reply #13 on: 16-09-2014, 13:04:23 »

E' un possibile approccio.

Piuttosto:
Quote
andiamo a considerare la stringa ~p",[Stringa]
Che operazione, procedura, procedimento particolare e' mai il "considerare"??   

FB
Logged
rox
Forumista
***
Offline Offline

Posts: 633


« Reply #14 on: 16-09-2014, 13:47:29 »

era per indicare che il manager sta prendendo in esame la stringa data in input e sta valutando se è accettata dall'automa o meno 
Logged

Una macchina è in grado di lavorare come cinquanta uomini comuni, ma nessuna macchina può svolgere il lavoro di un uomo straordinario.
Pages: [1] 2   Go Up
Print
Jump to: