/* * add x as a new member to this set. * If x is already a member, then self should not be changed * Be sure to restore the design invariant property that elemnts[] remains sorted * (yes, you can assume it is sorted when the function is called, that's what an invariant is all about) */ void insertSet(Set* self, int x) { int* setArr = (int*)malloc((self->len+1) * sizeof(int)); //allocate space for the new set int i = 0; bool isInserted = false; //just checking if x has already been inserted into the set //if self is empty dont check just insert if (isEmptySet(self)) { self->len += 1; //increment length setArr[0] = x; //insert } else { while (i < (self->len)) { if (self->elements[i] == x) { //if any element of the set is eql to x return free(setArr); return; } else { //if the ith element is less than x then if (self->elements[i] < x) { setArr[i] = self->elements[i]; i++; } else { //if ith element is greater than x then setArr[i] = x; //ith becomes x and the rest of the elements will be coppied isInserted = true; for (int j = i; j < self->len; j++) { setArr[j + 1] = self->elements[j]; //j+1 is because x has been inserted } self->len += 1; //update the set length i = self->len; //to break the while loop free(self->elements); //after finihsing setting up the temp set free up the old set } } } //if x hasn't already been inserted, then do it if (isInserted == false) { setArr[self->len] = x; //insert self->len++; //increment length } } self->elements = setArr; //copy the new array to the set }
/* remove all elements from self that are not also elements of other */ void intersectFromSet(Set* self, const Set* other) { if (isEmptySet(self)) { return; } //can't remove anything from empty set if (isEqualToSet (self, other)) { return; } //all elements aready in common if (isSubsetOf (self, other)) { return; } //everything in self is in other, nothing to remove if (self == other) { return; } //all elements already in common /*code here*/ //have two sets (one a copy of self), if they don't match increase other index until they do, if they match add to self and increase both indicies //might have to recreate remove code/subset code here Set copy_set; createCopySet (©_set, self); copy_set.capacity = copy_set.len; destroySet (self); self->elements = (int*) malloc (copy_set.capacity * sizeof (int)); //copy original set into copy_set and rebuild self int copy_index = 0; int other_index = 0; int self_index = 0; while (copy_index < copy_set.len && other_index < other->len) { if (copy_set.elements[copy_index] < other->elements[other_index]) { copy_index += 1; } else if (copy_set.elements[copy_index] > other->elements[other_index]) { other_index += 1; } else if (copy_set.elements[copy_index] == other->elements[other_index]) { self->elements[self_index] = copy_set.elements[copy_index]; self_index += 1; copy_index += 1; other_index += 1; } } self->len = self_index; self->capacity = copy_set.capacity; destroySet (©_set); //assert (checkValidSet (self)); //test code, remove later }
MyConstantRange binaryOr(const MyConstantRange &Other) const { if (isEmptySet() || Other.isEmptySet()) return MyConstantRange(getBitWidth(), /*isFullSet=*/false); if (!isWrappedSet() && !Other.isWrappedSet() && !isFullSet() && !Other.isFullSet()) { unsigned width1 = ((getUpper() - 1) ^ getLower()).getActiveBits(); unsigned width2 = ((Other.getUpper() - 1) ^ Other.getLower()).getActiveBits(); APInt res1 = getLower().lshr(width1) << width1; APInt res2 = Other.getLower().lshr(width2) << width2; APInt res_high1 = getLower(); APInt res_high2 = Other.getLower(); res_high1.setLowBits(width1); res_high2.setLowBits(width2); if ((res1 | res2).isNullValue() && (res_high1 | res_high2).isAllOnesValue()) { return MyConstantRange(getBitWidth(), /*isFullSet=*/true); } return MyConstantRange(res1 | res2, (res_high1 | res_high2) + 1); } APInt umax = APIntOps::umax(getUnsignedMin(), Other.getUnsignedMin()); if (umax.isNullValue()) return MyConstantRange(getBitWidth(), /*isFullSet=*/true); return MyConstantRange(std::move(umax), APInt::getNullValue(getBitWidth())); }
MyConstantRange binaryAnd(const ConstantRange &Other) const { if (isEmptySet() || Other.isEmptySet()) return MyConstantRange(getBitWidth(), /*isFullSet=*/false); if (!isWrappedSet() && !Other.isWrappedSet() && !isFullSet() && !Other.isFullSet()) { unsigned width1 = ((getUpper() - 1) ^ getLower()).logBase2() + 1; unsigned width2 = ((Other.getUpper() - 1) ^ Other.getLower()).logBase2() + 1; APInt res1 = getLower().lshr(width1) << width1; APInt res2 = Other.getLower().lshr(width2) << width2; APInt res_high1 = getLower(); APInt res_high2 = Other.getLower(); res_high1.setLowBits(width1); res_high2.setLowBits(width2); if ((res1 & res2).isNullValue() && (res_high1 & res_high2).isAllOnesValue()) { return MyConstantRange(getBitWidth(), /*isFullSet=*/true); } return MyConstantRange(res1 & res2, (res_high1 & res_high2) + 1); } APInt umin = APIntOps::umin(Other.getUnsignedMax(), getUnsignedMax()); if (umin.isAllOnesValue()) return MyConstantRange(getBitWidth(), /*isFullSet=*/true); return MyConstantRange(APInt::getNullValue(getBitWidth()), std::move(umin) + 1); }
/* remove all elements from self that are also elements of other */ void subtractFromSet(Set* self, const Set* other) { if (isEmptySet(self)) { return; } //can't remove anything from empty set if (isEmptySet(other)) { return; } //nothing to remove from self if (isSubsetOf (self, other)) { createEmptySet (self); return; } /*code here*/ //have two sets (one a copy of self), //might have to recreate remove code/subset code here /*Set intersect_set; createCopySet (&intersect_set, self); intersect_set.capacity = intersect_set.len; intersectFromSet (&intersect_set, other); //create temporary set with intersection of self and other */ Set copy_set; createCopySet (©_set, self); copy_set.capacity = copy_set.len; destroySet (self); self->elements = (int*) malloc (copy_set.capacity * sizeof (int)); //copy original set into copy_set and rebuild self /*int intersect_index = 0; int self_index = 0; int copy_index = 0; while (copy_index < copy_set.len) { if (copy_set.elements[copy_index] == intersect_set.elements[intersect_index]) { intersect_index += 1; copy_index += 1; } else if (intersect_index >= intersect_set.len || copy_set.elements[copy_index] < intersect_set.elements[intersect_index]) { self->elements[self_index] = copy_set.elements[copy_index]; copy_index += 1; self_index += 1; } else if (copy_set.elements[copy_index] > intersect_set.elements[intersect_index]) { intersect_index += 1; } }*/ int copy_index = 0; int self_index = 0; int other_index = 0; while (copy_index < copy_set.len) { if (other_index >= other->len || copy_set.elements[copy_index] < other->elements[other_index]) { self->elements[self_index] = copy_set.elements[copy_index]; self_index += 1; copy_index += 1; } else if (copy_set.elements[copy_index] > other->elements[other_index]) { other_index += 1; } else { copy_index += 1; other_index += 1; } } self->len = self_index; self->capacity = copy_set.capacity; destroySet (©_set); /*destroySet (&intersect_set);*/ //assert (checkValidSet (self)); //test code, remove later }
/* add all elements of other to self (obviously, without creating duplicate elements) */ void unionInSet(Set* self, const Set* other) { int* temp =(int*)malloc(sizeof(int) * (self->len + other->len)); //create a temp arr int* tempAddress = temp; //copy of the temp for later reference int i = 0, j = 0, newLen = 0; //two indeces for both sets //search throguh the sets until we reached the end of either of the sets //if the 1st set is empty then return the second set if (isEmptySet(self)) { //if both are empty just return the first set if (isEmptySet(self) && isEmptySet(other)) { free(temp); //freeup temporary return; } self->len = other->len; //copy elements of other to temp one by one for (int i = 0; i < other->len; i++){ temp[i] = other->elements[i]; } free(self->elements); self->elements = temp; //update address of self temp = tempAddress = 0; return; } //if the second set is zero just return if (isEmptySet(other)) { free(temp); //free up temporary coz unused return; } while (i != self->len && j != other->len) { if (self->elements[i] < other->elements[j]) { *temp = self->elements[i]; // if both elements are eql then it gonna be added to the intersection set (i.e. temp) ++temp; //increment temp ++newLen; //increment the length of the intersection set ++i; //if ith el of self is less then move to the next el } else { if (other->elements[j] < self->elements[i]) { *temp = other->elements[j]; // if both elements are eql then it gonna be added to the intersection set (i.e. temp) ++temp; //increment temp ++newLen; //increment the length of the intersection set ++j; //if jth el of other is less then move to the next el } else { *temp = self->elements[i]; // if both elements are eql then it gonna be added to the intersection set (i.e. temp) ++temp; //increment temp ++newLen; //increment the length of the intersection set ++i; //increment conters ++j; } } } //if either hasn't finished if (i != self->len) { while (i != self->len) { *temp = self->elements[i]; // if both elements are eql then it gonna be added to the intersection set (i.e. temp) ++temp; //increment temp ++newLen; //increment the length of the intersection set ++i; //if ith el of self is less then move to the next el } } if (j != other->len) { while(j != other->len) { *temp = other->elements[j]; // if both elements are eql then it gonna be added to the intersection set (i.e. temp) ++temp; //increment temp ++newLen; //increment the length of the intersection set ++j; //if jth el of other is less then move to the next el } } free(self->elements); //free up the old set before setting it eql to the new set self->elements = tempAddress; //update the address of intersection set tempAddress = temp = 0; //destroy the pointer self->len = newLen; //update the length of intersection set }
void specialCaseTests(void) { Set empty; Set universal; int i; Set s; Set r; createEmptySet(&empty); createEmptySet(&universal); createEmptySet(&r); for (i = 0; i < maximum_set_size; i += 1) { insertSet(&universal, i); } checkCase(&subtractFromSet, &universal, &universal, &empty); checkCase(&unionInSet, &universal, &universal, &universal); checkCase(&intersectFromSet, &universal, &universal, &universal); checkCase(&intersectFromSet, &universal, &empty, &empty); checkCase(&intersectFromSet, &empty, &universal, &empty); checkCase(&unionInSet, &universal, &empty, &universal); checkCase(&unionInSet, &empty, &universal, &universal); checkCase(&unionInSet, &empty, &empty, &empty); checkCase(&subtractFromSet, &empty, &empty, &empty); checkCase(&intersectFromSet, &empty, &empty, &empty); createEmptySet(&s); assert(isEmptySet(&s)); for (i = 0; i < 10; i += 1) { insertSet(&s, i); } assert(s.len == 10); for (i = 0; i < 10; i += 1) { assert(isMemberSet(&s, i)); } for (i = 0; i < 10; i += 1) { removeSet(&s, i); removeSet(&s, i); assert(s.len == 9 - i); } assert(isEmptySet(&s)); for (i = 0; i < number_of_tests; i += 1) { randomSet(&s); assert(isSubsetOf(&empty, &s)); assert(!isSubsetOf(&s, &empty)); assert(isSubsetOf(&s, &universal)); assert(!isSubsetOf(&universal, &s)); checkCase(&intersectFromSet, &empty, &s, &empty); checkCase(&intersectFromSet, &s, &empty, &empty); checkCase(&intersectFromSet, &universal, &s, &s); checkCase(&intersectFromSet, &s, &universal, &s); checkCase(&unionInSet, &universal, &s, &universal); checkCase(&unionInSet, &s, &universal, &universal); checkCase(&subtractFromSet, &s, &empty, &s); assignSet(&r, &universal); subtractFromSet(&r, &s); // r = u - s; checkCase(&subtractFromSet, &universal, &r, &s); // (u - (u - s) == s) checkCase(&unionInSet, &s, &r, &universal); // s + (u - s) == u checkCase(&unionInSet, &r, &s, &universal); // (u - s) + s == u } printf("The special case tests have been passed\n"); destroySet(&empty); destroySet(&universal); destroySet(&s); destroySet(&r); }
TEST(Test05, SpecialCaseTests) { { Set empty; Set universal; Set s; Set r; int i; createEmptySet(&empty); createEmptySet(&universal); createEmptySet(&r); for (i = 0; i < MAX_SET_SIZE; i++) { insertSet(&universal, i); } ASSERT_TRUE(checkCaseNew(&subtractFromSet, &universal, &universal, &empty)); ASSERT_TRUE(checkCaseNew(&unionInSet, &universal, &universal, &universal)); ASSERT_TRUE(checkCaseNew(&intersectFromSet, &universal, &universal, &universal)); ASSERT_TRUE(checkCaseNew(&intersectFromSet, &universal, &empty, &empty)); ASSERT_TRUE(checkCaseNew(&intersectFromSet, &empty, &universal, &empty)); ASSERT_TRUE(checkCaseNew(&unionInSet, &universal, &empty, &universal)); ASSERT_TRUE(checkCaseNew(&unionInSet, &empty, &universal, &universal)); ASSERT_TRUE(checkCaseNew(&unionInSet, &empty, &empty, &empty)); ASSERT_TRUE(checkCaseNew(&subtractFromSet, &empty, &empty, &empty)); ASSERT_TRUE(checkCaseNew(&intersectFromSet, &empty, &empty, &empty)); createEmptySet(&s); ASSERT_TRUE(isEmptySet(&s)); for (i = 0; i < 10; i++) { insertSet(&s, i); } ASSERT_TRUE(s.len == 10); for (i = 0; i < 10; i++) { ASSERT_TRUE(isMemberSet(&s, i)); } for (i = 0; i < 10; i++) { removeSet(&s, i); removeSet(&s, i); ASSERT_TRUE(s.len == 9 - i); } ASSERT_TRUE(isEmptySet(&s)); for (i = 0; i < NUM_TESTS; i++) { randomSet(&s); ASSERT_TRUE(isSubsetOf(&empty, &s)); ASSERT_FALSE(isSubsetOf(&s, &empty)); ASSERT_TRUE(isSubsetOf(&s, &universal)); ASSERT_FALSE(isSubsetOf(&universal, &s)); ASSERT_TRUE(checkCaseNew(&intersectFromSet, &empty, &s, &empty)); ASSERT_TRUE(checkCaseNew(&intersectFromSet, &s, &empty, &empty)); ASSERT_TRUE(checkCaseNew(&intersectFromSet, &universal, &s, &s)); ASSERT_TRUE(checkCaseNew(&intersectFromSet, &s, &universal, &s)); ASSERT_TRUE(checkCaseNew(&unionInSet, &universal, &s, &universal)); ASSERT_TRUE(checkCaseNew(&unionInSet, &s, &universal, &universal)); ASSERT_TRUE(checkCaseNew(&subtractFromSet, &s, &empty, &s)); assignSet(&r, &universal); subtractFromSet(&r, &s); ASSERT_TRUE(checkCaseNew(&subtractFromSet, &universal, &r, &s)); ASSERT_TRUE(checkCaseNew(&unionInSet, &s, &r, &universal)); ASSERT_TRUE(checkCaseNew(&unionInSet, &r, &s, &universal)); } destroySet(&empty); destroySet(&universal); destroySet(&s); destroySet(&r); } }