PsiTerm.html

`PsiTerm.java`

    // FILE. . . . . /home/hak/hlt/src/hlt/osf/base/PsiTerm.java
    // EDIT BY . . . Hassan Ait-Kaci
    // ON MACHINE. . Hp-Dv7
    // STARTED ON. . Sun Dec 16 01:34:12 2012

This is the class of ψ-terms as explained in the specification.
Author: |  | Hassan Aït-Kaci
Copyright: |  | © by the author
Version: |  | Last modified on Mon Jan 21 09:31:41 2013 by hak

    package hlt.osf.base;

    import java.util.HashSet;
    import java.util.HashMap;
    import java.util.Iterator;

    import hlt.language.tools.Misc;
    import hlt.language.util.ArrayList;

    public class PsiTerm extends OsfExpression
      {

This ψ-term's tag.

        private Tag _tag;

This ψ-term's sort expression.

        private SortExpression _sort;

This ψ-term's positional subterms if any.

        private ArrayList _positions;

This ψ-term's featured subterms, if any.

        private HashMap _features;

This is the next position where to store a new implicitly contiguous positional subterms (counting positions starting at 1 instead of 0). Since we may not rely on `add` to add contiguous positional subterms (they are set using the `set` method), we need to update this value for adding a new inplicitly contiguous positional subterm and must always ensure that the capacity is sufficient. This does not mean that it is a free position since a subterm may have already been stored there using an explicit feature position (in which case the new and old subterm must be merged). This value and `_maxPosition` must be ketp consistent.

        private int _nextContiguousPosition = 0;

This is the highest position that has an actual positional subterm for this ψ-term (counting postions starting at 1 instead of 0). Since subterms may be also stored using explicit positions that may be out of order and non-contiguous using the `set` method, this value must be updated explicit. We must always ensure that the capasity is sufficient.

        private int _maxPosition = 0;

        /* ************************************************************************ */

        public PsiTerm ()
          {
    	_sort = new SymbolSortExpression("@");
          }

        public PsiTerm (Tag tag)
          {
    	setTag(tag);
          }

        public PsiTerm (String sortName)
          {
    	_sort = new SymbolSortExpression(sortName);
          }

        public PsiTerm (SortExpression sort)
          {
    	_sort = sort;
          }

        /* ************************************************************************ */

        public Tag tag ()
          {
    	return _tag;
          }

        public PsiTerm deref ()
          {
    	return _tag.deref().term();
          }

Set this tag's ψ-term to the specified tag, sets the specified tag's term to this ψ-term, and returns this tag.

        public PsiTerm setTag (Tag tag)
          {
    	_tag = tag;
    	tag.setTerm(this);
    	return this;
          }

        /* ************************************************************************ */

Returns the sort expression of this ψ-term, or `null` if none has been set for it yet.

        public SortExpression sort ()
          {
    	return _sort;
          }

Sets this ψ-term's sort expression to the provided one and returns this ψ-term.

        public PsiTerm setSort (SortExpression sort)
          {
    	_sort = sort;
    	return this;
          }

        /* ************************************************************************ */

        public ArrayList positions ()
          {
    	return _positions;
          }

        public HashMap features ()
          {
    	return _features;
          }

        /* ************************************************************************ */

        public int maxPosition ()
          {
    	return _maxPosition;
          }

Returns the subterm at the next contiguous position if any, or `null`) if there isn't any.

        public PsiTerm getNextContiguousPositionSubterm ()
          {
    	if (_positions == null || _nextContiguousPosition == 0)
    	  return null;

    	return (PsiTerm)_positions.get(_nextContiguousPosition);
          }

This stores the provided term at the next contiguous position, whether or not a term is already stored there.

        public void addContiguousPositionSubterm (PsiTerm psiterm)
          {
    	if (_positions == null)
    	  _positions = new ArrayList(3);

    	_positions.ensureCapacity(_nextContiguousPosition+1);
    	_positions.set(_nextContiguousPosition,psiterm);
    	_nextContiguousPosition++;
    	_maxPosition = Math.max(_maxPosition,_nextContiguousPosition);
          }

