/*
   Tamot --- Task Modelling Editor
   Copyright (C) 2000 Commonwealth Scientific and Industrial Research Organisation
   (CSIRO), Australia. All rights reserved. 

   The Software, owned by CSIRO Australia, has been developed by the CSIRO 
   Intelligent Interactive Technology group. 
   For more information, please see http://www.cmis.csiro.au/iit/.

   The Software is a beta-test version for internal research and evaluation purposes 
   by the Licensee. The Software is still at a development stage. 
   It has not undergone complete testing and may have inherent errors,
   bugs or deficiencies that can affect the operation of the Software. 

   We encourage your feedback and suggestions. Any bugs / suggestions found please email to
   Shijian.Lu@cmis.csiro.au and Thomas.Lo@cmis.csiro.au. 

   After you have signed the Beta-Test Software License Agreement with the CSIRO,
   CSIRO grants you a non-exclusive, non-transferable license to use it only for your 
   personal, non-commercial and lawful end use. Implied licenses are negated. 

   Warranty Disclaimer : 

   CSIRO supplies the Software on an "as is" basis and makes no warranties that use of
   the Software by the Licensee will not infringe any third party’s 
   Intellectual Property Rights nor that the Software will be of merchantable quality,
   or suitable for a particular purpose. CSIRO excludes all terms, conditions and
   warranties implied by custom, the general law or statute in relation to the
   Software.
*/

//Source file: D:/Projects/Isolde/parser/ConstituentTable.java

package parser.FSParser;

import java.lang.String;
import java.util.*;
import domainModel.*;
import taskModellingTool.*;
import utility.*;

public class ConstituentTable {
  private int _type;          // type of table (precondition, purpose clause, ...)
  // operation codes:
  public static final int UNDERFLOW = 0;         // an underflow for the enumerated type
  public static final int PRECONDITION = 1; 	   // ("")
  public static final int POSTCONDITION = 2;     // ("")
  public static final int PURPOSE_CLAUSE = 3;    // ("to save a file")
  public static final int ACTION_CLAUSE = 4;     // default type ("click the button")
  public static final int IMPLEMENT_CLAUSE = 5;  // ("by clicking the button")
  public static final int OVERFLOW = 6;          // an overflow for the enumerated type
	
  public DmManager _dmManager;    // pointer to the domain model
  private Vector _constituents;   // list of constituents found in the grammar
  private Hashtable name2Index;   // maps from constituent name to constituent table index
  private Grammar _grammar;       // the finite-state grammar we are currently using
  private String _cnlString;      // the string being parsed
  private GenericComponent _gc;
   
  public ConstituentTable(DmManager inDmManager, Grammar grammar) 
  {
    _dmManager = inDmManager;
    _grammar = grammar;
    _type = ACTION_CLAUSE;
		
    // Set up the constituent table and map hash - parse() will initialize the indexes.
    _constituents = new Vector();
    name2Index = new Hashtable();
    Vector constituentNames = new Vector();
    constituentNames = _grammar.constituents();
    for (int i = 0; i < constituentNames.size(); i++)
      {
	Constituent tempConstituent =
	  new Constituent(((String)(constituentNames.elementAt(i))));
	_constituents.add(((Constituent)(tempConstituent)));
	name2Index.put(constituentNames.elementAt(i), new Integer(i));
      }
  }
	
  public int name2Index(String name) 
  {
    //shijian debuging
    //26-10-2001
    //System.out.println("constituent name: "+ name);
    //Iterator it = name2Index.keySet().iterator();
    //while (it.hasNext())
    //	System.out.println("All name: "+ it.next());
    	
    return ((Integer)name2Index.get(name)).intValue();
  }
	
  public Vector getConstituents() 
  {
    return _constituents;
  }
	
  public void setRole(String role) 
  {
    if (role.equals("purpose")) 
      _type = PURPOSE_CLAUSE;
    else if (role.equals("precond"))
      _type = PRECONDITION;	
    else if (role.equals("postcond"))
      _type = POSTCONDITION;
    else if (role.equals("implement"))
      _type = IMPLEMENT_CLAUSE;	
    else
      _type = ACTION_CLAUSE;	
  }
	
  public int getRole() 
  {
    return _type;
  }
	
	
  /**
    goes through the constituent start positions, creating DM concepts and instances
    as required.  It is careful not to "recreate" entities when they already exist in the DM.
    It is hard-coded for the constituents we know to be in the grammar.
    @roseuid 395A07B50266
    */
	
  //brasser 2001-7-13
  //moved from Parser.java
  public ActionInstance createDM(GenericComponent gc, String cnl, String showName)
  {
    //shijian 2001-10-24
    //check if action instance exists
    ActionInstance ai=_dmManager.getAInstanceByName(cnl.trim());
    if (ai != null) return ai;
	
    return createDMnoMatterWhat(gc,cnl,showName);
	
  } //brasser

  //brasser 2001-7-13
  //moved from Parser.java
  // This will return a new or existing user instance .
  //shijian 24-10-2001

  private EntityInstance createDMActor(String constituentName)
  {
    DmConcept dc;              // a utility variable for creating DmConcept objects
    EntityInstance ei = null;  // the entity being created/referenced

    // grab the constituent so that it's easy to refer to  //changed here //brasser 2001-7-12
    Constituent c = ((Constituent)(_constituents. 
				   elementAt((name2Index(constituentName)))));
    // skip non-existent constituents
    if (c.startPosition() != -1) {

      if (c.headPosition() == -1) {
	// There is a constituent, but no specified head, so create a canned instance.
    	
	String str = _cnlString.substring(c.startPosition(), 
					  c.endPosition());
	//System.err.println("     actor name=" + str);
	Sentence sen = new Sentence(str);
	String head=sen.getLastWord();
	String pro = sen.getAllWordsButLast();
	if (pro == null) pro = "";
			
	//check system type
	if ( str.equals(EntityInstance.getDefaultSystemInstance().getName())){
	  ei =_dmManager.getRelatedEInstance(_gc,str, head, pro,"",
					     ConceptType.getDefaultSystemType());
	} else 
	  ei =_dmManager.getRelatedEInstance(_gc,str, head, pro,"",
					     ConceptType.getDefaultUserType());
	return ei;

      		
      }
      else {
	// There is a constituent with a specified head

	// If an instance with the same name and same head exists, return it.
	// We check the full instance name rather than the c.domainObjectName()
	// because action instances use the full name tp distinguish them.
      		
	String instName = _cnlString.substring(c.startPosition(), 
					       c.endPosition());
	String conName = c.domainObjectName();
	String pre = "";
	String post = "";
			
	if (c.headPosition() != c.startPosition())
	  pre= _cnlString.substring(c.startPosition(), 
				    c.headPosition()-1);
	if ((c.headPosition() + c.headLength()) != c.endPosition())
	  post =_cnlString.substring(c.headPosition() +
				     c.headLength() + 1,
				     c.endPosition());
	//check system type
	if ( instName.equals(EntityInstance.getDefaultSystemInstance().getName())){
	  ei =_dmManager.getRelatedEInstance(_gc,instName, conName, pre,post,
					     ConceptType.getDefaultSystemType());
	} else 
								  
	  ei =_dmManager.getRelatedEInstance(_gc,instName,conName, pre,post,
					     ConceptType.getDefaultUserType());
	return ei;

      }
    }
    //if no actor has been specified, assume the actor is 'user'. brasser 2001-6-6
    else {
      ei = EntityInstance.getDefaultUserInstance();
      return ei;
    }
	
    // Add the entity instance to the DM, the calling program will link 
    // it to its action instance.
    //return null;
  }
  
  //shijian 2001-10-24
  /*
    private EntityInstance createDMActor(String constituentName)
    {
    DmConcept dc;              // a utility variable for creating DmConcept objects
    EntityInstance ei = null;  // the entity being created/referenced

    // grab the constituent so that it's easy to refer to
    Constituent c = ((Constituent)(_constituents.
    elementAt(((Integer)(name2Index.get(constituentName))).intValue())));
    // skip non-existent constituents
    if (c.startPosition() != -1) {

    if (c.headPosition() == -1) {
    // There is a constituent, but no specified head, so create a canned instance.
    	
    String str = _cnlString.substring(c.startPosition(), 
    c.endPosition());
    //System.err.println("     actor name=" + str);
    Sentence sen = new Sentence(str);
    String head=sen.getLastWord();
    String pro = sen.getAllWordsButLast();
    if (pro == null) pro = "";
			
    //shijian 27-july-2001
    // for a task, the concept will be "system-type" if it is 
    // an a"automatic", or "user-type" otherwise.
    if (_gc != null && _gc instanceof Task){
    Task t = (Task)_gc;
    if (t.style.equals(Task.STYLE_VALUE[1])){	//if automatic
    ei =_dmManager.getRelatedEInstance(_gc,str, head, pro,"",
    ConceptType.getDefaultSystemType());
    }else{
    ei =_dmManager.getRelatedEInstance(_gc,str, head, pro,"",
    ConceptType.getDefaultUserType());
    }
				
    } else{
    //check system type
    if ( str.equals(EntityInstance.getDefaultSystemInstance().getName())){
    ei =_dmManager.getRelatedEInstance(_gc,str, head, pro,"",
    ConceptType.getDefaultSystemType());
    } else 
    ei =_dmManager.getRelatedEInstance(_gc,str, head, pro,"",
    ConceptType.getDefaultUserType());
    }
    return ei;
      		
    }
    else {
    // There is a constituent with a specified head

    // If an instance with the same name and same head exists, return it.
    // We check the full instance name rather than the c.domainObjectName()
    // because action instances use the full name tp distinguish them.
      		
    String instName = _cnlString.substring(c.startPosition(), 
    c.endPosition());
    String conName = c.domainObjectName();
    String pre = "";
    String post = "";
			
    if (c.headPosition() != c.startPosition())
    pre= _cnlString.substring(c.startPosition(), 
    c.headPosition()-1);
    if ((c.headPosition() + c.headLength()) != c.endPosition())
    post =_cnlString.substring(c.headPosition() +
    c.headLength() + 1,
    c.endPosition());
			
    //shijian 27-july-2001
    // for a task, the concept will be "system-type" if it is 
    // an a"automatic", or "user-type" otherwise.
    if (_gc != null && _gc instanceof Task){
    Task t = (Task)_gc;
    if (t.style.equals(Task.STYLE_VALUE[1])){	//if automatic
    ei =_dmManager.getRelatedEInstance(_gc,instName, conName, pre,"",
    ConceptType.getDefaultSystemType());
    }else{
    ei =_dmManager.getRelatedEInstance(_gc,instName, conName, pre,"",
    ConceptType.getDefaultUserType());
    }
				
    } else{
    //check system type
    if ( instName.equals(EntityInstance.getDefaultSystemInstance().getName())){
    ei =_dmManager.getRelatedEInstance(_gc,instName, conName, pre,"",
    ConceptType.getDefaultSystemType());
    } else 
    ei =_dmManager.getRelatedEInstance(_gc,instName, conName, pre,"",
    ConceptType.getDefaultUserType());
    }
    return ei;

    }
      	
    }
    //if no actor has been specified, assume the actor is 'user'. brasser 2001-6-6
    else {
    ei = EntityInstance.getDefaultUserInstance();
    return ei;
    }
    }
    */	
  //brasser 2001-7-13
  //moved from Parser.java 
  // This will return a new or existing object for the DM.
  //shijian 2001-10-24
	
  private EntityInstance createDMObject(String constituentName)
  {
    DmConcept dc;              // a utility variable for creating DmConcept objects
    EntityInstance ei = null;  // the entity being created/referenced
    //shijian 6-6-2002
    //check if it is plural form
    boolean plural = false;


    // grab the constituent so that it's easy to refer to
    Constituent c = ((Constituent)(_constituents. //changed here //brasser 2001-7-12
				   elementAt(name2Index(constituentName))));
    // skip non-existent constituents
    if (c.startPosition() != -1) {

      if (c.headPosition() == -1) {
	// There is a constituent, but no specified head, so create a canned instance.
    	
	String str = _cnlString.substring(c.startPosition(), 
					  c.endPosition());
						     
	Sentence sen = new Sentence(str);
	DmConcept head;
	if (constituentName.equals("spatial-location")){
	  head= _dmManager.getEConcept(str,ConceptType.getD12Type());	
	} else {
	  head= _dmManager.getHead(str);
	}
	

	if ( head == null){
	  //System.out.println("No head found in =" + str);

	  String headName =sen.getLastWord();
	  String pro = sen.getAllWordsButLast();
	  
	  //shijian 6-6-2002
	  //check if it is plural form
	  StringTokenizer tokenized = new StringTokenizer(headName);
	  String singularForm = _dmManager.getParser().isNoun(headName,tokenized,"");
	//System.out.println("singular head name =" + singularForm);

	  if (!(headName.equals(singularForm)) && singularForm != null && 
	  		!(singularForm.equals("") )){
	  		headName = singularForm;
	  		plural= true;
	  }
	  
	  if(constituentName.equals("spatial-location")){
	    ei =_dmManager.getRelatedEInstance(_gc,headName, headName, pro,"",
					       ConceptType.getD12Type());
	  } else {
	    ei =_dmManager.getRelatedEInstance(_gc,headName, headName, pro,"",
					       ConceptType.getDefaultEntityType());
	  }
	  //	String head=sen.getLastWord();
	  //	String pro = sen.getAllWordsButLast();
	  //	ei =_dmManager.getRelatedEInstance(_gc,str, head, pro,"", ConceptType.getDefaultEntityType());
	} else {
	  String headName =head.getName();
	  //System.out.println("head name =" + headName);
	  String pro = sen.getAllWordsBefore(headName);
	  String post = sen.getAllWordsAfter(headName);			

	  ei =_dmManager.getRelatedEInstance(_gc,str, headName, pro,post,
					     head.getType());
	}
	
	//shijian 6-6-2002
	//check if it is plural form
	if (plural)
	  	ei.setCardinality("plural");
	  

	return ei;
      }
      else {
	// There is a constituent with a specified head

	// If an instance with the same name and same head exists, return it.
	// We check the full instance name rather than the c.domainObjectName()
	// because action instances use the full name tp distinguish them.
      		
	String instName = _cnlString.substring(c.startPosition(), 
					       c.endPosition());
	String conName = c.domainObjectName();
	
	//26-6-2002, get determiner
   String determiner = "";
   if (c.determinerStart() > -1){
   	String temp = _cnlString.substring(c.determinerStart(), 
   		c.startPosition());
   	temp = temp.trim();
   	if (!(_dmManager.getParser().article(temp)))
		determiner= temp;
   }	
	
	
	  //shijian 6-6-2002
	  //check if it is plural form
	  StringTokenizer tokenized = new StringTokenizer(conName);
	  String singularForm = _dmManager.getParser().isNoun(conName,tokenized,"");
	//System.out.println("singular head name =" + singularForm);

	  if (!(conName.equals(singularForm)) && singularForm != null && 
	  		!(singularForm.equals("")) ){
	  		instName = singularForm;
	  		conName = singularForm;
	  		plural= true;
	  }

	String pre = "";
	String post = "";
			
	if (c.headPosition() != c.startPosition()){
	  pre= _cnlString.substring(c.startPosition(), 
				    c.headPosition()-1);
		//25-6-2002
	  //strip off double-quotes if exists
	StringBuffer sb= new StringBuffer(pre);
	  if (pre.startsWith("\"")){
	  		sb= sb.replace(0,1,"");
	  }
	if (pre.endsWith("\"")){
	  		sb= sb.replace(sb.length()-1,sb.length(),"");
     }
     pre = sb.toString();
				    
   }
	if ((c.headPosition() + c.headLength()) != c.endPosition())
	  post =_cnlString.substring(c.headPosition() +
				     c.headLength() + 1,
				     c.endPosition());
	
	//26-6-2002, if the premodifier is a verb, set determiner to "the'
	// when it is empty
  //check if it is imperative form
  StringTokenizer pretokenized = new StringTokenizer(pre);
  String imperativeForm = _dmManager.getParser().isVerb(pre,pretokenized,"");
  //System.out.println("singular head name =" + imperativeForm);
  if (!(imperativeForm.equals("") ) && determiner.equals("") ){
  		determiner = "the";
  }

	
	DmConcept head;
	if (constituentName.equals("spatial-location")){
	  head= _dmManager.getEConcept(ConceptType.getD12Type());	
	}else{
	  head= _dmManager.getHead(conName);
	}

	if ( head == null)

	  if(constituentName.equals("spatial-location")){
	    ei =_dmManager.getRelatedEInstance(_gc,instName,conName, pre,post,
					       ConceptType.getD12Type());
	  }else{
	    ei =_dmManager.getRelatedEInstance(_gc,instName,conName, pre,post,
					       ConceptType.getDefaultEntityType());
	  }

				
	else
	  ei =_dmManager.getRelatedEInstance(_gc,instName,conName, pre,post,
					     head.getType());
	//	ei =_dmManager.getRelatedEInstance(_gc,instName,conName, pre,post,
	//					   ConceptType.getDefaultEntityType());
	
		//shijian 6-6-2002
	//check if it is plural form
	if (plural)
	  	ei.setCardinality("plural");
	  
	//26-6-2002, set determiner
   if (!(determiner.equals("")))
	  ei.setDeterminator(determiner);
	  
	return ei;

      }
    }
    // Add the entity instance to the DM, the calling program will link 
    // it to its action instance.
    return null;
  } 
  

