Pages: [1]   Go Down
Print
Author Topic: Sistema Sepi banca/bancomat/client  (Read 630 times)
0 Members e 1 Utente non registrato stanno visualizzando questa discussione.
rondey
Matricola
*
Offline Offline

Posts: 74


« on: 20-06-2016, 17:24:11 »

Code:
type pinManagerProt= !string.&{ok:?string.end, no:end}

type successProt=&{deposit: ?integer.!integer.end,
                        withdrawal: ?integer.+{dispense: end,
                                    overdraw: end}
    }

type bancomatProt =
    ?string.
        +{success: successProt,
           retry: bancomatProt,
           failure: end}

type bankAsBmProt = !string.!successProt.&{acceptMoney:?integer.end,
                                        dispenseMoney:?integer.end,
                                        error:end
                               }
 
type clientProt = dualof bancomatProt
 
def pinManager (pin1:string,cc1:string,pin2:string,cc2:string, chPin: *!pinManagerProt) =
def pinSessionManager ch: dualof pinManagerProt =
  //chiedi il pin
          ch?pin.
          if pin==pin1
  then ch select ok.
//Invia il relativo numero di conto corrente
                                ch!cc1.
//Richiama il pinManager in modo da poter soddisfare un
//ulteriore client
pinManager!(pin1,cc1,pin2,cc2, chPin)
              else if pin==pin2
                      then ch select ok.
                                        ch!cc2.
pinManager!(pin1,cc1,pin2,cc2, chPin)
                      else ch select no.
pinManager!(pin1,cc1,pin2,cc2, chPin)
new chPinCl chPinSr : pinManagerProt // crea un canale pinManagerProt
chPin!chPinCl. // pubblica l'estremità del client
pinSessionManager!chPinSr // tieni l'estremità del server 

//Creo un nuovo canale per il pinManager
new pinManagerServer pinManagerClient: *!pinManagerProt
//Inizializzo il pinManager
pinManager!("12345","001","54321","002", pinManagerServer) |

def bank (numcc1:string, owner1:string, amount1:integer,
          numcc2:string, owner2:string, amount2:integer,
  chBank: *!bankAsBmProt) =
def bankSessionManager bmSession: dualof bankAsBmProt =
//Richiedo il numero di conto corrente
bmSession?numcc.
//Richiedo il canale per ricevere le richieste dell'utente
bmSession?chSucc.
  case chSucc of
//Se l'utente vuole depositare, richiedo i soldi che vuole depositare
deposit -> chSucc?d.
     if numcc==numcc1
//Informo il bancomat che deve accettare
//soldi dall'utente
  then bmSession select acceptMoney.
//Precisamente d Euro
bmSession!d.
//Invio all'utente quanti soldi avrà nel conto
//in banca
chSucc!(amount1+d).
//aggiorno il conto in banca del relativo utente
bank!(numcc1, owner1, amount1+d,
                                          numcc2, owner2, amount2,
chBank)
                                    else bmSession select acceptMoney.
bmSession!d.
chSucc!(amount2+d).
bank!(numcc1, owner1, amount1,
                                          numcc2, owner2, amount2+d,
chBank)
//In caso di prelievo, chiedo all'utente quanti soldi vuole prelevare
                        withdrawal -> chSucc?w.
  if numcc==numcc1
//Nel caso abbia soldi a sufficienza in banca
  then if amount1>=w
//Informo il bancomat del prelievo in atto
  then bmSession select dispenseMoney.
//La cui somma è w
bmSession!w.
//Informo l'utente
chSucc select dispense.
//Aggiorno il conto in banca
bank!(numcc1, owner1, amount1-w,
                                          numcc2, owner2, amount2,
chBank)
//Altrimenti restituisco errore sia al
//bancomat
  else bmSession select error.
//Che al cliente
chSucc select overdraw.
//Lasciando inalterati i conti
//correnti e richiamo il bank per
//soddisfare altre richieste
  bank!(numcc1, owner1, amount1,
                                          numcc2, owner2, amount2,
             chBank)
  else if amount2>=w
  then bmSession select dispenseMoney.
bmSession!w.
chSucc select dispense.
  bank!(numcc1, owner1, amount1,
                                          numcc2, owner2, amount2-w,
chBank)
  else bmSession select error.
chSucc select overdraw.
  bank!(numcc1, owner1, amount1,
                                          numcc2, owner2, amount2,
chBank)

