// if it is another small list if ( IS_SMALL_LIST(list) ) {
// if <list> is the empty list, it is a set (:-) if ( LEN_LIST(list) == 0 ) {
PLAIN_LIST( list );
RetypeBagSMIfWritable(list, T_PLIST_EMPTY); returnTRUE;
}
// if <list> strictly sorted, it is a set elseif ( IS_SSORT_LIST(list) ) {
PLAIN_LIST( list ); // SET_FILT_LIST( list, FN_IS_HOMOG );
SET_FILT_LIST( list, FN_IS_SSORT ); returnTRUE;
}
}
returnFALSE;
}
/**************************************************************************** ** *FSetList(<list>)................makeasetfromalist ** **'SetList'returnsanewsetthatcontainstheelementsof<list>.Note **that'SetList'returnsanewplainlistevenif<list>wasalreadyaset. **Inthiscase'SetList'isequalto'ShallowCopy'. ** **'SetList'makesacopyofthelist<list>,removestheholes,sortsthe **copyandfinallyremovesduplicates,whichmustappearnexttoeachother **nowthatthecopyissorted.
*/
Obj SetList (
Obj list )
{
Obj set; // result set Int lenSet; // length of <set> Int lenList; // length of <list>
Obj elm; // one element of the list
UInt status; // the elements are mutable
UInt i; // loop variable
// make a dense copy
lenList = LEN_LIST( list );
set = NEW_PLIST( T_PLIST, lenList );
lenSet = 0; for ( i = 1; i <= lenList; i++ ) {
elm = ELMV0_LIST( list, i ); if ( elm != 0 ) {
lenSet += 1;
SET_ELM_PLIST( set, lenSet, elm );
CHANGED_BAG(set); // in case elm had to be made, not just extracted
}
}
SET_LEN_PLIST( set, lenSet );
SET_FILT_LIST( set, FN_IS_DENSE );
// sort the set (which is a dense plain list)
SortDensePlist( set );
// remove duplicates
status = RemoveDupsDensePlist( set );
// adjust flags where possible switch(status)
{ case0: break;
// if the list is empty create a new empty list if ( LEN_LIST(list) == 0 ) {
set = NewEmptyPlist();
}
// if <list> is a set just shallow copy it elseif ( /* IS_HOMOG_LIST(list) && */ IS_SSORT_LIST(list) ) {
set = SHALLOW_COPY_OBJ( list );
}
// otherwise let 'SetList' do the work else {
set = SetList( list );
}
// return the set return set;
}
/**************************************************************************** ** *FFuncIS_EQUAL_SET(<self>,<l1>,<l2>)testifatwolistsareequalassets ** **'FuncIS_EQUAL_SET'implementstheinternalfunction'IsEqualSet'. ** **'IsEqualSet(<list1>,<list2>)' ** **'IsEqualSet'returns'true'ifthetwolists<list1>and<list2>are **equal*whenviewedassets*,and'false'otherwise.<list1>and<list2> **areequalifeveryelementof<list1>isalsoanelementof<list2>and **ifeveryelementof<list2>isalsoanelementof<list1>.
*/ staticInt EqSet(Obj listL, Obj listR)
{ Int lenL; // length of the left operand Int lenR; // length of the right operand
Obj elmL; // element of the left operand
Obj elmR; // element of the right operand
UInt i; // loop variable
// get the lengths of the lists and compare them
lenL = LEN_PLIST( listL );
lenR = LEN_PLIST( listR ); if ( lenL != lenR ) { return0;
}
// loop over the elements and compare them for ( i = 1; i <= lenL; i++ ) {
elmL = ELM_PLIST( listL, i );
elmR = ELM_PLIST( listR, i ); if ( ! EQ( elmL, elmR ) ) { return0;
}
}
// no differences found, the lists are equal return1;
}
// and now compare them if (IS_PLIST(list1) && IS_PLIST(list2)) return EqSet(list1, list2) ? True : False; return EQ(list1, list2) ? True : False;
}
/**************************************************************************** ** *FFuncIS_SUBSET_SET(<self>,<s1>,<s2>)testifasetisasubsetofanother ** **'FuncIS_SUBSET_SET'implementstheinternalfunction'IsSubsetSet'. ** **'IsSubsetSet(<set1>,<set2>)' ** **'IsSubsetSet'returns'true'iftheset<set2>isasubsetoftheset **<set1>,thatisifeveryelementof<set2>isalsoanelementof<set1>. **Eitherargumentmayalsobealistthatisnotaproperset,inwhich **case'IsSubsetSet'silentlyapplies'Set'(see"Set")toitfirst.
*/ static Obj FuncIS_SUBSET_SET(Obj self, Obj set1, Obj set2)
{
UInt len1; // length of the left set
UInt len2; // length of the right set
UInt i1; // index into the left set
UInt i2; // index into the right set
Obj e1; // element of left set
Obj e2; // element of right set
RequireSmallList(SELF_NAME, set1);
RequireSmallList(SELF_NAME, set2); if (!IsPlainSet(set1)) set1 = SetList(set1); if (!IsPlainSet(set2)) set2 = SetList(set2);
// get the logical lengths and get the pointer
len1 = LEN_PLIST(set1);
len2 = LEN_PLIST(set2);
i1 = 1;
i2 = 1;
// now compare the two sets while (i1 <= len1 && i2 <= len2 && len2 - i2 <= len1 - i1) {
e1 = ELM_PLIST(set1, i1);
e2 = ELM_PLIST(set2, i2); if (EQ(e1, e2)) {
i1++;
i2++;
} elseif (LT(e1, e2)) {
i1++;
} else { break;
}
}
// return 'true' if every element of <set2> appeared in <set1> return ((i2 == len2 + 1) ? True : False);
}
/**************************************************************************** ** *FFuncADD_SET(<self>,<set>,<obj>).......addanelementtoaset ** **'FuncADD_SET'implementstheinternalfunction'AddSet'. ** **'AddSet(<set>,<obj>)' ** **'AddSet'adds<obj>,whichmaybeanobjectofanarbitrarytype,tothe **set<set>,whichmustbeaproperset.If<obj>isalreadyanelementof **theset<set>,then<set>isnotchanged.Otherwise<obj>isinsertedat **thecorrectpositionsuchthat<set>isagainasetafterwards. ** **'AddSet'doesnotreturnanything,itisonlycalledforthesideeffect **ofchanging<set>.
*/ static Obj FuncADD_SET(Obj self, Obj set, Obj obj)
{
UInt len; // logical length of the list
UInt pos; // position BOOL isCyc; /* True if the set being added to consists
of kernel cyclotomics */
UInt notpos; /* position of an original element
(not the new one) */
UInt wasHom;
UInt wasNHom;
UInt wasTab;
RequireMutableSet(SELF_NAME, set);
len = LEN_PLIST(set);
// perform the binary search to find the position
pos = PositionSortedDensePlist( set, obj );
// add the element to the set if it is not already there if ( len < pos || ! EQ( ELM_PLIST(set,pos), obj ) ) {
GROW_PLIST( set, len+1 );
SET_LEN_PLIST( set, len+1 );
Obj * ptr = ADDR_OBJ(set) + pos;
SyMemmove(ptr + 1, ptr, sizeof(Obj) * (len - pos + 1));
SET_ELM_PLIST( set, pos, obj );
CHANGED_BAG( set );
// fix up the type of the result if ( HAS_FILT_LIST( set, FN_IS_SSORT ) ) {
isCyc = (TNUM_OBJ(set) == T_PLIST_CYC_SSORT);
wasHom = HAS_FILT_LIST(set, FN_IS_HOMOG);
wasTab = HAS_FILT_LIST(set, FN_IS_TABLE);
wasNHom = HAS_FILT_LIST(set, FN_IS_NHOMOG);
CLEAR_FILTS_LIST(set); // the result of addset is always dense
SET_FILT_LIST( set, FN_IS_DENSE );
// if the object we added was not mutable then we might be able to // conclude more if ( ! IS_MUTABLE_OBJ(obj) ) { // a one element list is automatically homogeneous and ssorted if (len == 0 )
{ if (IS_CYC(obj))
RetypeBagIfWritable( set, T_PLIST_CYC_SSORT); else
{
SET_FILT_LIST( set, FN_IS_HOMOG );
SET_FILT_LIST( set, FN_IS_SSORT ); if (IS_HOMOG_LIST(obj)) // it might be a table
SET_FILT_LIST( set, FN_IS_TABLE );
}
} else
{ // Now determine homogeneity if (isCyc) if (IS_CYC(obj))
RetypeBagIfWritable( set, T_PLIST_CYC_SSORT); else
{
RESET_FILT_LIST(set, FN_IS_HOMOG);
SET_FILT_LIST(set, FN_IS_NHOMOG);
} elseif (wasHom)
{ if (!SyInitializing) {
notpos = (pos == 1) ? 2 : 1; if (FAMILY_OBJ(ELM_PLIST(set,notpos)) == FAMILY_OBJ(obj))
{
SET_FILT_LIST(set, FN_IS_HOMOG); if (wasTab) { if (IS_HOMOG_LIST( obj ))
SET_FILT_LIST(set, FN_IS_TABLE);
}
}
static Obj FuncUNITE_SET(Obj self, Obj set1, Obj set2)
{
UInt len1; // length of left set
UInt len2; // length of right set
UInt i1; // index into left set
UInt i2; // index into right set
Obj e1; // element of left set
Obj e2; // element of right set
Obj TmpUnion;
RequireMutableSet(SELF_NAME, set1);
RequireSmallList(SELF_NAME, set2); if (!IsPlainSet(set2)) set2 = SetList(set2);
// get the logical lengths and the pointer
len1 = LEN_PLIST( set1 );
len2 = LEN_PLIST( set2 );
TmpUnion = NEW_PLIST(T_PLIST,len1+len2);
i1 = 1;
i2 = 1;
// fix up the type of the result if ( 0 == LEN_PLIST(set1) ) {
RetypeBag( set1, MUTABLE_TNUM(TNUM_OBJ(set2)) );
} elseif ( 0 != LEN_PLIST(set2)) { if (HAS_FILT_LIST(set1, FN_IS_HOMOG)) { if( !HAS_FILT_LIST(set2, FN_IS_HOMOG))
RESET_FILT_LIST(set1, FN_IS_HOMOG); elseif (!SyInitializing &&
FAMILY_OBJ(ELM_PLIST(set1,1)) != FAMILY_OBJ(ELM_PLIST(set2,1)))
{
RetypeBag(set1, T_PLIST_DENSE_NHOM);
}
}
}
SET_FILT_LIST(set1, FN_IS_SSORT);
// resize the result and copy back from the union
UInt size = (LEN_PLIST(TmpUnion) + 1) * sizeof(Obj);
GROW_PLIST(set1, LEN_PLIST(TmpUnion));
memcpy(ADDR_OBJ(set1), CONST_ADDR_OBJ(TmpUnion), size);
CHANGED_BAG(set1);
// now merge the two sets into the intersection while ( i1 <= len1 && i2 <= len2 ) {
e1 = ELM_PLIST( set1, i1 );
e2 = ELM_PLIST( set2, i2 ); if ( EQ( e1, e2 ) ) {
lenr++;
SET_ELM_PLIST( set1, lenr, e1 );
i1++; i2++;
} elseif ( LT( e1, e2 ) ) {
i1++;
} else {
i2++;
}
} return lenr;
}
// set1 should be the smaller set. setr should be the one // in which to put the results static UInt InterSetInner2( Obj set1, Obj set2, Obj setr, UInt len1, UInt len2)
{
UInt i1,i2=1,bottom,top,middle,lenr=0,found;
Obj e1,e2; for( i1 = 1; i1 <= len1; i1++)
{
e1 = ELM_PLIST( set1, i1 );
bottom = i2;
top = len2;
found = 0; while (bottom <= top)
{
middle = (bottom + top)/2;
e2 = ELM_PLIST(set2,middle); if (LT(e1,e2))
top = middle-1; elseif (EQ(e1,e2)) {
lenr++;
SET_ELM_PLIST(setr,lenr,e1);
i2 = middle+1;
found = 1; break;
} else
bottom = middle+1;
} if (!found)
i2 = bottom;
} return lenr;
}
static Obj FuncINTER_SET(Obj self, Obj set1, Obj set2)
{
UInt len1; // length of left set
UInt len2; // length of right set
UInt lenr; // length of result set
RequireMutableSet(SELF_NAME, set1);
RequireSmallList(SELF_NAME, set2); if (!IsPlainSet(set2)) set2 = SetList(set2);
// get the logical lengths and the pointer
len1 = LEN_PLIST( set1 );
len2 = LEN_PLIST( set2 );
// decide how to do the calculation and do it if (len1 < len2)
{
UInt x = len2;
UInt ll = 0; while (x > 0)
{
ll++;
x >>= 1;
} if (len1*ll < len2)
lenr = InterSetInner2(set1,set2,set1,len1,len2); else
lenr = InterSetInner1(set1,set2,len1,len2);
} else
{
UInt x = len1;
UInt ll = 0; while (x > 0)
{
ll++;
x >>= 1;
} if (len2*ll < len1)
lenr = InterSetInner2(set2,set1,set1,len2,len1); else
lenr = InterSetInner1(set1,set2,len1,len2);
}
// resize the result or clear the rest of the bag
SET_LEN_PLIST( set1, lenr );
SHRINK_PLIST( set1, lenr );
// fix up the type of the result if ( lenr == 0 ) {
RetypeBag(set1, T_PLIST_EMPTY);
} elseif ( lenr == 1) { if (IS_CYC(ELM_PLIST(set1,1)))
RetypeBag(set1, T_PLIST_CYC_SSORT); else
RetypeBag(set1, T_PLIST_HOM_SSORT);
} else
{ if ( TNUM_OBJ(set2) >= T_PLIST_CYC )
RetypeBag(set1, MUTABLE_TNUM( TNUM_OBJ(set2))); else
{
RESET_FILT_LIST(set1, FN_IS_NHOMOG); if ( HAS_FILT_LIST( set2, FN_IS_HOMOG )) {
SET_FILT_LIST(set1, FN_IS_HOMOG );
SET_FILT_LIST(set1, FN_IS_SSORT );
}
}
}
static Obj FuncSUBTR_SET(Obj self, Obj set1, Obj set2)
{
UInt len1; // length of left set
UInt len2; // length of right set
UInt lenr; // length of result set
UInt x;
UInt ll;
RequireMutableSet(SELF_NAME, set1);
RequireSmallList(SELF_NAME, set2); if (!IsPlainSet(set2)) set2 = SetList(set2);
// get the logical lengths and the pointer
len1 = LEN_PLIST( set1 );
len2 = LEN_PLIST( set2 ); // decide how to do the calculation and do it
x = len2;
ll = 0; while (x > 0)
{
ll++;
x >>= 1;
} if (len1*ll < len2)
lenr = SubtrSetInner2(set1,set2,len1,len2); else
lenr = SubtrSetInner1(set1,set2,len1,len2);
// resize the result or clear the rest of the bag
SET_LEN_PLIST( set1, lenr );
SHRINK_PLIST( set1, lenr );
// fix up the type of the result if ( lenr == 0 ) {
RetypeBag(set1, T_PLIST_EMPTY);
} elseif ( lenr == 1) { if (IS_CYC(ELM_PLIST(set1,1)))
RetypeBag(set1, T_PLIST_CYC_SSORT); else
RetypeBag(set1, T_PLIST_HOM_SSORT);
} else
RESET_FILT_LIST(set1, FN_IS_NHOMOG);
/**************************************************************************** ** *FInitInfoSet()..................tableofinitfunctions
*/ static StructInitInfo module = { // init struct using C99 designated initializers; for a full list of // fields, please refer to the definition of StructInitInfo
.type = MODULE_BUILTIN,
.name = "set",
.initKernel = InitKernel,
.initLibrary = InitLibrary,
};
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.22Bemerkung:
(vorverarbeitet am 2026-09-28)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.