`PsiTerm.java`

    // FILE. . . . . /home/hak/hlt/src/hlt/osfv2/base/PsiTerm.java
    // EDIT BY . . . Hassan Ait-Kaci
    // ON MACHINE. . Hak-Laptop
    // STARTED ON. . Mon Sep 02 09:16:22 2013

This is the class of ψ-terms as explained in the specification.
Author: |  | Hassan Aït-Kaci
Copyright: |  | © by the author
Version: |  | Last modified on Tue Jan 21 08:05:55 2014 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;

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

        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;
          }

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

This is the maximal subterm position of positional subterms (counting from 1). Note that the actual number of positional subterms may be less than this number due to possible gaps in positions (for which missing subterms would be `null`).

        public int positionArity ()
          {
    	return _positions.size();
          }

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

This is the number of contiguous initial positional subterms (counting from 1). Note that the total number of positional subterms may be more than this number due to possible gaps in positions (for which missing subterms would be `null`).

        public int contiguousArity ()
          {
    	int arity = positionArity();

    	for (int position = 1; position <= arity; position++)
    	  if (_positions.get(position-1) == null) // -1 since positions are counted from 1
    	    return position;

    	return arity;
          }

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

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 > _positions.size())
    	  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.secureSet(position-1,psiterm); // -1 since positions are counted from 1
          }

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

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 this term's sort expression with the specified one by conjoining them into an "and"sort expression.

        public void mergeSortWith (SortExpression otherSort)
        {
          if (_sort.equals(otherSort))
    	// no need to duplicate since "foo & foo = foo":
    	return;

          // merge this term's sort expression with the specified one (ignoring top):
          if (_sort.isSymbol() && ((SymbolSortExpression)_sort).sort().isTop())
    	_sort = otherSort;
          else
    	if (!(otherSort.isSymbol() && ((SymbolSortExpression)otherSort).sort().isTop()))
    	  _sort = new AndSortExpression(_sort,otherSort);
        }

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

This merges the uninterpreted structure of the specified ψ-term into this one's 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):
    	mergeSortWith(other.sort());

    	// merge the features:
    	if (_features == null)
    	  _features = other.features();
    	else
    	  if (other.features() != null)
    	    for (Iterator it=other.features().keySet().iterator(); it.hasNext();)
    	      {
    		Feature feature = (Feature)it.next();
    		PsiTerm subterm = getSubterm(feature);
    		PsiTerm otherSubterm = other.getSubterm(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();
    	else
    	  if (other.positions() != null)
    	    {
    	      int arity = Math.max(positionArity(),other.positionArity());

    	      for (int i=1; i<=arity; i++)
    		{
    		  PsiTerm subterm = getSubterm(i);
    		  PsiTerm otherSubterm = other.getSubterm(i);
    		  if (subterm == null)
    		    {
    		      if (otherSubterm != null)
    			setSubterm(i,otherSubterm.deref());
    		    }
    		  else
    		    {
    		      if (otherSubterm != null)
    			setSubterm(i,subterm.deref().merge(otherSubterm.deref()));
    		    }
    		}
    	    }

    	return this;
          }

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

Returns a pretty-printed form offset by the specified margin of this dereferenced ψ-term.

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

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

        public String displayForm ()
          {
    	return displayForm(0);
          }

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

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

        private static boolean _evalSorts = false;

Returns the current value of the sort expression evaluation flag.

        public static boolean evalSorts ()
          {
    	return _evalSorts;
          }

Sets sort expression evaluation to the specified flag.

        public static void evaluateSorts (boolean flag)
          {
    	_evalSorts = flag;
          }

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))
    	  // a psiterm with this tag was already processed - just print the
    	  // tag alone:
    	  {
    	    buf.append(_tag.name());
    	    return buf;
    	  }

    	// use the sort expression for the header:
    	String header = _evalSorts
    	  ? _sort.maxLowerBound()	// interpret the sort expression
    	  : _sort.displayForm();	// do not interpret sort expression

    	if (_tag.isShared())
    	  // this tag is shared so it must be printed:
    	  {
    	    if (header == "@" && _positions == null && _features == null)
    	      {
    		// this is just top with no subterms - just print the tag alone:
    		buf.append(_tag.name());
    		return buf;
    	      }

    	    // this is a shared tag with a non-top sort or with subterms, 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;
    	  }

    	// print the header:
    	buf.append(header);

    	// record the tag as already processed:
    	tags.add(_tag);

    	// process the subterms if any:
    	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 position = 1;
    		// as long as there is no gap -> no feature needed
    		for (;position<=positionArity(); position++)
    		  {
    		    PsiTerm subterm = getSubterm(position);
    		    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');

    		    // add a comma if there are more subterms after this one
    		    if (position<positionArity() || _features != null)
    		      buf.append(offset + ", ");
    		  }

    		// above a gap up to positionArity(), print the position as a
    		// feature for non null subterms
    		for (;position<=positionArity(); position++)
    		  {
    		    PsiTerm subterm = getSubterm(position);
    		    if (subterm != null)
    		      {
    			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');

    			// add a comma if there are more subterms after this one
    			if (position<positionArity() || _features != null)
    			  buf.append(offset + ", ");
    		      }
    		  }
    	      }

    	    // do the features
    	    if (_features != null)
    	      for (Iterator it=_features.keySet().iterator(); it.hasNext();)
    		{
    		  Feature feature = (Feature)it.next();
    		  PsiTerm subterm = getSubterm(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 Tue Jan 21 09:56:10 CET 2014 from file `PsiTerm.java`
by the `hlt.language.tools.Hilite` Java tool written by Hassan Aït-Kaci