
/*******************************************************************
 CGIF file parser

            ---- Objective ----
 paser for CGIF file and generate tokens and elements, say, concept,
 relation, and comment. 

 Author: Da Sun     email: sunda@nsstc.uah.edu
 Nov. 23 2001
 ********************************************************************/

#pragma warning(disable: 4786)  // Disable debug information warning

#include "token.h"
#include "CGEngine/CKnowledgeBase.h"
#include "CGEngine/CTypeHierarchy.h"
#include "CGEngine/CTypeDefinition.h"
#include "CGEngine/CRelationHierarchy.h"
#include "CGEngine/CRelationDefinition.h"
#include "CGEngine/CCatalogOfIndividuals.h"
#include "CGEngine/CSheetOfAssertion.h"
#include "CGEngine/ACCGFactory.h"

/*******************************************************************
Define a simple version of CGIF file as following

  DefLabel    ::= "*" Identifier?
  BoundLabel  ::= "?" Identifier?
  concept     ::= "[" Type(1)? {corefLinks?, referent? }? comment? "]"
  corefLinks  ::= DefLabel | BoundLabel*
  referent    ::= ":" {designator?}
  designator  ::= Locator | Quantofier
  locator     ::= name | IndividualMarker | Indexical

  relation    ::= "(" Type(N) Arc* comment? ")"
  Arc         ::= concept | BoundLabel
  Type(N)     ::= Identifier
  
  CG          ::= (concept | relation |comment)*  

  ----------------------------------------------------------------------
  then we have the new expression of the above expression
  concept     ::= "[" Indentifier? {corefLinks?, referent? }? comment? "]"
  corefLinks  ::= DefLabel | BoundLabel*
  quantifier  ::= "@" (Identifier ( "{" Arc* "}" )?)
  referent    ::= ":" { name | IndividualMarker | Indexical | quantifier}?
  relation    ::= "(" Identifier Arc* comment? ")"
  Arc         ::= concept | BoundLabel
  DefLabel    ::= "*" Identifier?
  BoundLabel  ::= "?" Identifier?
  
  CG          ::= (concept | relation |comment)*  
***************************************************/

typedef struct stringlisttype
{
	char value[TOKENSIZE];
	stringlisttype* next;
} stringliststruct;

typedef struct quantifiertype
{
	char name[TOKENSIZE];
    stringlisttype* stringlist;
}quantifierstruct;

typedef struct coreflinktype
{
	char value[TOKENSIZE];
	char kind[KINDSIZE];
	coreflinktype *next;
} coreflinkstruct;

typedef struct referenttype
{
	char kind[KINDSIZE];
	char value[TOKENSIZE];
    quantifiertype* quantifier;

	referenttype *next;
}referentstruct;

typedef struct concepttype
{
	char name[NAMESIZE];
    coreflinktype *coreflinks;
    referenttype *referlinks;
	char comment[COMMENTSIZE];
} conceptstruct;

typedef struct arctype
{
	char con_bound[NAMESIZE];  //it is a "concept" or "boundlabel" 
	concepttype *concept;
	char boundLabel[NAMESIZE];
}arcstruct;

typedef struct arclisttype
{
	arctype *arc;
	arclisttype *next;
}arclist;

typedef struct relationtype
{
	char name[NAMESIZE];
    arclisttype *arcs;
    char comment[COMMENTSIZE];
} relationstruct;



/* the erro process */
void error(char *msg)
{
    perror(msg);
    exit(0);
}

//IndividualMarker | Indexical 
int getIndexIndiv(simpleTokenType *simpleTokenList, int* position,
				char* label, int tokenNumber)
{
	if( (*position < tokenNumber) &&
	    (!strcmp(simpleTokenList[*position].value,"#")) )
	{
	   if( (*position < tokenNumber-1) &&
	      (simpleTokenList[*position+1].kind == identifier) )
	   {
		  strcpy(label,simpleTokenList[*position+1].value);
		  (*position) +=2;
		  return 1;
	   }
	   else 
	   {
		  strcpy(label," ");
		  (*position) ++;
		  return 1;
	   }
	} 
	return 0;
}


