home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <stdarg.h>
- #include "sets.h"
- /***************************************************************************/
- int set_difference(set *difference, set *minuend, set *subtrahend)
- /***************************************************************************/
- /* This procedure computes the difference of two sets. The sets must
- have the same base_type in order for this to work. The input parameters
- are left unchanged.
- */
- {
- int i;
- defset(temp,UNIVERSAL,MAX_MEMBERS,0);
-
- /* first check for the same base_types */
- if(!cmp_base_types(minuend,subtrahend) ||
- !cmp_base_types(minuend,difference) ||
- !cmp_set_tags(minuend,subtrahend) ||
- !cmp_set_tags(minuend,difference))
- return NULL;
-
- /* zero out the result */
- set_clear(&temp);
-
- /* The difference of two sets is a set whose members are members of the
- minuend and not also of the subtrahend. The set_difference is found
- by first taking the XOR of the minuend and subtrahend and then ANDing
- that result with the minuend. This is expressed in C as
- ((minuend ^ subtrahend) & minuend). To prove it, consider the
- following (all operations are bitwise):
-
- minuend = 100111
- subtrahend = 101011
- ---------------------
- XOR => 001100
- minuend = 100111
- ---------------------
- & => 000100
-
- which is the member in the minuend that is not in the subtrahend.
- */
-
- /* The set, 'difference' must be at least the size of the minuend.
- Check this.
- */
- if(temp.set_size < minuend->set_size)
- return FAILURE;
- else
- {
- temp.set_size = minuend->set_size;
- temp.member_recs = minuend->member_recs;
- }
-
- /* Now the calculation for the difference...Note that the smaller set
- will have ALL bits at member locations higher than nmembers reset
- to zero.
- */
- for(i=0;i<minuend->member_recs;i++)
- temp.word[i] =
- (minuend->word[i] ^ subtrahend->word[i]) & minuend->word[i];
-
- /* correct the member count in the set record */
- temp.nmembers = set_member_count(&temp);
-
- /* now clear the destination and assign temp */
- set_clear(difference);
- if(set_assign(difference,&temp) == FAILURE)
- return FAILURE;
-
- /* done. */
- return SUCCESS;
-
- } /* end set_difference */
-
-