new chBankCl chBankSr : bankAsBmProt // crea un canale bankAsBmProt
chBank!chBankCl. // pubblica l'estremità del client
bankSessionManager!chBankSr // tieni l'estremità del server

//Creo un nuovo canale per il bank
new bankServer bankClient: *!bankAsBmProt
//Inizializzo i conti in banca
bank!("001","Davide",5000,"002","Gianluca",6000, bankServer) |

//Definisco il bancomat che fa da ponte fra l'utente e la banca, soddisfando gli eventuali
//prelievi e depositi richiesti dall'utente
def bancomat (schan: bancomatProt,trials:integer) =
   //Richiedo il pin
       schan?pin.
   //Richiedo l'estremità client del pinManager
       pinManagerClient?p.
   //Invio il pin e verifico la sua correttezza
   p!pin.case p of
  //In caso affermativo, richiedo il numero di conto corrente
          ok -> p?cc.
                schan select success.
//Richiedo l'estremità client del bank
bankClient?b.
//Invio sia il numero di conto corrente
//che il canale per soddisfare l'utente
                b!cc.b!schan.
{
case b of
                  //Se ricevo il comando di deposito soldi, informo l'utente
acceptMoney   -> b?d.printStringLn!("Inserire "++d++" Euro")
                    //Se ricevo il comando di prelievo soldi, informo l'utente
dispenseMoney -> b?w.printStringLn!("Prelevare i "++w++" Euro")
                  //Analogamente in caso di errore
error   -> printStringLn!("Spiacente, errore")
                }
  //Riprovo al massimo 3 volte
          no -> if trials>=3
  //Se supero il numero, restituisco all'utente l'errore
                  then schan select failure
  //Altrimenti riprovo
                  else schan select retry.
  //Aggiornando il numero di tentativi già effettuati
                  bancomat!(schan,(trials+1))

//Si occupa di fare da tramite fra bancomat e utente(in modo da non dover chiedere
//all'utente di fornire un estremità di canale per comunicare col bancomat, automatizzando
//tale procedura
def clientToBancomat (pin: string, command: string, money: integer, cChan: clientProt) =
//Invio il pin dell'utente al bancomat
   cChan!pin.
   case cChan of
//Se il pin è stato accettato, se l'utente vuole depositare
     success -> if command=="Deposita"
   then cChan select deposit.
//Invia la richiesta di soldi da depositare
        cChan!money.
//Ricevi il futuro saldo del conto corrente
cChan?d.
printStringLn!("La cifra del conto corrente sara': "++ d)
        //Se invece l'utente vuole depositare
   else cChan select withdrawal.
//Invia la richiesta di soldi da prelevare
        cChan!money.
{case cChan of
                          //Se la richiesta può essere soddisfatta
dispense -> printStringLn!("Prelievo consentito")
                          //Altrimenti
overdraw -> printStringLn!("Soldi in banca insufficenti")
                        }
//In caso di retry, informo l'utente e ripeto la procedura
     retry   -> printStringLn!("Si prega di riprovare").
clientToBancomat!(pin,command, money,cChan)
//In caso di fallimento, mi limito a informare l'utente
     failure -> printStringLn!("Fallimento")

def client (pin: string, command: string, money: integer) =
//Creo il canale per comunicare fra utente e bancomat
new  clientCh bancomatCh : clientProt
//Inizializzando a 0 il numero di tentativi
bancomat!(bancomatCh,0)|
//Invio la richiesta
clientToBancomat!(pin, command, money, clientCh)

//Esempi di client
client!("12345", "Preleva", 1000000)|client!("54321", "Deposita", 150)
Logged
Ocelot92
Apprendista Forumista
**
Offline Offline

Posts: 301



« Reply #1 on: 09-10-2016, 18:15:32 »

Ecco la mia versione:
L'interazione consiste tra client <-> ATM, l'ATM poi instaura prima una sessione col PinManager per verificare i dati e una volta ottenuta la risposta (ovvero il conto), instaura una connessione con la banca.
Code:
type Pin = string
type Amount = integer
type Outcome = string
type Message = string

//----- Bank Types -----------------------------------------------------
type bankSession = !cc:integer.!Amount.?Outcome.end
 
type BankShared = *?bankSession
//----------------------------------------------------------------------

//-------------- PIN Manager Types -------------------------------------
type PinManSession = !Pin.
&{pinOK: ?cc:integer. end,
  pinKO: end}
 
type PinManShared = *?PinManSession
//----------------------------------------------------------------------

