/////////////////////////////////////////////////////////////////////////////// version="version sets.lib 4.2.0.0 Dec_2020 "; //$Id$ category="Miscellaneous"; info=" LIBRARY: sets.lib Sets in Singular AUTHORS: J. Boehm, boehm @ mathematik.uni-kl.de D. Wienholz, wienholz @ mathematik.uni-kl.de S. Zillien, zillien @ rhrk.uni-kl.de OVERVIEW: We implement the new class set and all basic methods needed to work with sets. A set is generated from a list. After the generating of a set, the adding of an element or the union of two sets, automatically every double element is removed to secure that no element occurs in a set more than once. There is a comparison operator, we access the operator via the function isEqual. This function isEqual can be used to compare two elements of the same type (Set, list, int, bigint, string, intmat, bigintmat, intvec, ring, map, poly, matrix, ideal, module, vector, resolution) and also works for comparing of int, bigint and number with each other, similarly for matrix, bigintmat and intmat. The function size can be used to determine the number of elements. The + operator is used for the union, the * operator for the intersection. The operators < and > can be used for inclusion tests. The print function can be used for printing sets. Note that the implementation of the underlying data structure and algorithms is very trivial and will at some point be replaced with something more efficient. KEYWORDS: set, intersectionSet, union, complement, equality, isEqual TYPES: Set The class of all sets PROCEDURES: set(list) general procedure to generate a set from a list union(Set,Set) union of sets intersectionSet(Set,Set) intersection of sets complement(Set,Set) complement of sets isElement(def,Set) test whether an object is in a set isSubset(Set,Set) test whether a set is a subset of another set isSuperset(Set,Set) test whether a set is a superset of another set addElement(Set,def) adds an element to the set "; static proc mod_init() { LIB "methods.lib"; // mod_init needs Hashtable/Method from methods.lib newstruct("Set","list elements"); system("install","Set","print",printSet,1); system("install","Set","+",union,2); system("install","Set","*",intersectionSet,2); system("install","Set","<",isSubset,2); system("install","Set","size",sizeSet,1); system("install","Set",">",isSuperset,2); system("install","Set","==",isEqualSet,2); HashTable F = hashTable( list( list("Set","Set"), list("int","number"), list("number","bigint"), list("poly","poly"), list("matrix","matrix"), list("ideal","ideal"), list("map","map"), list("ring","ring"), list("list","list"), list("bigint","int"), list("int","bigint"), list("bigint","bigint"), list("string","string"), list("vector","vector"), list("intvec","intvec"), list("intmat","intmat"), list("bigintmat","bigintmat"), list("matrix","intmat"), list("intmat","matrix"), list("intmat","bigintmat"), list("bigintmat","intmat"), list("int","int"), list("number","int"), list("bigint","number"), list("module","module"), list("number","number"), list("resolution","resolution"), list("vector","intvec"), list("intvec","vector") ), list( "isEqualSet", "isEqualInt", "isEqualInt", "isEqualInt", "isEqualInt", "isEqualIdeal", "isEqualMap", "isEqualRing", "isEqualList", "isEqualInt", "isEqualInt", "isEqualInt", "isEqualInt", "isEqualInt", "isEqualInt", "isEqualInt", "isEqualInt", "isEqualInt", "isEqualInt", "isEqualInt", "isEqualInt", "isEqualInt", "isEqualInt", "isEqualInt", "isEqualModule", "isEqualInt", "isEqualResolution", "isEqualInt","isEqualInt" ) ); Method isEqual_ = method(F); export(isEqual_); installMethod(isEqual_,"isEqual"); system("install","Set","=",set,1); } proc sizeSet(Set a) { list L =a.elements; return(size(L)); } proc isEqualInt(def a,def b) //exists for matrix, int, bigint, poly, string, vector, intvec, number, intmat, bigintmat, cone { return(a==b); } proc isEqualMap(def a, def b) { if(!(isEqualRing(preimage(a),preimage(b)))) //check the startring of the maps { return(0); } for(int i=1;i<=size(ring_list(preimage(a))[2]);i++){ //check if the two maps are the same if(a[i]!=b[i]){ //in every component return(0); } } return(1);} proc isEqualModule(def m0, def s0) { intvec o=option(get); option(redSB); module m=std(m0); module s=std(s0); option(set,o); if(size(m)!=size(s)){return(0);} for(int i=1;i<=size(m);i++){ if(m[i]!=s[i]){return(0);} } return(1); } proc isEqualResolution(def r, def s) { list l=r; list j=s; return(isEqual(l,j)); } proc isEqualRing(def r, def t) { list a=ringlist(r); //creating two lists with everything that defines the rings list b=ringlist(t); return(isEqual(a,b)); } proc isEqualList(def a, def b) { if(size(a)!=size(b)){ //check if the two lists have the same size return(0); } for(int i=1;i<=size(a);i++){ //checking every element of the two lists if(!(isEqual(a[i],b[i]))){ return(0); } } return(1); } proc isEqualSet(def a, def b) { if(size(a)!=size(b)) //check if the two sets have the same size { return(0); } list L = a.elements; for(int i=1;i<=size(a);i++) //check if every element of the first set occurs in { if(!(isElement(L[i],b))) //the second set { return(0); } } return(1); } proc isEqualIdeal(def a, def b) { option(redSB); intvec o=option(get); ideal I = std(a); ideal J = std(b); option(set,o); if(size(I)!=size(J)){ return(0); } for(int i = 1;i<=size(I); i++){ if(I[i]!=J[i]){ return(0); } } return(1); } static proc removeDouble(list L) { int j; list L1; //creating a list tagging the first appearance with 1 and the following with 0 list Output; //creating an empty list for the return for(int i=1; i<=size(L); i++){ L1=insert(L1,1); //at the beginning every element is tagged with 1 } for(i=1; i1){st ="s";} print("Set with "+string(size(L))+" element"+st); //printing a string with the number } //of elements of the set } static proc setJoinOfLists(list L1,list L2) { for(int i=1; i<=size(L2); i++){ L1 = insert(L1,L2[i]); //adding every element of the second list to the first } return(L1); } proc union(Set N, Set M) "USAGE: union(N,M) or N+M; N,M sets RETURN: Set, the union of the sets N and M EXAMPLE: example union, shows an example " { Set S; list L1 = N.elements; //converting the sets into lists list L2 = M.elements; list L = setJoinOfLists(L1,L2); //creating the joint of the two lists S.elements = removeDouble(L); //removing every element which occurs more then once return(S); } example //example for union { "EXAMPLE:"; echo = 2; list l =1,2,3; list j =2,3,4; Set N=l; Set M=j; N; M; N+M; } static proc setIntersectionOfLists(list L1,list L2) { if(size(L1)>size(L2)){ //secure that the first list isn't bigger then the second list J = L1; L1=L2; L2=J; } list M; //creating an empty set, which will be returned if(size(L1)==0){ //if the first list is empty, the intersection is empty return(M); } Set S = set(L2); for(int i=1; i<=size(L1); i++){ //check for every element of the first list if(isElement(L1[i],S)){ //is in the second list M=insert(M,L1[i]); //an element of both lists, is added the set } } return(M); } proc intersectionSet(Set N, Set M) "USAGE: intersectionSet(N,M) or N*M; N,M sets RETURN: Set, the interseection of the sets N and M EXAMPLE: example intersection, shows an example KEYWORDS: intersection " { Set S; list L1 = N.elements; list L2 = M.elements; list L = setIntersectionOfLists(L1,L2); S.elements = removeDouble(L); return(S); } example //example for intersection { "EXAMPLE:"; echo = 2; list l =1,2,3; list j =2,3,4; Set N=l; Set M=j; N; M; N*M; } proc isElement(def a, Set M) "USAGE: isElement(a,M); M set a def RETURN: bool, 1 if a is an element of M, 0 if not EXAMPLE: example isElement, shows an example " { list L = M.elements; for(int i=1; i<=size(L); i++){ //test for every element of the set, if it is the if(isEqual(a,L[i])){ //element to be checked return(1); } } return(0); } example //example for isElement { "EXAMPLE:"; echo = 2; int i=1; int j=5; list k =1,2,3,4; Set M=k; i; j; M; isElement(i,M); isElement(j,M); } proc complement(Set S, Set M) "USAGE: complement(N,M); N,M sets RETURN: Set, the complement of the set N in M EXAMPLE: example complement, shows an example " { if (!(Ssize(J)){ //check if the first set is smaller then the second return(0); } for(int i=1; i<=size(L); i++){ if(!isElement(L[i],M)){ //check if every element of the first set is in the return(0); //second set } } return(1); } example //example for isSubset { "EXAMPLE:"; echo = 2; list l =1,2; list j =1,2,3,4; Set N=l; Set M=j; N; M; NM ; N,M sets RETURN: bool, 1 if N is a Superset of M or 0 if not EXAMPLE: example isSuperset, shows an example " { return(MM; M>N; }