/**************************************************************************** ** *FAddList(<list>,<obj>)........addanobjecttotheendofalist ** **'AddList'addstheobject<obj>totheendofthelist<list>,i.e., **itisequivalenttotheassignment'<list>[Length(<list>)+1]:=<obj>'. **Thelistisautomaticallyextendedtomakeroomforthenewelement. **'AddList'returnsnothing,itiscalledonlyforitssideeffect.
*/ staticvoid AddList3(Obj list, Obj obj, Int pos)
{ Int len; Int i;
len = LEN_LIST(list); if (pos == (Int)-1)
pos = len + 1; for (i = len + 1; i > pos; i--)
ASS_LIST(list, i, ELM_LIST(list, i - 1));
ASS_LIST(list, pos, obj);
}
void AddPlist3(Obj list, Obj obj, Int pos)
{
UInt len;
if (!IS_PLIST_MUTABLE(list)) {
ErrorMayQuit("List Assignment: <list> must be a mutable list", 0, 0);
} // in order to be optimistic when building list call assignment
len = LEN_PLIST(list); if (pos == (Int)-1)
pos = len + 1; if (len == 0) {
AssPlistEmpty(list, pos, obj); return;
} if (pos <= len) {
GROW_PLIST(list, len + 1);
SET_LEN_PLIST(list, len + 1);
Obj * ptr = ADDR_OBJ(list) + pos;
SyMemmove(ptr + 1, ptr, sizeof(Obj) * (len - pos + 1));
}
ASS_LIST(list, pos, obj);
}
/**************************************************************************** ** *FFuncAPPEND_LIST_INTR(<list1>,<list2>).....appendelementstoalist ** **'FuncAPPEND_LIST_INTR'implementsthefunction'Append'. ** **'Append(<list1>,<list2>)' ** **'Append'adds(see"Add")theelementsofthelist<list2>totheend **ofthelist<list1>.Itisallowedthat<list2>containsemptypositions, **inwhichcasethecorrespondingpositionswillbeleftemptyin<list1>. **'Append'returnsnothing,itiscalledonlyforitssideeffect.
*/ static Obj FuncAPPEND_LIST_INTR(Obj self, Obj list1, Obj list2)
{
UInt len1; // length of the first list
UInt len2; // length of the second list
Obj elm; // one element of the second list Int i; // loop variable
// handle the case of strings now if (IS_STRING_REP(list1) && IS_STRING(list2)) { if (!IS_STRING_REP(list2)) {
list2 = ImmutableString(list2);
}
AppendString(list1, list2); return0;
}
// check the type of the first argument if ( TNUM_OBJ( list1 ) != T_PLIST ) { if ( ! IS_PLIST( list1 ) ) {
PLAIN_LIST( list1 );
}
RetypeBag( list1, T_PLIST );
}
len1 = LEN_PLIST( list1 );
// check the type of the second argument if ( ! IS_PLIST( list2 ) ) {
len2 = LEN_LIST( list2 );
} else {
len2 = LEN_PLIST( list2 );
}
// if the list has no room at the end, enlarge it if ( 0 < len2 ) {
GROW_PLIST( list1, len1+len2 );
SET_LEN_PLIST( list1, len1+len2 );
}
// add the elements if ( IS_PLIST(list2) ) { // note that the two memory regions can never overlap, even // if list1 and list2 are identical
memcpy(ADDR_OBJ(list1) + 1 + len1, CONST_ADDR_OBJ(list2) + 1,
len2 * sizeof(Obj));
CHANGED_BAG( list1 );
} else { for ( i = 1; i <= len2; i++ ) {
elm = ELMV0_LIST( list2, i );
SET_ELM_PLIST( list1, i+len1, elm );
CHANGED_BAG( list1 );
}
}
/**************************************************************************** ** *FPOSITION_SORTED_LIST(<list>,<obj>)....findanobjectinasortedlist *FPositionSortedDensePlist(<list>,<obj>).findanobjectinasortedlist ** **'POSITION_SORTED_LIST'returnsthepositionoftheobject<obj>,whichmay **beanobjectofanytype,withrespecttothesortedlist<list>. ** **'POSITION_SORTED_LIST'returns<pos>suchthat'<list>[<pos>-1]<<obj>' **and'<obj><=<list>[<pos>]'.Thatmeansif<obj>appearsoncein<list> **itspositionisreturned.If<obj>appearsseveraltimesin<list>,the **positionofthefirstoccurrenceisreturned.If<obj>isnotanelement **of<list>,theindexwhere<obj>mustbeinsertedtokeepthelistsorted **isreturned.
*/ static UInt POSITION_SORTED_LIST(Obj list, Obj obj)
{
UInt l; // low
UInt h; // high
UInt m; // mid
Obj v; // one element of the list
// perform the binary search to find the position
l = 0; h = LEN_LIST( list ) + 1; while ( l+1 < h ) { // list[l] < obj && obj <= list[h]
m = (l + h) / 2; // l < m < h
v = ELMV_LIST( list, m ); if ( LT( v, obj ) ) { l = m; } else { h = m; }
}
// return the position return h;
}
UInt PositionSortedDensePlist (
Obj list,
Obj obj )
{
UInt l; // low
UInt h; // high
UInt m; // mid
Obj v; // one element of the list
// perform the binary search to find the position
l = 0; h = LEN_PLIST( list ) + 1; while ( l+1 < h ) { // list[l] < obj && obj <= list[h]
m = (l + h) / 2; // l < m < h
v = ELM_PLIST( list, m ); if ( LT( v, obj ) ) { l = m; } else { h = m; }
}
UInt h; if ( IS_DENSE_PLIST(list) ) {
h = PositionSortedDensePlist( list, obj );
} else {
h = POSITION_SORTED_LIST( list, obj );
}
return INTOBJ_INT( h );
}
/**************************************************************************** ** *FPOSITION_SORTED_LISTComp(<list>,<obj>,<func>)..findanobjectinalist *FPositionSortedDensePlistComp(<list>,<obj>,<func>)findanobjectinalist ** **'POSITION_SORTED_LISTComp'returnsthepositionoftheobject<obj>,which **maybeanobjectofanytype,withrespecttothelist<list>,whichis **sortedwithrespecttothecomparisonfunction<func>. ** **'POSITION_SORTED_LISTComp'returns<pos>suchthat'<list>[<pos>-1]<<obj>' **and'<obj><=<list>[<pos>]'.Thatmeansif<obj>appearsoncein<list> **itspositionisreturned.If<obj>appearsseveraltimesin<list>,the **positionofthefirstoccurrenceisreturned.If<obj>isnotanelement **of<list>,theindexwhere<obj>mustbeinsertedtokeepthelistsorted **isreturned.
*/ static UInt POSITION_SORTED_LISTComp(Obj list, Obj obj, Obj func)
{
UInt l; // low
UInt h; // high
UInt m; // mid
Obj v; // one element of the list
// perform the binary search to find the position
l = 0; h = LEN_LIST( list ) + 1; while ( l+1 < h ) { // list[l] < obj && obj <= list[h]
m = (l + h) / 2; // l < m < h
v = ELMV_LIST( list, m ); if ( CALL_2ARGS( func, v, obj ) == True ) { l = m; } else { h = m; }
}
// return the position return h;
}
static UInt PositionSortedDensePlistComp(Obj list, Obj obj, Obj func)
{
UInt l; // low
UInt h; // high
UInt m; // mid
Obj v; // one element of the list
// perform the binary search to find the position
l = 0; h = LEN_PLIST( list ) + 1; while ( l+1 < h ) { // list[l] < obj && obj <= list[h]
m = (l + h) / 2; // l < m < h
v = ELM_PLIST( list, m ); if ( CALL_2ARGS( func, v, obj ) == True ) { l = m; } else { h = m; }
}
// perform the binary search to find the position
UInt l = 0;
UInt h = LEN_PLIST(list) + 1; while (l + 1 < h) { // list[l] < val && val <= list[h]
UInt m = (l + h) / 2; // l < m < h
Obj v = CALL_1ARGS(func, ELM_PLIST(list, m)); if (LT(v, val)) {
l = m;
} else {
h = m;
}
}
// See sortbase.h for a description of these macros.
// We put these first, as they are the same for the next 4 functions so // we do not have to repeat them #define SORT_CREATE_TEMP_BUFFER(len) NEW_PLIST( T_PLIST, len + 1000); #define SORT_ASS_BUF_TO_LOCAL(buffer, t, i) t = ELM_PLIST(buffer, i); #define SORT_ASS_LOCAL_TO_BUF(buffer, i, j) \
SET_ELM_PLIST(buffer, i, j); \
CHANGED_BAG(buffer);
#define SORT_FUNC_NAME SORT_LIST #define SORT_FUNC_ARGS Obj list #define SORT_ARGS list #define SORT_CREATE_LOCAL(name) Obj name ; #define SORT_LEN_LIST() LEN_LIST(list) #define SORT_ASS_LIST_TO_LOCAL(t, i) t = ELMV_LIST(list, i) #define SORT_ASS_LOCAL_TO_LIST(i, j) ASS_LIST(list, i, j) #define SORT_COMP(v, w) LT(v, w) #define SORT_FILTER_CHECKS() \ if(IS_PLIST(list)) \
RESET_FILT_LIST(list, FN_IS_NSORT);
#include"sortbase.h"
#define SORT_FUNC_NAME SortDensePlist #define SORT_FUNC_ARGS Obj list #define SORT_ARGS list #define SORT_CREATE_LOCAL(name) Obj name ; #define SORT_LEN_LIST() LEN_PLIST(list) #define SORT_ASS_LIST_TO_LOCAL(t, i) t = ELM_PLIST(list, i) #define SORT_ASS_LOCAL_TO_LIST(i, j) \
SET_ELM_PLIST(list, i, j); \
CHANGED_BAG(list); #define SORT_COMP(v, w) LT(v, w) #define SORT_FILTER_CHECKS() \
RESET_FILT_LIST(list, FN_IS_NSORT);
#include"sortbase.h"
// This is a variant of SortDensePlist, which sorts plists by // Obj pointer. It works on non-dense plists, and can be // used to efficiently sort lists of small integers.
// Through this section, code of the form (void)(varname); stops // various compilers warning about unused variables. // These 3 macros are the same for all 4 of the following functions. #undef SORT_CREATE_TEMP_BUFFER #undef SORT_ASS_BUF_TO_LOCAL #undef SORT_ASS_LOCAL_TO_BUF
/**************************************************************************** ** *FRemoveDupsDensePlist(<list>)....removeduplicatesfromaplainlist ** **'RemoveDupsDensePlist'removesduplicateelementsfromthedense **plainlist<list>.<list>mustbesorted.'RemoveDupsDensePlist' **returns0if<list>containsmutableelements,1ifnotand2if **thelistcontainsimmutableelementsalllyinginthesamefamily.
*/
UInt RemoveDupsDensePlist (
Obj list )
{
UInt mutable; // the elements are mutable
UInt homog; // the elements all lie in the same family Int len; // length of the list
Obj v, w; // two elements of the list
UInt l, i; // loop variables
Obj fam;
// get the length, nothing to be done for empty lists
len = LEN_PLIST( list ); if ( len == 0 ) { return0; }
// select the first element as the first representative
l = 1;
v = ELM_PLIST( list, l ); mutable = IS_MUTABLE_OBJ(v);
homog = 1;
fam = FAMILY_OBJ(v);
// loop over the other elements, compare them with the current rep. for ( i = 2; i <= len; i++ ) {
w = ELM_PLIST( list, i ); mutable = (mutable || IS_MUTABLE_OBJ(w)); if ( ! EQ( v, w ) ) { if ( l+1 != i ) {
SET_ELM_PLIST( list, l+1, w );
SET_ELM_PLIST( list, i, (Obj)0 );
}
l += 1;
v = w;
homog = (!mutable && homog && fam == FAMILY_OBJ(w));
}
}
// the list may be shorter now
SET_LEN_PLIST( list, l );
SHRINK_PLIST( list, l );
// Set appropriate filters if (!mutable)
{ if (!homog)
SET_FILT_LIST(list, FN_IS_NHOMOG); else
SET_FILT_LIST(list, FN_IS_HOMOG);
SET_FILT_LIST(list, FN_IS_SSORT);
}
// return whether the list contains mutable elements if (mutable) return0; if (!homog) return1; else return2;
}
RequireSmallList(SELF_NAME, pair); if (LEN_LIST(pair) != 2) {
ErrorMayQuit("OnPairs: <pair> must have length 2, not length %d",
LEN_LIST(pair), 0);
}
// create a new bag for the result
img = NEW_PLIST_WITH_MUTABILITY( IS_MUTABLE_OBJ(pair), T_PLIST, 2 );
SET_LEN_PLIST( img, 2 );
// and enter the images of the points into the result bag
tmp = POW( ELMV_LIST( pair, 1 ), elm );
SET_ELM_PLIST( img, 1, tmp );
CHANGED_BAG( img );
tmp = POW( ELMV_LIST( pair, 2 ), elm );
SET_ELM_PLIST( img, 2, tmp );
CHANGED_BAG( img );
// special case for the empty list if (LEN_LIST(tuple) == 0) { if (IS_MUTABLE_OBJ(tuple)) {
img = NewEmptyPlist(); return img;
} else { return tuple;
}
} // special case for permutations if (IS_PERM(elm)) { return OnTuplesPerm( tuple, elm );
}
// special case for transformations if (IS_TRANS(elm)) { return OnTuplesTrans( tuple, elm );
}
// special case for partial perms if (IS_PPERM(elm)) { return OnTuplesPPerm( tuple, elm );
}
// create a new bag for the result
img = NEW_PLIST_WITH_MUTABILITY( IS_MUTABLE_OBJ(tuple), T_PLIST, LEN_LIST(tuple) );
SET_LEN_PLIST( img, LEN_LIST(tuple) );
// and enter the images of the points into the result bag for ( i = LEN_LIST(tuple); 1 <= i; i-- ) {
tmp = POW( ELMV_LIST( tuple, i ), elm );
SET_ELM_PLIST( img, i, tmp );
CHANGED_BAG( img );
}
// ADD_LIST can take 2 or 3 arguments; since NewOperation ignores the // handler for variadic operations, use DoOperation0Args as a placeholder.
{ "ADD_LIST", -1, "list, obj[, pos]", &AddListOper,
DoOperation0Args, "src/listfunc.c:ADD_LIST" },
// ADD_LIST needs special consideration because we want distinct kernel // handlers for 2 and 3 arguments
InitHandlerFunc( FuncADD_LIST, "src/listfunc.c:FuncADD_LIST" );
InitHandlerFunc( FuncADD_LIST3, "src/listfunc.c:FuncADD_LIST3" );
// make and install the 'ADD_LIST' operation
SET_HDLR_FUNC( AddListOper, 2, FuncADD_LIST);
SET_HDLR_FUNC( AddListOper, 3, FuncADD_LIST3);
return0;
}
/**************************************************************************** ** *FInitInfoListFunc()...............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 = "listfunc",
.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.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.