//----------- ATM Types ------------------------------------------------
type ATMSession = +{start:
  !P:Pin.
&{success:
+{withdrawal: !Amount.end,
  deposit: !A:Amount.end},
                          retry: ATMSession,
    quit: end},
  exit: end
  }

type ATMShared = *?ATMSession
//----------------------------------------------------------------------

//---------- unrestricted channels -------------------------------------
new atmSupplicant atmSpawner: ATMShared //channes used to give to the clients a channel with a dedicated ATM.
new pinManSupplicant pinManSpawner : PinManShared
new bankSupplicant bankSpawner : BankShared
//----------------------------------------------------------------------

//------------------- PinManager def processes -------------------------
def pinManProc (pin1:string,cc1:integer,pin2:string,cc2:integer) =
new clientPinMan serverPinMan : PinManSession
pinManSpawner!clientPinMan. //sending an endpoint for pinManagerSession to a client
pinManagerSlave!(serverPinMan,pin1,cc1,pin2,cc2). //sending an endpoint for pinManagerSession to a pinManager
pinManProc!(pin1,cc1,pin2,cc2)


def pinManagerSlave (serverPinMan: dualof PinManSession ,pin1:string,cc1:integer,pin2:string,cc2:integer) =
serverPinMan?inputPin.
if inputPin == pin1 then
serverPinMan select pinOK.
serverPinMan!cc1
else if inputPin == pin2 then
serverPinMan select pinOK.
serverPinMan!cc2
else
serverPinMan select pinKO
 
//----------------------------------------------------------------------

// ------------------------- Bank def processes ------------------------

def bankSlave (serverBank:dualof bankSession ,cc1:integer, amount1:integer, cc2:integer, amount2:integer) =
serverBank?account. //account = # conto
serverBank?amount.
if account == cc1 then
serverBank!"Account "++cc1++" has been updated: "++amount1+amount.
bankProc!(cc1,amount1+amount,cc2,amount2)
else {if account == cc2 then
serverBank!"Account "++cc2++" has been updated: "++amount2+amount.
      bankProc!(cc1,amount1,cc2,amount2+amount)
else
serverBank!"There has been an error, please try later again."}
 
def bankProc (cc1:integer,amount1:integer,cc2:integer,amount2:integer) =
new clientBank serverBank : bankSession
bankSpawner!clientBank.
bankSlave!(serverBank,cc1,amount1,cc2,amount2).
bankProc!(cc1,amount1,cc2,amount2)
//----------------------------------------------------------------------

//------------------ ATM def processes ---------------------------------
def atmSlave (atms: dualof ATMSession, tries:integer) =
case atms of
start ->
atms?pin.
pinManSupplicant?pinManCh.
pinManCh!pin.
{case pinManCh of
pinOK ->
pinManCh?cc.
atms select success.
{case atms of
withdrawal ->
atms?amount.
bankSupplicant?bankCh.
bankCh!cc.
bankCh!amount*-1.
bankCh?msg.
printStringLn!msg
deposit ->
atms?amount.
bankSupplicant?bankCh.
bankCh!cc.
bankCh!amount.
bankCh?msg.
printStringLn!msg
}
pinKO ->
if tries > 0 then
printStringLn!"Wrong pin. You have still "++tries -1 ++" attempts available.".
atms select retry.
atmSlave!(atms, tries -1)
else
printStringLn!"Your account has been blocked".
atms select quit
              }
exit ->
printStringLn!"exit selected"

def atmProc () = {//spawns ATMs for the clients.
new clientATM serverATM : ATMSession
atmSpawner!clientATM. //sending an endpoint for ATMSession to a client
atmSlave!(serverATM, 3).        //sending an endpoint for ATMSession to an ATM
atmProc!()
}
//----------------------------------------------------------------------

atmProc!().printStringLn!"Started atmproc"|
bankProc!(1,1000,2,1000). printStringLn!"Started bankProc" |
pinManProc!("aaa",1,"bbb",2). printStringLn!"Started pinManProc" |

atmSupplicant?atmCh.
atmCh select start.
atmCh!"aaa".
case atmCh of
success ->
atmCh select deposit.
atmCh!50
retry ->
atmCh select exit.
printStringLn!"exit"
quit ->
printStringLn!"Account blocked"

Logged

I'm happy to tell you all that...
((λf.λx.f(f(x))) (λy.y^2)) (5)  = 5^4

"Si ma dillo che bisogna cliccare APPLY per crearle le partizioni…" - cit. Utente dopo aver seguito un How-To... .-.
Pages: [1]   Go Up
Print
Jump to: