#ifdef DOC_BUILD_INTERNAL
#endif
#include "array.h"
const unsigned array_EXTRA = 2;
const int array_SIZE = -1;
const int array_CAPACITY = -2;
const int array_INCREASE = 200;
void array_Init(void)
{
  return;
}
void array_Free(void)
{
  return;
}
ARRAY array_CreateNoInit(MEMORY Memory, int Init)
{
  ARRAY ar;
  ar = (ARRAY)memory_Malloc(Memory, (Init+array_EXTRA)*sizeof(intptr_t));
  ar = ar + array_EXTRA;
  ar[array_CAPACITY] = Init;
  ar[array_SIZE] = 0;
  return ar;
}
ARRAY array_Create(MEMORY Memory, int Init)
{
  ARRAY ar;
  int i;
  ar = array_CreateNoInit(Memory, Init);
  for(i=0; i < Init; i++)
    ar[i] = (intptr_t)NULL;
  return ar;
}
void array_Claim(ARRAY Ar)
{
  int i;
  for(i = array_GetSize(Ar); i < array_GetCapacity(Ar); i++)
    Ar[i] = (intptr_t)NULL;
  array_SetSize(Ar, array_GetCapacity(Ar));
}
intptr_t array_GetSize(ARRAY Ar)
{
  return Ar[array_SIZE];
}
BOOL array_IsEmpty(ARRAY Ar)
{
  return array_GetSize(Ar) == 0;
}
intptr_t array_GetCapacity(ARRAY Ar)
{
  return Ar[array_CAPACITY];
}
void array_SetSize(ARRAY Ar,intptr_t Size)
{
  Ar[array_SIZE] = Size;
}
void array_SetCapacity(ARRAY Ar,intptr_t Capacity)
{
  Ar[array_CAPACITY] = Capacity;
}
ARRAY array_RemoveIndex(ARRAY Ar, int Idx)
{
  intptr_t i;
  for(i = Idx+1; i < array_GetSize(Ar); i++ )
    Ar[i-1] = Ar[i];
  array_SetSize(Ar, array_GetSize(Ar)-1);
  return Ar;
}
ARRAY array_RemoveIndexSwap(ARRAY Ar, int Idx)
{
  Ar[Idx] = Ar[array_GetSize(Ar)-1];
  array_SetSize(Ar, array_GetSize(Ar)-1);
  return Ar;
}
ARRAY array_RemoveSwap(ARRAY Ar, intptr_t* Idx)
{
#ifdef SPASS_DEBUG
  if (Idx < Ar || Idx > Ar + array_GetSize(Ar)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n %s: pointer outside array bounds. ",
       __func__);
    misc_FinishErrorReport();
  }
