Logic Sets

A.First Edition
This is the first edition of my LogicSets class and it has been lingering in my mind for a long time. 
B.Idea of program
1¡£ Basic idea: 
To create a couple of classes: LogicSets---the container, Elements---the member class. You can imagine it is 
something like linked list with parent having a list containing all his sons. Inside parent(LogicSets), I used
my own version of dynamic list which is a template. :)
My favourite part is the "for all" and "exist" function for a set. It is the implementation of logic universal 
and existential quantifiers! I used a call-back-function to implement them. 
2¡£ Program design: 
The two classes are recursively declared, so a forward declaration is necessary. Originally I plan to implement multi-type 
constructor for versatile. But later I found out it maybe useless. A general "traverse" call-back function is added besides 
the "universal" and "existential" quantifier functions. Actually there are quite few new codes apart from old "myList" which
is a dynamic template list.
3¡£ Major function
 A.  bool LogicSets::exists(bool (*checkEach)(Elements* each))
     bool LogicSets::forAll(bool (*checkEach)(Elements* each))
     void LogicSets::forEach(void (*checkEach)(Elements* each))
These are three call-back functions. The first two are "universal" and "existential" quantifier for sets.
The last one is only general purpose callback.
4¡£ Further improvement£º
	A. To include this class in my further projects like "relations".
#include <iostream>

using namespace std;

template<class T>
class mylist
{
private:
	T *flist;
	int LENGTH;
	int SIZE;
	int counter;
protected:
	void uninitialize();
	void initialize();
	bool checksize();
	void expand();
	int locate(T ptr);
public:
	mylist();
	~mylist();
	void add(T ptr);
	bool find(T ptr);
	void display();
	int count();
	T& items(int index);
	void insert(int index, T ptr);

};


class LogicSets;

class Elements
{
	long ID;  //plan to use address to represent as ID
	char* name;
	LogicSets* parent;
public:
	LogicSets* belong() { return parent; }
	char* getName() { return name;}
	void setName(const char* givenName);
	bool belong(LogicSets* father){ return father== parent;}
	void setParent(LogicSets* father) { parent = father;}
	Elements(LogicSets* father);
	~Elements();
};

class LogicSets 
{
private:
	mylist<Elements*> lst;
public:
	bool include(Elements* pElement);
	void add(Elements* pElement);
	void create(char* givenName);
	bool forAll( bool (*checkEach)(Elements* each)); //call back function "for all"
	bool exists( bool (*checkEach)(Elements* each)); //call back function "exist"
	void forEach( void (*checkEach)(Elements* each)); //call back function for general purpose
	~LogicSets();
};

//to check all if all are string like "this is no.5"
bool allCheck(Elements* each)
{
	return strcmp(each->getName(), "this is no.5") == 0;
}

bool existCheck(Elements* each)
{
	return strcmp(each->getName(), "this is no.5") == 0;
}

void showEach(Elements* each)
{
	cout<<each->getName()<<endl;
}


int main()
{
	LogicSets someSets;
	char nameBuffer[15];
	char buffer[3];
	for (int i =0; i<20; i++)
	{
		itoa(i, buffer, 10);
		strcpy(nameBuffer, "this is no.");
		someSets.create(strcat(nameBuffer, buffer));
	}
	cout<<"now output all elements by showing their name"<<endl;
	someSets.forEach(showEach);
	cout<<endl;
	cout<<"now for all check to see if all elments' name are 'this is no.5'"<<endl;
	cout<<"allcheck result is: "<<(someSets.forAll(allCheck)?"true":"false")<<endl;
	cout<<endl;
	cout<<"now check if exist an element such that its name is 'this is no.5'"<<endl;
	cout<<"exist check result is:"<<(someSets.exists(existCheck)?"true":"false")<<endl;

	return 0;
}


LogicSets::~LogicSets()
{
	for (int i=0; i<lst.count(); i++)
	{
		delete lst.items(i);
	}
}

void LogicSets::forEach(void (*checkEach)(Elements* each))
{
	for (int i = 0; i< lst.count(); i++)
	{
		checkEach(lst.items(i));
	}
}


Elements::~Elements()
{
	if (name!=NULL)
	{
		free(name);
	}
}



Elements::Elements(LogicSets* father)
{
	parent = father;
	setName("no name");
}

