All Downloads are FREE. Search and download functionalities are using the official Maven repository.

epic.parser.UnrefinedGrammarAnchoring.scala Maven / Gradle / Ivy

The newest version!
package epic.parser
/*
 Copyright 2012 David Hall

 Licensed under the Apache License, Version 2.0 (the "License")
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
*/

import nak.inference.Factor
import epic.lexicon.Lexicon
import epic.constraints.{TagConstraints, ChartConstraints}
import breeze.numerics.logI

/**
 * [[epic.parser.UnrefinedGrammarAnchoring]] score rules and labels in a particular context
 * without needed extra "refined" categories. That is, an anchoring can
 * score x-bar spans in a particular context.
 *
 * @author dlwh
 */
@SerialVersionUID(1)
trait UnrefinedGrammarAnchoring[L, W] extends GrammarAnchoring[L, W] with Factor[UnrefinedGrammarAnchoring[L, W]] {
  def topology: RuleTopology[L]
  def lexicon: Lexicon[L, W]
  def words: IndexedSeq[W]

//  def sparsityPattern = ChartConstraints.noSparsity[L]
  def addConstraints(cs: ChartConstraints[L]):UnrefinedGrammarAnchoring[L, W]

  /**
   * Scores the indexed [[epic.trees.BinaryRule]] rule when it occurs at (begin,split,end)
   */
  def scoreBinaryRule(begin: Int, split: Int, end: Int, rule: Int): Double

  /**
   * Scores the indexed [[epic.trees.UnaryRule]] rule when it occurs at (begin,end)
   */
  def scoreUnaryRule(begin: Int, end: Int, rule: Int): Double

  /**
   * Scores the indexed label rule when it occurs at (begin,end). Can be used for tags, or for a
   * "bottom" label. Typically it is used to filter out impossible rules (using Double.NegativeInfinity)
   */
  def scoreSpan(begin: Int, end: Int, tag: Int): Double

  // Factor stuff
  /**
   * Computes the point-wise product of this grammar with some other grammar.
   *
   * Note that scores are in log space, so we actually sum scores.
   * @param other
   * @return
   */
  override def *(other: UnrefinedGrammarAnchoring[L, W]): UnrefinedGrammarAnchoring[L, W] = {
    // hacky multimethod dispatch is hacky
    if (other eq null) this // ugh
    else if(other.isInstanceOf[UnrefinedGrammarAnchoring.Identity[L, W]]) this.addConstraints(other.sparsityPattern)
    else if(this.isInstanceOf[UnrefinedGrammarAnchoring.Identity[L, W]]) other.addConstraints(this.sparsityPattern)
    else new ProductUnrefinedGrammarAnchoring(this,other)
  }


  /**
   * The annotationTag controls if two grammars are over the same refinements.
   * If they are, then * and / can be much faster.
   *
   * Note that 0 is reserved for unrefined anchorings, and -1 never matches other tags.
   *
   * Reserved:
   * 1 - Lexicalized Parsers with no symbol or rule annotation
   *
   * 0's will be optimized
   */
  override def annotationTag: Int = 0

  /**
   * Computes the point-wise division of this grammar with some other grammar.
   *
   * Note that scores are in log space, so we actually subtract scores.
   * @param other
   * @return
   */
  def /(other: UnrefinedGrammarAnchoring[L, W]) = {
    // hacky multimethod dispatch is hacky
    if (other eq null) this // ugh
    else if(this eq other) new UnrefinedGrammarAnchoring.Identity[L, W](topology, lexicon, words, this.sparsityPattern)
    else if(other.isInstanceOf[UnrefinedGrammarAnchoring.Identity[L, W]]) this.addConstraints(other.sparsityPattern)
    else new ProductUnrefinedGrammarAnchoring(this, other, -1)
  }

  /** Is this CoreAnchoring nearly the same as that core anchoring? */
  def isConvergedTo(f: UnrefinedGrammarAnchoring[L, W], diff: Double) = isConvergedTo(f:GrammarAnchoring[L, W],diff)

  final def validLabelRefinements(begin: Int, end: Int, label: Int) = Array(0)

  final def numValidRefinements(label: Int) = 1

  final def numValidRuleRefinements(rule: Int) = 1

  private final val zeroArray = Array(0)
  final def validRuleRefinementsGivenParent(begin: Int, end: Int, rule: Int, parentRef: Int) = zeroArray