#endif
  *Idx = Ar[array_GetSize(Ar)-1];
  array_SetSize(Ar, array_GetSize(Ar)-1);
  return Ar;
}
ARRAY array_Clean(ARRAY Ar)
{
  array_SetSize(Ar, 0);
  return Ar;
}
ARRAY array_Copy(MEMORY Memory, ARRAY Ar)
{
  ARRAY new;
  unsigned cap;
  cap = array_GetCapacity(Ar);
  new = array_CreateNoInit(Memory, cap);
  memcpy(new-array_EXTRA, Ar-array_EXTRA, (cap+array_EXTRA)*sizeof(intptr_t));
  return new;
}
void array_Reverse(ARRAY Ar)
{
  unsigned i,k;
  intptr_t e;
  k = array_GetSize(Ar);
  if (k==0)
    return;
  for (i=0, k--; i<k; i++, k--) {
    e = Ar[i];
    Ar[i] = Ar[k];
    Ar[k] = e;
  }
}
ARRAY array_CopyBySize(MEMORY Memory, ARRAY Ar)
{
  ARRAY new;
  unsigned size;
  size = array_GetSize(Ar);
  if (size > 0) {
    new = array_CreateNoInit(Memory, size);
    array_SetSize(new, size);
    memcpy(new, Ar, array_GetCapacity(new)*sizeof(intptr_t));
  }
  else {
    new = array_Create(Memory, 1);
  }
  return new;
}
ARRAY array_CopyWithElement(MEMORY Memory, const ARRAY Ar,
       intptr_t (*CopyElement)(MEMORY, intptr_t))
{
  ARRAY new;
  unsigned cap, i;
  cap = array_GetCapacity(Ar);
  new = array_Create(Memory, cap);
  for (i = 0; i < array_GetSize(Ar); i++)
    array_SetElement(new, i, CopyElement(Memory,
      array_GetElement(Ar, i)));
  return new;
}
ARRAY array_Extend(MEMORY Memory, ARRAY Ar, intptr_t Extend)
{
  int oldcap;
  unsigned i;
  oldcap = array_GetCapacity(Ar);
  array_SetCapacity(Ar, (array_GetCapacity(Ar) + Extend));
  Ar = memory_Realloc(Memory, Ar-array_EXTRA,
        (oldcap+array_EXTRA)*sizeof(intptr_t),
        (array_GetCapacity(Ar)+array_EXTRA)
        * sizeof(intptr_t));
  Ar = Ar + array_EXTRA;
  for(i = oldcap; i < array_GetCapacity(Ar); i++)
    Ar[i] = (intptr_t)NULL;
  return Ar;
}
ARRAY array_Reserve(MEMORY Memory, ARRAY Ar, intptr_t Cap)
{
  intptr_t pow;
  if (array_GetCapacity(Ar) >= Cap) return Ar;
  for (pow=1; pow < Cap+array_EXTRA;) pow *=2;
  return array_Extend(Memory, Ar,
        pow - array_EXTRA - array_GetCapacity(Ar));
}
ARRAY array_Add(MEMORY Memory, ARRAY Ar, intptr_t El)
{
  if (array_GetSize(Ar) + 1 > array_GetCapacity(Ar))
  {
    int oldcap;
    oldcap = array_GetCapacity(Ar);
    array_SetCapacity(Ar, (array_GetCapacity(Ar) *
      array_INCREASE)/100 + 1);
    Ar = memory_Realloc(Memory, Ar-array_EXTRA,
   (oldcap+array_EXTRA)*sizeof(intptr_t),
   (array_GetCapacity(Ar)+array_EXTRA)
   * sizeof(intptr_t));
    Ar = Ar + array_EXTRA;
    for(oldcap = array_GetSize(Ar);
 oldcap < array_GetCapacity(Ar); oldcap++)
      Ar[oldcap] = (intptr_t)NULL;
  }
  Ar[array_GetSize(Ar)] = El;
  array_SetSize(Ar, array_GetSize(Ar) + 1);
  return Ar;
}
void array_AddNoGrow(ARRAY Ar, intptr_t El)
{
#ifdef SPASS_CHECK
  if (array_GetSize(Ar) + 1 > array_GetCapacity(Ar)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n %s: adding to full array ",
       __func__);
    misc_FinishErrorReport();
  }