  //shijian 2001-10-24
  // This will return a new or existing object for the DM.
  /*
    private EntityInstance createDMObject(String constituentName)
    {
    DmConcept dc;              // a utility variable for creating DmConcept objects
    EntityInstance ei = null;  // the entity being created/referenced
    // grab the constituent so that it's easy to refer to
    Constituent c = ((Constituent)(_constituents.
    elementAt(((Integer)(name2Index.get(constituentName))).intValue())));
    // skip non-existent constituents
    if (c.startPosition() != -1) {

    if (c.headPosition() == -1) {
    // There is a constituent, but no specified head, .
    	
    String str = _cnlString.substring(c.startPosition(), 
    c.endPosition());
    //System.out.println("create actee(no head)=" + str);
			     
    Sentence sen = new Sentence(str);
    DmConcept head;
    if (constituentName.equals("spatial-location")){
    head= _dmManager.getEConcept(ConceptType.getD12Type());	
    }else{
    head= _dmManager.getHead(str);
    }
    if ( head == null){
    //System.out.println("No head found in =" + str);

    String headName =sen.getLastWord();
    String pro = sen.getAllWordsButLast();
    if(constituentName.equals("spatial-location")){
    ei =_dmManager.getRelatedEInstance(_gc,str, headName, pro,"",
    ConceptType.getD12Type());
    }else{
    ei =_dmManager.getRelatedEInstance(_gc,str, headName, pro,"",
    ConceptType.getDefaultEntityType());
    }
    return ei;
    } else {
    String headName =head.getName();
    //System.out.println("head name =" + headName);
    String pro = sen.getAllWordsBefore(headName);
    String post = sen.getAllWordsAfter(headName);			

    ei =_dmManager.getRelatedEInstance(_gc,str, headName, pro,post,
    head.getType());
    return ei;
    }
    }
    else {
    // There is a constituent with a specified head

    // If an instance with the same name and same head exists, return it.
    // We check the full instance name rather than the c.domainObjectName()
    // because action instances use the full name tp distinguish them.
      		
    String instName = _cnlString.substring(c.startPosition(), 
    c.endPosition());
    String conName = c.domainObjectName();
    String pre = "";
    String post = "";
			
    if (c.headPosition() != c.startPosition())
    pre= _cnlString.substring(c.startPosition(), 
    c.headPosition()-1);
    if ((c.headPosition() + c.headLength()) != c.endPosition())
    post =_cnlString.substring(c.headPosition() +
    c.headLength() + 1,
    c.endPosition());
    DmConcept head;
    if (constituentName.equals("spatial-location")){
    head= _dmManager.getEConcept(ConceptType.getD12Type());	
    }else{
    head= _dmManager.getHead(conName);
    }

    if ( head == null)

    if(constituentName.equals("spatial-location")){
    ei =_dmManager.getRelatedEInstance(_gc,instName,conName, pre,post,
    ConceptType.getD12Type());
    }else{
    ei =_dmManager.getRelatedEInstance(_gc,instName,conName, pre,post,
    ConceptType.getDefaultEntityType());
    }

				
    else
    ei =_dmManager.getRelatedEInstance(_gc,instName,conName, pre,post,
    head.getType());
    return ei;

    }
    }
    // Add the entity instance to the DM, the calling program will link 
    // it to its action instance.
    return null;
    }

    */
  //shijian
  //2001-8-21
  //check if there such a constituent ttt
  private boolean relationExists(String ttt) {
    String cn;
    Constituent c1;
  	
    for (int i = 0; i < _constituents.size(); i++) {
      cn = ((Constituent)(_constituents.elementAt(i))).name();
      c1 = ((Constituent)(_constituents.
			  elementAt(((Integer)(name2Index.get(cn))).intValue())));
      // skip non-existent constituents
      if (c1.startPosition() != -1) {
	//System.out.println(" there is dm-relation " + cn );
	if (cn.equals(ttt.trim()))
	  return true;
      }
    }
    return false;
  }
  