  final def validUnaryRuleRefinementsGivenChild(begin: Int, end: Int, rule: Int, childRef: Int) = zeroArray

  final def leftChildRefinement(rule: Int, ruleRef: Int) = 0

  final def rightChildRefinement(rule: Int, ruleRef: Int) = 0

  final def parentRefinement(rule: Int, ruleRef: Int) = 0

  final def childRefinement(rule: Int, ruleRef: Int) = 0

  final def ruleRefinementFromRefinements(r: Int, refA: Int, refB: Int) = 0

  final def ruleRefinementFromRefinements(r: Int, refA: Int, refB: Int, refC: Int) = 0

  def validCoarseRulesGivenParentRefinement(a: Int, refA: Int) = topology.indexedBinaryRulesWithParent(a)

  def validParentRefinementsGivenRule(begin: Int, splitBegin: Int, splitEnd: Int, end: Int, rule: Int): Array[Int] = validLabelRefinements(begin, end, topology.parent(rule))

  def validRuleRefinementsGivenLeftChild(begin: Int, split: Int, completionBegin: Int, completionEnd: Int, rule: Int, childRef: Int): Array[Int] = {
    zeroArray
  }

  def validRuleRefinementsGivenRightChild(completionBegin: Int, completionEnd: Int, split: Int, end: Int, rule: Int, childRef: Int): Array[Int] =  {
    zeroArray
  }

  def validLeftChildRefinementsGivenRule(begin: Int, end: Int, completionBegin: Int, completionEnd: Int, rule: Int): Array[Int] =  {
    zeroArray
  }

  def validRightChildRefinementsGivenRule(completionBegin: Int, completionEnd: Int, begin: Int, end: Int, rule: Int): Array[Int] =  {
    zeroArray
  }

  /**
   * Scores the indexed [[epic.trees.UnaryRule]] rule when it occurs at (begin, end)
   */
  override def scoreUnaryRule(begin: Int, end: Int, rule: Int, ref: Int): Double = {
    scoreUnaryRule(begin, end, rule)
  }

  /**
   * Scores the indexed [[epic.trees.BinaryRule]] rule when it occurs at (begin, split, end)
   */
  override def scoreBinaryRule(begin: Int, split: Int, end: Int, rule: Int, ref: Int): Double = {
    scoreBinaryRule(begin, split, end, rule)
  }

  /**
   * Scores the indexed label rule with refinenemnt ref, when it occurs at (begin, end). Can be used for s, or for a
   * "bottom" label. Mainly used for s.
   */
  override def scoreSpan(begin: Int, end: Int, label: Int, ref: Int): Double = {
    scoreSpan(begin, end, label)
  }
}

object UnrefinedGrammarAnchoring {
  /**
   * Returns an [[epic.parser.UnrefinedGrammarAnchoring.Identity]], which assigns 0
   * to everything that is allowed.
   * @param topology
   * @param lexicon
   * @param words
   * @tparam L
   * @tparam W
   * @return
   */
  def identity[L, W](topology: RuleTopology[L],
                     lexicon: Lexicon[L, W],
                     words: IndexedSeq[W],
                     constraints: ChartConstraints[L]):UnrefinedGrammarAnchoring[L, W] = {
    new Identity(topology, lexicon, words, constraints)
  }

  /**
   * Assigns 0 to everything
   * @param topology
   * @param lexicon
   * @param words
   * @tparam L
   * @tparam W
   * @return
   */
  @SerialVersionUID(1L)
  case class Identity[L, W](topology: RuleTopology[L], lexicon: Lexicon[L, W], words: IndexedSeq[W], sparsityPattern: ChartConstraints[L]) extends UnrefinedGrammarAnchoring[L, W] {


    //  def sparsityPattern = ChartConstraints.noSparsity[L]
    override def addConstraints(cs: ChartConstraints[L]): UnrefinedGrammarAnchoring[L, W] = copy(sparsityPattern = sparsityPattern & cs)

    def scoreBinaryRule(begin: Int, split: Int, end: Int, rule: Int) = 0.0

    def scoreUnaryRule(begin: Int, end: Int, rule: Int) = 0.0

    def scoreSpan(begin: Int, end: Int, tag: Int) = 0.0


  }

}









© 2015 - 2025 Weber Informatics LLC | Privacy Policy