Code Search for Developers
 
 
  

TermFinderFacadeBean.java from Texai at Krugle


Show TermFinderFacadeBean.java syntax highlighted

/*
 * TermFinderFacadeBean.java
 *
 * Created on October 18, 2006, 3:36 PM
 *
 * Description: Provides methods to find terms in a particular knowledge base shard.
 *
 * Copyright (C) 2006 Stephen L. Reed.
 *
 * This program is free software; you can redistribute it and/or modify it under the terms
 * of the GNU General Public License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with this program;
 * if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

package org.texai.kb.ejb.session.shared;

import com.sleepycat.je.DatabaseException;
import com.sleepycat.persist.EntityCursor;
import com.sleepycat.persist.EntityIndex;
import com.sleepycat.persist.EntityStore;
import com.sleepycat.persist.PrimaryIndex;
import com.sleepycat.persist.SecondaryIndex;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
import org.apache.log4j.Logger;
import org.texai.kb.Constants;
import org.texai.kb.entity.AtomicTerm;
import org.texai.kb.entity.BinaryGAF;
import org.texai.kb.entity.Formula;
import org.texai.kb.entity.NonAtomicTerm;
import org.texai.kb.entity.PByteArray;
import org.texai.kb.entity.PDate;
import org.texai.kb.entity.PDouble;
import org.texai.kb.entity.PLong;
import org.texai.kb.entity.PString;
import org.texai.kb.entity.PVariable;
import org.texai.kb.entity.QuaternaryGAF;
import org.texai.kb.entity.QuintaryGAF;
import org.texai.kb.entity.AbstractReifiedTerm;
import org.texai.kb.entity.Rule;
import org.texai.kb.entity.Symbol;
import org.texai.kb.entity.AbstractTerm;
import org.texai.kb.entity.LocalTermIdReference;
import org.texai.kb.entity.RemoteTermIdReference;
import org.texai.kb.entity.TermIdSequence;
import org.texai.kb.entity.TernaryGAF;
import org.texai.kb.entity.UnaryGAF;
import org.texai.util.ByteUtils;
import org.texai.util.TexaiException;

/**
 *
 * @author reed
 */
@Stateless
public class TermFinderFacadeBean implements TermFinderFacadeLocal {
  
  /** the lowest termId in this database shard */
  private static int lowestTermId = -1;
  
  /** the highest termId in this database shard */
  private static int highestTermId = -1;
  
  /** the primary index for the term id sequence */
  private static PrimaryIndex<Integer, TermIdSequence> termIdSequenceById;
  
  /** the logger */
  private transient Logger logger;               // NOPMD
  
  /** the entity store */
  private EntityStore entityStore;
  
  /** the primary index for atomic terms */
  private transient PrimaryIndex<Integer, AtomicTerm> atomicTermByTermId;
  
  /** the primary index for formulas */
  private transient PrimaryIndex<Integer, Formula> formulaByTermId;
  
  /** the primary index for non-atomic terms */
  private transient PrimaryIndex<Integer, NonAtomicTerm> nonAtomicTermByTermId;
  
  /** the primary index for persistent byte arrays */
  private transient PrimaryIndex<Integer, PByteArray> pByteArrayByTermId;
  
  /** the primary index for presistent dates */
  private transient PrimaryIndex<Integer, PDate> pDateByTermId;
  
  /** the primary index for presistent longs */
  private transient PrimaryIndex<Integer, PLong> pLongByTermId;
  
  /** the primary index for presistent doubles */
  private transient PrimaryIndex<Integer, PDouble> pDoubleByTermId;
  
  /** the primary index for persistent strings */
  private transient PrimaryIndex<Integer, PString> pStringByTermId;
  
  /** the primary index for persistent variables */
  private transient PrimaryIndex<Integer, PVariable> pVariableByTermId;
  
  /** the primary index for rules */
  private transient PrimaryIndex<Integer, Rule> ruleByTermId;
  
  /** the primary index for symbols */
  private transient PrimaryIndex<Integer, Symbol> symbolByTermId;
  
  /** the primary index for unary GAFS */
  private transient PrimaryIndex<Integer, UnaryGAF> unaryGAFByTermId;
  
  /** the primary index for binary GAFS */
  private transient PrimaryIndex<Integer, BinaryGAF> binaryGAFByTermId;
  
  /** the primary index for ternary GAFS */
  private transient PrimaryIndex<Integer, TernaryGAF> ternaryGAFByTermId;
  
  /** the primary index for quaternary GAFS */
  private transient PrimaryIndex<Integer, QuaternaryGAF> quaternaryGAFByTermId;
  
  /** the primary index for quintary GAFS */
  private transient PrimaryIndex<Integer, QuintaryGAF> quintaryGAFByTermId;
  
  /** the primary index for local term id references */
  private transient PrimaryIndex<Integer, LocalTermIdReference> localTermIdReferenceByTermId;
  
  /** the primary index for remote term id references */
  private transient PrimaryIndex<Integer, RemoteTermIdReference> remoteTermIdReferenceByTermId;
  
  /** the secondary index for symbols */
  private transient SecondaryIndex<String, Integer, Symbol> symbolByNameValue;
  
  /** the secondary index for persistent variables */
  private transient SecondaryIndex<String, Integer, PVariable> pVariableByNameValue;
  
  /** the secondary index for persistent longs */
  private transient SecondaryIndex<Long, Integer, PLong> pLongByLongValue;
  
  /** the secondary index for persistent doubles */
  private transient SecondaryIndex<Double, Integer, PDouble> pDoubleByDoubleValue;
  
  /** the secondary index for persistent strings */
  private static SecondaryIndex<Integer, Integer, PString> pStringByStringHashCode;
  
  /** the secondary index for persistent dates */
  private transient SecondaryIndex<Date, Integer, PDate> pDateByDateValue;
  
  /** the term name hash code secondary index for atomic terms */
  private transient SecondaryIndex<Integer, Integer, AtomicTerm> atomicTermByTermNameHashCode;
  
  /** the term name hash code secondary index for non-atomic terms */
  private transient SecondaryIndex<Integer, Integer, NonAtomicTerm> nonAtomicTermByTermNameHashCode;
  
  /** the formula string hash code secondary index for formulas */
  private transient SecondaryIndex<Integer, Integer, Formula> formulaByFormulaStringHashCode;
  
  /** the secondary index for rules */
  private transient SecondaryIndex<Integer, Integer, Rule> ruleByFormulaId;
  
  /** the secondary index for Unary GAFs */
  private transient SecondaryIndex<Integer, Integer, UnaryGAF> unaryGAFByArg1TermId;
  
  /** the secondary index for Binary GAFs */
  private transient SecondaryIndex<Integer, Integer, BinaryGAF> binaryGAFByArg1TermId;
  
  /** the secondary index for Ternary GAFs */
  private transient SecondaryIndex<Integer, Integer, TernaryGAF> ternaryGAFByArg1TermId;
  
  /** the secondary index for Quaternary GAFs */
  private transient SecondaryIndex<Integer, Integer, QuaternaryGAF> quaternaryGAFByArg1TermId;
  
  /** the secondary index for Quintary GAFs */
  private transient SecondaryIndex<Integer, Integer, QuintaryGAF> quintaryGAFByArg1TermId;
  
  /** the secondary index for local term id references */
  private transient SecondaryIndex<Byte[], Integer, LocalTermIdReference> localTermIdReferenceByUUIDBytes;
  
  /** Creates a new instance of TermFinderFacadeBean */
  public TermFinderFacadeBean() {
    super();
    getLogger().debug("instantiated TermFinderFacadeBean");
  }
  
  /** Returns the highest term id without incrementing it.
   *
   * @return the highest term id without incrementing it
   */
  public int peekHighestTermId() {
    //Preconditions
    assert highestTermId > -1 : "highestTermId must be initialized";
    
    return highestTermId;
  }
  
