Package synalp.commons.grammar

Source Code of synalp.commons.grammar.GrammarEntry

package synalp.commons.grammar;

import java.util.*;

import synalp.commons.input.Lemma;
import synalp.commons.lexicon.*;
import synalp.commons.semantics.Semantics;
import synalp.commons.unification.*;
import synalp.commons.utils.Utils;
import synalp.generation.configuration.GeneratorOption;


/**
* A GrammarEntry is an entry in a grammar.
* @author Alexandre Denis
*/
public class GrammarEntry implements UnifiableComponent
{
  private String name;
  private String originalName; // the name of this entry as it was in the grammar
  private Tree tree;
  private Trace trace;
  private String family;
  private Semantics semantics;
  private InstantiationContext context;
  private FeatureStructure entryInterface;


  /**
   * Renames all variables of all given entries such that no entry share any variable.
   * @param entries
   */
  public static void renameVariables(Collection<GrammarEntry> entries)
  {
    for(GrammarEntry entry : entries)
      for(FeatureVariable var : entry.getAllVariables())
        entry.replaceVariable(var, new FeatureVariable(UUID.randomUUID().toString()));
  }


  /**
   * Displays a String representation of the given entries names. If the entry has an anchor add
   * it.
   * @param entries
   * @return a String
   */
  public static String toString(Collection<GrammarEntry> entries)
  {
    StringBuilder ret = new StringBuilder();
    for(GrammarEntry entry : entries)
    {
      ret.append(entry.toMiniString());
      ret.append(" ");
    }
    return ret.toString().trim();
  }


  /**
   * Creates a new empty tree with given name.
   * @param name
   */
  public GrammarEntry(String name)
  {
    this.name = name;
    this.setOriginalName(name);
    this.context = new InstantiationContext();
  }


  /**
   * Deep copies this Grammar entry.
   * @param entry
   */
  public GrammarEntry(GrammarEntry entry)
  {
    this.name = entry.getName();
    this.originalName = entry.getOriginalName();
    this.family = entry.getFamily();
    this.tree = new Tree(entry.getTree());
    this.trace = new Trace(entry.getTrace());
    this.semantics = new Semantics(entry.getSemantics());
    this.context = new InstantiationContext(entry.getContext());
    this.entryInterface = new FeatureStructure(entry.getInterface());
  }


  /**
   * @return the name
   */
  public String getName()
  {
    return name;
  }


  /**
   * @param name the name to set
   */
  public void setName(String name)
  {
    this.name = name;
  }


  /**
   * @return a family name
   */
  public final String getFamily()
  {
    return family;
  }


  /**
   * Sets the family name of the entry.
   * @param family
   */
  public void setFamily(String family)
  {
    this.family = family;
  }


  /**
   * @return the semantics of the entry
   */
  public Semantics getSemantics()
  {
    return semantics;
  }


  /**
   * @param semantics
   */
  public void setSemantics(Semantics semantics)
  {
    this.semantics = semantics;
  }


  /**
   * Returns the instantiated semantics of the entry. It creates a new semantics from the entry
   * semantics and instantiates it (resolve variables) in the entry current context.
   * @return a new Semantics
   */
  public Semantics getInstantiatedSemantics()
  {
    Semantics ret = new Semantics(semantics);
    semantics.instantiate(context);
    return ret;
  }


  /**
   * @return the trace of the entry
   */
  public final Trace getTrace()
  {
    return trace;
  }


  /**
   * @param trace
   */
  public void setTrace(Trace trace)
  {
    this.trace = trace;
  }


  /**
   * @return the interface of the entry
   */
  public final FeatureStructure getInterface()
  {
    return entryInterface;
  }


  /**
   * @param fs
   */
  public void setInterface(FeatureStructure fs)
  {
    entryInterface = fs;
  }


  /**
   * @return a tree
   */
  public Tree getTree()
  {
    return tree;
  }


  /**
   * @param tree
   */
  public void setTree(Tree tree)
  {
    this.tree = tree;
  }


  /**
   * Sets the lemma of the main anchor of this entry's tree. If no main anchor node can be found,
   * return false.
   * @param lemma
   * @return true if main anchor lemma has been set
   */
  public boolean setMainAnchorLemma(Lemma lemma)
  {
    Node mainAnchor = getTree().getMainAnchor();
    if (mainAnchor == null)
      return false;
    else
    {
      mainAnchor.setAnchorLemma(lemma);
      return true;
    }
  }


  /**
   * Returns the lemma of the main anchor if it exists.
   * @return null if not found
   */
  public Lemma getMainAnchorLemma()
  {
    Node mainAnchor = getTree().getMainAnchor();
    if (mainAnchor == null)
      return null;
    else return mainAnchor.getAnchorLemma();
  }


  /**
   * Returns the surface form of the entry in terms of the anchored lemmas.
   * @return the anchored lemmas of this entry's tree separated by space
   */
  public String getLemmasSurface()
  {
    return Lemma.printLemmas(tree.getLemmas(), context, false);
  }


  /**
   * Applies all given equations to the given entry. If one equation cannot be applied returns
   * false without trying the other equations. Warning: if some equations can be applied they are
   * still applied (to fix).
   * @param equations
   * @param overwrite if true, overwrites the features (see applyEquation(Equation, boolean)).
   * @return true if all equations have been applied, false if one failed
   */
  public boolean applyEquations(Equations equations, boolean overwrite)
  {
    for(Equation equation : equations)
      if (!applyEquation(equation, overwrite))
        return false;
    return true;
  }