#endif
  Ar[array_GetSize(Ar)] = El;
  array_SetSize(Ar, array_GetSize(Ar) + 1);
}
void array_AddToArrayAtIndex(MEMORY Mem, ARRAY Ar, int Idx, intptr_t El)
{
  array_SetElement(Ar, Idx,
     (intptr_t)array_Add(Mem,
           (ARRAY)array_GetElement(Ar, Idx),
           El));
}
ARRAY array_Append(MEMORY Mem, ARRAY Ar1, ARRAY Ar2)
{
  unsigned i;
  Ar1 = array_Reserve(Mem, Ar1, array_GetSize(Ar1)+array_GetSize(Ar2)+1);
  for (i=0; i<array_GetSize(Ar2); ++i)
    array_AddNoGrow(Ar1, array_GetElement(Ar2, i));
  return Ar1;
}
ARRAY array_Union(MEMORY Mem, ARRAY Ar1, ARRAY Ar2)
{
  unsigned i,j;
  ARRAY new;
  new = array_Create(Mem, array_GetSize(Ar1)+array_GetSize(Ar2));
  array_SetSize(new, array_GetSize(Ar1)+array_GetSize(Ar2));
  for(i = 0; i < array_GetSize(Ar1); i++)
    array_SetElement(new,i,array_GetElement(Ar1,i));
  j = i;
  for(i = 0; i < array_GetSize(Ar2); i++,j++)
    array_SetElement(new,j,array_GetElement(Ar2,i));
  return new;
}
ARRAY array_AddAtIndex(MEMORY Memory, ARRAY Ar, int Idx,
    intptr_t El)
{
  int oldcap;
  oldcap = array_GetCapacity(Ar);
  while (array_GetCapacity(Ar) <= Idx)
    array_SetCapacity(Ar, (array_GetCapacity(Ar)
      * array_INCREASE)/100 + 1);
  if (oldcap !=array_GetCapacity(Ar)) {
    Ar = memory_Realloc(Memory, Ar-array_EXTRA,
   (oldcap+array_EXTRA)*sizeof(intptr_t),
   (array_GetCapacity(Ar)+array_EXTRA)
   * sizeof(intptr_t));
    Ar = Ar + array_EXTRA;
    for(oldcap = array_GetSize(Ar);
 oldcap < array_GetCapacity(Ar); oldcap++)
      Ar[oldcap] = (intptr_t)NULL;
  }
  if (array_GetSize(Ar) <= Idx)
    array_SetSize(Ar, Idx+1);
  Ar[Idx] = El;
  return Ar;
}
void array_NAddAtIndex(ARRAY Ar, int Idx, intptr_t El)
{
  Ar[Idx] = El;
}
void array_RemoveAtIndex(ARRAY Ar, int Idx)
{
  array_SetSize(Ar, array_GetSize(Ar) - 1);
  Ar[Idx] = Ar[array_GetSize(Ar)];
}
ARRAY array_AddGetIndex(MEMORY Memory, ARRAY Ar, intptr_t El,
   int *Index)
{
  int oldcap;
  if (array_GetSize(Ar) == array_GetCapacity(Ar))
  {
    oldcap = array_GetCapacity(Ar);
    array_SetCapacity(Ar, (array_GetCapacity(Ar)
      * array_INCREASE)/100 + 1);
    Ar = memory_Realloc(Memory, Ar-array_EXTRA,
   (oldcap+array_EXTRA)*sizeof(intptr_t),
   (array_GetCapacity(Ar)+array_EXTRA)
   * sizeof(intptr_t));
    for(oldcap = array_GetSize(Ar);
 oldcap < array_GetCapacity(Ar); oldcap++)
      Ar[oldcap] = (intptr_t)NULL;
  }
  Ar[array_GetSize(Ar)] = El;
  *Index = array_GetSize(Ar);
  array_SetSize(Ar, + 1);
  return Ar;
}
intptr_t array_GetElement(ARRAY Ar, int Idx)
{
#ifdef SPASS_CHECK
  if (!((Idx >= 0) && (Idx < array_GetSize(Ar)))) {
    misc_StartErrorReport();
    misc_ErrorReport("\n %s: %d outside array bounds. ",
       __func__, Idx);
    misc_FinishErrorReport();
  }
#endif
  return Ar[Idx];
}
void array_SetElement(ARRAY Ar, int Idx, intptr_t New_el)
{
#ifdef SPASS_CHECK
  if (!((Idx >= 0) && (Idx < array_GetSize(Ar)))) {
    misc_StartErrorReport();
    misc_ErrorReport("\n %s: %d outside array bounds (size: %d). ",
       __func__, Idx, array_GetSize(Ar));
    misc_FinishErrorReport();
  }
#endif
  Ar[Idx] = New_el;
}
BOOL array_ContainsElement(ARRAY Ar, intptr_t El, int * Index)
{
  int i;
  for(i = 0; i < array_GetSize(Ar); i++)
    if (Ar[i] == El) {
      *Index = i;
      return TRUE;
    }
  return FALSE;
}
BOOL array_Member(ARRAY Ar, intptr_t Element,
    BOOL (*Equal)(intptr_t, intptr_t))
{
  unsigned i;
  for (i = 0; i < array_GetSize(Ar); i++)
    if (Equal(Element, array_GetElement(Ar, i)))
      return TRUE;
  return FALSE;
}
BOOL array_HasElement(ARRAY Ar, intptr_t El)
{
  int i;
  for(i = 0; i < array_GetSize(Ar); i++)
    if (Ar[i] == El) {
      return TRUE;
    }
  return FALSE;
}
ARRAY array_Sort(ARRAY Ar,
     int (* Compartor) ( const void *, const void * ))
{
  qsort(Ar, array_GetSize(Ar), sizeof(Ar[0]), Compartor);
  return Ar;
}
size_t array_BSearch_r(ARRAY Ar, const void * Key, COMPARE_FUNC Compartor, void *arg)
{
  size_t l,m,u;
  int comp;
  const void * cur;
  l = 0;
  u = array_GetSize(Ar);
  while(l < u) {
    m = ((l+u)/2);
    cur = &(Ar[m]);
    comp = Compartor(Key,cur,arg);
    if(comp < 0)
      u=m;
    else if (comp > 0)
      l=m+1;
    else
      return m;
  }
  return SIZE_MAX;
}
int array_BSearch(ARRAY Ar, const void * Key,
       int (* Comparator) ( const void *, const void * ))
{
  intptr_t* result;
  result = (intptr_t*)bsearch(Key, Ar, array_GetSize(Ar),
         sizeof(Ar[0]), Comparator);
  if (result == NULL)
    return -1;
  else
    return (result - Ar);
}
ARRAY array_RemoveDuplicates(MEMORY Memory, ARRAY Ar,
        BOOL (*Equal)(intptr_t, intptr_t))
{
  unsigned i;
  for (i = 0; i < array_GetSize(Ar); i++)
    array_RemoveElementIndex(Ar, i+1,
        array_GetElement(Ar, i), Equal);
  return Ar;
}
void array_RemoveDuplicatesSorted(ARRAY Ar, BOOL (*Equal)(intptr_t, intptr_t))
{
  intptr_t i, j;
  if (array_GetSize(Ar) == 0) return;
  for (i=0,j=1; j<array_GetSize(Ar); ++j) {
    if (!Equal(array_GetElement(Ar, i), array_GetElement(Ar, j))) {
      array_SetElement(Ar, ++i, array_GetElement(Ar, j));
    }
  }
  array_SetSize(Ar, ++i);
}
void array_DeleteDuplicates(ARRAY Ar,
       BOOL (*Equal)(intptr_t, intptr_t),
       void* FreeState,
       void (*Free)(void* , intptr_t))
{
  unsigned i;
  for (i = 0; i < array_GetSize(Ar); i++)
    array_DeleteElementFreeIndex(Ar, i+1,
     array_GetElement(Ar, i),
     Equal, FreeState, Free);
}
void array_DeleteDuplicatesSorted(ARRAY Ar,
      BOOL (*Equal)(intptr_t, intptr_t),
      void* FreeState,
      void (*Free)(void*, intptr_t))
{
  intptr_t i, j;
  if (array_GetSize(Ar) == 0) return;
  for (i=0,j=1; j<array_GetSize(Ar); ++j) {
    if (!Equal(array_GetElement(Ar, i), array_GetElement(Ar, j))) {
      array_SetElement(Ar, ++i, array_GetElement(Ar, j));
    } else {
      Free(FreeState, array_GetElement(Ar, j));
    }
  }
  array_SetSize(Ar, ++i);
}
void array_Delete(MEMORY Memory, ARRAY Ar)
{
  memory_Free(Memory, Ar-array_EXTRA, (array_GetCapacity(Ar)+array_EXTRA)*sizeof(intptr_t));
}
intptr_t array_Top(ARRAY Ar)
{
  return Ar[array_GetSize(Ar)-1];
}
ARRAY array_Push(MEMORY Memory, ARRAY Ar, intptr_t El)
{
  return array_Add(Memory, Ar, El);
}
intptr_t array_Pop(ARRAY Ar)
{
  array_SetSize(Ar, array_GetSize(Ar) - 1);
  return Ar[array_GetSize(Ar)];
}
ARRAY array_Nconc(MEMORY Memory, ARRAY Ar1, ARRAY Ar2)
{
  int i;
  for(i = 0; i < array_GetSize(Ar2) ; i++){
    Ar1 = array_Add(Memory, Ar1,array_GetElement(Ar2,i));
  }
  array_Clean(Ar2);
  return Ar1;
}
ARRAY array_AddList(MEMORY Memory, ARRAY Ar, LIST List)
{
  while(!list_Empty(List)){
    Ar = array_Add(Memory, Ar,(intptr_t)list_Car(List));
    List = list_Cdr(List);
  }
  return Ar;
}
LIST array_ToList(MEMORY Memory, ARRAY Ar)
{
  LIST list1;
  list1 = list_Nil();
  while(array_GetSize(Ar) > 0){
    list1 = list_Cons(Memory, (POINTER)array_Pop(Ar),list1);
  }
  return list1;
}
void array_PointerRemoveElement(ARRAY Ar, intptr_t Element)
{
  unsigned i,j;
  for (i = 0, j = 0; i < array_GetSize(Ar); i++)
    if (array_GetElement(Ar, i) != Element) {
      array_SetElement(Ar, j, array_GetElement(Ar, i));
      j++;
    }
  array_SetSize(Ar, j);
}
void array_RemoveElementIndex( ARRAY Ar,
          unsigned Idx, intptr_t Element,
          BOOL (*Equal)(intptr_t, intptr_t))
{
  unsigned j, k;
  for (j = Idx, k = Idx; j < array_GetSize(Ar); j++)
    if (!Equal(Element, array_GetElement(Ar, j))) {
      array_SetElement(Ar, k, array_GetElement(Ar, j));
      k++;
    }
  array_SetSize(Ar, k);
}
void array_DeleteWithElement(MEMORY Memory, ARRAY Ar,
        void* FreeState, void (*Free)(void* , intptr_t))
{
  intptr_t i;
  for (i = 0; i < array_GetSize(Ar); i++)
    Free(FreeState, array_GetElement(Ar, i));
  array_Delete(Memory, Ar);
}
void array_DeleteElementFreeIndex(ARRAY Ar,
       unsigned Idx, intptr_t Element,
       BOOL (*Equal)(intptr_t, intptr_t),
       void *FreeState,
       void (*Free)(void*, intptr_t))
{
  unsigned j, k;
  for (j = Idx, k = Idx; j < array_GetSize(Ar); j++)
    if (!Equal(Element, array_GetElement(Ar, j))) {
      array_SetElement(Ar, k, array_GetElement(Ar, j));
      k++;
    } else
      Free(FreeState, array_GetElement(Ar, j));
  array_SetSize(Ar, k);
}
ARRAY array_DeleteElementIf(ARRAY Ar, BOOL (*Test)(intptr_t),
    void* FreeState, void (*Free)(void*,intptr_t))
{
  intptr_t scan;
  int i,j;
  i = j = 0;
  while(i < array_GetSize(Ar)){
    scan = array_GetElement(Ar,i);
    if(Test(scan)){
      Free(FreeState,scan);
      array_SetElement(Ar,i,(intptr_t)NULL);
    }else{
      array_SetElement(Ar,j,scan);
      j++;
    }
    i++;
  }
  i = i-j;
  while(i>0){
    array_Pop(Ar);
    i--;
  }
  return Ar;
}
void array_NMap(ARRAY Ar, intptr_t (*ElementFunc)(intptr_t))
{
  unsigned i;
  for (i = 0; i < array_GetSize(Ar); i++)
    array_SetElement(Ar, i,
       ElementFunc(array_GetElement(Ar, i)));
}
void array_Apply(void (*Function)(intptr_t), ARRAY Ar)
{
  unsigned i;
  for (i = 0; i < array_GetSize(Ar); i++)
    Function(array_GetElement(Ar, i));
}
ARRAY array_PairCreate(MEMORY Mem, intptr_t P1, intptr_t P2)
{
  ARRAY pair;
  pair = array_Create(Mem, 2);
  return array_Add(Mem, array_Add(Mem, pair, P1), P2);
}
void array_PairDelete(MEMORY Mem, intptr_t Ar)
{
  array_Delete(Mem, (intptr_t *)Ar);
}
intptr_t array_PairFirst(ARRAY Ar)
{
  return array_GetElement(Ar, 0);
}
intptr_t array_PairSecond(ARRAY Ar)
{
  return array_GetElement(Ar, 1);
}
void array_PairRplacSecond(ARRAY Ar, intptr_t P)
{
  array_SetElement(Ar, 1, P);
}
void array_DeletePairArray(MEMORY Mem, ARRAY Ar)
{
  array_DeleteWithElement(Mem, Ar, (void*)Mem,
     (void (*)(void *, intptr_t))array_PairDelete);
}
ARRAY array_TripleCreate(MEMORY Mem, intptr_t P1, intptr_t P2, intptr_t P3)
{
  ARRAY pair;
  pair = array_Create(Mem, 3);
  return array_Add(Mem, array_Add(Mem, array_Add(Mem, pair, P1), P2), P3);
}
void array_TripleDelete(MEMORY Mem, ARRAY Ar)
{
  array_Delete(Mem, Ar);
}
intptr_t array_TripleFirst(ARRAY Ar)
{
  return array_GetElement(Ar, 0);
}
intptr_t array_TripleSecond(ARRAY Ar)
{
  return array_GetElement(Ar, 1);
}
intptr_t array_TripleThird(ARRAY Ar)
{
  return array_GetElement(Ar, 2);
}
ARRAY array_QTupleCreate(MEMORY Mem, intptr_t P1, intptr_t P2, intptr_t P3, intptr_t P4)
{
  ARRAY pair;
  pair = array_Create(Mem, 4);
  return array_Add(Mem, array_Add(Mem, array_Add(Mem, array_Add(Mem, pair, P1), P2), P3), P4);
}
void array_QTupleDelete(MEMORY Mem, ARRAY Ar)
{
  array_Delete(Mem, Ar);
}
intptr_t array_QTupleFirst(ARRAY Ar)
{
  return array_GetElement(Ar, 0);
}
intptr_t array_QTupleSecond(ARRAY Ar)
{
  return array_GetElement(Ar, 1);
}
intptr_t array_QTupleThird(ARRAY Ar)
{
  return array_GetElement(Ar, 2);
}
intptr_t array_QTupleFourth(ARRAY Ar)
{
  return array_GetElement(Ar, 3);
}
ARRAY array_STupleCreate(MEMORY Mem, intptr_t P1, intptr_t P2, intptr_t P3, intptr_t P4, intptr_t P5, intptr_t P6)
{
  ARRAY pair;
  pair = array_Create(Mem, 6);
  return array_Add(Mem, array_Add(Mem,array_Add(Mem,array_Add(Mem, array_Add(Mem, array_Add(Mem, pair, P1), P2), P3), P4), P5), P6);
}
void array_STupleDelete(MEMORY Mem, ARRAY Ar)
{
  array_Delete(Mem, Ar);
}
intptr_t array_STupleFirst(ARRAY Ar)
{
  return array_GetElement(Ar, 0);
}
intptr_t array_STupleSecond(ARRAY Ar)
{
  return array_GetElement(Ar, 1);
}
intptr_t array_STupleThird(ARRAY Ar)
{
  return array_GetElement(Ar, 2);
}
intptr_t array_STupleFourth(ARRAY Ar)
{
  return array_GetElement(Ar, 3);
}
intptr_t array_STupleFifth(ARRAY Ar)
{
  return array_GetElement(Ar, 4);
}
intptr_t array_STupleSixth(ARRAY Ar)
{
  return array_GetElement(Ar, 5);
}
void array_DeleteDistribution(MEMORY Mem, ARRAY Ar)
{
  array_DeletePairArray(Mem, Ar);
}
ARRAY array_AssocAdd(MEMORY Mem, ARRAY Ar, intptr_t Key,
       intptr_t Value)
{
  return array_Add(Mem, Ar, (intptr_t)
     array_PairCreate(Mem, Key, Value));
}
ARRAY array_AssocArrayPair(ARRAY Ar, intptr_t Key)
{
  unsigned i;
  for (i = 0; i < array_GetSize(Ar); i++)
    if (Key == array_GetElement((ARRAY)
    array_GetElement(Ar, i), 0))
      return (ARRAY)array_GetElement(Ar, i);
  return NULL;
}
ARRAY array_MultisetDistribution(MEMORY Mem, ARRAY Multiset)
{
  ARRAY distribution, count;
  unsigned i;
  intptr_t element;
  distribution = array_Create(Mem, 2);
  for (i = 0; i < array_GetSize(Multiset); i++) {
    element = array_GetElement(Multiset, i);
    count = array_AssocArrayPair(distribution, element);
    if (count) {
      array_SetElement(count, 1, array_GetElement(count, 1)+1);
    } else {
      distribution = array_AssocAdd(Mem, distribution,
        element, 1);
    }
  }
  return distribution;
}
int array_CompareLexicographical(ARRAY left, ARRAY right, COMPARE_FUNC compare, void* arg)
{
  int res,i,s1,s2;
  intptr_t elLeft,elRight;
  s1 = array_GetSize(left);
  s2 = array_GetSize(right);
  res = misc_IntCmp(&s1,&s2);
  if(res==0){
    for(i = 0;i<array_GetSize(left);i++){
      elLeft = array_GetElement(left,i);
      elRight = array_GetElement(right,i);
      res = compare(&elLeft,&elRight,arg);
      if(res!=0)
        break;
    }
  }
  return res;
}
int array_CompareLexicographical_func(const void* left, const void* right, void* arg_packed)
{
  void **args;
  COMPARE_FUNC compare;
  void* arg;
  args = (void**) arg_packed;
  compare = (COMPARE_FUNC) (((misc_func *)(args[0]))->func);
  arg = (args[1]);
  return array_CompareLexicographical(*((ARRAY*) left), *((ARRAY*) right), compare, arg);
}
int array_CompareElementDistribution(ARRAY LeftPair,
         ARRAY RightPair)
{
  if (array_PairSecond(LeftPair) <
      array_PairSecond(RightPair)) {
    return -1;
  }
  else if (array_PairSecond(LeftPair) >
    array_PairSecond(RightPair)) {
    return 1;
  }
  return 0;
}
BOOL array_CompareElementDistributionLEQ(ARRAY LeftPair,
      ARRAY RightPair) {
  return (array_CompareElementDistribution(LeftPair, RightPair) <= 0);
}
int array_CompareDistributions(ARRAY Left, ARRAY Right)
{
  unsigned i;
  int result;
  result = 0;
  for (i = 0; i < array_GetSize(Left) &&
  i < array_GetSize(Right); i++) {
    result = array_CompareElementDistribution((ARRAY)
           array_GetElement(Left, i),
           (ARRAY)
           array_GetElement(Right, i));
  if (result != 0)
    break;
  }
  if(result == 0) {
    if(array_GetSize(Left) < array_GetSize(Right))
      return -1;
    else
      if(array_GetSize(Left) > array_GetSize(Right))
 return 1;
  }
  return result;
}
int array_CompareMultisetsByElementDistribution(MEMORY Mem,
      ARRAY Left,
      ARRAY Right)
{
  ARRAY lmsd, rmsd;
  int result;
  lmsd = array_MultisetDistribution(Mem, Left);
  rmsd = array_MultisetDistribution(Mem, Right);
  lmsd = array_Sort(lmsd, ((int (*) (const void*, const void*))
      array_CompareElementDistribution));
  rmsd = array_Sort(rmsd, (int (*) (const void*, const void*))
      array_CompareElementDistribution);
  result = array_CompareDistributions(lmsd, rmsd);
  array_DeleteDistribution(Mem, lmsd);
  array_DeleteDistribution(Mem, rmsd);
  return result;
}
BOOL array_Exist(ARRAY Ar)
{
  return Ar != NULL;
}
unsigned array_Bytes(ARRAY Ar)
{
  return (array_GetCapacity(Ar)+array_EXTRA)*sizeof(intptr_t);
}
