1 / 113

ESC/Java de digital (esc/modula-3) devenu compaq

ESC/Java de digital (esc/modula-3) devenu compaq. ESC/Java version 1.2.4, 27 September 2001 Cnam/Paris jean-michel Douin, douin@cnam.fr Version du 25 Mars 2003 Présentation et exemples d’utilisation Ces notes de cours accompagnent ou précèdent

afric
Télécharger la présentation

ESC/Java de digital (esc/modula-3) devenu compaq

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. ESC/Javade digital (esc/modula-3) devenu compaq ESC/Java version 1.2.4, 27 September 2001 Cnam/Paris jean-michel Douin, douin@cnam.fr Version du 25 Mars 2003 Présentation et exemples d’utilisation Ces notes de cours accompagnent ou précèdent une première lecture manuel d’utilisation de ESC La dernière version est à cette url : http://jfod.cnam.fr/tp_cdi/douin/ESC_Java.pdf

  2. Bibliographie Utilisée L’outil ESC/Java à télécharger, le manuel de l’utilisateur et d’autres documents • http://research.compaq.com/SRC/esc/ Une présentation de Rustan Leino, faite au Static Analysis Symposium 2001, SAS ’01 July, La Sorbonne, Paris • http://www.research.compaq.com/SRC/personal/rustan/papers/ApplicationsOfESC.ppt Les notes de cours de Dwyer et Hatcliff ( le support de « Week 15 et 16 ») • http://www.cis.ksu.edu/~hatcliff/771/ Cours Cnam/CDL B3, notes de J-L Dewez Avril 2002 • http://lmi90.cnam.fr:6666/ESC.pdf ESC/Java et la JavaCard Le travail de erik Poll sur les API Javacard annotées en esc/java • http://www.cs.kun.nl/~erikpoll/publications/jc211_specs.html JavaCard GEMPlus/INRIA : le projet lemme • http://www-sop.inria.fr/lemme/verificard/electronic_purse/ et ftp://ftp-sop.inria.fr/lemme/Marieke.Huisman/paper.ps.gz Esc/java et les Threads La thèse de Cyrille Artho, un comparatif des outils statiques • http://www.inf.ethz.ch/~artho/papers/mthesis.pdf et http://www.inf.ethz.ch/~artho/slides/ArthoBiere-ASWEC2001.pdf De Silvija Seres, Oxford • http://gatekeeper.dec.com/pub/DEC/SRC/technical-notes/SRC-1999-003-html/seres.html A voir ensuite Le projet LOOP : vers la preuve ? • http://www.cs.kun.nl/~bart/LOOP/ JML, Java Modeling language • http://www.cs.iastate.edu/~leavens/JML.html Bandera cours 842, université du Kansas (voir le support Week 7) • http://www.cis.ksu.edu/~hatcliff/842/ Certains éléments de cette liste se trouvent en http://jfod.cnam.fr/tp_cdi/douin/biblio_ESC_Java/

  3. Sommaire • Objectifs • Comment • Présentation: un premier exemple • assert, assume, unreachable, loop_invariant • Programmation par contrats • requires, ensures, modifies (\old, \result, \fresh…) • Invariant de classe • Programmation concurrente • \monitored, \monitored_by, \lockset, \max, e < f, • Conclusion ? • Première étape vers une preuve formelle ? • LOOP, Bandera, …

  4. Objectifs • Approche pragmatique et simple • Annotations en syntaxe java, voir JLS(Java Language Specification) • Aide à la détection d’erreurs « classiques » de programmation • Null, dépassement de bornes,erreur de typage, interblocage, …. • Vérification de la cohérence des annotations et du programme. Attention ce n’est pas une preuve ! • ESC/Java’s extended static checking isn’t perfect (un paragraphe du manuel) • « Vérification » par réfutation : ESC est à la recherche d’erreurs possibles, par un contre-exemple • ==> Annotations des méthodes sensibles, • ==> Commentaires pertinents (sans ambiguïté)

  5. Static program checking Extrait de la présentation de Rustan Leino

  6. Static program checkers Extrait de la présentation de Rustan Leino

  7. ESC architecture Extrait de la présentation de Rustan Leino

  8. Extended Static Checker Architecture Java method + annotations Translator Verification conditions Automatic theorem prover Counterexamples Post-processor Warning messages ESC/Java The translator “understands” the semantics of Java. A verification condition is a logical formula that, ideally, is valid if and only if the program is free of the kinds of error under consideration. The automatic theorem prover is invisible to users. Counterexamples are turned into precise warning messages. Index out of bounds on line 218 Method does not preserve object invariant on line 223

  9. ESC/Java Analyse statique du source Java Invisible au programmeur … • Détection d’erreurs ( qui sont levées d’ordinaire à l’exécution) • null dereferences • Dépassement des bornes d’un tableau • Changement de type hasardeux • … • Cohérence des annotations et du programme • Pre conditions • Post conditions • Invariant de classe • Environnement multi-”thread” • Accès concurrents à une variable non-protégée (Race) • Interblocage (DeadLocks)

  10. Un tout premier exemple public class TestESC1{ public static void test(String[] args){ args[2] = "esc"; } }

  11. Un tout premier exemple public class TestESC1{ public static void test(String[] args){ args[2] = "esc"; } } dos>escjava TestESC1.java ESC/Java version 1.2.4, 27 September 2001 TestESC1 ... TestESC1: test(java.lang.String[]) ... -------------------------------------------------------------- TestESC1.java:3: Warning: Possible null dereference (Null) args[2] = "esc"; ^ --------------------------------------------------------------- TestESC1.java:3: Warning: Array index possibly too large (IndexTooBig) args[2] = "esc"; ^ …

  12. ESC/Java : les options escjava: usage: escjava options* <source files> where options include: -v -bootclasspath <classpath> -classpath <classpath> -depend -f <file containing source file names> -counterexample -loopSafe -loop <iterCount>[.0|.5] -nocheck -notrace -nowarn <category> -plainwarning -quiet -routine <routineId> -routine <fullyQualifiedRoutineSignature> -routineIndirect <routineFile> -start <line#> -suggest -vclimit <n> -warn <category>

  13. Options d’ ESC/Java : un exemple public class TestESC1{ public static void test(String[] args){ args[2] = "esc"; } } dos>escjava –nowarn Null –suggest TestESC1.java ESC/Java version 1.2.4, 27 September 2001 TestESC1 ... TestESC1: test(java.lang.String[]) ... -------------------------------------------------------------- TestESC1.java:6: Warning: Array index possibly too large (IndexTooBig) args[2] = "esc"; ^ Suggestion [6,8]: none -------------------------------------------------------------- …

  14. Annotations • Annotations transformées en formules logiques • Assertions installées, (contrats à respecter) • ou affirmations (hypothèses décidées ) par le spécifieur/programmeur • À l’aide de pragmas • //@ assert une_expression_esc • //@ assume une_expression_esc • … • Les mots-clés utilisés dans les expressions esc sont préfixés par « \ » • \old, \return, \type(T), \typeof(E) … • L’exemple précédent • public class TestESC1{ • public static void test(String[] args){ • //@ assume args != null && args.length == 3; • // attention cette expression est une affirmation ... • args[2] = "esc"; • } • } • dos>escjava TestESC1.java • ==> No Warning

  15. Annotations : Syntaxe • //@ un_pragma_esc • Exemple : //@ assert i >= 0; • /*@ un_pragma_esc une_expression_esc*/ • /*@ //commentaire : plusieurs pragmas • * un_pragma_esc une_expression_esc; • * un_pragma_esc une_expression_esc; • * // un commentaire • */ • /** à l’intérieur d’un commentaire destiné à javadoc • * <esc> un_pragma_esc une_expression_esc </esc> • */ • A voir : dans le manuel de l’utilisateur les possibilités de commentaires imbriqués

  16. Pragmas : classification, expressions ESC • Pragma comme instructions, ( au sens java) • nowarn, assert, assume, unreachable, loop_invariant • Pragma comme modificateurs, • non_null, • spec_public, readable_if, unitialized, • requires, modifies, ensures, exsures, // par méthode • also_requires, also_modifies, also_ensures, also_exsures, // héritage • monitored, monitored_by, // concurrence • … • Pragma comme declarations, • invariant, axiom, • … • Expressions esc : expressions java et • ==> , < = = > , Quantificateurs \forall, \exists, \old , \result, \type(), …. • Déclarations et instructions pour les variables « esc » (appelées ghost variables) • ghost déclarations //@ ghost public Object o; • set instructions //@ set o = this;

  17. Pragma nowarn, lexical • ArrayStore      Invariant       Post Assert          LoopInv         Pre Cast            NegSize         Race Deadlock        NonNull         Reachable Exception       NonNullInit     Unreadable IndexNegative   Null            Uninit IndexTooBig     OwnerNull       ZeroDiv Type des erreurs possibles recherchées par ESC • nowarn L ;opt L peut contenir le ou les items ci-dessus

  18. Pragmas comme instruction • assert • employée comme une instruction Java, l ’assertion doit être vérifiée • assume • l ’expression devient une affirmation, sans aucun contrôle • unreachable • <==> assert false; • loop_invariant • L ’expression est vraie à chaque itération • decreases * • Le variant doit décroître à chaque tour de boucle • loop_predicate * • Les expressions esc sont constituées de : • \forall, \exists, ==>, <==, <==>, <=!=>, … • Exemple : t!=null & (\forall int i; i>=0 & i < t.length ==> t[i] != null) • * pragma non documenté

  19. ESC/Java : premières limites • Les expressions esc ne peuvent contenir des appels de méthodes • « Simplify (le démonstrateur) has no built-in semantics for multiplication, except by constants. » • Attention aux « warning » qui ne semblent pas être justifiés … Warning: Array index possibly too large (IndexTooBig)

  20. Exemple : une copie de tableaux /** CDI cours B3, ED 14, Ex06 Hoare et tableaux */ public class CopieDeTableaux { public static void main(/*@ non_null */String[] args){ int[] t = {1,9,11,15,56,78,89}; //@ assert (\exists int x; x>=0 & x<t.length & t[x]==89); int[] t1 = new int[t.length]; //@ assert t != null & t1 != null; //@ assert t.length == t1.length; int i = 0; int n = t.length-1; //@ loop_invariant (\forall int j; j>=0 & j < i ==> t[j] == t1[j]); while( i <= n){ t1[i] = t[i]; i++; } //@ assert (\forall int j; j>=0 & j <= n ==> t[j] == t1[j]); } }

  21. Variant de boucle : « à la main » public class CopieDeTableaux { public static void main(/*@ non_null */String[] args){ int[] t = {1,9,11,15,56,78,89}; int[] t1 = new int[t.length]; //@ assert t != null & t1 != null; //@ assert t.length == t1.length; int i = 0; int n = t.length-1; //@ loop_invariant (\forall int j; j>=0 & j < i ==> t[j] == t1[j]); while( i <= n){ int v = n+1-i; // le variant v, ici installé dans le code source … //@ assert v > 0 t1[i] = t[i]; i++; //@ assert n+1-i < v; } //@ assert (\forall int j; j>=0 & j <= n ==> t[j] == t1[j]); } }

  22. ghost + variant de boucle public class CopieDeTableaux { //@ ghost public static int v; public static void main(/*@ non_null */String[] args){ int[] t = {1,9,11,15,56,78,89}; int[] t1 = new int[t.length]; //@ assert t != null & t1 != null; //@ assert t.length == t1.length; int i = 0; int n = t.length-1; //@ loop_invariant (\forall int j; j>=0 & j < i ==> t[j] == t1[j]); while( i <= n){ //@ set v = n+1-i; // le variant v, en variable de spécifieur //@ assert v > 0 t1[i] = t[i]; i++; //@ assert n+1-i < variant; } //@ assert (\forall int j; j>=0 & j <= n ==> t[j] == t1[j]); } }

  23. Variant de boucle \decreases public static void main(/*@ non_null */String[] args){ int[] t = {1,9,11,15,56,78,89,89}; //@ assert (\exists int x; x>=0 & x<t.length & t[x]==89); int[] t1 = new int[t.length]; //@ assert t != null & t1 != null; //@ assert t.length == t1.length; int i = 0; int n = t.length-1; //@ loop_invariant (\forall int j; j>=0 & j<i==>t[j]==t1[j]); //@ decreases n-i; // le variant de boucle while( i <= n){ t1[i] = t[i]; i++; } //@ assert (\forall int j; j>=0 & j <= n ==> t[j] == t1[j]); } }

  24. TriDeTableaux public class TriDeTableaux{ public static void main(/*@ non_null */String[] args){ int [] n = {9,1,15,11,56,89,78}; //@ assert n =! null && n.length > 2; boolean sorted = false; while(!sorted){ sorted = true; //@ loop_invariant (\forall int j;(j>=0 & j < i) ==> n[j] <= n[j+1]); //@ decreases n.length-1-i; for(int i = 0; i < n.length-1; i++){ if (n[i] > n[i + 1]){ int temp = n[i]; n[i] = n[i + 1]; n[i + 1] = temp; sorted = false; } //@ assert n[i] <= n[i+1]; } } //@ assert (\forall int j;(j>=0 & j < n.length-1) ==> n[j] <= n[j+1]); }

  25. Affirmations ? affirmatif ! public class TestIf { public static void test(boolean b, int h, int i, int j){ int r; //@ assume i != 0 & b == true; if(b) r = h/i; else r = h/i + h*j; } /*@ axiom (\forall int x, y; x >= 0 & y >= 0 ==> x*y >= 0); */ }

  26. Programmation par Contrats • Un contrat est établi entre l’appelant et l’appelé • Pré-conditions et Post-conditions • qu’une méthode doit respecter • Invariants de classe

  27. Pré/post conditions, invariant de classe • //@ requires • pré-conditions • //@ ensures • post_conditions • //@ modifies • ce qui est modifié par la méthode • //@ exsures • Pour les exceptions • //@ invariant • de classe, vrai avant et après l ’appel de chaque méthode, et vrai après l ’appel d ’un constructeur • \result, \old, \fresh • \result : le résultat d ’une fonction ( en liaison avec modifies) • \old : la valeur avant • \fresh(v) : v nouvelle allocation dans cette méthode • Attention Pas de contrôle du pragma \modifies

  28. La pile (encore), les pré-conditions public class Pile{ private int[] zone; private int ptr; //@ requires taille > 0; public Pile(int taille){ zone = new int[ taille]; } //@ requires ptr < zone.length; // !estPleine(); public void empiler(int elt){ zone[ptr] = elt;ptr++; } //@ requires ptr > 0; // !estVide(); public int depiler(){ ptr--;return zone[ptr]; }

  29. La pile, /*@ spec_public */ public class Pile{ private /*@ spec_public */ int[] zone; private /*@ spec_public */ int ptr; //@ requires taille > 0; public Pile(int taille){ zone = new int[ taille]; } //@ requires ptr < zone.length; public void empiler(int elt){ zone[ptr] = elt;ptr++; } //@ requires ptr > 0; public int depiler(){ ptr--;return zone[ptr]; }

  30. La pile, les post conditions public class Pile{ private /*@ spec_public */ int[] zone; private /*@ spec_public */ int ptr; //@ requires taille > 0; //@ ensures zone != null & ptr == 0 && zone.length == taille; public Pile(int taille){ zone = new int[ taille]; } //@ requires ptr < zone.length; //@ modifies ptr, zone[ptr-1]; //@ ensures \old(ptr) + 1 == ptr && zone[\old(ptr)] == elt; public void empiler(int elt){ zone[ptr] = elt;ptr++; } //@ requires ptr > 0; //@ modifies ptr; //@ ensures \old(ptr)-1==ptr && \result ==zone[ptr]; public int depiler(){ ptr--;return zone[ptr]; }

  31. invariant Quels sont les invariants de cette classe ? • Le champ zone != null • Le champ ptr évolue entre 0 et zone.length • Vrai avant et après l’appel de chaque méthode et en sortie du constructeur Affirmation globale : axiom

  32. La pile , invariant public class Pile{ private /*@ spec_public */ int[] zone; private /*@ spec_public */ int ptr; //@ invariant ptr >= 0 && ptr <= zone.length; //@ invariant zone != null; //@ requires taille > 0; //@ ensures ptr == 0 && zone.length == taille; public Pile(int taille){ zone = new int[ taille]; } //@ requires ptr < zone.length; //@ modifies ptr, zone[ptr-1]; //@ ensures \old(ptr) + 1 == ptr && zone[\old(ptr)] == elt; public void empiler(int elt){ zone[ptr] = elt;ptr++; } //@ requires ptr > 0; //@ modifies ptr; //@ ensures \old(ptr)-1==ptr && \result ==zone[ptr]; public int depiler(){ ptr--;return zone[ptr]; }

  33. Un test … une trace qui déborde public static void main(String[]a){ Pile p = new Pile(2); p.empiler(5); int res = p.depiler(); //@ assert res == 5; p.empiler(3); p.empiler(5); 51 p.empiler(7); … dos>escjava -quiet Pile.java Pile.java:51: Warning: Precondition possibly not established (Pre) p.empiler(7); ^ Associated declaration is "Pile.java", line 13, col 7: //@ requires ptr < zone.length; ^ 1 warning

  34. Un autre exemple : la file, en mode défensif • Défensif • Par des pré-conditions évitant les levées d’exception • pragma exsure • //@ exsures (Exception) false; • En exemple la file (FIFO, complète en annexe 1) • Offensif • Par la levée d’exception spécifiée comme impossible, • try{ • }catch(Exception e){ • @unreachable; • } • Puis suppression du code devenu inutile ... Comme le try/catch

  35. Une file : la déclaration public class FileInt{ private /*@ spec_public */ int[] zone; private /*@ spec_public */ int entree,sortie; private /*@ spec_public */ int taille; //@ requires capacite > 0; //@ ensures \fresh(this); //@ ensures entree == 0 && sortie == 0 && taille==0; //@ ensures zone.length == capacite; public FileInt(int capacite){ zone = new int[ capacite]; }

  36. Une file : la méthode enfiler //@ requires taille < zone.length; //@ modifies entree, taille, zone[*]; //@ ensures (\old(entree) + 1) % zone.length==entree; //@ ensures zone[\old(entree)] == elt; //@ ensures \old(taille) + 1 == taille; //@ exsures (FilePleineException) false; public void enfiler(int elt) throws FilePleineException{ if (filePleine()) throw new FilePleineException(); zone[entree] = elt; entree = (entree+1) % zone.length; taille++; } L’exception ne peut être levée //@ exsures (FilePleineException) false;

  37. Une file : le test public static void main(String[]a) FileInt f = new FileInt(3); try{ f.enfiler(3); f.enfiler(3); f.enfiler(4); • …… • …. • …. }catch(FilePleineException e){ //@unreachable; } En offensif, levée d’exception et bloc try/catch sont supprimés

  38. Typage et hiérarchie • \typeof(E), ==, <:, \elemtype(\typeof(E)), \type(T) //@ requires \typeof(elt) == \type(Integer); public m( Integer elt){ … Le type des éléments doit être « Integer »   //@ requires \typeof(elt) <: \type(Integer); public m( Integer elt){ … Le type des éléments doit appartenir au graphe dont la racine est la classe « Integer » le type des éléments d ’un tableau   //@ requires \typeof(elt) <: \elemtype(\typeof(zone)); //@ requires \typeof(elt) <: \typeof(zone[]);

  39. La pile d’Integer public class PileInteger{ private /*@ spec_public */ Integer[] zone; private /*@ spec_public */ int ptr; //@ invariant ptr >= 0 && ptr <= zone.length; //@ invariant zone != null; //@ requires taille > 0; //@ ensures ptr == 0 && zone.length == taille; public PileInteger(int taille){ zone = new Integer[ taille];} //@ requires ptr < zone.length; //@ requires elt != null && \typeof(elt) <:\elementype(\typeof(zone)); //@ modifies ptr, zone[ptr-1]; //@ ensures \old(ptr) + 1 == ptr && zone[\old(ptr)] == elt; public void empiler(Integer elt){ zone[ptr] = elt;ptr++; } /** <esc>requires ptr < zone.length; </esc><br> * <esc>modifies ptr, zone[ptr- 1];</esc> **/ public void empiler(int elt){ empiler(new Integer(elt)); }

  40. La pile d’Integer suite //@ requires ptr > 0; //@ modifies ptr; //@ ensures \old(ptr)-1==ptr && \result ==zone[ptr]; public Integer depiler(){ ptr--; return zone[ptr]; } public static void main(String[]a){ PileInteger p = new PileInteger(2); p.empiler(new Integer(6)); p.empiler(new Integer(5)); Integer i = p.depiler();; //@ assert i.value == 5; } ? Accès au champ value de la classe Integer ? si le champ value est déclaré /*@ spec_public */

  41. java/lang/Integer.spec • Fichier .spec ? • Fichier .spec si le source n’est pas disponible Pour que le champ value soit pris en compte • Légère modification de java.util.Integer.spec

  42. Integer.spec : la modification Répertoire java.lang; (voir escjava-specs-1.2.4-win.zip) package java.lang; public class Integer extends Number{ … private /*@spec_public */ int value; … //@ensures this.value==value; public Integer(int value) { this.value = value; } …

  43. Partage des champs d’instances p1 et p2 deux instances … Le démonstrateur utilise BrokenObj afin de démontrer qu’une erreur de partage est possible • Ici partage entre deux instances de la même zone • En fonction de la spécification, cela peut engendrer des erreurs d’accès possibles… • ESC suppose aussi qu’un accès concurrent est toujours possible … p1 p2 BrokenObj

  44. Exemple avec partage de « obj » public class TestOwner{ private /*@ spec_public */ Object obj; //@ ensures obj != null; public TestOwner(){ obj = new Object(); } public static void test(){ TestOwner t1 = new TestOwner(); TestOwner t2 = new TestOwner(); t1.obj = t2.obj; // ici on partage //@ assert t1.obj == t2.obj; } }

  45. ghost public Object owner Le spécifieur/programmeur indique alors quel est le propriétaire de zone, Pour cela il existe une variable ghost particulière : owner, déclarée dans la classe Object (java/lang/Object.spec) public class Object { /** ** The Object that has a field pointing to this Object. ** Used to specify (among other things) injectivity (see ** the ESC/Java User's Manual. **/ //@ ghost public Object owner; ……

  46. Exemple avec partage impossible de « obj » public class TestOwner{ private /*@ spec_public */ Object obj; //@ invariant this.obj.owner == this; //@ ensures obj != null; public TestOwner(){ obj = new Object(); //@ set obj.owner = this; } public static void test(){ TestOwner t1 = new TestOwner(); TestOwner t2 = new TestOwner(); t1.obj = t2.obj; // ici on ne partage plus //@ assert t1.obj == t2.obj; } }

  47. Le message devient explicite … TestOwner.java:18: Warning: Possible violation of object invariant (Invariant) } ^ Associated declaration is "TestOwner.java", line 4, col 6: //@ invariant this.obj.owner == this; ^ Possibly relevant items from the counterexample context: (after@13.20-13.20 <= vAllocTime(brokenObj.(obj:16.8))) (alloc <= vAllocTime(brokenObj.(obj@pre:2.39))) (vAllocTime(brokenObj) < after@13.20-13.20) (alloc <= vAllocTime(brokenObj)) typeof(brokenObj.(obj@pre:2.39)) <: T_java.lang.Object (RES-14.20:14.20).(obj@pre:2.39) == brokenObj.(obj:16.8) // 10 lignes plus bas … brokenObj != null (brokenObj* refers to the object for which the invariant is broken.) Suggestion [18,2]: none

  48. L’exemple de manuel public class PileObject{ private /*@ non_null *//*@ spec_public */ Object[] zone; private /*@ spec_public */ int ptr; //@ invariant ptr >= 0 && ptr <= zone.length; //@ invariant zone != null; //@ invariant (\forall int i; i>=ptr & i<this.zone.length ==> this.zone[i] == null); //@ invariant \elemtype(\typeof(zone)) == \type(Object); //@ requires taille > 0; //@ ensures ptr == 0 && zone.length == taille; public PileObject(int taille){ zone = new Object[ taille]; } //@ requires ptr < zone.length; public void empiler(Object elt){zone[ptr] = elt;ptr++;} //@ requires ptr > 0; public Object depiler(){ ptr--;Object obj = zone[ptr]; zone[ptr] = null; return obj; }

  49. L’exemple en images La pile p null null null null p.ptr null « 3 » « 2 » p.zone //@ invariant (\forall int i; i>=ptr & i<this.zone.length ==> this.zone[i] == null);

  50. Recherche d’une erreur La pile p Prenons Pile brokenObj si brokenObj.ptr = p.ptr; brokenObj.zone = p.zone; et p.empiler(new Integer(4)); alors l’invariant est faux null null null null p.ptr brokenObj.ptr « 4 » « 3 » « 2 » p.zone /*@ invariant (\forall int i; i>=ptr & i<this.zone.length ==> this.zone[i] == null); */

More Related