This returns the subterm at the given position if there is one stored there, or `null` otherwise, where positions are counted sarting from 1.

        public PsiTerm getSubterm (int position)
          {
    	if (_positions == null || position > _maxPosition)
    	  return null;

    	return (PsiTerm)_positions.get(position-1); // -1 since positions are counted from 1
          }

This stores the provided ψ-term at the specified position (counting positions from 1), whether or not a term is already stored there.

        public void setSubterm (int position, PsiTerm psiterm)
          {
    	if (_positions == null)
    	  _positions = new ArrayList(position);

    	_positions.ensureCapacity(position);
    	_positions.set(position-1,psiterm); // -1 since positions are counted from 1

    	_maxPosition = Math.max(_maxPosition,position);

          }

This returns the subterm for the specified feature (which may be `null`).

        public PsiTerm getSubterm (Feature feature)
        {
          if (_features == null || _features.isEmpty())
    	return null;

          return (PsiTerm)_features.get(feature);
        }

This stores the provided term for the specified feature, whether or not a term is already stored there.

        public void setSubterm (Feature feature, PsiTerm psiterm)
          {
    	if (_features == null)
    	  _features = new HashMap();

    	_features.put(feature,psiterm);
          }

        /* ************************************************************************ */

This merges the uninterpreted structure of the specified ψ-term into this one's as explained in the specification, and returns this ψ-term resulting after the merging. This assumes that the specified ψ-term has been dereferenced to its true identity. NB: Merging subterms must ensure dereferencing them first.

        public PsiTerm merge (PsiTerm other)
          {
    	// if these are the same psiterm, no need to do anything:
    	if (this == other)
    	  return this;

    	// merge the tags, binding the other term's tag to this one's:
    	other.tag().bind(_tag);

    	// merge the sort expressions if needed (i.e., ignoring top):
    	if (_sort.isSymbol() && ((SymbolSortExpression)_sort).sort().isTop())
    	  _sort = other.sort();
    	else
    	  if (!(other.sort().isSymbol() && ((SymbolSortExpression)other.sort()).sort().isTop()))
    	    _sort = new AndSortExpression(_sort, other.sort());

    	// merge the features:
    	if (_features == null)
    	  _features = other.features();

    	if (other.features() != null)
    	  for (Iterator it=other.features().keySet().iterator(); it.hasNext();)
    	    {
    	      Feature feature = (Feature)it.next();
    	      PsiTerm subterm = (PsiTerm)_features.get(feature);
    	      PsiTerm otherSubterm = (PsiTerm)other.features().get(feature);
    	      if (subterm == null)
    		{
    		  if (otherSubterm != null)
    		    _features.put(feature,otherSubterm.deref());
    		}
    	      else
    		{
    		  if (otherSubterm != null)
    		    _features.put(feature,subterm.deref().merge(otherSubterm.deref()));
    		}
    	    }

    	// merge the positions:
    	if (_positions == null)
    	  _positions = other.positions();

    	if (other.positions() != null)
    	  for (int i = other.maxPosition(); i-->0;)
    	    {
    	      PsiTerm subterm = (i < _maxPosition) ? (PsiTerm)_positions.get(i) : null;
    	      PsiTerm otherSubterm = (PsiTerm)other.positions().get(i);
    	      if (subterm == null)
    		{
    		  if (otherSubterm != null)
    		    setSubterm(i,otherSubterm.deref());
    		}
    	      else
    		{
    		  if (otherSubterm != null)
    		    _positions.set(i,subterm.deref().merge(otherSubterm.deref()));
    		}
    	    }

    	return this;
          }

        /* ************************************************************************ */

Returns a pretty-printed form of this ψ-term.

        public String displayForm ()
          {
    	return deref().prettyPrint(0,new HashSet()).toString();
          }

        /* ************************************************************************ */

Flag to determine whether or not to evaluate sort expressions. This is `false` by default.

        private static boolean _evalSorts = false;