  /** Finds the LocalTermIdReference having the given termId.
   *
   * @param termId the given term id
   * @return the LocalTermIdReference having the given termId
   * @throws TexaiException if the term is not found
   */
  public LocalTermIdReference findLocalTermIdReferenceByTermId(final int termId) {
    //Preconditions
    assert termId != 0 : "termId must not be zero";
    assert localTermIdReferenceByTermId != null : "localTermIdReferenceByTermId must not be null";
    try {

      return localTermIdReferenceByTermId.get(termId);
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
  }
  
  /** Finds the LocalTermIdReference having the given UUID.
   *
   * @param uuid the given UUID
   * @return the LocalTermIdReference having the given UUID
   */
  public LocalTermIdReference findLocalTermIdReferenceByUUID(final UUID uuid) {
    //Preconditions
    assert uuid != null : "uuid must not be null";
    assert localTermIdReferenceByUUIDBytes != null : "localTermIdReferenceByUUIDBytes must not be null";
    
    try {
      return localTermIdReferenceByUUIDBytes.get(ByteUtils.toByteObjectArray(uuid));
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
  }
  
  /** Finds the RemoteTermIdReference having the given termId.
   *
   * @param termId the given term id
   * @return the RemoteTermIdReference having the given termId
   */
  public RemoteTermIdReference findRemoteTermIdReferenceByTermId(final int termId) {
    //Preconditions
    assert termId != 0 : "termId must not be zero";
    assert remoteTermIdReferenceByTermId != null : "remoteTermIdReferenceByTermId must not be null";

    try {
      return remoteTermIdReferenceByTermId.get(termId);
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
  }
  
  /** Finds the Term having the given termType and termId.
   *
   * @param termType the given term type
   * @param termId the given term id
   * @return the Term having the given termType and termId
   * @throws TexaiException if the term is not found
   */
  public AbstractTerm findTermByTermTypeAndId(final byte termType, final int termId) {
    //Preconditions
    assert termType != 0 : "termType must not be zero";
    assert termId != 0 : "termId must not be zero";
    
    final Cache cache = CacheManager.getInstance().getCache(Constants.CACHE_TERMS);
    assert cache != null : "cache not found for: " + Constants.CACHE_TERMS;
    final Object[] termTypeAndId = {Byte.valueOf(termType), Integer.valueOf(termId)};
    Element element = cache.get(termTypeAndId);
    if (element != null) {
      return (AbstractTerm) element.getObjectValue();
    }
    AbstractTerm term = null;
    switch (termType) {
      case Constants.SYMBOL :
        term = findSymbolByTermId(termId);
        break;
      case Constants.VARIABLE :
        term = findPVariableByTermId(termId);
        break;
      case Constants.LONG :
        term = findPLongByTermId(termId);
        break;
      case Constants.DOUBLE :
        term = findPDoubleByTermId(termId);
        break;
      case Constants.STRING :
        term = findPStringByTermId(termId);
        break;
      case Constants.BYTE_ARRAY :
        term = findPByteArrayByTermId(termId);
        break;
      case Constants.DATE :
        term = findPDateByTermId(termId);
        break;
      case Constants.ATOMIC :
        term = findAtomicTermByTermId(termId);
        break;
      case Constants.NON_ATOMIC :
        term = findNonAtomicTermByTermId(termId);
        break;
      case Constants.FORMULA :
        term = findFormulaByTermId(termId);
        break;
      case Constants.RULE :
        term = findRuleByTermId(termId);
        break;
      case Constants.UNARY_GAF :
        term = findUnaryGAFByTermId(termId);
        break;
      case Constants.BINARY_GAF :
        term = findBinaryGAFByTermId(termId);
        break;
      case Constants.TERNARY_GAF :
        term = findTernaryGAFByTermId(termId);
        break;
      case Constants.QUATERNARY_GAF :
        term = findQuaternaryGAFByTermId(termId);
        break;
      case Constants.QUINTARY_GAF :
        term = findQuintaryGAFByTermId(termId);
        break;
      default :
        throw new TexaiException("unhandled termType " + termType + ", termId " + termId);
    }
    if (term != null) {
      element = new Element(termTypeAndId, term);
      cache.put(element);
    }
    return term;
  }
  
  /** Finds the Symbol having the given termId.
   *
   * @param termId the given term id
   * @return the Symbol having the given termId
   * @throws TexaiException if the term is not found
   */
  public Symbol findSymbolByTermId(final int termId) {
    //Preconditions
    assert termId != 0 : "termId must not be zero";
    assert symbolByTermId != null : "symbolByTermId must not be null";
    
    try {
      final Symbol symbol = symbolByTermId.get(termId);
      if (symbol == null) {
        throw new TexaiException("Symbol not found for id " + termId);
      }
      return symbol;
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
  }
  
  /** Finds the Symbol having the given nameValue or null if not found.
   *
   * @param nameValue the given name value
   * @return the Symbol having the given nameValue or null if not found
   */
  public Symbol findSymbolByNameValue(final String nameValue) {
    //Preconditions
    assert nameValue != null : Constants.NAME_VALUE_NULL_ERR;
    assert nameValue.length() > 0 : Constants.NAME_VALUE_EMPTY_ERR;
    assert symbolByNameValue != null : "symbolByNameValue must not be null";
    try {
      return symbolByNameValue.get(nameValue);
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
  }
  
  /** Finds the PVariable having the given termId.
   *
   * @param termId the given term id
   * @return the PVariable having the given termId
   * @throws TexaiException if the term is not found
   */
  public PVariable findPVariableByTermId(final int termId) {
    //Preconditions
    assert termId != 0 : "termId must not be zero";
    assert pVariableByTermId != null : "pVariableByTermId must not be null";
    
    try {
      final PVariable pVariable = pVariableByTermId.get(termId);
      if (pVariable == null) {
        throw new TexaiException("PVariable not found for id " + termId);
      }
      return pVariable;
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
  }
  
  /** Finds the PVariable having the given nameValue or null if not found.
   *
   * @param nameValue the given name value
   * @return the PVariable having the given nameValue or null if not found
   */
  public PVariable findPVariableByNameValue(final String nameValue) {
    //Preconditions
    assert nameValue != null : Constants.NAME_VALUE_NULL_ERR;
    assert nameValue.length() > 0 : Constants.NAME_VALUE_EMPTY_ERR;
    assert pVariableByNameValue != null : "pVariableByNameValue must not be null";
    
    try {
      return pVariableByNameValue.get(nameValue);
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
  }
  
  /** Finds the PLong having the given termId.
   *
   * @param termId the given term id
   * @return the PLong having the given termId
   * @throws TexaiException if the term is not found
   */
  public PLong findPLongByTermId(final int termId) {
    //Preconditions
    assert pLongByTermId != null : "pLongByTermId must not be null";
    
    try {
      final PLong pLong = pLongByTermId.get(termId);
      if (pLong == null) {
        throw new TexaiException("PLong not found for id " + termId);
      }
      return pLong;
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
  }
  
  /** Finds the PLong having the given longValue or null if not found.
   *
   * @param longValue the given long value
   * @return the PLong having the given nameValue or null if not found
   */
  public PLong findPLongByLongValue(final Long longValue) {
    //Preconditions
    assert longValue != null : "longValue must not be null";
    assert pLongByLongValue != null : "pLongByLongValue must not be null";
    
    try {
      return pLongByLongValue.get(longValue);
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
  }
  
  /** Finds the PDouble having the given termId.
   *
   * @param termId the given term id
   * @return the PDouble having the given termId
   * @throws TexaiException if the term is not found
   */
  public PDouble findPDoubleByTermId(final int termId) {
    //Preconditions
    assert termId != 0 : "termId must not be zero";
    assert pDoubleByTermId != null : "pDoubleByTermId must not be null";
    
    try {
      final PDouble pDouble = pDoubleByTermId.get(termId);
      if (pDouble == null) {
        throw new TexaiException("PDouble not found for id " + termId);
      }
      return pDouble;
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
  }
  
  /** Finds the PDouble having the given doubleValue or null if not found.
   *
   * @param doubleValue the given double value
   * @return the PDouble having the given doubleValue or null if not found
   */
  public PDouble findPDoubleByDoubleValue(final Double doubleValue) {
    //Preconditions
    assert doubleValue != null : "doubleValue must not be null";
    assert pDoubleByDoubleValue != null : "pDoubleByDoubleValue must not be null";
    
    try {
      return pDoubleByDoubleValue.get(doubleValue);
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
  }
  
  /** Finds the PString having the given termId.
   *
   * @param termId the given term id
   * @return the PString having the given termId
   * @throws TexaiException if the term is not found
   */
  public PString findPStringByTermId(final int termId) {
    //Preconditions
    assert termId != 0 : "termId must not be zero";
    assert pStringByTermId != null : "pStringByTermId must not be null";
    
    try {
      final PString pString = pStringByTermId.get(termId);
      if (pString == null) {
        throw new TexaiException("PString not found for id " + termId);
      }
      return pString;
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
  }
  
  /** Finds the PString having the given stringValue or null if not found.
   *
   * @param stringValue the given string value
   * @return the PString having the given stringValue or null if not found
   */
  public PString findPStringByStringValue(final String stringValue) {
    //Preconditions
    assert stringValue != null : "stringValue must not be null";
    assert pStringByStringHashCode != null : "pStringByStringHashCode must not be null";
    
    try {
      final EntityIndex<Integer, PString> entityIndex = pStringByStringHashCode.subIndex(stringValue.hashCode());
      final EntityCursor<PString> entityCursor = entityIndex.entities();
      for (final PString pString : entityCursor) {
        if (pString.getStringValue().equals(stringValue)) {
          entityCursor.close();
          return pString;
        }
      }
      entityCursor.close();
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
    return null;
  }
  
  /** Finds the PByteArray having the given termId.
   *
   * @param termId the given term id
   * @return the PByteArray having the given termId
   * @throws TexaiException if the term is not found
   */
  public PByteArray findPByteArrayByTermId(final int termId) {
    //Preconditions
    assert termId != 0 : "termId must not be zero";
    assert pByteArrayByTermId != null : "pByteArrayByTermId must not be null";
    
    try {
      final PByteArray pByteArray = pByteArrayByTermId.get(termId);
      if (pByteArray == null) {
        throw new TexaiException("PByteArray not found for id " + termId);
      }
      return pByteArray;
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
  }
  
  /** Finds the PDate having the given termId.
   *
   * @param termId the given term id
   * @return the PDate having the given termId
   * @throws TexaiException if the term is not found
   */
  public PDate findPDateByTermId(final int termId) {
    //Preconditions
    assert termId != 0 : "termId must not be zero";
    assert pDateByTermId != null : "pDateByTermId must not be null";
    
    try {
      final PDate pDate = pDateByTermId.get(termId);
      if (pDate == null) {
        throw new TexaiException("PDate not found for id " + termId);
      }
      return pDate;
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
  }
  
  /** Finds the PDate having the given dateValue or null if not found.
   *
   * @param dateValue the given date value
   * @return the PDate having the given dateValue or null if not found
   */
  public PDate findPDateByDateValue(final Date dateValue) {
    //Preconditions
    assert dateValue != null : "dateValue must not be null";
    assert pDateByDateValue != null : "pDateByDateValue must not be null";
    
    try {
      return pDateByDateValue.get(dateValue);
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
  }
  
  /** Finds the AtomicTerm having the given UUID.
   *
   * @param uuid the given uuid
   * @return the AtomicTerm having the given termId
   * @throws TexaiException if the term is not found
   */
  public AtomicTerm findAtomicTermByUUID(final UUID uuid) {
    //Preconditions
    assert uuid != null : "uuid must not be null";
    assert localTermIdReferenceByTermId != null : "localTermIdReferenceByTermId must not be null";
    assert atomicTermByTermId != null : "atomicTermByTermId must not be null";
    final LocalTermIdReference localTermIdReference;
    try {
      localTermIdReference = localTermIdReferenceByUUIDBytes.get(ByteUtils.toByteObjectArray(uuid));
      if (localTermIdReference == null) {
        return null;
      }
      return atomicTermByTermId.get(localTermIdReference.getTermId());
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
  }
  
  /** Finds the AtomicTerm having the given termId.
   *
   * @param termId the given term id
   * @return the AtomicTerm having the given termId
   * @throws TexaiException if the term is not found
   */
  public AtomicTerm findAtomicTermByTermId(final int termId) {
    //Preconditions
    assert termId != 0 : "termId must not be zero";
    assert atomicTermByTermId != null : "atomicTermByTermId must not be null";
    
    try {
      final AtomicTerm atomicTerm = atomicTermByTermId.get(termId);
      if (atomicTerm == null) {
        throw new TexaiException("AtomicTerm not found for id " + termId);
      }
      return atomicTerm;
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
  }
  
  /** Finds the AtomicTerm having the given termName or null if not found.
   *
   * @param termName the given term name
   * @return the AtomicTerm having the given termName or null if not found
   */
  public AtomicTerm findAtomicTermByTermName(final String termName) {
    //Preconditions
    assert termName != null : Constants.TERM_NAME_NULL_ERR;
    assert termName.length() > 0 : Constants.TERM_NAME_EMPTY_ERR;
    assert atomicTermByTermNameHashCode != null : "atomicTermByTermNameHashCode must not be null";
    
    final int hashCode = termName.hashCode();
    try {
      final EntityIndex<Integer, AtomicTerm> entityIndex = atomicTermByTermNameHashCode.subIndex(hashCode);
      final EntityCursor<AtomicTerm> entityCursor = entityIndex.entities();
      for (final AtomicTerm atomicTerm : entityCursor) {
        if (atomicTerm.getTermName().equals(termName)) {
          entityCursor.close();
          return atomicTerm;
        }
      }
      entityCursor.close();
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
    return null;
  }
  
  /** Finds the NonAtomicTerm having the given UUID.
   *
   * @param uuid the given uuid
   * @return the NonAtomicTerm having the given termId
   * @throws TexaiException if the term is not found
   */
  public NonAtomicTerm findNonAtomicTermByUUID(final UUID uuid) {
    //Preconditions
    assert uuid != null : "uuid must not be null";
    assert localTermIdReferenceByTermId != null : "localTermIdReferenceByTermId must not be null";
    assert nonAtomicTermByTermId != null : "nonAtomicTermByTermId must not be null";
    
    try {
      final LocalTermIdReference localTermIdReference = localTermIdReferenceByUUIDBytes.get(ByteUtils.toByteObjectArray(uuid));
      if (localTermIdReference == null) {
        return null;
      }
      return nonAtomicTermByTermId.get(localTermIdReference.getTermId());
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
  }
  
  /** Finds the NonAtomicTerm having the given termId.
   *
   * @param termId the given term id
   * @return the NonAtomicTerm having the given termId
   * @throws TexaiException if the term is not found
   */
  public NonAtomicTerm findNonAtomicTermByTermId(final int termId) {
    //Preconditions
    assert termId != 0 : "termId must not be zero";
    assert nonAtomicTermByTermId != null : "nonAtomicTermByTermId must not be null";
    
    try {
      final NonAtomicTerm nonAtomicTerm = nonAtomicTermByTermId.get(termId);
      if (nonAtomicTerm == null) {
        throw new TexaiException("NonAtomicTerm not found for id " + termId);
      }
      return nonAtomicTerm;
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
  }
  
  /** Finds the NonAtomicTerm having the given termName or null if not found.
   *
   * @param termName the given term name
   * @return the NonAtomicTerm having the given termName or null if not found
   */
  public NonAtomicTerm findNonAtomicTermByTermName(final String termName) {
    //Preconditions
    assert termName != null : Constants.TERM_NAME_NULL_ERR;
    assert termName.length() > 0 : Constants.TERM_NAME_EMPTY_ERR;
    assert nonAtomicTermByTermNameHashCode != null : "nonAtomicTermByTermNameHashCode must not be null";
    
    final int hashCode = termName.hashCode();
    try {
      final EntityIndex<Integer, NonAtomicTerm> entityIndex = nonAtomicTermByTermNameHashCode.subIndex(hashCode);
      final EntityCursor<NonAtomicTerm> entityCursor = entityIndex.entities();
      for (final NonAtomicTerm nonAtomicTerm : entityCursor) {
        if (nonAtomicTerm.getTermName().equals(termName)) {
          entityCursor.close();
          return nonAtomicTerm;
        }
      }
      entityCursor.close();
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
    return null;
  }
  
  /** Finds the Formula having the given termId.
   *
   * @param termId the given term id
   * @return the Formula having the given termId
   * @throws TexaiException if the term is not found
   */
  public Formula findFormulaByTermId(final int termId) {
    //Preconditions
    assert termId != 0 : "termId must not be zero";
    assert formulaByTermId != null : "formulaByTermId must not be null";
    
    try {
      final Formula formula = formulaByTermId.get(termId);
      if (formula == null) {
        throw new TexaiException("Formula not found for id " + termId);
      }
      return formula;
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
  }
  
  /** Finds the Formula having the given term list or null if not found.
   *
   * @param termList the given term list
   * @return the Formula having the given term list or null if not found
   */
  public Formula findFormulaByTermList(final List<AbstractTerm> termList) {
    //Preconditions
    assert termList != null : "termList must not be null";
    assert !termList.isEmpty() : "termList must not be empty";
    
    return findFormulaByFormulaString(Formula.composeFormulaStringFromTermList(termList));
  }
  
  /** Finds the Formula having the given formulaString or null if not found.
   *
   * @param formulaString the given formula string
   * @return the Formula having the given formulaString or null if not found
   */
  public Formula findFormulaByFormulaString(final String formulaString) {
    //Preconditions
    assert formulaString != null : "formulaString must not be null";
    assert formulaString.length() > 0 : "formulaString must not be an empty string";
    assert formulaByFormulaStringHashCode != null : "formulaByFormulaStringHashCode must not be null";
    
    final int hashCode = formulaString.hashCode();
    try {
      final EntityIndex<Integer, Formula> entityIndex = formulaByFormulaStringHashCode.subIndex(hashCode);
      final EntityCursor<Formula> entityCursor = entityIndex.entities();
      for (final Formula formula : entityCursor) {
        if (formula.getFormulaString().equals(formulaString)) {
          entityCursor.close();
          return formula;
        }
      }
      entityCursor.close();
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
    return null;
  }
  
  /** Finds the Rule having the given UUID.
   *
   * @param uuid the given uuid
   * @return the Rule having the given termId
   * @throws TexaiException if the term is not found
   */
  public Rule findRuleByUUID(final UUID uuid) {
    //Preconditions
    assert uuid != null : "uuid must not be null";
    assert localTermIdReferenceByTermId != null : "localTermIdReferenceByTermId must not be null";
    assert ruleByTermId != null : "ruleByTermId must not be null";
    
    try {
      final LocalTermIdReference localTermIdReference = localTermIdReferenceByUUIDBytes.get(ByteUtils.toByteObjectArray(uuid));
      if (localTermIdReference == null) {
        return null;
      }
      return ruleByTermId.get(localTermIdReference.getTermId());
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
  }
  
  /** Finds the Rule having the given termId.
   *
   * @param termId the given term id
   * @return the Rule having the given termId
   * @throws TexaiException if the term is not found
   */
  public Rule findRuleByTermId(final int termId) {
    //Preconditions
    assert termId != 0 : "termId must not be zero";
    assert ruleByTermId != null : "ruleByTermId must not be null";
    
    try {
      final Rule rule = ruleByTermId.get(termId);
      if (rule == null) {
        throw new TexaiException("rule not found for id " + termId);
      }
      return rule;
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
  }
  
  /** Finds the Rule having the given formula or null if not found.
   *
   * @param formula the given formula
   * @return the Rule having the given formula or null if not found
   */
  public Rule findRuleByFormula(
          final Formula formula) {
    //Preconditions
    assert formula != null : "formula must not be null";
    assert formula.getTermId() != 0 : "formula termId must not be zero";
    assert ruleByFormulaId != null : "ruleByFormulaId must not be null";
    
    try {
      return ruleByFormulaId.get(formula.getTermId());
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
  }
  
  /** Finds the UnaryGAF having the given UUID.
   *
   * @param uuid the given uuid
   * @return the UnaryGAF having the given termId
   * @throws TexaiException if the term is not found
   */
  public UnaryGAF findUnaryGAFByUUID(final UUID uuid) {
    //Preconditions
    assert uuid != null : "uuid must not be null";
    assert localTermIdReferenceByTermId != null : "localTermIdReferenceByTermId must not be null";
    assert unaryGAFByTermId != null : "unaryGAFByTermId must not be null";
    
    try {
      final LocalTermIdReference localTermIdReference = localTermIdReferenceByUUIDBytes.get(ByteUtils.toByteObjectArray(uuid));
      if (localTermIdReference == null) {
        return null;
      }
      return unaryGAFByTermId.get(localTermIdReference.getTermId());
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
  }
  
  /** Finds the UnaryGAF having the given termId.
   *
   * @param termId the given term id
   * @return the UnaryGAF having the given termId
   * @throws TexaiException if the term is not found
   */
  public UnaryGAF findUnaryGAFByTermId(final int termId) {
    //Preconditions
    assert termId != 0 : "termId must not be zero";
    assert unaryGAFByTermId != null : "unaryGAFByTermId must not be null";
    
    try {
      final UnaryGAF unaryGAF = unaryGAFByTermId.get(termId);
      if (unaryGAF == null) {
        throw new TexaiException("UnaryGAF not found for id " + termId);
      }
      return unaryGAF;
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
  }
  
  /** Finds the UnaryGAF having the given constitutents or null if not found.
   *
   * @param predicate the given predicate
   * @param args the argument list
   * @param context the context
   * @return the UnaryGAF having the given constitutents or null if not found
   */
  public UnaryGAF findUnaryGAFByConstituents(
          final AbstractReifiedTerm predicate,
          final List<AbstractTerm> args,
          final AbstractReifiedTerm context) {
    //Preconditions
    assert predicate != null : Constants.PREDICATE_ERR;
    assert args != null : Constants.ARGS_ERR;
    assert args.size() ==  Constants.UNARY_ARGS_SIZE : "unary gaf must have one argument";
    assert context != null : Constants.CONTEXT_ERR;
    assert unaryGAFByArg1TermId != null : "unaryGAFByArg1TermId must not be null";
    
    final AbstractTerm arg1 = args.get(0);
    try {
      final EntityIndex<Integer, UnaryGAF> entityIndex = unaryGAFByArg1TermId.subIndex(arg1.getTermId());
      final EntityCursor<UnaryGAF> entityCursor = entityIndex.entities();
      for (final UnaryGAF unaryGAF : entityCursor) {
        if (unaryGAF.getTermType() == Constants.UNARY_GAF
                && unaryGAF.getPredicateTermType() == predicate.getTermType()
                && unaryGAF.getPredicateTermId() == predicate.getTermId()
                && unaryGAF.getArg1TermType() == arg1.getTermType()
                && unaryGAF.getArg1TermId() == arg1.getTermId()
                && unaryGAF.getContextTermType() == context.getTermType()
                && unaryGAF.getContextTermId() == context.getTermId()) {
          entityCursor.close();
          return unaryGAF;
        }
      }
      entityCursor.close();
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
    return null;
  }
  
  /** Finds the BinaryGAF having the given UUID.
   *
   * @param uuid the given uuid
   * @return the BinaryGAF having the given termId
   * @throws TexaiException if the term is not found
   */
  public BinaryGAF findBinaryGAFByUUID(final UUID uuid) {
    //Preconditions
    assert uuid != null : "uuid must not be null";
    assert localTermIdReferenceByTermId != null : "localTermIdReferenceByTermId must not be null";
    assert binaryGAFByTermId != null : "binaryGAFByTermId must not be null";
    
    try {
      final LocalTermIdReference localTermIdReference = localTermIdReferenceByUUIDBytes.get(ByteUtils.toByteObjectArray(uuid));
      if (localTermIdReference == null) {
        return null;
      }
      return binaryGAFByTermId.get(localTermIdReference.getTermId());
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
  }
  
  /** Finds the BinaryGAF having the given termId.
   *
   * @param termId the given term id
   * @return the BinaryGAF having the given termId
   * @throws TexaiException if the term is not found
   */
  public BinaryGAF findBinaryGAFByTermId(final int termId) {
    //Preconditions
    assert termId != 0 : "termId must not be zero";
    assert binaryGAFByTermId != null : "binaryGAFByTermId must not be null";
    
    try {
      final BinaryGAF binaryGAF = binaryGAFByTermId.get(termId);
      if (binaryGAF == null) {
        throw new TexaiException("BinaryGAF not found for id " + termId);
      }
      return binaryGAF;
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
  }
  
  /** Finds the BinaryGAF having the given constitutents or null if not found.
   *
   * @param predicate the given predicate
   * @param args the argument list
   * @param context the context
   * @return the BinaryGAF having the given constitutents or null if not found
   */
  public BinaryGAF findBinaryGAFByConstituents(
          final AbstractReifiedTerm predicate,
          final List<AbstractTerm> args,
          final AbstractReifiedTerm context) {
    //Preconditions
    assert predicate != null : Constants.PREDICATE_ERR;
    assert args != null : Constants.ARGS_ERR;
    assert args.size() ==  Constants.BINARY_ARGS_SIZE : "binary gaf must have two arguments";
    assert context != null : Constants.CONTEXT_ERR;
    assert binaryGAFByArg1TermId != null : "binaryGAFByArg1TermId must not be null";
    
    final AbstractTerm arg1 = args.get(0);
    try {
      final EntityIndex<Integer, BinaryGAF> entityIndex = binaryGAFByArg1TermId.subIndex(arg1.getTermId());
      final EntityCursor<BinaryGAF> entityCursor = entityIndex.entities();
      for (final BinaryGAF binaryGAF : entityCursor) {
        if (binaryGAF.getPredicateTermType() == predicate.getTermType()
        && binaryGAF.getPredicateTermId() == predicate.getTermId()
        && binaryGAF.getArg1TermType() == arg1.getTermType()
        && binaryGAF.getContextTermType() == context.getTermType()
        && binaryGAF.getContextTermId() == context.getTermId()
        && binaryGAF.getArg2TermType() == args.get(1).getTermType()
        && binaryGAF.getArg2TermId() == args.get(1).getTermId()) {
          entityCursor.close();
          return binaryGAF;
        }
      }
      entityCursor.close();
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
    return null;
  }
  
  /** Finds the TernaryGAF having the given UUID.
   *
   * @param uuid the given uuid
   * @return the TernaryGAF having the given termId
   * @throws TexaiException if the term is not found
   */
  public TernaryGAF findTernaryGAFByUUID(final UUID uuid) {
    //Preconditions
    assert uuid != null : "uuid must not be null";
    assert localTermIdReferenceByTermId != null : "localTermIdReferenceByTermId must not be null";
    assert ternaryGAFByTermId != null : "ternaryGAFByTermId must not be null";
    
    try {
      final LocalTermIdReference localTermIdReference = localTermIdReferenceByUUIDBytes.get(ByteUtils.toByteObjectArray(uuid));
      if (localTermIdReference == null) {
        return null;
      }
      return ternaryGAFByTermId.get(localTermIdReference.getTermId());
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
  }
  
  /** Finds the TernaryGAF having the given termId.
   *
   * @param termId the given term id
   * @return the TernaryGAF having the given termId
   * @throws TexaiException if the term is not found
   */
  public TernaryGAF findTernaryGAFByTermId(final int termId) {
    //Preconditions
    assert termId != 0 : "termId must not be zero";
    assert ternaryGAFByTermId != null : "ternaryGAFByTermId must not be null";
    
    try {
      final TernaryGAF ternaryGAF = ternaryGAFByTermId.get(termId);
      if (ternaryGAF == null) {
        throw new TexaiException("TernaryGAF not found for id " + termId);
      }
      return ternaryGAF;
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
  }
  
  /** Finds the TernaryGAF having the given constitutents or null if not found.
   *
   * @param predicate the given predicate
   * @param args the argument list
   * @param context the context
   * @return the TernaryGAF having the given constitutents or null if not found
   */
  public TernaryGAF findTernaryGAFByConstituents(
          final AbstractReifiedTerm predicate,
          final List<AbstractTerm> args,
          final AbstractReifiedTerm context) {
    //Preconditions
    assert predicate != null : Constants.PREDICATE_ERR;
    assert args != null : Constants.ARGS_ERR;
    assert args.size() ==  Constants.TERNARY_ARGS_SIZE : "ternary gaf must have three arguments";
    assert context != null : Constants.CONTEXT_ERR;
    assert ternaryGAFByArg1TermId != null : "ternaryGAFByArg1TermId must not be null";
    
    final AbstractTerm arg1 = args.get(0);
    try {
      final EntityIndex<Integer, TernaryGAF> entityIndex = ternaryGAFByArg1TermId.subIndex(arg1.getTermId());
      final EntityCursor<TernaryGAF> entityCursor = entityIndex.entities();
      for (final TernaryGAF ternaryGAF : entityCursor) {
        if (ternaryGAF.getPredicateTermType() == predicate.getTermType()
        && ternaryGAF.getPredicateTermId() == predicate.getTermId()
        && ternaryGAF.getArg1TermId() == arg1.getTermId()
        && ternaryGAF.getContextTermType() == context.getTermType()
        && ternaryGAF.getContextTermId() == context.getTermId()
        && ternaryGAF.getArg2TermType() == args.get(1).getTermType()
        && ternaryGAF.getArg2TermId() == args.get(1).getTermId()
        && ternaryGAF.getArg3TermType() == args.get(2).getTermType()
        && ternaryGAF.getArg3TermId() == args.get(2).getTermId()) {
          entityCursor.close();
          return ternaryGAF;
        }
      }
      entityCursor.close();
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
    return null;
  }
  
  /** Finds the QuaternaryGAF having the given UUID.
   *
   * @param uuid the given uuid
   * @return the QuaternaryGAF having the given termId
   * @throws TexaiException if the term is not found
   */
  public QuaternaryGAF findQuaternaryGAFByUUID(final UUID uuid) {
    //Preconditions
    assert uuid != null : "uuid must not be null";
    assert localTermIdReferenceByTermId != null : "localTermIdReferenceByTermId must not be null";
    assert quaternaryGAFByTermId != null : "quaternaryGAFByTermId must not be null";
    
    try {
      final LocalTermIdReference localTermIdReference = localTermIdReferenceByUUIDBytes.get(ByteUtils.toByteObjectArray(uuid));
      if (localTermIdReference == null) {
        return null;
      }
      return quaternaryGAFByTermId.get(localTermIdReference.getTermId());
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
  }
  
  /** Finds the QuaternaryGAF having the given termId.
   *
   * @param termId the given term id
   * @return the QuaternaryGAF having the given termId
   * @throws TexaiException if the term is not found
   */
  public QuaternaryGAF findQuaternaryGAFByTermId(final int termId) {
    //Preconditions
    assert termId != 0 : "termId must not be zero";
    assert quaternaryGAFByTermId != null : "quaternaryGAFByTermId must not be null";
    
    try {
      final QuaternaryGAF quaternaryGAF = quaternaryGAFByTermId.get(termId);
      if (quaternaryGAF == null) {
        throw new TexaiException("QuaternaryGAF not found for id " + termId);
      }
      return quaternaryGAF;
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
  }
  
  /** Finds the QuaternaryGAF having the given constitutents or null if not found.
   *
   * @param predicate the given predicate
   * @param args the argument list
   * @param context the context
   * @return the QuaternaryGAF having the given constitutents or null if not found
   */
  public QuaternaryGAF findQuaternaryGAFByConstituents(
          final AbstractReifiedTerm predicate,
          final List<AbstractTerm> args,
          final AbstractReifiedTerm context) {
    //Preconditions
    assert predicate != null : Constants.PREDICATE_ERR;
    assert args != null : Constants.ARGS_ERR;
    assert args.size() ==  Constants.QUATERNARY_ARGS_SIZE : "quaternary gaf must have four arguments";
    assert context != null : Constants.CONTEXT_ERR;
    assert quaternaryGAFByArg1TermId != null : "quaternaryGAFByArg1TermId must not be null";
    
    final AbstractTerm arg1 = args.get(0);
    try {
      final EntityIndex<Integer, QuaternaryGAF> entityIndex = quaternaryGAFByArg1TermId.subIndex(arg1.getTermId());
      final EntityCursor<QuaternaryGAF> entityCursor = entityIndex.entities();
      for (final QuaternaryGAF quaternaryGAF : entityCursor) {
        if (quaternaryGAF.getPredicateTermType() == predicate.getTermType()
        && quaternaryGAF.getPredicateTermId() == predicate.getTermId()
        && quaternaryGAF.getArg1TermType() == arg1.getTermType()
        && quaternaryGAF.getContextTermType() == context.getTermType()
        && quaternaryGAF.getContextTermId() == context.getTermId()
        && quaternaryGAF.getArg2TermType() == args.get(1).getTermType()
        && quaternaryGAF.getArg2TermId() == args.get(1).getTermId()
        && quaternaryGAF.getArg3TermType() == args.get(2).getTermType()
        && quaternaryGAF.getArg3TermId() == args.get(2).getTermId()
        && quaternaryGAF.getArg4TermType() == args.get(3).getTermType()
        && quaternaryGAF.getArg4TermId() == args.get(3).getTermId()) {
          entityCursor.close();
          return quaternaryGAF;
        }
      }
      entityCursor.close();
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
    return null;
  }
  
  /** Finds the QuintaryGAF having the given UUID.
   *
   * @param uuid the given uuid
   * @return the QuintaryGAF having the given termId
   * @throws TexaiException if the term is not found
   */
  public QuintaryGAF findQuintaryGAFByUUID(final UUID uuid) {
    //Preconditions
    assert uuid != null : "uuid must not be null";
    assert localTermIdReferenceByTermId != null : "localTermIdReferenceByTermId must not be null";
    assert quintaryGAFByTermId != null : "quintaryGAFByTermId must not be null";
    
    try {
      final LocalTermIdReference localTermIdReference = localTermIdReferenceByUUIDBytes.get(ByteUtils.toByteObjectArray(uuid));
      if (localTermIdReference == null) {
        return null;
      }
      return quintaryGAFByTermId.get(localTermIdReference.getTermId());
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
  }
  
  /** Finds the QuintaryGAF having the given termId.
   *
   * @param termId the given term id
   * @return the QuintaryGAF having the given termId
   * @throws TexaiException if the term is not found
   */
  public QuintaryGAF findQuintaryGAFByTermId(final int termId) {
    //Preconditions
    assert termId != 0 : "termId must not be zero";
    assert quintaryGAFByTermId != null : "quintaryGAFByTermId must not be null";
    
    try {
      final QuintaryGAF quintaryGAF = quintaryGAFByTermId.get(termId);
      if (quintaryGAF == null) {
        throw new TexaiException("QuintaryGAF not found for id " + termId);
      }
      return quintaryGAF;
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
  }
  
  /** Finds the QuintaryGAF having the given constitutents or null if not found.
   *
   * @param predicate the given predicate
   * @param args the argument list
   * @param context the context
   * @return the QuintaryGAF having the given constitutents or null if not found
   */
  public QuintaryGAF findQuintaryGAFByConstituents(
          final AbstractReifiedTerm predicate,
          final List<AbstractTerm> args,
          final AbstractReifiedTerm context) {
    //Preconditions
    assert predicate != null : Constants.PREDICATE_ERR;
    assert args != null : Constants.ARGS_ERR;
    assert args.size() ==  Constants.QUINTARY_ARGS_SIZE : "quintary gaf must have five arguments";
    assert context != null : Constants.CONTEXT_ERR;
    assert quintaryGAFByArg1TermId != null : "quintaryGAFByArg1TermId must not be null";
    
    final AbstractTerm arg1 = args.get(0);
    try {
      final EntityIndex<Integer, QuintaryGAF> entityIndex = quintaryGAFByArg1TermId.subIndex(arg1.getTermId());
      final EntityCursor<QuintaryGAF> entityCursor = entityIndex.entities();
      for (final QuintaryGAF quintaryGAF : entityCursor) {
        if (quintaryGAF.getPredicateTermType() == predicate.getTermType()
        && quintaryGAF.getPredicateTermId() == predicate.getTermId()
        && quintaryGAF.getArg1TermType() == arg1.getTermType()
        && quintaryGAF.getArg1TermId() == arg1.getTermId()
        && quintaryGAF.getContextTermType() == context.getTermType()
        && quintaryGAF.getContextTermId() == context.getTermId()
        && quintaryGAF.getArg2TermType() == args.get(1).getTermType()
        && quintaryGAF.getArg2TermId() == args.get(1).getTermId()
        && quintaryGAF.getArg3TermType() == args.get(2).getTermType()
        && quintaryGAF.getArg3TermId() == args.get(2).getTermId()
        && quintaryGAF.getArg4TermType() == args.get(3).getTermType()
        && quintaryGAF.getArg4TermId() == args.get(3).getTermId()
        && quintaryGAF.getArg5TermType() == args.get(4).getTermType()
        && quintaryGAF.getArg5TermId() == args.get(4).getTermId()) {
          entityCursor.close();
          return quintaryGAF;
        }
      }
      entityCursor.close();
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
    return null;
  }
  
  /** Creates the Symbol having the given nameValue.
   *
   * @param nameValue the given name value
   * @return the Symbol having the given nameValue
   */
  public Symbol createSymbolByNameValue(final String nameValue) {
    //Preconditions
    assert nameValue != null : Constants.NAME_VALUE_NULL_ERR;
    assert nameValue.length() > 0 : Constants.NAME_VALUE_EMPTY_ERR;
    assert symbolByTermId != null : "symbolByTermId must not be null";
    
    final Symbol symbol = new Symbol(getNextTermId(), nameValue);
    try {
      symbolByTermId.putNoReturn(symbol);
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
    
    //Postconditions
    assert symbol.getTermId() != 0 : "termId must not be zero for " + symbol;
    
    return symbol;
  }
  
  /** Creates the PVariable having the given nameValue.
   *
   * @param nameValue the given name value
   * @return the PVariable having the given nameValue
   */
  public PVariable createPVariableByNameValue(final String nameValue) {
    //Preconditions
    assert nameValue != null : Constants.NAME_VALUE_NULL_ERR;
    assert nameValue.length() > 0 : Constants.NAME_VALUE_EMPTY_ERR;
    assert pVariableByTermId != null : "pVariableByTermId must not be null";
    
    final PVariable pVariable = new PVariable(getNextTermId(), nameValue);
    try {
      pVariableByTermId.putNoReturn(pVariable);
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
    
    //Postconditions
    assert pVariable.getTermId() != 0 : "termId must not be zero for " + pVariable;
    
    return pVariable;
  }
  
  /** Creates the PLong having the given longValue.
   *
   * @param longValue the given long value
   * @return the PLong having the given nameValue
   */
  public PLong createPLongByLongValue(final Long longValue) {
    //Preconditions
    assert longValue != null : "longValue must not be null";
    assert pLongByTermId != null : "pLongByTermId must not be null";
    
    final PLong pLong = new PLong(getNextTermId(), longValue);
    try {
      pLongByTermId.putNoReturn(pLong);
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
    
    //Postconditions
    assert pLong.getTermId() != 0 : "termId must not be zero for " + pLong;
    
    return pLong;
  }
  
  /** creates the PDouble having the given doubleValue.
   *
   * @param doubleValue the given double value
   * @return the PLong having the given doubleValue
   */
  public PDouble createPDoubleByDoubleValue(final Double doubleValue) {
    //Preconditions
    assert doubleValue != null : "doubleValue must not be null";
    assert pDoubleByTermId != null : "pDoubleByTermId must not be null";
    
    final PDouble pDouble = new PDouble(getNextTermId(), doubleValue);
    try {
      pDoubleByTermId.putNoReturn(pDouble);
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
    
    //Postconditions
    assert pDouble.getTermId() != 0 : "termId must not be zero for " + pDouble;
    
    return pDouble;
  }
  
  /** Creates the PString having the given stringValue.
   *
   * @param stringValue the given double value
   * @return the PLong having the given doubleValue
   */
  public PString createPStringByStringValue(final String stringValue) {
    //Preconditions
    assert stringValue != null : "stringValue must not be null";
    assert pStringByTermId != null : "pStringByTermId must not be null";
    
    final PString pString = new PString(getNextTermId(), stringValue);
    try {
      pStringByTermId.putNoReturn(pString);
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
    
    //Postconditions
    assert pString.getTermId() != 0 : "termId must not be zero for " + pString;
    
    return pString;
  }
  
  /** creates the PDate having the given dateValue.
   *
   * @param dateValue the given date value
   * @return the PDate having the given dateValue
   */
  public PDate createPDateByDateValue(final Date dateValue) {
    //Preconditions
    assert dateValue != null : "dateValue must not be null";
    assert pDateByTermId != null : "pDateByTermId must not be null";
    
    final PDate pDate = new PDate(getNextTermId(), dateValue);
    try {
      pDateByTermId.putNoReturn(pDate);
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
    
    //Postconditions
    assert pDate.getTermId() != 0 : "termId must not be zero for " + pDate;
    
    return pDate;
  }
  
  /** Creates the bootstrap AtomicTerm having the given termName.
   *
   * @param uuid the UUID
   * @param termName the term name
   * @param prettyName the pretty name
   * @return the AtomicTerm having the given termName
   */
  public AtomicTerm createBootstrapAtomicTerm(
          final UUID uuid,
          final String termName,
          final String prettyName) {
    //Preconditions
    assert uuid != null : "uuid must not be null";
    assert termName != null : Constants.TERM_NAME_NULL_ERR;
    assert termName.length() > 0 : Constants.TERM_NAME_EMPTY_ERR;
    assert atomicTermByTermId != null : "atomicTermByTermId must not be null";
    assert localTermIdReferenceByTermId != null : "localTermIdReferenceByTermId must not be null";
    
    final AtomicTerm atomicTerm = new AtomicTerm(
            getNextTermId(),
            termName,
            prettyName,
            new Date());
    try {
      atomicTermByTermId.putNoReturn(atomicTerm);
      localTermIdReferenceByTermId.putNoReturn(new LocalTermIdReference(atomicTerm.getTermId(), uuid));
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
    //Postconditions
    assert atomicTerm.getTermId() != 0 : "termId must not be zero for " + atomicTerm;
    
    return atomicTerm;
  }
  
  /** Creates the AtomicTerm having the given termName.
   *
   * @param termName the term name
   * @param prettyName the pretty name
   * @param creator the creator
   * @param creationPurpose the creation purpose
   * @return the AtomicTerm having the given termName
   */
  public AtomicTerm createAtomicTermByTermName(
          final String termName,
          final String prettyName,
          final AbstractReifiedTerm creator,
          final AbstractReifiedTerm creationPurpose) {
    //Preconditions
    assert termName != null : Constants.TERM_NAME_NULL_ERR;
    assert termName.length() > 0 : Constants.TERM_NAME_EMPTY_ERR;
    assert (creator == null && creationPurpose == null)
    || (creator != null && creationPurpose != null) : "creator and creationPurpose must either both be null, or both be non-null";
    assert atomicTermByTermId != null : "atomicTermByTermId must not be null";
    assert localTermIdReferenceByTermId != null : "localTermIdReferenceByTermId must not be null";
    
    AtomicTerm atomicTerm = null;
    if (creator == null && creationPurpose == null) {
      atomicTerm = new AtomicTerm(
              getNextTermId(),
              termName,
              prettyName,
              new Date());
    } else {
      atomicTerm = new AtomicTerm(
              getNextTermId(),
              termName,
              prettyName,
              creator,
              creationPurpose,
              new Date());
    }
    try {
      atomicTermByTermId.putNoReturn(atomicTerm);
      localTermIdReferenceByTermId.putNoReturn(new LocalTermIdReference(atomicTerm.getTermId(), UUID.randomUUID()));
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
    
    //Postconditions
    assert atomicTerm.getTermId() != 0 : "termId must not be zero for " + atomicTerm;
    
    return atomicTerm;
  }
  
  /** Creates the NonAtomicTerm having the given termName.
   *
   * @param termName the term name
   * @param prettyName the pretty name
   * @param formula the formula
   * @param creator the creator
   * @param creationPurpose the creation purpose
   * @return the NonAtomicTerm having the given termName or a new one having
   * the given constituents
   */
  public NonAtomicTerm createNonAtomicTermByTermName(
          final String termName,
          final String prettyName,
          final Formula formula,
          final AbstractReifiedTerm creator,
          final AbstractReifiedTerm creationPurpose) {
    //Preconditions
    assert termName != null : Constants.TERM_NAME_NULL_ERR;
    assert termName.length() > 0 : Constants.TERM_NAME_EMPTY_ERR;
    assert formula != null : "formula must not be null";
    assert nonAtomicTermByTermId != null : "nonAtomicTermByTermId must not be null";
    assert localTermIdReferenceByTermId != null : "localTermIdReferenceByTermId must not be null";
    
    final NonAtomicTerm nonAtomicTerm = new NonAtomicTerm(
            getNextTermId(),
            termName,
            prettyName,
            formula,
            creator,
            creationPurpose,
            new Date());
    try {
      nonAtomicTermByTermId.putNoReturn(nonAtomicTerm);
      localTermIdReferenceByTermId.putNoReturn(new LocalTermIdReference(nonAtomicTerm.getTermId(), UUID.randomUUID()));
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
    
    //Postconditions
    assert nonAtomicTerm.getTermId() != 0 : "termId must not be zero for " + nonAtomicTerm;
    
    return nonAtomicTerm;
  }
  
  /** Creates the Formula having the given term list.
   * }
   *
   * @param formulaTerms the list of terms that constitute this formula
   * @param creator the creator
   * @param creationPurpose the creation purpose
   * @return the persisted Formula having the given term list
   */
  public Formula createFormulaByTermList(
          final List<AbstractTerm> formulaTerms,
          final AbstractReifiedTerm creator,
          final AbstractReifiedTerm creationPurpose) {
    //Preconditions
    assert formulaTerms != null : "termList must not be null";
    assert formulaByTermId != null : "formulaByTermId must not be null";
    
    final Formula formula = new Formula(
            getNextTermId(),
            formulaTerms,
            creator,
            creationPurpose,
            new Date());
    try {
      formulaByTermId.putNoReturn(formula);
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
    
    //Postconditions
    assert formula.getTermId() != 0 : "termId must not be zero for " + formula;
    
    return formula;
  }
  
  /** Creates (with the term list omitted) the Formula having the given formulaString.
   *
   * @param formulaString the given formula string
   * @param creator the creator
   * @param creationPurpose the creation purpose
   * @return the persisted Formula having the given formulaString or a new Formula having the
   * given term list
   */
  public Formula createFormulaByFormulaString(
          final String formulaString,
          final AbstractReifiedTerm creator,
          final AbstractReifiedTerm creationPurpose) {
    //Preconditions
    assert formulaString != null : "formulaString must not be null";
    assert formulaString.length() > 0 : "formulaString must not be an empty string";
    assert formulaByTermId != null : "formulaByTermId must not be null";
    
    final Formula formula = new Formula(
            getNextTermId(),
            formulaString,
            creator,
            creationPurpose,
            new Date());
    try {
      formulaByTermId.putNoReturn(formula);
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
    
    //Postconditions
    assert formula.getTermId() != 0 : "termId must not be zero for " + formula;
    
    return formula;
  }
  
  /** Creates the Rule having the given formula.
   *
   * @param formula the given formula
   * @param context the context
   * @param strength the strength
   * @param creator the creator
   * @param creationPurpose the creation purpose
   * @param creationDate the creation date
   * @return the Rule having the given formulaString
   */
  public Rule createRuleByFormula(
          final Formula formula,
          final AbstractReifiedTerm context,
          final Double strength,
          final AbstractReifiedTerm creator,
          final AbstractReifiedTerm creationPurpose) {
    //Preconditions
    assert formula != null : "formula must not be null";
    assert ruleByTermId != null : "ruleByTermId must not be null";
    assert localTermIdReferenceByTermId != null : "localTermIdReferenceByTermId must not be null";
    
    final Rule rule = new Rule(
            getNextTermId(),
            formula,
            context,
            strength,
            creator,
            creationPurpose,
            new Date());
    try {
      ruleByTermId.putNoReturn(rule);
      localTermIdReferenceByTermId.putNoReturn(new LocalTermIdReference(rule.getTermId(), UUID.randomUUID()));
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
    
    //Postconditions
    assert rule.getTermId() != 0 : "termId must not be zero for " + rule;
    
    return rule;
  }
  
  /** Creates the UnaryGAF having the given constitutents.
   *
   * @param predicate the given predicate
   * @param args the argument list
   * @param context the context
   * @param strength the assertion strength
   * @param generatedPhrase the generated phrase for this ground atomic formula
   * @param creator the creator
   * @param creationPurpose the creation purpose
   * @return the UnaryGAF having the given constitutents
   */
  public UnaryGAF createUnaryGAFByConstituents(
          final AbstractReifiedTerm predicate,
          final List<AbstractTerm> args,
          final AbstractReifiedTerm context,
          final Double strength,
          final String generatedPhrase,
          final AbstractReifiedTerm creator,
          final AbstractReifiedTerm creationPurpose) {
    //Preconditions
    assert predicate != null : Constants.PREDICATE_ERR;
    assert args != null : Constants.ARGS_ERR;
    assert args.size() ==  Constants.UNARY_ARGS_SIZE : "unary gaf must have one argument";
    assert context != null : Constants.CONTEXT_ERR;
    assert unaryGAFByTermId != null : "unaryGAFByTermId must not be null";
    assert localTermIdReferenceByTermId != null : "localTermIdReferenceByTermId must not be null";
    
    final UnaryGAF unaryGAF = new UnaryGAF(
            getNextTermId(),
            predicate,
            args,
            context,
            strength,
            generatedPhrase,
            creator,
            creationPurpose,
            new Date());
    try {
      unaryGAFByTermId.putNoReturn(unaryGAF);
      localTermIdReferenceByTermId.putNoReturn(new LocalTermIdReference(unaryGAF.getTermId(), UUID.randomUUID()));
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
//    getLogger().debug("persisted new unary GAF: " + unaryGAF + " " + unaryGAF.getStrength());
    
    //Postconditions
    assert unaryGAF.getTermId() != 0 : "termId must not be zero for " + unaryGAF;
    
    return unaryGAF;
  }
  
  /**
   * Creates the BinaryGAF having the given constitutents.
   *
   * @param predicate the given predicate
   * @param args the argument list
   * @param context the context
   * @param strength the assertion strength
   * @param generatedPhrase the generated phrase for this ground atomic formula
   * @param validateWellFormedFormula the indicator to validate the gaf as a well-formed formula
   * @param creator the creator
   * @param creationPurpose the creation purpose
   * @return the BinaryGAF having the given constitutents
   */
  public BinaryGAF createBinaryGAFByConstituents(
          final AbstractReifiedTerm predicate,
          final List<AbstractTerm> args,
          final AbstractReifiedTerm context,
          final Double strength,
          final String generatedPhrase,
          boolean validateWellFormedFormula,
          final AbstractReifiedTerm creator,
          final AbstractReifiedTerm creationPurpose) {
    //Preconditions
    assert predicate != null : Constants.PREDICATE_ERR;
    assert args != null : Constants.ARGS_ERR;
    assert args.size() ==  Constants.BINARY_ARGS_SIZE : "binary gaf must have two arguments";
    assert args.get(0) != null : "binary gaf arg1 must not be null";
    assert args.get(1) != null : "binary gaf arg2 must not be null";
    assert context != null : Constants.CONTEXT_ERR;
    assert strength != null : "strength must not be null";
    assert binaryGAFByTermId != null : "binaryGAFByTermId must not be null";
    assert localTermIdReferenceByTermId != null : "localTermIdReferenceByTermId must not be null";
    
    final BinaryGAF binaryGAF = new BinaryGAF(
            getNextTermId(),
            predicate,
            args,
            context,
            strength,
            generatedPhrase,
            creator,
            creationPurpose,
            new Date());
    try {
      binaryGAFByTermId.putNoReturn(binaryGAF);
      localTermIdReferenceByTermId.putNoReturn(new LocalTermIdReference(binaryGAF.getTermId(), UUID.randomUUID()));
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
//    getLogger().debug("persisted new binary GAF: " + binaryGAF + " " + binaryGAF.getStrength());
    
    //Postconditions
    assert binaryGAF.getTermId() != 0 : "termId must not be zero for " + binaryGAF;
    
    return binaryGAF;
  }
  
  /** Creates the TernaryGAF having the given constitutents.
   *
   * @param predicate the given predicate
   * @param args the argument list
   * @param context the context
   * @param strength the assertion strength
   * @param generatedPhrase the generated phrase for this ground atomic formula
   * @param creator the creator
   * @param creationPurpose the creation purpose
   * @return the TernaryGAF having the given constitutents
   */
  public TernaryGAF createTernaryGAFByConstituents(
          final AbstractReifiedTerm predicate,
          final List<AbstractTerm> args,
          final AbstractReifiedTerm context,
          final Double strength,
          final String generatedPhrase,
          final AbstractReifiedTerm creator,
          final AbstractReifiedTerm creationPurpose) {
    //Preconditions
    assert predicate != null : Constants.PREDICATE_ERR;
    assert args != null : Constants.ARGS_ERR;
    assert args.size() ==  Constants.TERNARY_ARGS_SIZE : "ternary gaf must have three arguments";
    assert context != null : Constants.CONTEXT_ERR;
    assert ternaryGAFByTermId != null : "ternaryGAFByTermId must not be null";
    assert localTermIdReferenceByTermId != null : "localTermIdReferenceByTermId must not be null";
    
    final TernaryGAF ternaryGAF = new TernaryGAF(
            getNextTermId(),
            predicate,
            args,
            context,
            strength,
            generatedPhrase,
            creator,
            creationPurpose,
            new Date());
    try {
      ternaryGAFByTermId.putNoReturn(ternaryGAF);
      localTermIdReferenceByTermId.putNoReturn(new LocalTermIdReference(ternaryGAF.getTermId(), UUID.randomUUID()));
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
//    getLogger().debug("persisted new ternary GAF: " + ternaryGAF + " " + ternaryGAF.getStrength());
    
    //Postconditions
    assert ternaryGAF.getTermId() != 0 : "termId must not be zero for " + ternaryGAF;
    
    return ternaryGAF;
  }
  
  /** Creates the QuaternaryGAF having the given constitutents.
   *
   * @param predicate the given predicate
   * @param args the argument list
   * @param context the context
   * @param strength the assertion strength
   * @param generatedPhrase the generated phrase for this ground atomic formula
   * @param creator the creator
   * @param creationPurpose the creation purpose
   * @return the QuaternaryGAF having the given constitutents
   */
  public QuaternaryGAF createQuaternaryGAFByConstituents(
          final AbstractReifiedTerm predicate,
          final List<AbstractTerm> args,
          final AbstractReifiedTerm context,
          final Double strength,
          final String generatedPhrase,
          final AbstractReifiedTerm creator,
          final AbstractReifiedTerm creationPurpose) {
    //Preconditions
    assert predicate != null : Constants.PREDICATE_ERR;
    assert args != null : Constants.ARGS_ERR;
    assert args.size() ==  Constants.QUATERNARY_ARGS_SIZE : "quaternary gaf must have four arguments";
    assert context != null : Constants.CONTEXT_ERR;
    assert quaternaryGAFByTermId != null : "quaternaryGAFByTermId must not be null";
    assert localTermIdReferenceByTermId != null : "localTermIdReferenceByTermId must not be null";
    
    final QuaternaryGAF quaternaryGAF = new QuaternaryGAF(
            getNextTermId(),
            predicate,
            args,
            context,
            strength,
            generatedPhrase,
            creator,
            creationPurpose,
            new Date());
    try {
      quaternaryGAFByTermId.putNoReturn(quaternaryGAF);
      localTermIdReferenceByTermId.putNoReturn(new LocalTermIdReference(quaternaryGAF.getTermId(), UUID.randomUUID()));
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
//    getLogger().debug("persisted new quaternary GAF: " + quaternaryGAF + " " + quaternaryGAF.getStrength());
    
    //Postconditions
    assert quaternaryGAF.getTermId() != 0 : "termId must not be zero for " + quaternaryGAF;
    
    return quaternaryGAF;
  }
  
  /** Creates the QuintaryGAF having the given constitutents.
   *
   * @param predicate the given predicate
   * @param args the argument list
   * @param context the context
   * @param strength the assertion strength
   * @param generatedPhrase the generated phrase for this ground atomic formula
   * @param creator the creator
   * @param creationPurpose the creation purpose
   * @return the QuintaryGAF having the given constitutents
   */
  public QuintaryGAF createQuintaryGAFByConstituents(
          final AbstractReifiedTerm predicate,
          final List<AbstractTerm> args,
          final AbstractReifiedTerm context,
          final Double strength,
          final String generatedPhrase,
          final AbstractReifiedTerm creator,
          final AbstractReifiedTerm creationPurpose) {
    //Preconditions
    assert predicate != null : Constants.PREDICATE_ERR;
    assert args != null : Constants.ARGS_ERR;
    assert args.size() ==  Constants.QUINTARY_ARGS_SIZE : "quintary gaf must have five arguments";
    assert context != null : Constants.CONTEXT_ERR;
    assert quintaryGAFByTermId != null : "quintaryGAFByTermId must not be null";
    assert localTermIdReferenceByTermId != null : "localTermIdReferenceByTermId must not be null";
    
    final QuintaryGAF quintaryGAF = new QuintaryGAF(
            getNextTermId(),
            predicate,
            args,
            context,
            strength,
            generatedPhrase,
            creator,
            creationPurpose,
            new Date());
    try {
      quintaryGAFByTermId.putNoReturn(quintaryGAF);
      localTermIdReferenceByTermId.putNoReturn(new LocalTermIdReference(quintaryGAF.getTermId(), UUID.randomUUID()));
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
//    getLogger().debug("persisted new quintary GAF: " + quintaryGAF + " " + quintaryGAF.getStrength());
    
    //Postconditions
    assert quintaryGAF.getTermId() != 0 : "termId must not be zero for " + quintaryGAF;
    
    return quintaryGAF;
  }
  
  /**
   * Creates the defined atomic term.
   *
   * @param termName the term name
   * @param prettyName the pretty name
   * @param commentString the comment string
   * @param isaTerms the list of isa (type) terms
   * @param creator the creator
   * @param creationPurpose the creation purpose
   * @return the specified defined term
   */
  public AtomicTerm createDefinedTerm(
          final String termName,
          final String prettyName,
          final String commentString,
          final List<AbstractReifiedTerm> isaTerms,
          final AbstractReifiedTerm creator,
          final AbstractReifiedTerm creationPurpose) {
    //Preconditions
    assert termName != null : "termName must not be null";
    assert termName.length() > 0 : "termName must not be an empty string";
    assert prettyName != null : "prettyName must not be null";
    assert prettyName.length() > 0 : "prettyName must not be an empty string";
    assert commentString != null : "comment must not be null";
    assert commentString.length() > 0 : "comment must not be an empty string";
    assert isaTerms != null : "isaTerms must not be null";
    assert creator != null : "creator must not be null";
    assert creationPurpose != null : "creationPurpose must not be null";
    assert atomicTermByTermId != null : "atomicTermByTermId must not be null";
    assert binaryGAFByTermId != null : "binaryGAFByTermId must not be null";
    assert localTermIdReferenceByTermId != null : "localTermIdReferenceByTermId must not be null";
    
    final AtomicTerm definedTerm = new AtomicTerm(
            getNextTermId(),
            termName,
            prettyName,
            creator,
            creationPurpose,
            new Date());
    try {
      atomicTermByTermId.putNoReturn(definedTerm);
      localTermIdReferenceByTermId.putNoReturn(new LocalTermIdReference(definedTerm.getTermId(), UUID.randomUUID()));
      final AtomicTerm comment = findAtomicTermByTermName("comment");
      final AtomicTerm universalVocabularyMt = findAtomicTermByTermName("UniversalVocabularyMt");
      final PString commentStringTerm = createPStringByStringValue(commentString);
      BinaryGAF commentGAF = new BinaryGAF(
              getNextTermId(),
              comment,
              Arrays.asList((AbstractTerm) definedTerm, commentStringTerm),
              universalVocabularyMt,
              Constants.STRENGTH_MONOTONIC,
              null,
              creator,
              creationPurpose,
              new Date());
      assert commentGAF.getArg1TermId() == definedTerm.getTermId();
      getLogger().info("persisting: " + commentGAF);
      binaryGAFByTermId.putNoReturn(commentGAF);
      localTermIdReferenceByTermId.putNoReturn(new LocalTermIdReference(commentGAF.getTermId(), UUID.randomUUID()));
      final AtomicTerm isa = findAtomicTermByTermName("isa");
      for (final AbstractReifiedTerm isaTerm : isaTerms) {
        BinaryGAF isaGAF = new BinaryGAF(
                getNextTermId(),
                isa,
                Arrays.asList((AbstractTerm) definedTerm, isaTerm),
                universalVocabularyMt,
                Constants.STRENGTH_MONOTONIC,
                null,
                creator,
                creationPurpose,
                new Date());
        getLogger().info("persisting: " + isaGAF);
        binaryGAFByTermId.putNoReturn(isaGAF);
        localTermIdReferenceByTermId.putNoReturn(new LocalTermIdReference(isaGAF.getTermId(), UUID.randomUUID()));
      }
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
    return definedTerm;
  }
  
  /** Creates the specified binary predicate term with default list of isa (type) terms [BinaryPredicate, PredicateFocalInArg1],
   * and list of genlPreds (super property) terms [conceptuallyRelated].
   *
   * @param termName the predicate name
   * @param prettyName the pretty name
   * @param commentString the comment string
   * @param creator the creator
   * @param argConstraintTerms the list of argument constraint terms
   * @param creationPurpose the creation purpose
   * @return the specified binary predicate term
   */
  public AtomicTerm createBinaryPredicateTerm(
          final String termName,
          final String prettyName,
          final String commentString,
          final List<AbstractReifiedTerm> argConstraintTerms,
          final AbstractReifiedTerm creator,
          final AbstractReifiedTerm creationPurpose) {
    return createBinaryPredicateTerm(
            termName,
            prettyName,
            commentString,
            new ArrayList<AbstractReifiedTerm>(0),
            new ArrayList<AbstractReifiedTerm>(0),
            argConstraintTerms,
            creator,
            creationPurpose);
  }
  
  /** Creates the specified binary predicate term.
   *
   * @param termName the predicate name
   * @param prettyName the pretty name
   * @param commentString the comment string
   * @param isaTerms the list of isa (type) terms, defaults to [BinaryPredicate, PredicateFocalInArg1]
   * @param genlPredTerms the list of genlPreds (super property) terms, defaults to [conceptuallyRelated]
   * @param argConstraintTerms the list of argument constraint terms
   * @param creator the creator
   * @param creationPurpose the creation purpose
   * @return the specified binary predicate term
   */
  public AtomicTerm createBinaryPredicateTerm(
          final String termName,
          final String prettyName,
          final String commentString,
          final List<AbstractReifiedTerm> isaTerms,
          final List<AbstractReifiedTerm> genlPredTerms,
          final List<AbstractReifiedTerm> argConstraintTerms,
          final AbstractReifiedTerm creator,
          final AbstractReifiedTerm creationPurpose) {
    //Preconditions
    assert termName != null : "termName must not be null";
    assert termName.length() > 0 : "termName must not be an empty string";
    assert prettyName != null : "prettyName must not be null";
    assert prettyName.length() > 0 : "prettyName must not be an empty string";
    assert commentString != null : "comment must not be null";
    assert commentString.length() > 0 : "comment must not be an empty string";
    assert isaTerms != null : "isaTerms must not be null";
    assert genlPredTerms != null : "genlPredTerms must not be null";
    assert argConstraintTerms != null : "argConstraintTerms must not be null";
    assert argConstraintTerms.size() == 2 : "there must be two argument constraint terms in the list";
    assert creator != null : "creator must not be null";
    assert creationPurpose != null : "creationPurpose must not be null";
    assert binaryGAFByTermId != null : "binaryGAFByTermId must not be null";
    assert localTermIdReferenceByTermId != null : "localTermIdReferenceByTermId must not be null";
    
    AtomicTerm predicateTerm = findAtomicTermByTermName(termName);
    if (predicateTerm != null) {
      return predicateTerm;
    }
    if (isaTerms.isEmpty()) {
      isaTerms.add(findAtomicTermByTermName("BinaryPredicate"));
      isaTerms.add(createCollectionTerm(
              "PredicateFocalInArg1",
              "predicates in which their first argument is the most important",
              "PredicateFocalInArg1 is the collection of predicates in which the first argument is most important.",
              Arrays.asList((AbstractReifiedTerm) findAtomicTermByTermName("PredicateType")),
              Arrays.asList((AbstractReifiedTerm) findAtomicTermByTermName("Predicate")),
              creator,
              creationPurpose));
    }
    predicateTerm = createDefinedTerm(
            termName,
            prettyName,
            commentString,
            isaTerms,
            creator,
            creationPurpose);
    final BinaryGAF arityGAF = new BinaryGAF(
            getNextTermId(),
            findAtomicTermByTermName(Constants.TERM_NAME_ARITY),
            Arrays.asList((AbstractTerm) predicateTerm, createPLongByLongValue(2L)),
            findAtomicTermByTermName(Constants.TERM_NAME_UNIVERSAL_VOCABULARY_MT),
            Constants.STRENGTH_MONOTONIC,
            null,
            creator,
            creationPurpose,
            new Date());
    getLogger().info("persisting: " + arityGAF);
    try {
      binaryGAFByTermId.putNoReturn(arityGAF);
      localTermIdReferenceByTermId.putNoReturn(new LocalTermIdReference(arityGAF.getTermId(), UUID.randomUUID()));
      if (genlPredTerms.isEmpty()) {
        genlPredTerms.add(findAtomicTermByTermName(Constants.TERM_NAME_CONCEPTUALLY_RELATED));
      }
      final AtomicTerm genlPreds = findAtomicTermByTermName(Constants.TERM_NAME_GENL_PREDS);
      for (final AbstractReifiedTerm genlPredTerm : genlPredTerms) {
        BinaryGAF genlsGAF = new BinaryGAF(
                getNextTermId(),
                genlPreds,
                Arrays.asList((AbstractTerm) predicateTerm, genlPredTerm),
                findAtomicTermByTermName(Constants.TERM_NAME_UNIVERSAL_VOCABULARY_MT),
                Constants.STRENGTH_MONOTONIC,
                null,
                creator,
                creationPurpose,
                new Date());
        getLogger().info("persisting: " + genlsGAF);
        binaryGAFByTermId.putNoReturn(genlsGAF);
        localTermIdReferenceByTermId.putNoReturn(new LocalTermIdReference(genlsGAF.getTermId(), UUID.randomUUID()));
      }
      final BinaryGAF arg1IsaGAF = new BinaryGAF(
              getNextTermId(),
              findAtomicTermByTermName(Constants.TERM_NAME_ARG1_ISA),
              Arrays.asList((AbstractTerm) predicateTerm, argConstraintTerms.get(0)),
              findAtomicTermByTermName(Constants.TERM_NAME_UNIVERSAL_VOCABULARY_MT),
              Constants.STRENGTH_MONOTONIC,
              null,
              creator,
              creationPurpose,
              new Date());
      getLogger().info("persisting: " + arg1IsaGAF);
      binaryGAFByTermId.putNoReturn(arg1IsaGAF);
      localTermIdReferenceByTermId.putNoReturn(new LocalTermIdReference(arg1IsaGAF.getTermId(), UUID.randomUUID()));
      final BinaryGAF arg2IsaGAF = new BinaryGAF(
              getNextTermId(),
              findAtomicTermByTermName(Constants.TERM_NAME_ARG2_ISA),
              Arrays.asList((AbstractTerm) predicateTerm, argConstraintTerms.get(1)),
              findAtomicTermByTermName(Constants.TERM_NAME_UNIVERSAL_VOCABULARY_MT),
              Constants.STRENGTH_MONOTONIC,
              null,
              creator,
              creationPurpose,
              new Date());
      getLogger().info("persisting: " + arg2IsaGAF);
      binaryGAFByTermId.putNoReturn(arg2IsaGAF);
      localTermIdReferenceByTermId.putNoReturn(new LocalTermIdReference(arg2IsaGAF.getTermId(), UUID.randomUUID()));
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
    return predicateTerm;
  }
  
  /**
   * Creates the specified collection term.
   *
   * @param termName the term name
   * @param prettyName the pretty name
   * @param commentString the comment string
   * @param isaTerms the list of isa (type) terms
   * @param genlsTerms the list of genls (superclass) terms
   * @param creator the creator
   * @param creationPurpose the creation purpose
   * @return the specified collection term
   */
  public AtomicTerm createCollectionTerm(
          final String termName,
          final String prettyName,
          final String commentString,
          final List<AbstractReifiedTerm> isaTerms,
          final List<AbstractReifiedTerm> genlsTerms,
          final AbstractReifiedTerm creator,
          final AbstractReifiedTerm creationPurpose) {
    //Preconditions
    assert termName != null : "termName must not be null";
    assert termName.length() > 0 : "termName must not be an empty string";
    assert prettyName != null : "prettyName must not be null";
    assert prettyName.length() > 0 : "prettyName must not be an empty string";
    assert commentString != null : "comment must not be null";
    assert commentString.length() > 0 : "comment must not be an empty string";
    assert isaTerms != null : "isaTerms must not be null";
    assert genlsTerms != null : "genlsTerms must not be null";
    assert creator != null : "creator must not be null";
    assert creationPurpose != null : "creationPurpose must not be null";
    assert binaryGAFByTermId != null : "binaryGAFByTermId must not be null";
    assert localTermIdReferenceByTermId != null : "localTermIdReferenceByTermId must not be null";
    
    AtomicTerm collectionTerm = findAtomicTermByTermName(termName);
    if (collectionTerm != null) {
      return collectionTerm;
    }
    collectionTerm = createDefinedTerm(
            termName,
            prettyName,
            commentString,
            isaTerms,
            creator,
            creationPurpose);
    final AtomicTerm genls = findAtomicTermByTermName(Constants.TERM_NAME_GENLS);
    for (final AbstractReifiedTerm genlsTerm : genlsTerms) {
      BinaryGAF genlsGAF = new BinaryGAF(
              getNextTermId(),
              genls,
              Arrays.asList((AbstractTerm) collectionTerm, genlsTerm),
              findAtomicTermByTermName(Constants.TERM_NAME_UNIVERSAL_VOCABULARY_MT),
              Constants.STRENGTH_MONOTONIC,
              null,
              creator,
              creationPurpose,
              new Date());
      getLogger().info("persisting: " + genlsGAF);
      try {
        binaryGAFByTermId.putNoReturn(genlsGAF);
        localTermIdReferenceByTermId.putNoReturn(new LocalTermIdReference(genlsGAF.getTermId(), UUID.randomUUID()));
      } catch (final DatabaseException ex) {
        throw new TexaiException(ex);
      }
    }
     return collectionTerm;
  }
  
  /**
   * Creates the specified context term.
   *
   * @param termName the term name
   * @param prettyName the pretty name
   * @param commentString the comment string
   * @param isaTerms the list of isa (type) terms which defaults to [Microtheory] when empty
   * @param genlMtTerms the list of genlMt (super context) terms which defaults to [BaseKB] when empty
   * @param creator the creator
   * @param creationPurpose the creation purpose
   * @return the specified collection term
   */
  public AtomicTerm createContextTerm(
          final String termName,
          final String prettyName,
          final String commentString,
          final List<AbstractReifiedTerm> isaTerms,
          final List<AbstractReifiedTerm> genlMtTerms,
          final AbstractReifiedTerm creator,
          final AbstractReifiedTerm creationPurpose) {
    assert termName != null : "termName must not be null";
    assert termName.length() > 0 : "termName must not be an empty string";
    assert prettyName != null : "prettyName must not be null";
    assert prettyName.length() > 0 : "prettyName must not be an empty string";
    assert commentString != null : "comment must not be null";
    assert commentString.length() > 0 : "comment must not be an empty string";
    assert isaTerms != null : "isaTerms must not be null";
    assert genlMtTerms != null : "genlMtTerms must not be null";
    assert creator != null : "creator must not be null";
    assert creationPurpose != null : "creationPurpose must not be null";
    assert binaryGAFByTermId != null : "binaryGAFByTermId must not be null";
    assert localTermIdReferenceByTermId != null : "localTermIdReferenceByTermId must not be null";
    
    AtomicTerm contextTerm = findAtomicTermByTermName(termName);
    if (contextTerm != null) {
      return contextTerm;
    }
    if (isaTerms.isEmpty()) {
      isaTerms.add(findAtomicTermByTermName(Constants.TERM_NAME_MICROTHEORY));
    }
    contextTerm = createDefinedTerm(
            termName,
            prettyName,
            commentString,
            isaTerms,
            creator,
            creationPurpose);
    if (genlMtTerms.isEmpty()) {
      genlMtTerms.add(findAtomicTermByTermName(Constants.TERM_NAME_BASE_KB));
    }
    final AtomicTerm genlMt = findAtomicTermByTermName(Constants.TERM_NAME_GENL_MT);
    for (final AbstractReifiedTerm genlMtTerm : genlMtTerms) {
      BinaryGAF genlMtGAF = new BinaryGAF(
              getNextTermId(),
              genlMt,
              Arrays.asList((AbstractTerm) contextTerm, genlMtTerm),
              findAtomicTermByTermName(Constants.TERM_NAME_UNIVERSAL_VOCABULARY_MT),
              Constants.STRENGTH_MONOTONIC,
              null,
              creator,
              creationPurpose,
              new Date());
      getLogger().info("persisting: " + genlMtGAF);
      try {
        binaryGAFByTermId.putNoReturn(genlMtGAF);
        localTermIdReferenceByTermId.putNoReturn(new LocalTermIdReference(genlMtGAF.getTermId(), UUID.randomUUID()));
      } catch (final DatabaseException ex) {
        throw new TexaiException(ex);
      }
    }
    return contextTerm;
  }
  
  /** Returns a description of why the given formula is not well formed, or an empty string if the formula is well formed.
   *
   * @param predicate the predicate
   * @param args the argument list
   * @param context the context
   */
  public String getReasonWhyFormulaIsNotWellFormed(
          final AbstractReifiedTerm predicate,
          final List<AbstractTerm> args,
          final AbstractReifiedTerm context) {
    throw new TexaiException("not implemented");
  }
  
  /** Sets the entity store.
   *
   * @param entityStore
   */
  public void setEntityStore(final EntityStore entityStore) {
    //Preconditions
    assert entityStore != null : "entityStore must not be null";
    
    this.entityStore = entityStore;
  }
  
  /** Initializes the primary and secondary indicies. */
  public void initializeIndices() {
    //Preconditions
    assert entityStore != null : "entityStore must not be null";
    
    // primary indicies
    try {
      termIdSequenceById = entityStore.getPrimaryIndex(Integer.class, TermIdSequence.class);
      atomicTermByTermId = entityStore.getPrimaryIndex(Integer.class, AtomicTerm.class);
      formulaByTermId = entityStore.getPrimaryIndex(Integer.class, Formula.class);
      nonAtomicTermByTermId = entityStore.getPrimaryIndex(Integer.class, NonAtomicTerm.class);
      pByteArrayByTermId = entityStore.getPrimaryIndex(Integer.class, PByteArray.class);
      pDateByTermId = entityStore.getPrimaryIndex(Integer.class, PDate.class);
      pDoubleByTermId = entityStore.getPrimaryIndex(Integer.class, PDouble.class);
      pLongByTermId = entityStore.getPrimaryIndex(Integer.class, PLong.class);
      pStringByTermId = entityStore.getPrimaryIndex(Integer.class, PString.class);
      pVariableByTermId = entityStore.getPrimaryIndex(Integer.class, PVariable.class);
      ruleByTermId = entityStore.getPrimaryIndex(Integer.class, Rule.class);
      symbolByTermId = entityStore.getPrimaryIndex(Integer.class, Symbol.class);
      unaryGAFByTermId = entityStore.getPrimaryIndex(Integer.class, UnaryGAF.class);
      binaryGAFByTermId = entityStore.getPrimaryIndex(Integer.class, BinaryGAF.class);
      ternaryGAFByTermId = entityStore.getPrimaryIndex(Integer.class, TernaryGAF.class);
      quaternaryGAFByTermId = entityStore.getPrimaryIndex(Integer.class, QuaternaryGAF.class);
      quintaryGAFByTermId = entityStore.getPrimaryIndex(Integer.class, QuintaryGAF.class);
      localTermIdReferenceByTermId = entityStore.getPrimaryIndex(Integer.class, LocalTermIdReference.class);
      remoteTermIdReferenceByTermId = entityStore.getPrimaryIndex(Integer.class, RemoteTermIdReference.class);
      initializeHighestTermId();
      
      // secondary indicies
      symbolByNameValue = entityStore.getSecondaryIndex(symbolByTermId, String.class, Constants.FIELD_NAME_VALUE);
      pVariableByNameValue = entityStore.getSecondaryIndex(pVariableByTermId, String.class, Constants.FIELD_NAME_VALUE);
      pLongByLongValue = entityStore.getSecondaryIndex(pLongByTermId, Long.class, Constants.FIELD_LONG_VALUE);
      pDoubleByDoubleValue = entityStore.getSecondaryIndex(pDoubleByTermId, Double.class, Constants.FIELD_DOUBLE_VALUE);
      pStringByStringHashCode = entityStore.getSecondaryIndex(pStringByTermId, Integer.class, Constants.FIELD_STRING_VALUE_HASH_CODE);
      pDateByDateValue = entityStore.getSecondaryIndex(pDateByTermId, Date.class, Constants.FIELD_DATE_VALUE);
      atomicTermByTermNameHashCode = entityStore.getSecondaryIndex(atomicTermByTermId, Integer.class, Constants.FIELD_TERM_NAME_HASH_CODE);
      nonAtomicTermByTermNameHashCode = entityStore.getSecondaryIndex(nonAtomicTermByTermId, Integer.class, Constants.FIELD_TERM_NAME_HASH_CODE);
      formulaByFormulaStringHashCode = entityStore.getSecondaryIndex(formulaByTermId, Integer.class, Constants.FIELD_FORMULA_STRING_HASH_CODE);
      ruleByFormulaId = entityStore.getSecondaryIndex(ruleByTermId, Integer.class, Constants.FIELD_FORMULA_TERM_ID);
      unaryGAFByArg1TermId = entityStore.getSecondaryIndex(unaryGAFByTermId, Integer.class, Constants.FIELD_ARG1_TERM_ID);
      binaryGAFByArg1TermId = entityStore.getSecondaryIndex(binaryGAFByTermId, Integer.class, Constants.FIELD_ARG1_TERM_ID);
      ternaryGAFByArg1TermId = entityStore.getSecondaryIndex(ternaryGAFByTermId, Integer.class, Constants.FIELD_ARG1_TERM_ID);
      quaternaryGAFByArg1TermId = entityStore.getSecondaryIndex(quaternaryGAFByTermId, Integer.class, Constants.FIELD_ARG1_TERM_ID);
      quintaryGAFByArg1TermId = entityStore.getSecondaryIndex(quintaryGAFByTermId, Integer.class, Constants.FIELD_ARG1_TERM_ID);
      localTermIdReferenceByUUIDBytes =
              entityStore.getSecondaryIndex(localTermIdReferenceByTermId, Byte[].class, Constants.FIELD_UUID_BYTES) ;
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
    
    //Postconditions
    assert termIdSequenceById != null : "termIdSequenceById must not be null";
    assert atomicTermByTermId != null : "atomicTermByTermId must not be null";
    assert formulaByTermId != null : "formulaByTermId must not be null";
    assert nonAtomicTermByTermId != null : "nonAtomicTermByTermId must not be null";
    assert pByteArrayByTermId != null : "pByteArrayByTermId must not be null";
    assert pDateByTermId != null : "pDateByTermId must not be null";
    assert pDoubleByTermId != null : "pDoubleByTermId must not be null";
    assert pLongByTermId != null : "pLongByTermId must not be null";
    assert pStringByTermId != null : "pStringByTermId must not be null";
    assert pVariableByTermId != null : "pVariableByTermId must not be null";
    assert ruleByTermId != null : "ruleByTermId must not be null";
    assert symbolByTermId != null : "symbolByTermId must not be null";
    assert unaryGAFByTermId != null : "unaryGAFByTermId must not be null";
    assert binaryGAFByTermId != null : "binaryGAFByTermId must not be null";
    assert ternaryGAFByTermId != null : "ternaryGAFByTermId must not be null";
    assert quaternaryGAFByTermId != null : "quaternaryGAFByTermId must not be null";
    assert quintaryGAFByTermId != null : "quintaryGAFByTermId must not be null";
    assert localTermIdReferenceByTermId != null : "localTermIdReferenceByTermId must not be null";
    assert remoteTermIdReferenceByTermId != null : "remoteTermIdReferenceByTermId must not be null";
    
    assert symbolByNameValue != null : "symbolByNameValue must not be null";
    assert pVariableByNameValue != null : "pVariableByNameValue must not be null";
    assert pLongByLongValue != null : "pLongByLongValue must not be null";
    assert pDoubleByDoubleValue != null : "pDoubleByDoubleValue must not be null";
    assert pStringByStringHashCode != null : "pStringByStringValue must not be null";
    assert pDateByDateValue != null : "pDateByDateValue must not be null";
    assert atomicTermByTermNameHashCode != null : "atomicTermByTermNameHashCode must not be null";
    assert nonAtomicTermByTermNameHashCode != null : "nonAtomicTermByTermNameHashCode must not be null";
    assert formulaByFormulaStringHashCode != null : "formulaByFormulaStringHashCode must not be null";
    assert ruleByFormulaId != null : "ruleByFormulaId must not be null";
    assert unaryGAFByArg1TermId != null : "unaryGAFByArg1TermId must not be null";
    assert binaryGAFByArg1TermId != null : "binaryGAFByArg1TermId must not be null";
    assert ternaryGAFByArg1TermId != null : "ternaryGAFByArg1TermId must not be null";
    assert quaternaryGAFByArg1TermId != null : "quaternaryGAFByArg1TermId must not be null";
    assert quintaryGAFByArg1TermId != null : "quintaryGAFByArg1TermId must not be null";
    assert localTermIdReferenceByUUIDBytes != null : "localTermIdReferenceByUUIDBytes must not be null";
  }
  
  /** Initializes the highest term id. */
  private synchronized void initializeHighestTermId() {
    //Preconditions
    assert termIdSequenceById != null : "termIdSequenceById must not be null";
    
    if (highestTermId >= 0) {
      // only the first thread to invoke this method performs the initialization
      return;
    }
    TermIdSequence termIdSequence = null;
    try {
      termIdSequence = termIdSequenceById.get(Constants.ID_FOR_SINGLETON_TERM_ID_SEQUENCE);
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
    if (termIdSequence.isTermIdSequencePersisted()) {
      lowestTermId = termIdSequence.getLowestTermId();
      highestTermId = termIdSequence.getHighestTermId();
    } else {
      getLogger().info("recovering term id sequence");
      lowestTermId = atomicTermByTermId.sortedMap().lastKey();
      highestTermId = atomicTermByTermId.sortedMap().lastKey();
      
      int highestKeyInIndex = formulaByTermId.sortedMap().lastKey();
      if (highestKeyInIndex >  highestTermId) {
        highestTermId = highestKeyInIndex;
      }
      int lowestKeyInIndex = formulaByTermId.sortedMap().firstKey();
      if (lowestKeyInIndex < lowestTermId) {
        lowestTermId = lowestKeyInIndex;
      }
      
      highestKeyInIndex = nonAtomicTermByTermId.sortedMap().lastKey();
      if (highestKeyInIndex >  highestTermId) {
        highestTermId = highestKeyInIndex;
      }
      lowestKeyInIndex = nonAtomicTermByTermId.sortedMap().firstKey();
      if (lowestKeyInIndex < lowestTermId) {
        lowestTermId = lowestKeyInIndex;
      }
      
      highestKeyInIndex = pByteArrayByTermId.sortedMap().lastKey();
      if (highestKeyInIndex >  highestTermId) {
        highestTermId = highestKeyInIndex;
      }
      lowestKeyInIndex = pByteArrayByTermId.sortedMap().firstKey();
      if (lowestKeyInIndex < lowestTermId) {
        lowestTermId = lowestKeyInIndex;
      }
      
      highestKeyInIndex = pDateByTermId.sortedMap().lastKey();
      if (highestKeyInIndex >  highestTermId) {
        highestTermId = highestKeyInIndex;
      }
      lowestKeyInIndex = pDateByTermId.sortedMap().firstKey();
      if (lowestKeyInIndex < lowestTermId) {
        lowestTermId = lowestKeyInIndex;
      }
      
      highestKeyInIndex = pDoubleByTermId.sortedMap().lastKey();
      if (highestKeyInIndex >  highestTermId) {
        highestTermId = highestKeyInIndex;
      }
      lowestKeyInIndex = pDoubleByTermId.sortedMap().firstKey();
      if (lowestKeyInIndex < lowestTermId) {
        lowestTermId = lowestKeyInIndex;
      }
      
      highestKeyInIndex = pLongByTermId.sortedMap().lastKey();
      if (highestKeyInIndex >  highestTermId) {
        highestTermId = highestKeyInIndex;
      }
      lowestKeyInIndex = pLongByTermId.sortedMap().firstKey();
      if (lowestKeyInIndex < lowestTermId) {
        lowestTermId = lowestKeyInIndex;
      }
      
      highestKeyInIndex = pStringByTermId.sortedMap().lastKey();
      if (highestKeyInIndex >  highestTermId) {
        highestTermId = highestKeyInIndex;
      }
      lowestKeyInIndex = pStringByTermId.sortedMap().firstKey();
      if (lowestKeyInIndex < lowestTermId) {
        lowestTermId = lowestKeyInIndex;
      }
      
      highestKeyInIndex = pVariableByTermId.sortedMap().lastKey();
      if (highestKeyInIndex >  highestTermId) {
        highestTermId = highestKeyInIndex;
      }
      lowestKeyInIndex = pVariableByTermId.sortedMap().firstKey();
      if (lowestKeyInIndex < lowestTermId) {
        lowestTermId = lowestKeyInIndex;
      }
      
      highestKeyInIndex = ruleByTermId.sortedMap().lastKey();
      if (highestKeyInIndex >  highestTermId) {
        highestTermId = highestKeyInIndex;
      }
      lowestKeyInIndex = ruleByTermId.sortedMap().firstKey();
      if (lowestKeyInIndex < lowestTermId) {
        lowestTermId = lowestKeyInIndex;
      }
      
      highestKeyInIndex = symbolByTermId.sortedMap().lastKey();
      if (highestKeyInIndex >  highestTermId) {
        highestTermId = highestKeyInIndex;
      }
      lowestKeyInIndex = symbolByTermId.sortedMap().firstKey();
      if (lowestKeyInIndex < lowestTermId) {
        lowestTermId = lowestKeyInIndex;
      }
      
      highestKeyInIndex = unaryGAFByTermId.sortedMap().lastKey();
      if (highestKeyInIndex >  highestTermId) {
        highestTermId = highestKeyInIndex;
      }
      lowestKeyInIndex = unaryGAFByTermId.sortedMap().firstKey();
      if (lowestKeyInIndex < lowestTermId) {
        lowestTermId = lowestKeyInIndex;
      }
      
      highestKeyInIndex = binaryGAFByTermId.sortedMap().lastKey();
      if (highestKeyInIndex >  highestTermId) {
        highestTermId = highestKeyInIndex;
      }
      lowestKeyInIndex = binaryGAFByTermId.sortedMap().firstKey();
      if (lowestKeyInIndex < lowestTermId) {
        lowestTermId = lowestKeyInIndex;
      }
      
      highestKeyInIndex = ternaryGAFByTermId.sortedMap().lastKey();
      if (highestKeyInIndex >  highestTermId) {
        highestTermId = highestKeyInIndex;
      }
      lowestKeyInIndex = ternaryGAFByTermId.sortedMap().firstKey();
      if (lowestKeyInIndex < lowestTermId) {
        lowestTermId = lowestKeyInIndex;
      }
      
      highestKeyInIndex = quaternaryGAFByTermId.sortedMap().lastKey();
      if (highestKeyInIndex >  highestTermId) {
        highestTermId = highestKeyInIndex;
      }
      lowestKeyInIndex = quaternaryGAFByTermId.sortedMap().firstKey();
      if (lowestKeyInIndex < lowestTermId) {
        lowestTermId = lowestKeyInIndex;
      }
      
      highestKeyInIndex = quintaryGAFByTermId.sortedMap().lastKey();
      if (highestKeyInIndex >  highestTermId) {
        highestTermId = highestKeyInIndex;
      }
      lowestKeyInIndex = quintaryGAFByTermId.sortedMap().firstKey();
      if (lowestKeyInIndex < lowestTermId) {
        lowestTermId = lowestKeyInIndex;
      }
      
      termIdSequence.setLowestTermId(lowestTermId);
      termIdSequence.setHighestTermId(highestTermId);
    }
    termIdSequence.setIsTermIdSequencePersisted(false);
    try {
      termIdSequenceById.putNoReturn(termIdSequence);
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
    
    //Postconditions
    assert highestTermId >= 0 : "highestTermId must be initialized";
  }
  
  /** Persists the term id sequence for this shard. */
  public synchronized void persistTermIdSequence() {
    //Preconditions
    assert termIdSequenceById != null : "termIdSequenceById must not be null";
    TermIdSequence termIdSequence = null;
    try {
      termIdSequence = termIdSequenceById.get(Constants.ID_FOR_SINGLETON_TERM_ID_SEQUENCE);
      termIdSequence.setHighestTermId(highestTermId);
      termIdSequence.setIsTermIdSequencePersisted(true);
      termIdSequenceById.putNoReturn(termIdSequence);
    } catch (final DatabaseException ex) {
      throw new TexaiException(ex);
    }
  }
  
  /** Increments and returns the next term id for this shard*/
  private static synchronized int getNextTermId() {
    if (highestTermId >= lowestTermId + Constants.NBR_TERMS_PER_DB_SHARD) {
      throw new TexaiException("attempting to create a term in a full shard");
    }
    return ++highestTermId;
  }
  
  /** Gets the logger.
   *
   * @return the logger
   */
  private Logger getLogger() {
    if (logger == null) {
      logger = Logger.getLogger(TermFinderFacadeBean.class.getName());
    }
    return logger;
  }
  
}                  // NOPMD




See more files for this project here

Texai

Texai is an chatbot that intelligently seeks to acquire knowledge and friendly behaviors.

Project homepage: http://sourceforge.net/projects/texai
Programming language(s): Java,Shell Script,XML
License: other

  AssociationEditorBean.java
  AssociationEditorLocal.java
  AssociationFinderBean.java
  AssociationFinderLocal.java
  KBPartitionFacadeBean.java
  KBPartitionFacadeLocal.java
  KBShardFacadeBean.java
  TermDeleterFacadeBean.java
  TermDeleterFacadeLocal.java
  TermFinderFacadeBean.java
  TermFinderFacadeLocal.java
  TermManagerBean.java
  TermManagerLocal.java