Svigruppo. Monga. Il modello di. Asserzioni. What & How Contratti ed ereditarietà Eccezioni. Svigruppo. Monga. Il modello di.

Documenti analoghi
Svigruppo. Monga. Il modello di. Asserzioni. What & How Contratti ed ereditarietà Eccezioni Qualche dettaglio in più sul linguaggio. Svigruppo.

Sviluppo software in gruppi di lavoro complessi 1

Prova di esame del 19 giugno 2017

Compito di Fondamenti della Programmazione: Metodi Evoluti - A.A Prova di esame del 24 settembre 2015

Compito di Fondamenti della Programmazione: Metodi Evoluti - A.A Prova di esame del 19 luglio 2014

Prova di esame del 22 luglio 2016

Compito di Fondamenti della Programmazione: Metodi Evoluti - A.A Prova di esame del 24 settembre 2013

Uso di Asserzioni alla Hoare nei Linguaggi O.O. Java Modeling Language

Compito di Fondamenti della Programmazione: Metodi Evoluti - A.A Prova di esame del 18 giugno 2013

Prova di esame del 16 giugno 2016

SOLUZIONE: come antenato comune. Fondamenti della Programmazione: Metodi Evoluti - A.A Prova d esame del 24 febbraio 2014

Prova di esame del 1 luglio 2019

Prova di esame del 21 giugno 2018

Asserzioni in Java fondamenti

INTRODUZIONE ALLA LOGICA DI HOARE. Corso di Logica per la Programmazione

Logica per la Programmazione

Linguaggi di programmazione: sintassi e semantica Sintassi fornita con strumenti formali: Semantica spesso data in modo informale

Semantiche dei linguaggi di programmazione

Logica per la Programmazione

Concetti Base Encapsulation ed Ereditarietà Programmare con l Ereditarietà. Java: Ereditarietà. Damiano Macedonio

Problema: stampa degli interi compresi tra n e m

Controllo del flusso. Laboratorio di Sistemi Operativi primavera if/else. if/else

Sistemi Operativi 1. Lezione III: Concetti fondamentali. Mattia Monga. 7 marzo 2008

Sistemi Operativi 1. Mattia Monga. 7 marzo Dip. di Informatica e Comunicazione Università degli Studi di Milano, Italia

Python. Loriano Storchi.

Progettazione By Contract

SOMMARIO Tipo di dato astratto (ADT) : Interfacce: interface. TIPI DI DATI ASTRATTI. Polimorfismo: Tipo class. Tipo interface. Tipi run-time: is e as.

Logica per la Programmazione

Stringhe. Prof. Lorenzo Porcelli

Istruzioni condizionali di diramazione in Fortran 90

Logica per la Programmazione

Logica per la Programmazione

Logica per la Programmazione

PROGRAMMAZIONE Nomi, binding, regole di visibilità (scope)

Prova di esame del 19 luglio 2019

Programmazione a Oggetti. Astrazione sui Dati e Iteratori