void Elements::setName(const char* givenName)
{
	name = (char*)malloc(strlen(givenName)+1);
	strcpy(name, givenName);
}



void LogicSets::create(char* givenName)
{
	Elements* ptr;
	ptr = new Elements(this);
	ptr->setParent(this);
	ptr->setName(givenName);
	lst.add(ptr);
}

void LogicSets::add(Elements* pElement)
{
	lst.add(pElement);
}

bool LogicSets::forAll(bool (*checkEach)(Elements* each))
{
	for (int i=0; i< lst.count() - 1; i++)
	{
		if (!checkEach(lst.items(i)))
		{
			return false;
		}
	}
	return true;
}

bool LogicSets::exists(bool (*checkEach)(Elements* each))
{
	for (int i=0; i< lst.count() - 1; i++)
	{
		if (checkEach(lst.items(i)))
		{
			return true;
		}
	}
	return false;
}



//dynamic list

template<class T>
void mylist<T>::insert(int index, T ptr)
{
	if (!checksize())
		expand();

	if (counter == 0)
	{
		items(0) = ptr;
		counter++;
	}
	else
	{
		if (index>=0&& index<=counter)
		{
			int i=index;
			T hold1 = items(index), hold2= items(index+1);
			while (i<counter)
			{	
				hold2 = items(i+1);
				items(i+1) = hold1;
				hold1 = hold2;				
				i++;
			}
			items(index) = ptr; //any exception trap???
			counter++;
		}
	}
}
			
template<class T>
int mylist<T>::locate(T ptr)
{
	int index = 0;
	while (items(index) <ptr &&index <counter)
	{
		index++;
	}
	return index;
}



template<class T>
bool mylist<T>::find(T ptr)
{
	int index = 0;

	index = locate(ptr);
	if (index == counter)
	{
		return false;
	}
	else
	{
		return (items(index) == ptr);
	}
}


template<class T>
int mylist<T>::count()
{
	return counter;
}

template<class T>
T& mylist<T>::items(int index)
{
	return flist[index];
}


template<class T>
void mylist<T>::display()
{
	cout<<setiosflags(ios::showpoint|ios::fixed);
	for (int i = 0; i < counter; i ++)
	{
		cout<<"Number "<<i<<" item is:"<<flist[i]<<endl;
	}
}

template<class T>
void mylist<T>::uninitialize()
{
	free(flist);
}

template<class T>
mylist<T>::~mylist()
{
	uninitialize();
}


template<class T>
void mylist<T>::add(T ptr)
{ 
	int index;
	index = locate(ptr);
	if (items(index)!=ptr)
	{
		insert(index, ptr);
	}
}

template<class T>
void mylist<T>::initialize()
{
	LENGTH = 10;
	SIZE = LENGTH;
	if ((flist =(T*)(malloc(sizeof(T) * SIZE)))==NULL)
		cout<<"Unable malloc memory for size of "<<SIZE<<endl;  //exception need to be handled here!!
	counter = 0;
}

template<class T>
bool mylist<T>::checksize()
{
	return (counter < SIZE);
}

template<class T>
void mylist<T>::expand()
{
	SIZE += LENGTH;
	if ((flist = (T*)(realloc(flist, sizeof(T) * SIZE)))== NULL)
		cout<<"Unable realloc memory for mylist of size "<<SIZE<<endl;
}

template<class T>
mylist<T>::mylist()
{
	initialize();
}



¡¡ This simple output result demonstrate the 3 call-back functions:

1. The forEach can "traverse" all members with programmer-defined call-back function to do specific job for

each element.

2. The "universal" and "existential" quantifier check to give correct results.

now output all elements by showing their name
this is no.1
this is no.0
this is no.11
this is no.19
this is no.18
this is no.17
this is no.16
this is no.15
this is no.14
this is no.13
this is no.12
this is no.10
this is no.9
this is no.8
this is no.7
this is no.6
this is no.5
this is no.4
this is no.3
this is no.2

now for all check to see if all elments' name are 'this is no.5'
allcheck result is: false

now check if exist an element such that its name is 'this is no.5'
exist check result is:true
¡¡


¡¡

                                                        back.gif (341 bytes)       up.gif (335 bytes)         next.gif (337 bytes)

Hosted by www.Geocities.ws

1