/*@ also @ public normal_behavior @ requires obj != null && obj instanceof JMLEqualsToEqualsRelation; @ ensures \result == @ this.theRelation.equals( @ ((JMLEqualsToEqualsRelation)obj).theRelation); @ also @ public normal_behavior @ requires obj == null @ || !(obj instanceof JMLEqualsToEqualsRelation); @ ensures !\result; @*/ public boolean equals(/*@ nullable @*/ Object obj) { if (obj == null || !(obj instanceof JMLEqualsToEqualsRelation)) { return false; } JMLEqualsToEqualsRelation rel = (JMLEqualsToEqualsRelation) obj; if (size_ != rel.int_size()) { return false; } JMLEqualsToEqualsRelationImageEnumerator imagePairEnum = this.imagePairs(); JMLEqualsValuePair imagePair; JMLEqualsSet img; while (imagePairEnum.hasMoreElements()) { imagePair = imagePairEnum.nextImagePair(); // @ assume imagePair.value != null; // @ assume imagePair.value instanceof JMLEqualsSet; img = (JMLEqualsSet) imagePair.value; if (!img.equals(rel.elementImage(imagePair.key))) { return false; } } return true; }
/*@ public normal_behavior @ requires othRel != null; @ ensures (\forall JMLValueEqualsPair pair; ; @ \result.theRelation.has(pair) @ == (\exists Object val; @ othRel.elementImage(pair.key).has(val); @ this.elementImage(val).has(pair.value) @ ) @ ); @*/ public /*@ non_null @*/ JMLObjectToEqualsRelation compose( /*@ non_null @*/ JMLObjectToEqualsRelation othRel) { JMLValueSet newImagePairSet = new JMLValueSet(); JMLObjectSet newDom = new JMLObjectSet(); int newSize = 0; JMLObjectToEqualsRelationImageEnumerator imagePairEnum = othRel.imagePairs(); JMLObjectValuePair imagePair; JMLEqualsSet img1; JMLEqualsSet img2; int imgSize; while (imagePairEnum.hasMoreElements()) { imagePair = imagePairEnum.nextImagePair(); // @ assume imagePair.value != null; // @ assume imagePair.value instanceof JMLEqualsSet; img1 = (JMLEqualsSet) imagePair.value; img2 = this.image(img1); imgSize = img2.int_size(); if (imgSize > 0) { newImagePairSet = newImagePairSet.insert(new JMLObjectValuePair(imagePair.key, img2)); newSize = newSize + imgSize; newDom = newDom.insert(imagePair.key); } } return new JMLObjectToEqualsRelation(newImagePairSet, newDom, newSize); } // @ nowarn Exception;
/*@ public normal_behavior @ ensures (\forall Object dv; dv != null; @ (this.isDefinedAt(dv) == \result.isDefinedAt(dv)) @ && \result.elementImage(dv).isSubset(this.elementImage(dv)) @ && \result.elementImage(dv).int_size() == 1); @*/ public /*@ non_null @*/ JMLEqualsToEqualsMap toFunction() { JMLEqualsSet newDom = domain_; int newSize = domain_.int_size(); JMLValueSet newImagePairSet = imagePairSet_; if (newSize != size_) { // Have to restrict the result to be a function JMLEqualsToEqualsRelationImageEnumerator imagePairEnum = this.imagePairs(); newImagePairSet = new JMLValueSet(); JMLEqualsValuePair imagePair; JMLEqualsSet img; while (imagePairEnum.hasMoreElements()) { imagePair = imagePairEnum.nextImagePair(); // @ assume imagePair.value != null; // @ assume imagePair.value instanceof JMLEqualsSet; img = (JMLEqualsSet) imagePair.value; Enumeration imgEnum = img.elements(); // @ assume imgEnum.moreElements; Object o = imgEnum.nextElement(); if (o == null) { img = new JMLEqualsSet(null); } else { // @ assume o != null && o instanceof Object; Object rv = (Object) o; img = new JMLEqualsSet(rv); } newImagePairSet = newImagePairSet.insert(new JMLEqualsValuePair(imagePair.key, img)); } } return new JMLEqualsToEqualsMap(newImagePairSet, newDom, newSize); } // @ nowarn Exception;
/*@ public normal_behavior @ ensures (\forall Object rv; ; @ \result.has(rv) @ == (\exists Object dv; ; @ elementImage(dv).has(rv)) @ ); @*/ public /*@ non_null @*/ JMLEqualsSet range() { JMLEqualsSet rangeSet = new JMLEqualsSet(); JMLEqualsToEqualsRelationImageEnumerator imagePairEnum = this.imagePairs(); JMLEqualsValuePair imagePair; JMLEqualsSet img; while (imagePairEnum.hasMoreElements()) { imagePair = imagePairEnum.nextImagePair(); // @ assume imagePair.value != null; // @ assume imagePair.value instanceof JMLEqualsSet; img = (JMLEqualsSet) imagePair.value; rangeSet = rangeSet.union(img); } return rangeSet; } // @ nowarn Exception;
/*@ public normal_behavior @ requires rng != null; @ ensures \result.equals(inverse().image(rng)); @ @ implies_that @ ensures \result != null && !\result.containsNull; @*/ public /*@ non_null @*/ JMLEqualsSet inverseImage(/*@ non_null @*/ JMLEqualsSet rng) { JMLEqualsSet invImg = new JMLEqualsSet(); JMLEqualsToEqualsRelationImageEnumerator imagePairEnum = this.imagePairs(); JMLEqualsValuePair imagePair; // @ loop_invariant !invImg.containsNull; while (imagePairEnum.hasMoreElements()) { // @ nowarn LoopInv; imagePair = imagePairEnum.nextImagePair(); // @ assume imagePair.value != null && imagePair.key != null; // @ assume imagePair.value instanceof JMLEqualsSet; JMLEqualsSet img = (JMLEqualsSet) imagePair.value; if (!img.intersection(rng).isEmpty()) { invImg = invImg.insert(imagePair.key); } } return invImg; } // @ nowarn Exception;
/*@ public normal_behavior @ requires dv != null && rv != null; @ requires int_size() < Integer.MAX_VALUE || elementImage(dv).has(rv); @ ensures \result.theRelation.equals( @ this.theRelation.insert(new JMLEqualsEqualsPair(dv, rv))); @*/ public /*@ pure @*/ /*@ non_null @*/ JMLEqualsToEqualsRelation add( /*@ non_null @*/ Object dv, /*@ non_null @*/ Object rv) throws NullPointerException, IllegalStateException { if (rv == null) { throw new NullPointerException(); } JMLValueSet newImagePairSet; JMLEqualsSet newDom; int newSize; JMLEqualsSet img; if (!domain_.has(dv)) { if (size_ == Integer.MAX_VALUE) { throw new IllegalStateException(TOO_BIG_TO_INSERT); } newDom = domain_.insert(dv); newSize = size_ + 1; img = new JMLEqualsSet(rv); newImagePairSet = imagePairSet_.insert(new JMLEqualsValuePair(dv, img)); } else { newImagePairSet = new JMLValueSet(); newDom = domain_; newSize = 0; JMLEqualsToEqualsRelationImageEnumerator imagePairEnum = this.imagePairs(); JMLEqualsValuePair imagePair; while (imagePairEnum.hasMoreElements()) { imagePair = imagePairEnum.nextImagePair(); // @ assume imagePair.value != null; // @ assume imagePair.value instanceof JMLEqualsSet; img = (JMLEqualsSet) imagePair.value; if (imagePair.keyEquals(dv)) { img = img.insert(rv); } int size_inc = img.int_size(); if (newSize <= Integer.MAX_VALUE - size_inc) { newSize = newSize + size_inc; } else { throw new IllegalStateException(TOO_BIG_TO_INSERT); } newImagePairSet = newImagePairSet.insert(new JMLEqualsValuePair(imagePair.key, img)); } } return new JMLEqualsToEqualsRelation(newImagePairSet, newDom, newSize); }
/*@ public normal_behavior @ requires dom != null; @ ensures (\forall Object o; \result.has(o) @ <==> (\exists JMLEqualsEqualsPair pair; @ theRelation.has(pair); @ dom.has(pair.key) && pair.valueEquals(o))); @ ensures_redundantly @ (\forall JMLEqualsEqualsPair pair; @ theRelation.has(pair); @ dom.has(pair.key) ==> \result.has(pair.value)); @ @ implies_that @ ensures \result != null && !\result.containsNull; @*/ public /*@ non_null @*/ JMLEqualsSet image(/*@ non_null @*/ JMLEqualsSet dom) { JMLEqualsSet img = new JMLEqualsSet(); JMLEqualsToEqualsRelationImageEnumerator imagePairEnum = this.imagePairs(); JMLEqualsValuePair imagePair; // @ loop_invariant !img.containsNull; while (imagePairEnum.hasMoreElements()) { imagePair = imagePairEnum.nextImagePair(); // @ assume imagePair.value != null; // @ assume imagePair.value instanceof JMLEqualsSet; if (dom.has(imagePair.key)) { JMLEqualsSet ipv = (JMLEqualsSet) imagePair.value; // @ assume !ipv.containsNull; img = img.union(ipv); } } return img; } // @ nowarn Exception;
/*@ public normal_behavior @ requires rng != null; @ ensures (\forall JMLEqualsEqualsPair pair; ; @ \result.theRelation.has(pair) @ == rng.has(pair.value) @ && elementImage(pair.key).has(pair.value) @ ); @*/ public /*@ non_null @*/ JMLEqualsToEqualsRelation restrictRangeTo( /*@ non_null @*/ JMLEqualsSet rng) { JMLValueSet newImagePairSet = new JMLValueSet(); JMLEqualsSet newDom = new JMLEqualsSet(); int newSize = 0; JMLEqualsToEqualsRelationImageEnumerator imagePairEnum = this.imagePairs(); JMLEqualsValuePair imagePair; JMLEqualsSet img; while (imagePairEnum.hasMoreElements()) { imagePair = imagePairEnum.nextImagePair(); // @ assume imagePair.value != null; // @ assume imagePair.value instanceof JMLEqualsSet; img = ((JMLEqualsSet) imagePair.value).intersection(rng); if (!img.isEmpty()) { newImagePairSet = newImagePairSet.insert(new JMLEqualsValuePair(imagePair.key, img)); newDom = newDom.insert(imagePair.key); newSize = newSize + img.int_size(); } } return new JMLEqualsToEqualsRelation(newImagePairSet, newDom, newSize); } // @ nowarn Exception;
/*@ public normal_behavior @ requires dom != null; @ ensures (\forall JMLEqualsEqualsPair pair; pair != null; @ \result.theRelation.has(pair) == dom.has(pair.key) @ && elementImage(pair.key).has(pair.value) @ ); @*/ public /*@ non_null @*/ JMLEqualsToEqualsRelation restrictDomainTo( /*@ non_null @*/ JMLEqualsSet dom) { JMLValueSet newImagePairSet = new JMLValueSet(); JMLEqualsSet newDom = domain_.intersection(dom); // @ assume (\forall Object dv; newDom.has(dv); dv != null); int newSize = 0; JMLEqualsToEqualsRelationImageEnumerator imagePairEnum = this.imagePairs(); JMLEqualsValuePair imagePair; JMLEqualsSet img; while (imagePairEnum.hasMoreElements()) { imagePair = imagePairEnum.nextImagePair(); // @ assume imagePair.value != null; // @ assume imagePair.value instanceof JMLEqualsSet; if (newDom.has(imagePair.key)) { newImagePairSet = newImagePairSet.insert(imagePair); img = (JMLEqualsSet) imagePair.value; newSize = newSize + img.int_size(); } } return new JMLEqualsToEqualsRelation(newImagePairSet, newDom, newSize); } // @ nowarn Exception;
/*@ public normal_behavior @ ensures \result != null @ && (\forall Object val; domain().has(val); @ (\forall Object r; r != null; @ (elementImage(val).has(r) @ <==> \result.theRelation @ .has(new JMLEqualsEqualsPair(val,r)) @ && !val.equals(dv)))); @ implies_that @ public normal_behavior @ requires dv == null; @ ensures \result != null && \result.equals(this); @*/ public /*@ non_null @*/ JMLEqualsToEqualsRelation removeFromDomain(/*@ nullable @*/ Object dv) { if (!domain_.has(dv)) { return (this); } JMLValueSet newImagePairSet = new JMLValueSet(); JMLEqualsSet newDom = domain_.remove(dv); int newSize = 0; JMLEqualsToEqualsRelationImageEnumerator imagePairEnum = this.imagePairs(); JMLEqualsValuePair imagePair; while (imagePairEnum.hasMoreElements()) { imagePair = imagePairEnum.nextImagePair(); // @ assume imagePair.value != null; // @ assume imagePair.value instanceof JMLEqualsSet; if (!imagePair.keyEquals(dv)) { newImagePairSet = newImagePairSet.insert(imagePair); JMLEqualsSet img = (JMLEqualsSet) imagePair.value; newSize = newSize + img.int_size(); } } return new JMLEqualsToEqualsRelation(newImagePairSet, newDom, newSize); } // @ nowarn Exception;
/*@ public normal_behavior @ requires othRel != null; @ requires int_size() @ < Integer.MAX_VALUE - othRel.difference(this).int_size(); @ ensures \result.theRelation.equals( @ this.theRelation.union(othRel.theRelation)); @*/ public /*@ non_null @*/ JMLEqualsToEqualsRelation union( /*@ non_null @*/ JMLEqualsToEqualsRelation othRel) throws IllegalStateException { JMLValueSet newImagePairSet = new JMLValueSet(); JMLEqualsSet newDom = domain_; int newSize = 0; JMLEqualsToEqualsRelationImageEnumerator imagePairEnum = this.imagePairs(); JMLEqualsValuePair imagePair; JMLEqualsSet img; while (imagePairEnum.hasMoreElements()) { imagePair = imagePairEnum.nextImagePair(); // @ assume imagePair.value != null; // @ assume imagePair.value instanceof JMLEqualsSet; img = (JMLEqualsSet) imagePair.value; img = img.union(othRel.elementImage(imagePair.key)); newImagePairSet = newImagePairSet.insert(new JMLEqualsValuePair(imagePair.key, img)); int size_inc = img.int_size(); if (newSize <= Integer.MAX_VALUE - size_inc) { newSize = newSize + size_inc; } else { throw new IllegalStateException(TOO_BIG_TO_UNION); } } JMLEqualsSet diffDom = othRel.domain().difference(this.domain_); imagePairEnum = othRel.imagePairs(); while (imagePairEnum.hasMoreElements()) { imagePair = imagePairEnum.nextImagePair(); // @ assume imagePair.value != null; // @ assume imagePair.value instanceof JMLEqualsSet; if (diffDom.has(imagePair.key)) { newImagePairSet = newImagePairSet.insert(imagePair); newDom = newDom.insert(imagePair.key); // @ assume imagePair.value != null; // @ assume imagePair.value instanceof JMLEqualsSet; img = (JMLEqualsSet) imagePair.value; int size_inc = img.int_size(); if (newSize <= Integer.MAX_VALUE - size_inc) { newSize = newSize + size_inc; } else { throw new IllegalStateException(TOO_BIG_TO_UNION); } } } return new JMLEqualsToEqualsRelation(newImagePairSet, newDom, newSize); }
/*@ public normal_behavior @ requires dv != null && rv != null; @ ensures \result.theRelation.equals( @ theRelation.remove(new JMLEqualsEqualsPair(dv, rv))); @ also @ requires dv == null || rv == null; @ ensures \result != null && \result.equals(this); @*/ public /*@ non_null @*/ JMLEqualsToEqualsRelation remove(Object dv, Object rv) { if (!domain_.has(dv)) { return (this); } // @ assume dv != null; JMLValueSet newImagePairSet = new JMLValueSet(); JMLEqualsSet newDom = domain_; int newSize = 0; JMLEqualsToEqualsRelationImageEnumerator imagePairEnum = this.imagePairs(); JMLEqualsValuePair imagePair; JMLEqualsSet img; while (imagePairEnum.hasMoreElements()) { imagePair = imagePairEnum.nextImagePair(); // @ assume imagePair.value != null; // @ assume imagePair.value instanceof JMLEqualsSet; img = (JMLEqualsSet) imagePair.value; int imgSize = img.int_size(); if (imagePair.keyEquals(dv)) { img = img.remove(rv); imgSize = img.int_size(); if (imgSize > 0) { newImagePairSet = newImagePairSet.insert(new JMLEqualsValuePair(dv, img)); newSize = newSize + imgSize; } else { // @ assert imgSize == 0; newDom = newDom.remove(dv); } } else { newImagePairSet = newImagePairSet.insert(imagePair); newSize = newSize + imgSize; } } return new JMLEqualsToEqualsRelation(newImagePairSet, newDom, newSize); } // @ nowarn Exception;
/*@ public normal_behavior @ ensures \result <==> domain().has(dv) && elementImage(dv).has(rv); @ ensures_redundantly dv == null || rv == null ==> !\result; @*/ public /*@ pure @*/ boolean has(/*@ nullable @*/ Object dv, /*@ nullable @*/ Object rv) { // @ assume domain_.has(dv) ==> dv != null; return domain_.has(dv) && elementImage(dv).has(rv); }
/*@ public normal_behavior @ ensures \result == (elementImage(dv).int_size() > 0); @ ensures_redundantly dv == null ==> !\result; @*/ public boolean isDefinedAt(Object dv) { return domain_.has(dv); }
/*@ public normal_behavior @ ensures \result == (\forall Object dv; isDefinedAt(dv); @ elementImage(dv).int_size() == 1); @*/ public boolean isaFunction() { return size_ == domain_.int_size(); }
/*@ public normal_behavior @ ensures \result.equals(domain().elements()); @*/ public /*@ non_null @*/ JMLEqualsSetEnumerator domainElements() { return domain_.elements(); }