// DefLabel ::= "*" Identifier
int getDefLabel(simpleTokenType *simpleTokenList, int* position,
				char* label, int tokenNumber)
{
	if( (*position < tokenNumber) &&
	    (!strcmp(simpleTokenList[*position].value,"*")) )
	{
	   if( (*position < tokenNumber-1) &&
	      (simpleTokenList[*position+1].kind == identifier) )
	   {
		  strcpy(label,simpleTokenList[*position+1].value);
		  (*position) +=2;
		  return 1;
	   }
	   else error("unend defLabel\n");
	} 
	return 0;
}


// BoundLabel ::= "?" Indetifier
int getBoundLabel (simpleTokenType *simpleTokenList, int* position, 
				   char*label, int tokenNumber)
{
	if(*position < tokenNumber-1)
	{
		if(!strcmp(simpleTokenList[*position].value,"?") )
		{
			if(simpleTokenList[*position+1].kind == identifier) 
			{
				strcpy(label,simpleTokenList[*position+1].value);
		        (*position) += 2;
		        return 1;
			} 
			else error("Unend Bound Label\n");
		}
	}
	return 0;
}


/*typedef struct stringlisttype
{
	char value[TOKENSIZE];
	stringlisttype* next;
} stringliststruct;

typedef struct quantifiertype
{
	char name[TOKENSIZE];
    stringlisttype* stringlist;
}  */


//quantifier  ::= "@" (Identifier ( "{" Arc* "}" )?)
int getQuantifier(simpleTokenType *simpleTokenList, int* position, 
				  quantifiertype* quan, int tokenNumber)
{
	int cur= *position;

	(*position) ++;
	if( (*position < tokenNumber) &&
		(!strcmp(simpleTokenList[*position].value,"@") ) )
	{
		if(*position < tokenNumber-1) 
		{
		   if (simpleTokenList[*position+1].kind == identifier) 
		   {
		       strcpy(quan->name,simpleTokenList[*position+1].value);
		       (*position) += 2;
		   }
		    
		   if( (*position < tokenNumber) &&
		       (!strcmp(simpleTokenList[*position].value,"{") ) )
		   {
			   (*position) ++;
			   int curpos= *position;

			   while( strcmp(simpleTokenList[*position].value, "}") )
			   {
			       if( simpleTokenList[*position].kind == identifier )
				   {
					   stringlisttype *node=new stringlisttype;
					   strcpy(node->value,simpleTokenList[*position].value);
					   node->next=NULL;

					   if(quan->stringlist == NULL) 
					      quan->stringlist = node;
 				       else
					   {
					      stringlisttype *temp=quan->stringlist;
					      while(temp->next != NULL) temp= temp->next;
					      temp->next = node;
					   }
				   }
				   (*position)++;
			   }

			   if( strcmp(simpleTokenList[*position].value,"}") )
			   {
				   *position = curpos;
				   return 0;
			   }
			   else 
			   {
				   (*position)++;
				   return 1;
			   }
		   }
		}
	} else *position =cur;

	return 0;
}

int getReferent (simpleTokenType *simpleTokenList, int* position, 
				 referenttype* ref, int tokenNumber)
{
	if( (*position < tokenNumber) &&
		(!strcmp(simpleTokenList[*position].value,":") ) )
	{
		if(*position < tokenNumber-1) 
		{
		   if (simpleTokenList[*position+1].kind == identifier) 
		   {
		       strcpy(ref->value,simpleTokenList[*position+1].value);
			   strcpy( ref->kind, "name");
			   (*position) += 2;
		       return 1;
			}
			
		    else
			{
				if( (!strcmp(simpleTokenList[*position+1].value, "#") )
			         && (*position < tokenNumber-2) &&  
					(simpleTokenList[*position+2].kind == identifier) )
				{
					strcpy(ref->value,simpleTokenList[*position+2].value);
					strcpy( ref->kind, "indmaker");
		            (*position) += 3;
		            return 1;
				}
				
				else 
				{
				    quantifiertype* quan = new quantifiertype;
				    quan->stringlist = NULL;

					if( getQuantifier(simpleTokenList, position, 
				          quan,tokenNumber) )
					{
						ref->quantifier = quan;
						strcpy( ref->kind, "quant");
						return 1;
					}
                }
			}
		}
	}
	return 0;
}

//";" anything ";"
int getComment (simpleTokenType *simpleTokenList, int* position, 
				char* com, int tokenNumber)
{
	strcpy(com, "");
	if(*position < tokenNumber)
	{
		int temp=*position;
        if( !strcmp(simpleTokenList[*position].value , ";") && 
			(*position < tokenNumber-1) )
		{
		   if(*position < tokenNumber) 
		   {
			   (*position)++;
	           while( strcmp(simpleTokenList[*position].value, ";") )
			   {
		          strcat( com, " ");
		          strcat( com, simpleTokenList[*position].value);
		          if(*position < tokenNumber) (*position)++;
		          else error("unend comment\n");
			   }
			   (*position)++;
			   return 1;
		   } else return 0;
		}  
	} 
	return 0;
}
	
//corefLinks  ::= DefLabel | BoundLabel*
int getCorefLinks(simpleTokenType *simpleTokenList, int* position, 
				  char* coref,char* type, int tokenNumber)
{
	if(*position < tokenNumber)
	{
		char label[NAMESIZE];
        if(getDefLabel(simpleTokenList, position, label, tokenNumber) )
		{
	       strcpy(coref, label);
	       strcpy(type,"*");
		   return 1;
		}

        else
		{ 
	       if (getBoundLabel(simpleTokenList, position, label,tokenNumber) )
		   {
		      strcpy(coref, label);
		      strcpy(type, "?");
		      return 1;
		   }
		   else return 0;
		}

	} 
	return 0;
}


//concept::= "[" Indentifier? {corefLinks?, referent? }? comment? "]"
int getConcept(simpleTokenType *simpleTokenList, int* position, 
			   concepttype* concept, int tokenNumber)
{
	int startPosition = *position;
	if(*position < tokenNumber)
	{
	    if( (!strcmp(simpleTokenList[*position].value, "[") ) &&
			(*position < tokenNumber-1) )
		{
           if(simpleTokenList[(*position) +1].kind == identifier)
		   {
		       strcpy(concept->name, simpleTokenList[*position+1].value);  
		      (*position) +=2;
		   }
	       else (*position) +=1;
	   
	       int flag=0;
	       do
		   {
		      char coref[NAMESIZE];
		      char type[KINDSIZE];

		      if(flag=getCorefLinks(simpleTokenList, position, coref, 
				                    type, tokenNumber))
			  {
                 coreflinktype *coreftemp = new coreflinktype;
			     coreftemp->next =NULL;

                 strcpy( coreftemp->value, coref);
			     strcpy( coreftemp->kind, type);
			   
			     if(concept->coreflinks == NULL) concept->coreflinks = coreftemp;
			     else
				 {
				    coreflinktype *curr= concept->coreflinks;
				    coreflinktype *next= curr->next;

				    while(next != NULL) 
					{
					   curr = curr->next;
					   next = curr->next;
					}
				    curr->next = coreftemp;
				 }
			  }
		   } while(flag);

	       flag=0;
	       do 
		   {
			  referenttype *ref = new referenttype;
			  ref->next = NULL;
		      if(flag=getReferent(simpleTokenList, position, ref,tokenNumber))
			  {
                  if(concept->referlinks == NULL) concept->referlinks = ref;
			      else
				  {
				      referenttype *curr= concept->referlinks;
				      referenttype *next= curr->next;

				      while(next != NULL) 
					  {
					     curr = curr->next;
					     next = curr->next;
					  }
				      curr->next = ref;
				  }
			  }
		   } while(flag);

           char com[COMMENTSIZE];
	       if(getComment (simpleTokenList, position, com, tokenNumber) )
		       strcpy(concept->comment, com);
           if( !strcmp(simpleTokenList[*position].value, "]") )
		   {
		      (*position)++;
		      return 1;
		   }
	    }
	} 

	*position = startPosition;
	return 0;
}	