  /**
   * Applies the given equation to the given entry for a specified node. It also sets the lemma of
   * the node if specified in the equation. Warning: each application if successful can modify the
   * entry context.
   * @param eq
   * @param overwrite if overwrite is true, the unification is not tested and all the features of
   *            the equations overwrite features of the node. It always returns true except if the
   *            node cannot be found.
   * @return false if the equation cannot be applied
   */
  public boolean applyEquation(Equation eq, boolean overwrite)
  {
    // find node first
    String nodeId = eq.getNodeId();
    Node node = null;
    if (nodeId.equals("anchor"))
    {
      node = tree.getMainAnchor();
      if (node == null)
        return false;
    }
    else if (nodeId.equals("foot"))
    {
      node = tree.getFoot();
      if (node == null)
        return false;
    }
    else if (nodeId.equals("root"))
    {
      node = tree.getRoot();
      if (node == null)
        return false;
    }
    else
    {
      node = tree.getNodeById(nodeId);
      if (node == null)
      {
        if (!GeneratorOption.ALLOW_MISSING_COANCHORS)
          return false;
        else return true; // ignores the application but don't fail
      }
    }

    // we found it, now check the FS unification, return false if failed
    FeatureStructure eqFs = eq.getFeatureStructure();
    FeatureStructure nodeFs = node.getFs(eq.getType());

    if (overwrite)
    {
      for(Feature feat : eqFs.getFeatures())
      {
        String name = feat.getName();
        if (nodeFs.hasFeature(name))
        {
          Feature nodeFeat = nodeFs.getFeature(name);
          if (nodeFeat.getValue() instanceof FeatureConstant)
          {
            nodeFs.removeFeature(name);
            nodeFs.add(new Feature(feat));
          }
          else if (nodeFeat.getValue() instanceof FeatureVariable)
          {
            if (feat.getValue() instanceof FeatureConstant)
              context.put((FeatureVariable) nodeFeat.getValue(), feat.getValue().copy());
            else if (feat.getValue() instanceof FeatureVariable)
              context.put((FeatureVariable) nodeFeat.getValue(), context.getValue(feat.getValue()).copy());
          }
        }
        else nodeFs.add(new Feature(feat));
      }
      node.setFs(eq.getType(), nodeFs);
    }
    else
    {
      FeatureStructure result = Unifier.unify(nodeFs, eqFs, context);
      if (result == null)
        return false;
      else node.setFs(eq.getType(), result);

    }

    // eventually, if the equation specifies a lemma feature sets the lemma of the node
    setLemma(node, eqFs, context);

    return true;
  }


  /**
   * Sets the lemma of the given Node considering a given value in the given context.
   * @param node
   * @param fs
   * @param context
   */
  private static void setLemma(Node node, FeatureStructure fs, InstantiationContext context)
  {
    Feature lemmaFeat = fs.getFeature("lemma");
    if (lemmaFeat != null)
    {
      FeatureValue val = context.getValue(lemmaFeat.getValue());
      node.setAnchorLemma(new Lemma(val.toString()));
    }
  }


  @Override
  public String toString()
  {
    return name + " " + tree.toString(context);
  }


  /**
   * Returns a String representation of this entry with given NodeFormat.
   * @param format
   * @return a String
   */
  public String toString(NodeFormat format)
  {
    return name + " " + tree.toString(format, context);
  }


  /**
   * Returns a short one line String representation of this entry.
   * @return a String
   */
  public String toShortString()
  {
    return family + "." + tree.getId() + " " + tree.toString(context) + " " + semantics;
  }


  /**
   * Returns a mini String representation of this entry.
   * @return a String
   */
  public String toMiniString()
  {
    return name + "." + Utils.print(tree.getLemmas(), " ", "[", "]");
  }


  /**
   * Returns a full representation of this entry.
   * @return a String
   */
  public String toFullString()
  {
    return "id: " + name + "\nfamily: " + family + "\ntrace: " + trace + "\ninterface:" + entryInterface.toString(context) + "\ntree:" +
        tree.toString(NodeFormat.INDENTED, context) + "\nsemantics:" +
        semantics.toString(context) + "\ncontext:" + context;
  }


  /**
   * @return the context
   */
  public InstantiationContext getContext()
  {
    return context;
  }


  /**
   * @param context
   */
  public void setContext(InstantiationContext context)
  {
    this.context = context;
  }


  @Override
  public Set<FeatureVariable> getAllVariables()
  {
    Set<FeatureVariable> ret = new HashSet<FeatureVariable>();
    ret.addAll(tree.getAllVariables());
    ret.addAll(context.getAllVariables());
    ret.addAll(semantics.getAllVariables());
    ret.addAll(entryInterface.getAllVariables());
    return ret;
  }


  @Override
  public void replaceVariable(FeatureVariable variable, FeatureValue value)
  {
    tree.replaceVariable(variable, value);
    context.replaceVariable(variable, value);
    semantics.replaceVariable(variable, value);
    entryInterface.replaceVariable(variable, value);
  }


  /**
   * This method has been added for coherence reason. I do not think it will be of practical use.
   */
  @Override
  public void instantiate(InstantiationContext context)
  {
    for(FeatureVariable var : getAllVariables())
      if (context.containsKey(var))
        replaceVariable(var, context.get(var));
  }


  /**
   * Returns the original name of the entry as it was in the grammar.
   * @return a String
   */
  public String getOriginalName()
  {
    return originalName;
  }


  /**
   * @param originalName
   */
  public void setOriginalName(String originalName)
  {
    this.originalName = originalName;
  }

}
TOP

Related Classes of synalp.commons.grammar.GrammarEntry

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.