Conoscere l uso delle collezioni in Java. Conoscere il concetto di Generics (programmazione

Corso di laurea triennale in Informatica Turno A

Programma del corso. Elementi di Programmazione. Introduzione agli algoritmi. Rappresentazione delle Informazioni. Architettura del calcolatore

FUNZIONI PARAMETRI DEFINIZIONI DI PROCEDURE PROCEDURE

FUNZIONI. Dichiarazione: Definizione:

LA LOGICA DI HOARE. Corso di Logica per la Programmazione A.A. 2010/11 Andrea Corradini, Paolo Mancarella

public static boolean occorre (int[] a, int n) { int i = 0; boolean trovato = false;

Verifica di programmi

College Algebra. Logarithms: Denitions and Domains. Dr. Nguyen November 9, Department of Mathematics UK

Progettazione By Contract

Design by contract. Angelo Gargantini

Logica per la Programmazione

PROGRAMMAZIONE II Seconda Valutazione Intermedia 29 Maggio Si consideri la specifica parziale di una gerarchia di classi:

Finite Model Theory / Descriptive Complexity: bin

INTRODUZIONE ALLA LOGICA DI HOARE. Corso di Logica per la Programmazione A.A. 2013/14

Basi di Dati: Corso di laboratorio

OOP: Object Oriented Programming

Introduzione al VHDL Lezione 3

Array in Fortran 90. Ing. Luca De Santis. Anno accademico 2006/2007. DIS - Dipartimento di informatica e sistemistica

Richiami Java e Arrays

Verifica dei programmi

Le basi del linguaggio Java

Capitolo 3 Sviluppo di Programmi Strutturati

Cast implicito. Il cast è fatto automaticamente quando un tipo più basso viene assegnato ad un tipo più alto. byte short int long float double

Fondamenti di Informatica T2 Modulo 2. Corso di Laurea in Ingegneria Informatica Anno accademico 2008/2009. Enumerativi

Tipi di segnali (logici) predefiniti. Rappresentazione dei segnali in VHDL. Tipo bit (definito nel package standard)

Sistemi Operativi 1. Mattia Monga. a.a. 2010/11. Dip. di Informatica e Comunicazione Università degli Studi di Milano, Italia

Esercitazione di lunedì - TUTTE LE MATRICOLE -

19 - Eccezioni. Programmazione e analisi di dati Modulo A: Programmazione in Java. Paolo Milazzo

ECOLE POLYTECHNIQlE FEDERALE DE LAUSANNE

contiene il valore e nel range [l, u]. Funziona correttamente solo se 0 l e u a.

Le interfacce nella OOP ad ereditarietà singola

Graphs: Cycles. Tecniche di Programmazione A.A. 2012/2013

Fondamenti di Informatica

PL/SQL e PLpgSQL. Audiolezione 28b. Necessità. Soluzioni. Embedded SQL. Alfio Ferrara - Stefano Montanelli. Estensioni procedurali di SQL

Le gerarchie di tipi: implementazioni multiple e principio di sostituzione

Excel & VBA. Excel e Visual Basic for Application

Programmazione con Java

Programma del corso. Elementi di Programmazione. Introduzione agli algoritmi. Rappresentazione delle Informazioni. Architettura del calcolatore

A.A. 2006/2007 Laurea di Ingegneria Informatica. Fondamenti di C++ Horstmann Capitolo 3: Oggetti Revisione Prof. M. Angelaccio

Java thread, concorrenza

Sistemi Operativi 1. Lezione IV: Processi e thread. Mattia Monga. 11 marzo 2008

Programmazione lato client. JavaScript. Applicazioni di Rete M. Ribaudo - DISI. JavaScript

UML: Aggregazione. class A { int s; public void sets(int){ }; public int gets() { }; class B {A ob; public void usea() { }; }

Università Ca Foscari Dipartimento di informatica. Programmazione part-time. Esame Ocaml

Università degli Studi di Roma Tor Vergata Facoltà di Ingegneria Corso di Laurea in Ingegneria Informatica. Programmazione orientata agli Oggetti

Programmazione in Java (I modulo) Lezione 21: Classi derivate e l'operatore instanceof Riscrivere il metodo tostring() Riscrivere il metodo equals()

Fondamenti di Programmazione

Informatica (A-K) 5. Algoritmi e pseudocodifica

JavaScript JavaScript Programmazione lato client JScript JavaScript ECMAScript

Fondamenti di Informatica 6. Algoritmi e pseudocodifica

Polimorfismo parametrico vs polimorfismo per inclusione

Catia Trubiani. Laboratorio di Ingegneria del Software a.a

A review of some Java basics. Java pass-by-value and List<> references

Downloading and Installing Software Socio TIS

Transcript:

Sviluppo software in gruppi di lavoro complessi 1 Mattia Lezione VI: Design by Contract Dip. di Informatica Università degli Studi di Milano, Italia mattia.monga@unimi.it Anno accademico 2017/18, I semestre 1 cba 2017 M.. Creative Commons Attribuzione Condividi allo stesso mo 4.0 Internazionale. http://creativecommons.org/licenses/by-sa/4.0/deed.it 1 65 Contratti La tripla di Hoare {P}S{Q} può diventare un contratto fra chi implementa (fornitore) S e chi usa (cliente) S L implementatore di S si impegna a garantire Q in tutti gli stati che soddisfano P L utilizzatore di S si impegna a chiedere il servizio in un stato che soddisfa P ed è certo che se S termina, si giungerà in uno stato in Q vale Il lavoro dell implementatore è particolarmente facile quan: Q è True (vera per ogni risultato!) o quan P è False (l utilizzatore non riuscirà mai a portare il sistema in uno stato in cui tocchi fare qualcosa!). Weakest precondition (data Q) o strongest postcondition (data P) determinano il ruolo di una feature. Un linguaggio object-oriented che introduce i contratti nell interfaccia delle classi. Il contratto di default per un meto ( feature ) F è {True}F {True}. feature decrement is -- Decrease counter by one. item > 0 -- pre-condition item := item - 1 -- implementation item = old item - 1 -- post-condition 66 67

Organizzazione delle asserzioni è esplicitamente progettato come linguaggio di progetto, non solo di programmazione : pre/post-condizioni sulle feature (, ) specify, design, implement and modify quality software [Ecma standard 367] Invarianti di classe (invariant) asserzioni (check) Programmazione in grande con oggetti, derivati da classi organizzate in gerarchie di e raggruppate in cluster, che forniscono feature (command o query) ai loro client. loop invariant (from.. invariant.. until.. variant.. loop.. ) 68 Demo 69 Il supporto del linguaggio invarianti di classe sono condizioni che devono essere vere in ogni momento critico, ossia osservabile dall esterno. In pratica e come se facessero parte di ogni pre- e post-condizione. è possibile avere un supporto run-time alle violazioni: se una condizione non vale viene sollevata un eccezione L eccezione porta il sistema nel precedente stato stabile ed è possibile terminare con un fallimento riprovare class ROOT_TEST_STABLE_STATES create make feature {NONE} secret: BOOLEAN feature {ANY} make -- root class cannot have preconditions -- ok_pre("make") print("executing make%n") mycommand; secret := TRUE ok_post("make") mycommand ok_pre("mycommand") print("executing mycommand%n") secret := FALSE; myother("1"); secret := TRUE -- But what happens if myother is a "client"? -- secret := FALSE; Current.myother("2"); secret := TRUE ok_post("mycommand") myother (s: STRING) ok_pre("myother") print("executing myother " + s + "%N") ok_post("myother") ok_inv: BOOLEAN print("checking ok_inv!%n"); Result := secret; ok_pre (w: STRING): BOOLEAN print("checking ok_pre @ " + w + "%N"); Result := True; ok_post (w: STRING): BOOLEAN print("checking ok_post @ " + w + "%N"); Result := True; invariant ok_inv 70 71

Demo I Demo II class GCD create make feature gcd (x: INTEGER; y: INTEGER): INTEGER positive_parms: x >= 0 and y >= 0 not_zero: x /= 0 or y /= 0 local t: INTEGER if x = 0 or y = 0 then Result := x.max (y) else from Result := x; t := y invariant positive_result: Result > 0 positive_t: t > 0 gcd_inv: mathgcd(x, y) = mathgcd(result, t) until Result = t loop if Result > t then Result := Result - t else t := t - Result variant t.max(result) positive_ris: Result > 0 dividex: x = 0 or else x.integer_remainder(result) = 0 dividey: y = 0 or else y.integer_remainder(result) = 0 Result = x.min(y) or else across ((Result+1).to_integer.. x.min(y)) as ic all (x.integer_remainder(ic.item) /= 0 or y.integer_remainder(ic.item) /= 0) 72 make print("ris: " + gcd(126,294).out + " %N") print("ris: " + gcd(0,294).out + " %N") mathgcd(x,y: INTEGER):INTEGER from Result := x.min(y) until y.integer_remainder(result) = 0 and then x.integer_remainder(result) = 0 loop Result := Result - 1 73 Procedurale vs. Dichiarativo Spesso si scrivono le stesse cose due volte: balance := balance - x Implementazione e specifica How & What balance = old balance - x Il client è responsabile delle precondizioni, il fornitore di postcondizioni e invarianti. Il principio di sostituzione di Liskov stabilisce che, perché un oggetto di una classe derivata soddisfi la relazione is-a, ogni suo meto: deve essere accessibile a pre-condizioni uguali o piú deboli del meto della superclasse; deve garantire post-condizioni uguali o piú forti del meto della superclasse; Altrimenti il figlio non può essere sostituito al padre senza alterare il sistema. 74 75

Principio di sostituibilità Principio di sostituibilità (cont.) Le due condizioni sono quindi: PRE parent = PRE derived (1) POST derived = POST parent (2) (1) in un programma corretto non può succedere che PRE parent valga e PRE derived no; l oggetto evoluto deve funzionare in ogni stato in cui funzionava l originale: non può avere obbligazioni piú stringenti, semmai piú lasche. (2) in un programma corretto non può succedere che valga POST derived ma non POST parent ; un stato corretto dell oggetto evoluto deve essere corretto anche quan ci si atte i benefici dell originale. 76 Un mo per garantire che le condizioni (1) e (2) siano automaticamente vere consiste nell assumere implicitamente che, se la classe evoluta specifica esplicitamente una precondizione P e una postcondizione Q, le reali pre- e post-condizioni siano: PRE derived = PRE parent P (3) POST derived = POST parent Q (4) In : else e then PRE parent = PRE derived POST derived = POST parent 77 Contratti astratti Problema: i parametri... ext (x: G) -- Add `x' at of list. space_available: not full deferred one_more: count = old count + 1 full: BOOLEAN -- Is representation full? -- (Default: no) Result := False Stronger precondition... ma weaker (uguali in realtà) in astratto full: BOOLEAN -- Is representation full? -- (Answer: if and only if -- number of items is equal -- to capacity) Result := (count = capacity) Animale mangia Cibo (is a Cosa) Mucca (is a Animale) mangia Erba (is a Cibo) Ma questa covarianza è contraria al principio di Liskov perché restringe le precondizioni. La controvarianza (Mucca mangia Cosa, Sather) e l invarianza (Mucca mangia Cibo, Java) vanno bene. invece è covariante... (il che, impeden un controllo di conformità statico, introduce parecchie complicazioni CATcall, run time type identification... ). 78 79

Trattamento delle situazioni anomale Anti-pattern Nel modello di hanno un ruolo importante le eccezioni, che vengono trattate in un mo differente da quello dei piú diffusi linguaggi di programmazione (Ada-like). Exception An exception is a run-time event that may cause a routine call to fail (contract violation). A failure of a routine causes an exception in its caller. sqrt (n: REAL): REAL if x < 0.0 then raise Negative else normal_square_root_computation exception when Negative => print("negative argument%n") return when others =>.. In questo caso il meccanismo delle eccezioni è usato come strumento di controllo del flusso! 80 81 Il trattamento delle eccezioni in Esempio Due modalità: div (num: REAL, denom: REAL): REAL denom /= 0 deferred 1 Failure (organized panic): clean up the environment, terminate the call and report failure to the caller. 2 Retry: attempt to change the conditions that led to the exception and to execute the routine again from the start. Per trattare il secon caso, introduce il costrutto rescue/retry. Se il corpo del rescue non fa retry, si ha un failure. 82 quasi_inverse (x: REAL): REAL -- div(1, x) if possible, otherwise 0 local division_tried: BOOLEAN if not division_tried then Result := div (1, x) else Result := 0 rescue division_tried := True retry 83

Correttezza Per ogni feature (pubblica) f : {PRE f INV } body f {POST f INV } {True} rescue f {INV } {True} retry f {INV PRE f } 84