//Arc ::= concept | BoundLabel
int getArc(simpleTokenType *simpleTokenList, int* position, 
		   arctype *arc, int tokenNumber)
{
	if(*position < tokenNumber)
	{
		int result=0;
        char label[NAMESIZE];
        concepttype *concept;

        if( !(concept = new concepttype) ) error(" no enough memory");
	    concept->coreflinks = NULL;
        concept->referlinks = NULL;

        if( getConcept(simpleTokenList, position, concept, tokenNumber) )
		{
	       arc->concept = concept;
	       strcpy(arc->con_bound, "concept");
	       return 1;
		}

        else
		{
			if(getBoundLabel (simpleTokenList, position, label,tokenNumber) )
			{
	           strcpy(arc->boundLabel, label);
	           strcpy(arc->con_bound, "boundLabel");
	           return 1;
			} else return 0;
		}    
	} 
	return 0;
}


//relation::= "(" Identifier Arc* comment? ")"
int getRelation(simpleTokenType *simpleTokenList, int* position, 
				relationtype* relation, int tokenNumber)
{
	int startPosition = *position;
	if( *position < tokenNumber )
	{
	    if( !strcmp (simpleTokenList[*position].value, "(") &&
	   	   (*position < tokenNumber-1) &&
	       (simpleTokenList[(*position) +1].kind == identifier) )
		{
           strcpy(relation->name, simpleTokenList[*position+1].value);  
	       (*position) +=2;
	   	  
		   int flag=0;
	       
		   do
		   {
		      arctype *arc;
		      if( !(arc = new arctype)) error("no enough memory");
	          	   
		      if(flag=getArc(simpleTokenList, position, arc, tokenNumber) )
			  {
                 arclisttype *arclist;
			     if( !(arclist = new arclisttype)) error(" no enough memory");
	             arclist->arc = arc;
			     arclist->next =NULL;
		   
			     if(relation->arcs == NULL) 
				 {
				    relation->arcs = arclist;
				    (relation->arcs)->arc = arclist->arc;
				 }
			     
				 else
				 {
				   arclisttype *curr= relation->arcs;
				   arclisttype *next= curr->next;

				   while(next != NULL) 
				   {
					   curr = curr->next;
					   next = curr->next;
				   }
				   curr->next = arclist;
				 }
			  }
		   } while(flag);

	       char com[COMMENTSIZE];
	       if(getComment (simpleTokenList, position, com, tokenNumber) )
		      strcpy(relation->comment, com);
     
		   if( !strcmp(simpleTokenList[*position].value, ")") )
		   {
		      (*position)++;
		      return 1;
		   }
	  	} 
	}

    *position = startPosition;
	return 0;
}


//generate concept, relation, or comment
int getOneElement(simpleTokenType* simpleTokenList, int tokenNumber,
					   concepttype *concept, relationtype *relation,
                       char comment[COMMENTSIZE],int *position)	
{
	if( getConcept(simpleTokenList, position, concept, tokenNumber))    
		return 1;  //concept
	else
	{
	    if( getRelation(simpleTokenList, position, relation, tokenNumber))
			return 2;   //relation
		else
		{
		   if(getComment (simpleTokenList, position, comment, tokenNumber))
			   return 3;   //comment
		   else return 0;  //nothing
		}
	}
}


