#ifndef _LIST_
#define _LIST_ 
#include "memory.h"
#include "misc.h"
typedef struct LIST_HELP {
  struct LIST_HELP *cdr;
  POINTER car;
} LIST_NODE;
typedef LIST_NODE *LIST;
void list_Free(MEMORY, LIST);
LIST list_Nil(void);
BOOL list_Empty(LIST);
BOOL list_Exist(LIST);
POINTER list_Car(LIST);
POINTER list_NCar(MEMORY, LIST *);
LIST list_Cdr(LIST L);
POINTER list_First(LIST L);
POINTER list_Second(LIST L);
POINTER list_Third(LIST L);
POINTER list_Fourth(LIST L);
POINTER list_Fifth(LIST L);
void list_Rplacd(LIST L1, LIST L2);
void list_Rplaca(LIST L, POINTER P);
void list_RplacSecond(LIST L, POINTER P);
LIST list_Copy(MEMORY, const LIST);
LIST list_CopyWithElement(MEMORY, const LIST, POINTER (*)(MEMORY, POINTER));
void list_InsertNext(MEMORY, LIST, POINTER);
void list_NMapCar(LIST, POINTER (*)(POINTER));
void list_Apply(void (*)(POINTER), LIST);
LIST list_Reverse(MEMORY, const LIST);
LIST list_NReverse(MEMORY, LIST);
void list_Split(LIST, LIST *, LIST *);
LIST list_PointerSort(LIST);
LIST list_Merge(LIST, LIST, BOOL (*)(POINTER, POINTER));
LIST list_MergeSort(LIST, BOOL (*)(POINTER, POINTER));
LIST list_InsertionSort(LIST, BOOL (*)(POINTER, POINTER));
LIST list_Sort(LIST, BOOL (*)(POINTER, POINTER));
BOOL list_SortedInOrder(LIST, BOOL (*)(POINTER, POINTER));
LIST list_NumberSort(LIST , NAT (*)(POINTER));
LIST list_GreaterNumberSort(LIST , NAT (*)(POINTER));
LIST list_NNumberMerge(LIST , LIST, NAT (*)(POINTER));
POINTER list_DequeueNext(MEMORY, LIST);
POINTER list_NthElement(LIST, NAT);
void list_DeleteWithElement(MEMORY, LIST, void (*)(MEMORY, POINTER));
NAT list_DeleteWithElementCount(MEMORY, LIST, void (*)(MEMORY, POINTER));
LIST list_DeleteElement(MEMORY, LIST, POINTER, BOOL (*)(POINTER, POINTER));
LIST list_DeleteElementIf(MEMORY, LIST, BOOL (*)(POINTER));
LIST list_DeleteElementIfFree(MEMORY, LIST, BOOL (*)(POINTER), void (*)(POINTER));
LIST list_DeleteElementFree(MEMORY, LIST, POINTER, BOOL (*)(POINTER, POINTER), void (*)(MEMORY, POINTER));
LIST list_DeleteOneElement(MEMORY, LIST, POINTER, BOOL (*)(POINTER, POINTER));
LIST list_PointerDeleteElement(MEMORY, LIST, POINTER);
LIST list_PointerDeleteElementFree(MEMORY, LIST, POINTER, void (*)(POINTER));
LIST list_PointerDeleteOneElement(MEMORY, LIST, POINTER);
BOOL list_DeleteFromList(MEMORY,LIST*, POINTER);
BOOL list_DeleteOneFromList(MEMORY, LIST*, POINTER);
LIST list_DeleteDuplicates(MEMORY, LIST, BOOL (*)(POINTER, POINTER));
LIST list_DeleteDuplicatesFree(MEMORY, LIST, BOOL (*)(POINTER, POINTER), void (*)(MEMORY,POINTER));
LIST list_PointerDeleteDuplicates(MEMORY, LIST);
BOOL list_IsSetOfPointers(LIST);
LIST list_NPointerUnion(MEMORY, LIST, LIST);
LIST list_NUnion(MEMORY, LIST, LIST, BOOL (*)(POINTER, POINTER));
LIST list_NListTimes(MEMORY, LIST, LIST);
LIST list_NIntersect(MEMORY, LIST, LIST, BOOL (*)(POINTER, POINTER));
LIST list_Nconc(LIST, LIST);
void list_NInsert(LIST, LIST);
LIST list_NPointerIntersect(MEMORY, LIST, LIST);
BOOL list_HasIntersection(LIST, LIST);
LIST list_NPointerDifference(MEMORY, LIST, LIST);
LIST list_NDifference(MEMORY, LIST, LIST, BOOL (*)(POINTER, POINTER));
LIST list_NMultisetDifference(MEMORY, LIST, LIST, BOOL (*)(POINTER, POINTER));
BOOL list_PointerReplaceMember(LIST, POINTER, POINTER);
void list_DeleteAssocListWithValues(MEMORY, LIST, void (*)(MEMORY, POINTER));
POINTER list_AssocListValue(LIST, POINTER);
LIST list_AssocListPair(LIST, POINTER);
LIST list_MultisetDistribution(MEMORY, LIST);
int list_CompareMultisetsByElementDistribution(MEMORY, LIST, LIST);
NAT list_Length(LIST);
NAT list_Bytes(LIST);
LIST list_Cons(MEMORY, POINTER, const LIST);
LIST list_List(MEMORY, POINTER P);
LIST list_Append(MEMORY, LIST List1, LIST List2);
void list_Delete(MEMORY, LIST L);
BOOL list_Member(LIST List, POINTER Element,
       BOOL (*Test)(POINTER, POINTER));
POINTER list_GetMember(LIST List, POINTER Element,
       BOOL (*Test)(POINTER, POINTER));
BOOL list_PointerMember(LIST List, POINTER Element);
LIST list_StackBottom(void);
BOOL list_StackEmpty(LIST);
LIST list_Push(MEMORY, POINTER, LIST);
POINTER list_Top(LIST);
LIST list_Pop(MEMORY, LIST);
void list_RplacTop(LIST, POINTER);
LIST list_StackFree(MEMORY, LIST);
LIST list_PairNull(void);
LIST list_PairCreate(MEMORY, POINTER, POINTER);
void list_PairFree(MEMORY, LIST);
POINTER list_PairFirst(LIST);
POINTER list_PairSecond(LIST);
void list_PairRplacSecond(LIST, POINTER);
void list_DeletePairList(MEMORY, LIST);
void list_DeleteDistribution(MEMORY, LIST);
LIST list_AssocCons(MEMORY, LIST, POINTER, POINTER);
#endif