Returns the current sort expression evaluation flag's value.

        public static boolean evaluateSorts ()
          {
    	return _evalSorts;
          }

Toggles sort expression evaluation.

        public static void toggleSortEvaluation ()
          {
    	_evalSorts = !_evalSorts;
          }

Returns a pretty printed form of this ψ-term, starting at the specified margin width and the array list of already processed tags.

        public StringBuffer prettyPrint (int margin, HashSet tags)
          {
    	StringBuffer buf = new StringBuffer();

    	if (tags.contains(_tag))
    	  buf.append(_tag.name());
    	else
    	  {
    	    String header = _evalSorts
    	      ? _sort.maxLowerBound()	// the header is the interpreted sort expression
    	      : _sort.toString();	// the header is the uninterpreted sort expression

    	    if (_tag.isShared())
    	      { // this is a shared tag, so the header must start with tagging:
    		header = _tag.name() + " : " + header;
    		// since in this case the sort expression is preceded by
    		// tagging, the margin is augmented with the length of the tag
    		// and the 3 characters " : " that follow it:
    		margin += _tag.name().length() + 3;
    	      }

    	    tags.add(_tag);

    	    buf.append(header);

    	    if (_positions != null || _features != null)
    	      { // When this psiterm has a body, the open and closed
    		// parentheses, as well as the comma between subterms, are
    		// always aligned vertically under the first character of the
    		// sort expression whether tagged or not.  So we must compute
    		// the marginal offset depending on whether or not the sort
    		// expression is preceded by a tag

    		String offset = Misc.repeat(margin,' ');
    		buf.append('\n' + offset + "( ");

    		// do the positions
    		if (_positions != null)
    		  {
    		    int index = 0;
    		    // as long as there is no gap -> no feature needed
    		    for (index=0; index<_maxPosition; index++)
    		      {
    			PsiTerm subterm = (PsiTerm)_positions.get(index);
    			if (subterm == null)
    			  break;

    			// pretty-print the subterm with a margin augmented with
    			// the 2 characters of the initial "( " or ", "
    			buf.append(subterm.deref().prettyPrint(margin+2,tags));
    			buf.append('\n');

    			if (index<_maxPosition-1)
    			  buf.append(offset + ", ");
    		      }

    		    // above a gap up to maxPosition, print the position as a
    		    // feature for non null subterms
    		    for (;index<_maxPosition; index++)
    		      {
    			PsiTerm subterm = (PsiTerm)_positions.get(index);
    			if (subterm != null)
    			  {
    			    int position = index+1;
    			    subterm = subterm.deref();
    			    buf.append(position + " => ");
    			    // pretty-print the subterm with a margin augmented
    			    // with the width of the position + the 2 characters
    			    // of the initial "( " or ", " + the 4 characters of
    			    // " => "
    			    buf.append(subterm.prettyPrint(margin+Misc.numWidth(position)+6,tags));
    			    buf.append('\n');

    			    if (index<_maxPosition-1)
    			      buf.append(offset + ", ");
    			  }
    		      }
    		  }

    		// do the features
    		if (_features != null)
    		  for (Iterator it=_features.keySet().iterator(); it.hasNext();)
    		    {
    		      Feature feature = (Feature)it.next();
    		      PsiTerm subterm = ((PsiTerm)_features.get(feature)).deref();
    		      buf.append(feature.name() + " => ");
    		      // pretty-print the subterm with a margin augmented with
    		      // the length of the feature name + the 2 characters of the
    		      // initial "( " or ", " + the 4 characters of " => "
    		      buf.append(subterm.prettyPrint(margin+feature.name().length()+6,tags));
    		      buf.append('\n');

    		      if (it.hasNext())
    			buf.append(offset + ", ");
    		    }

    		buf.append(offset + ')');
    	      }
    	  }

    	return buf;
          }

      }

This file was generated on Wed Jan 30 13:26:29 CET 2013 from file `PsiTerm.java`
by the `hlt.language.tools.Hilite` Java tool written by Hassan Aït-Kaci