int parser(char *sourceFile,CKnowledgeBase** KBPP, ACCGFactory *pFactory)	
{
   string_vector_type tokens;
   int tokenNumber = readCGIF(sourceFile, tokens);

   //output the tokens into output file
   //printTokens(outputFile,tokens);

   simpleTokenType* simpleTokenList;
   simpleTokenList = new simpleTokenType[tokenNumber];

   //convert token list into token array
   int newTokenNumber;
   int seg[8];  //CGIF file have 4 partitions: typehierarchy, 
                //relationhierarchy, catalog of individual, and 
                //assertion. seg[8] will remember their start and end position 
                //for each segment

   convertTokens(tokens, simpleTokenList,&newTokenNumber,seg);
   //element is ready to transfer to CG Engine

	int position=0;
	static int CONCEPT =1, RELATION=2, COMMENT=3;
		           
	concepttype *concept;
	relationtype *relation;
    char comment[COMMENTSIZE];
	if( !(concept = new concepttype) )  error("no enough memory");
	if( !(relation = new relationtype) ) error("No enough memory");
		
	//CKnowledgeBase *pKnowledge = pFactory->NewKnowledgeBase;
    std::cout << "Starting..." << std::endl;

	//-- [Knowledge Base:

	// Creating Knowledge Base
    std::cout << "Creating Knowledge Base" << std::endl;
    CKnowledgeBase* kb = pFactory->NewKnowledgeBase();
    *KBPP = kb; 
	 
	//-- [TypeHierarchy:

	// Creating Type Hierarchy
    std::cout << "Creating Type Hierarchy" << std::endl;
    CTypeHierarchy* th = pFactory->NewTypeHierarchy();
    kb->SetTypes(th);

	position =seg[0];

	int type=0;
	do 
	{
		concept->coreflinks = NULL;
        concept->referlinks = NULL;
        relation->arcs = NULL;
		strcpy(comment,"");

		type = getOneElement(simpleTokenList, newTokenNumber, concept, relation,
                      comment,&position);
        if( (type == RELATION ) && ( !strcmp(relation->name, "GT")) &&
			(!strcmp((((((relation->arcs)->next)->arc)->concept)->referlinks)->kind, "name")) )
			
		{
            // Create Type Defintion
        	std::cout << "Creating Type Definition" << std::endl;
        	
			CTypeDefinition* td1 = th->FindByName( ((((relation->arcs)->
				arc)->concept)->referlinks)->value);
      
			if (!td1)
			{
		       td1 = pFactory->NewTypeDefinition( ((((relation->arcs)->
				                          arc)->concept)->referlinks)->value);
		       th->Insert(td1);
			}


	        CTypeDefinition* td2 = th->FindByName( (((((relation->arcs)->next)->
				                          arc)->concept)->referlinks)->value);
    
	        if (!td2)
			{
		        td2 = pFactory->NewTypeDefinition((((((relation->arcs)->next)->
				                     arc)->concept)->referlinks)->value);
		        th->Insert(td2);
			}

	        td2->SetComment(relation->comment);
	        td2->AddSuperclass(td1);
		}

		if( (type == RELATION ) && ( !strcmp(relation->name, "GT")) &&
			(!strcmp((((((relation->arcs)->next)->arc)->concept)
			->referlinks)->kind, "quant")) )
			
		{
            // Create Type Defintion
        	std::cout << "Creating Type Definition" << std::endl;
        	
			CTypeDefinition* td1 = th->FindByName( ((((relation->arcs)->
				arc)->concept)->referlinks)->value);
      
			if (!td1)
			{
		       td1 = pFactory->NewTypeDefinition( ((((relation->arcs)->
				                          arc)->concept)->referlinks)->value);
		       th->Insert(td1);
			}


			while( (((((((relation->arcs)->next)->arc)->concept)
			->referlinks)->quantifier)->stringlist)->value != NULL)
			{
				CTypeDefinition* td2 = th->FindByName( (((((((relation->arcs)->next)->arc)->concept)
			                          ->referlinks)->quantifier)->stringlist)->value);
    
	           if (!td2)
			   {
		          td2 = pFactory->NewTypeDefinition((((((((relation->arcs)->next)->arc)->concept)
			                          ->referlinks)->quantifier)->stringlist)->value);
		          th->Insert(td2);
			   }
			   td2->SetComment(relation->comment);
	           td2->AddSuperclass(td1);

			   ((((((relation->arcs)->next)->arc)->concept)
			      ->referlinks)->quantifier)->stringlist = 
				  (((((((relation->arcs)->next)->arc)->concept)
			              ->referlinks)->quantifier)->stringlist)->next;
			}  
		}
        
		if( type == COMMENT ) //it is comment
		{
            th->SetComment(comment);
		}

	} while ( (type ==RELATION) | (type ==COMMENT) );

    th->Commit();

	// Creating Relation Hierarchy
    std::cout << "Creating Relation Hierarchy" << std::endl;

    // -- [RelationHierarchy:
	CRelationHierarchy* rh = pFactory->NewRelationHierarchy();

    kb->SetRelations(rh);

    position =seg[2];

	type=0;
	do 
	{
		concept->coreflinks = NULL;
        concept->referlinks = NULL;
        relation->arcs = NULL;
		strcpy(comment,"");

		type = getOneElement(simpleTokenList, newTokenNumber, concept, relation,
                      comment,&position);
        if( (type == RELATION ) && ( !strcmp(relation->name, "GT")) &&
			(!strcmp((((((relation->arcs)->next)->arc)->concept)->referlinks)->kind, "name")) )
			
		{
            // Create relation Defintion
        	std::cout << "Creating relation Definition" << std::endl;
        	
			CRelationDefinition* td1 = rh->FindByName( ((((relation->arcs)->
				arc)->concept)->referlinks)->value);
      
			if (!td1)
			{
		       td1 = pFactory->NewRelationDefinition( ((((relation->arcs)->
				                          arc)->concept)->referlinks)->value);
		       rh->Insert(td1);
			}


	        CRelationDefinition* td2 = rh->FindByName( (((((relation->arcs)->next)->
				                          arc)->concept)->referlinks)->value);
    
	        if (!td2)
			{
		        td2 = pFactory->NewRelationDefinition((((((relation->arcs)->next)->
				                     arc)->concept)->referlinks)->value);
		        rh->Insert(td2);
			}

	        td2->SetComment(relation->comment);
	        td2->AddSuperclass(td1);
		}

		if( (type == RELATION ) && ( !strcmp(relation->name, "GT")) &&
			(!strcmp((((((relation->arcs)->next)->arc)->concept)
			->referlinks)->kind, "quant")) )
			
		{
            // Create relation Defintion
        	std::cout << "Creating relation Definition" << std::endl;
        	
			CRelationDefinition* td1 = rh->FindByName( ((((relation->arcs)->
				arc)->concept)->referlinks)->value);
      
			if (!td1)
			{
		       td1 = pFactory->NewRelationDefinition( ((((relation->arcs)->
				                          arc)->concept)->referlinks)->value);
		       rh->Insert(td1);
			}


			while( (((((((relation->arcs)->next)->arc)->concept)
			->referlinks)->quantifier)->stringlist)->value != NULL)
			{
				CRelationDefinition* td2 = rh->FindByName( (((((((relation->arcs)->next)->arc)->concept)
			                          ->referlinks)->quantifier)->stringlist)->value);
    
	           if (!td2)
			   {
		          td2 = pFactory->NewRelationDefinition((((((((relation->arcs)->next)->arc)->concept)
			                          ->referlinks)->quantifier)->stringlist)->value);
		          rh->Insert(td2);
			   }
			   td2->SetComment(relation->comment);
	           td2->AddSuperclass(td1);

			   ((((((relation->arcs)->next)->arc)->concept)
			      ->referlinks)->quantifier)->stringlist = 
				  (((((((relation->arcs)->next)->arc)->concept)
			              ->referlinks)->quantifier)->stringlist)->next;
			}  
		}
        
		if( type == COMMENT ) //it is comment
		{
            rh->SetComment(comment);
		}

	} while ( (type ==RELATION) | (type ==COMMENT) );

    rh->Commit();


    // Creating Catalog Of Individuals

    std::cout << "Creating COI" << std::endl;

    // -- [CatalogOfIndividuals:
    
	CCatalogOfIndividuals* coi = pFactory->NewCatalogOfIndividuals();

    kb->SetCOI(coi);

    position =seg[4];

	type=0;
	do 
	{
		concept->coreflinks = NULL;
        concept->referlinks = NULL;
        relation->arcs = NULL;
		strcpy(comment,"");

		type = getOneElement(simpleTokenList, newTokenNumber, concept, relation,
                      comment,&position);
        if( type == CONCEPT ) //it is CONCEPT
		{
			CTypeDefinition *pTypeDef = th->FindByName( concept->name);

	        if (!pTypeDef)
			{
		       pTypeDef = pFactory->NewTypeDefinition(concept->name);
		       th->Insert(pTypeDef);
		       pTypeDef->Commit();
			}

            CConcept *con = pFactory->NewConcept();
            con->SetName("");   // Need to check for name in COI area
	        con->SetTypeDef(pTypeDef);
			char strtmp[100];
			strcpy(strtmp,"#");
			strcat(strtmp, (concept->referlinks)->value);
	        con->SetIndividualMarker(strtmp);
            coi->Insert(con);
		}
		
		if( type == COMMENT ) //it is comment
		{
            coi->SetComment(comment);
		}

	} while ( (type ==CONCEPT) | (type ==COMMENT) );


	const CCatalogOfIndividuals::IndividualMap* pmapIndividual = coi->GetIndividuals();
    CCatalogOfIndividuals::IndividualMap::const_iterator iterIndividual;

	iterIndividual = pmapIndividual->begin();
	while ( iterIndividual != pmapIndividual->end())
	{
		CConcept *theConcept = (*iterIndividual).second;
		std::cout << "[" << theConcept->GetTypeDef()->GetTypeName() << ":" << theConcept->GetIndividualMarker() << "]" << std::endl;
		iterIndividual++;
	}

	// Creating Sheet Of Assertion
    std::cout << "Creating Sheet Of Assertion" << std::endl;

    
    // -- [Assertion:

	CSheetOfAssertion* soa = pFactory->NewSheetOfAssertion();

    kb->SetSOA(soa);

	position =seg[6];
	type=0;
	do 
	{
		concept->coreflinks = NULL;
        concept->referlinks = NULL;
        relation->arcs = NULL;
		strcpy(comment,"");

		type = getOneElement(simpleTokenList, newTokenNumber, concept, relation,
                      comment,&position);
        if( type == RELATION ) //it is RELATION
		{
			CRelationDefinition *pRelType = rh->FindByName(relation->name);

	        if (!pRelType)
			{
		       pRelType = pFactory->NewRelationDefinition(relation->name);
		       rh->Insert(pRelType);
		       pRelType->Commit();
			}
    
			CRelation *rel1 = pFactory->NewRelation();
			while( relation->arcs != NULL)
			{
				if( !strcmp( ((relation->arcs)->arc)->con_bound, "concept") )
				{
					
					if( !strcmp( ((((relation->arcs)->arc)->concept)->referlinks)->kind, "indmaker") )
					{
						char strtmp[100];
			            strcpy(strtmp,"#");
			            strcat(strtmp, ((((relation->arcs)->arc)->concept)->referlinks)->value);
						
						

                        CConcept* arc1 = coi->FindByMarker(strtmp);
                        soa->Insert(arc1);
	                    rel1->AddArc(arc1);
					}

	                if( !strcmp( ((((relation->arcs)->arc)->concept)->referlinks)->kind, "name") )
					{

					    CTypeDefinition *pArcType = th->FindByName( ((((relation->arcs)->arc)->
					  	               concept)->referlinks)->value);

	                   if (!pArcType)
					   {
		                   pArcType = pFactory->NewTypeDefinition( (((relation->arcs)->arc)->
					  	                       concept)->name);
		                   th->Insert(pArcType);
		                   pArcType->Commit();
					   }
					   CConcept *arc = pFactory->NewConcept();
                       arc->SetName( ((((relation->arcs)->arc)->
					  	                       concept)->referlinks)->value );
	                   arc->SetTypeDef(pArcType);
                       soa->Insert(arc);
				       rel1->AddArc(arc);
					}	
				}
                relation->arcs = relation->arcs->next;
			}
	        
            soa->Insert(rel1);
        }

	} while ( type !=0 );

    // -- (ATTR [Block:#1] [Color:'Red'] ;Block #1 is red;)
    // -- (OnTable [Block:#1] [Location:#5])
    
	
	// Some more testing
	std::cout << "Finding By UID" << std::endl;
	ACConstruct* construct1 = ACConstruct::FindByUid(5);

	std::cout << "Opening CLIPS shell" << std::endl;
    //clpcontrol.shell();

	std::cout << "Finished!!!" << std::endl;

	return 0;
}