  //shijian
  //30-10-2001
  public ActionInstance createDMnoMatterWhat(GenericComponent gc, String cnl, String showName)
  {
    ActionInstance ai;
    DmConcept dc;       // a utility variable for creating DmConcept objects
    EntityInstance ei;  // another utility variable for entity instances
    String cn;          // a temporary constituent name string
    _cnlString = cnl.trim();
	
    _gc = gc;
    
    //25-6-2002
    //check if a verb is imperative form
    boolean imperative = false;

    // grab the process constituent //changed here //brasser 2001-7-12
    Constituent c = ((Constituent)(_constituents.elementAt(name2Index("process"))));

    // create a new process instance - there has to be one no matter what
    if (c.startPosition() == -1) { 
      // there is no process, so it must all be canned
      /*  ai = new ActionInstance(_cnlString);
	  // change this to the "generic"/"canned" action - kvlinden, 8jan2001
	  ai.setConceptOf(DmConcept.getDefaultActionConcept());  // canned strings are "generic"
	  */ //add star here
      // use simple parser here
      Parser _defaultParser=new Parser(_dmManager,"simple.grammar");  // for 3-word expressions

      boolean returnCode = _defaultParser.parse(_cnlString);
      ai=_defaultParser.createDM(gc);
      ai.setName(showName);
      return ai;

     
    }

    else if (c.headPosition() == -1) { 
    	
      //System.out.println("action Instance name2: " +_cnlString);
      //System.out.println("action concept name2: " +
      //	 _cnlString.substring(c.startPosition(), c.endPosition()));

      // there is a process, but no head
      //Shijian 2001-2-8 
      //use semantics as Action Instance name instead of Action Concept
      String proConstituent = _cnlString.substring(c.startPosition(), 
						   c.endPosition());
      //get the last word as head if more than one words
      Sentence sen = new Sentence(proConstituent);
      String actConName = sen.getLastWord();
      
      //shijian 25-6-2002
	  //check if it is imperative form
	  StringTokenizer tokenized = new StringTokenizer(actConName);
	  String imperativeForm = _dmManager.getParser().isVerb(actConName,tokenized,"");
	  System.out.println("singular head name =" + imperativeForm);

	  if (!(actConName.equals(imperativeForm)) && imperativeForm != null && 
	  		!(imperativeForm.equals("") )){
	  		actConName = imperativeForm;
	  		imperative= true;
	  }
	  

      
      
      // Make sure there is a domain concept for the specified head.  
      dc = _dmManager.getAConcept(actConName);
      if (dc == null) {
	// the DM doesn't contain the required concept, make one now & put it in the DM
	dc = new DmConcept(actConName, ConceptType.getDefaultActionType()); //"action type");
			 
	//add language card to DmManager collection
	_dmManager.addEnglishV((EnglishVerb)dc.getCard(DmConcept._ENGLISH));
		  
	dc.setParent(DmConcept.getDefaultActionConcept());
	_dmManager.addConcept(dc);
      }
      // link the process instance to its action concept
      ai = _dmManager.getAInstanceByName(_cnlString);
      if (ai == null)
	ai = new ActionInstance(_cnlString);
      	
      ai.setConceptOf(dc);
      if (sen.getWordCount() > 1) {
			String premod=sen.getAllWordsButLast();
			ai.setPreModifier(premod);
      }
      
      //25-6-2002
      //use contextual type to store non-imperative forms
      if (imperative){
      	ai.setEntityContextType(DmRelation.ACTION_PROCESS,
      		sen.getLastWord());
      }
						   
    }
    else { 
      // There is a process and a specified head

      // Make sure there is a domain concept for the specified head.  
      // Make sure there is a domain concept for the specified head.
      String actConName = _cnlString.substring(c.headPosition(), 
						   c.headPosition()+c.headLength() );
      
      //shijian 25-6-2002
	  //check if it is imperative form
	  String actConName1 = actConName; 
	  StringTokenizer tokenized = new StringTokenizer(actConName);
	  String imperativeForm = _dmManager.getParser().isVerb(actConName,tokenized,"");
	  System.out.println("singular head name =" + imperativeForm);
	  if (!(actConName.equals(imperativeForm)) && imperativeForm != null && 
	  		!(imperativeForm.equals("") )){
	  		actConName = imperativeForm;
	  		imperative= true;
	  }

       if(relationExists("actee"))
	dc = _dmManager.getConcept(actConName,
				   ConceptType.getDefaultActionType());
      else  
	dc = _dmManager.getConcept(actConName,
				   ConceptType.getMotionActionType());
      //dc = _dmManager.getAConcept(c.domainObjectName());

      if (dc == null) {
	// the DM doesn't contain the required concept, make one now & put it in the DM
	if(relationExists("actee"))
	  dc = new DmConcept(actConName, 
			     ConceptType.getDefaultActionType()); //"action type");
	else  
	  dc = new DmConcept(actConName, 
			     ConceptType.getMotionActionType()); //"action type");
	//shijian 17-1-2001
	//add language card to DmManager collection
	_dmManager.addEnglishV((EnglishVerb)dc.getCard(DmConcept._ENGLISH));
	dc.setParent(DmConcept.getDefaultActionConcept());
	_dmManager.addConcept(dc);
      }
     
      /** 19-6-2002
      if(relationExists("process"))
	dc = _dmManager.getConcept(c.domainObjectName(),
				   ConceptType.getDefaultActionType());
      else  
	dc = _dmManager.getConcept(c.domainObjectName(),
				   ConceptType.getMotionActionType());
      //dc = _dmManager.getAConcept(c.domainObjectName());

      if (dc == null) {
	// the DM doesn't contain the required concept, make one now & put it in the DM
	if(relationExists("process"))
	  dc = new DmConcept(c.domainObjectName(), 
			     ConceptType.getDefaultActionType()); //"action type");
	else  
	  dc = new DmConcept(c.domainObjectName(), 
			     ConceptType.getMotionActionType()); //"action type");
	//shijian 17-1-2001
	//add language card to DmManager collection
	_dmManager.addEnglishV((EnglishVerb)dc.getCard(DmConcept._ENGLISH));
	dc.setParent(DmConcept.getDefaultActionConcept());
	_dmManager.addConcept(dc);
      }
**/
      // link the process instance to its action concept
      ai = _dmManager.getAInstanceByName(_cnlString);
      if (ai == null)
	ai = new ActionInstance(_cnlString);
      	
      ai.setConceptOf(dc);
      /*	System.out.println("      head position= " + c.headPosition() + 
		"\n    start position= " +c.startPosition()+
		"\n end postion "+ c.endPosition()+
		"\n head length+ " +c.headLength() );
		*/	// link the pre and post modifiers (if there are any)
      if (c.headPosition() != c.startPosition())
	ai.setPreModifier(_cnlString.substring(c.startPosition(),
					       c.headPosition()-1));
      if ((c.headPosition() + c.headLength()) != c.endPosition())
	ai.setPostModifier(_cnlString.substring(c.headPosition() + 
						c.headLength()+1,c.endPosition()));
						
      //25-6-2002
      //use contextual type to store non-imperative forms
      if (imperative){
      	ai.setEntityContextType(DmRelation.ACTION_PROCESS,
      		actConName1);
      }

    }
    // Deal with the objects (agent, patient, location, etc.)
    //    These may come up with canned or non-canned processes, 
    //    so we do this outside of the if statement.
    Constituent con;
    String preposition;
    for (int i = 0; i < _constituents.size(); i++) { //changed here /brasser 2001-7-12
      con =(Constituent)_constituents.elementAt(i);
      cn = con.name();
      
      //24-1-2002
      //retrieve preposition key words
      if (con.prepositionPosition() > -1) {
      	if (con.determinerStart() == -1){
	      preposition = _cnlString.substring(con.prepositionPosition(), 
	      		con.startPosition());
	      }else{
	      preposition = _cnlString.substring(con.prepositionPosition(), 
	      		con.determinerStart());
	      }
	      
      	if (preposition != null){
      		preposition=preposition.trim();
         	System.out.println("preposition for : " +cn + " is:|" + preposition +"|");
      		if (preposition.equals("onto") ||preposition.equals("on")){
      			ai.setEntityContextType(cn,ContextualType.get12DType());
      		} else if (preposition.equals("in") ||preposition.equals("into"))
      	   ai.setEntityContextType(cn,ContextualType.get3DType());
      	//may need to handle "out of" and "off of" for sources
      	}
         //System.out.println("preposition for : " +cn + " is:" + preposition.trim());
      	
      }
      
      if (!cn.equals("process")){
	EntityInstance eInst;
	if (cn.equals("actor"))
	  eInst= createDMActor(cn);
	else 
	  eInst= createDMObject(cn);

	if (eInst != null) {
	  ai.setActionRelation(cn,eInst);	//createDMObject(cn) );
	  //	System.out.println("      dm-relation " + cn + ": " +eInst.getName());
	}
      }
    }
    // now that it is fixed up, add the action instance.
    ai.setName(showName);
    _dmManager.addAInstance(ai);
    return ai;
  }

  // Function that prints the constituent table.
  public String toString()
  {
    String returnString = "";
    // First, get the header...
    if (getConstituents().size() > 0)
      returnString = ((Constituent)(getConstituents().elementAt(0))).getHeader();
    // ... then get the constituent values  - kvlinden, 23jan2002
    for (int i = 0; i < getConstituents().size(); i++) 
      returnString += ((Constituent)(getConstituents().elementAt(i))).toString();
    return returnString;
  }
  
}
