
epic.parser.RefinedChartMarginal.scala Maven / Gradle / Ivy
The newest version!
package epic.parser
import epic.trees.{Span, UnaryTree, BinarizedTree}
import epic.util.{SafeLogging, Arrays}
import breeze.numerics
import breeze.collection.mutable.TriangularArray
import com.typesafe.scalalogging.slf4j.LazyLogging
import breeze.linalg.{max, DenseVector, softmax, Counter2}
import epic.constraints.ChartConstraints
/*
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.
*/
/**
* Holds the information for the marginals for a sentence.
* That is, the inside and outside scores for a sentence
* and anchoring.
*
* @param anchoring the specialized grammar used to construct the marginals for this sentence
* @param inside inside chart
* @param outside outside chart
* @param logPartition the normalization constant aka inside score of the root aka probability of the sentence
* @tparam L the label type
* @tparam W the word type
*/
final case class RefinedChartMarginal[L, W](anchoring: GrammarAnchoring[L, W],
inside: RefinedParseChart[L], outside: RefinedParseChart[L],
logPartition: Double,
override val isMaxMarginal: Boolean) extends ParseMarginal[L, W] with SafeLogging {
override def insideTopScore(begin: Int, end: Int, sym: Int, ref: Int): Double = inside.top(begin, end, sym, ref)
override def insideBotScore(begin: Int, end: Int, sym: Int, ref: Int): Double = inside.bot(begin, end, sym, ref)
def marginalAt(begin: Int, end: Int):Counter2[L, Int, Double] = {
val in = inside.bot.decodedLabelScores(begin, end)
in += outside.bot.decodedLabelScores(begin, end)
in -= logPartition
breeze.numerics.exp(in)
}
def feasibleSplitPoints(begin: Int, end: Int, leftChild: Int, leftChildRef: Int, rightChild: Int, rightChildRef: Int):IndexedSeq[Int] = {
inside.top.feasibleSplitPoints(begin, end, leftChild, leftChildRef, rightChild, rightChildRef).toIndexedSeq
}
/**
* Forest traversal that visits spans in a "bottom up" order.
*/
def visitPostorder(spanVisitor: AnchoredVisitor[L], spanThreshold: Double = Double.NegativeInfinity):Unit = {
if(logPartition.isInfinite) throw new RuntimeException("No parse for " + words)
if(logPartition.isNaN) throw new RuntimeException("NaN prob!")
val itop = inside.top
val lexLoc = anchoring.tagConstraints
// handle lexical
for (i <- 0 until words.length) {
var visitedSomething = false
for {
a <- lexLoc.allowedTags(i) if anchoring.sparsityPattern.bot.isAllowedLabeledSpan(i, i+1, a)
ref <- anchoring.validLabelRefinements(i, i+ 1, a)
} {
val score:Double = anchoring.scoreSpan(i, i+1, a, ref) + outside.bot(i, i+1, a, ref) - logPartition
assert(!score.isNaN, anchoring.scoreSpan(i, i+1, a, ref) + " " + outside.bot(i, i+1, a, ref) + " "+ logPartition)
if (score != Double.NegativeInfinity) {
spanVisitor.visitSpan(i, i+1, a, ref, math.exp(score))
visitedSomething = true
}
}
assert(visitedSomething, lexLoc.allowedTags(i).toIndexedSeq + " " + logPartition + " " + anchoring.words)
}
// handle binaries
for {
span <- 2 to inside.length
begin <- 0 to (inside.length - span)
} {
val end:Int = begin + span
for (a <- inside.bot.enteredLabelIndexes(begin, end); refA <- inside.bot.enteredLabelRefinements(begin, end, a)) {
var i = 0
val aOutside = outside.bot.labelScore(begin, end, a, refA)
val labelMarginal = aOutside + inside.bot.labelScore(begin, end, a, refA) - logPartition
val aScore = aOutside + anchoring.scoreSpan(begin, end, a, refA)
if(labelMarginal > spanThreshold) {
spanVisitor.visitSpan(begin, end, a, refA, math.exp(labelMarginal))
if(!spanVisitor.skipBinaryRules) {
val rules = anchoring.validCoarseRulesGivenParentRefinement(a, refA)
while(i < rules.length) {
val r = rules(i)
val b = topology.leftChild(r)
val c = topology.rightChild(r)
i += 1
val feasibleCoarseRange = inside.top.feasibleSplitPoints(begin, end, b, c)
if(feasibleCoarseRange.nonEmpty) {
val refinements = anchoring.validRuleRefinementsGivenParent(begin, end, r, refA)
var ruleRefIndex = 0
while(ruleRefIndex < refinements.length) {
val refR = refinements(ruleRefIndex)
ruleRefIndex += 1
val refB = anchoring.leftChildRefinement(r, refR)
val refC = anchoring.rightChildRefinement(r, refR)
val feasibleSplitRange = inside.top.feasibleSplitPoints(begin, end, b, refB, c, refC)
var split = feasibleSplitRange.begin
val endSplit = feasibleSplitRange.end
while(split < endSplit) {
val bInside = itop.labelScore(begin, split, b, refB)
val cInside = itop.labelScore(split, end, c, refC)
val withoutRefined = bInside + cInside
if (!java.lang.Double.isInfinite(withoutRefined)) {
val ruleScore = anchoring.scoreBinaryRule(begin, split, end, r, refR)
val score = aScore + withoutRefined + ruleScore - logPartition
val expScore = math.exp(score)
spanVisitor.visitBinaryRule(begin, split, end, r, refR, expScore)
}
split += 1
}
}
}
}
}
}
}
}
// Unaries
if(!spanVisitor.skipUnaryRules)
for {
span <- 1 to words.length
begin <- 0 to (words.length - span)
end = begin + span
a <- inside.top.enteredLabelIndexes(begin, end)
refA <- inside.top.enteredLabelRefinements(begin, end, a)
} {
val aScore = outside.top.labelScore(begin, end, a, refA)
for (r <- topology.indexedUnaryRulesWithParent(a); refR <- anchoring.validRuleRefinementsGivenParent(begin, end, r, refA)) {
val b = topology.child(r)
val refB = anchoring.childRefinement(r, refR)
val bScore = inside.bot.labelScore(begin, end, b, refB)
val rScore = anchoring.scoreUnaryRule(begin, end, r, refR)
val prob = math.exp(bScore + aScore + rScore - logPartition)
if (prob > 0)
spanVisitor.visitUnaryRule(begin, end, r, refR, prob)
}
}
}
def checkForTree(tree: BinarizedTree[(L, Int)]) = {
for (t <- tree.allChildren) t match {
case UnaryTree( (label, ref), _, _, span) =>
val labelScore = inside.top(span.begin, span.end, anchoring.topology.labelIndex(label), ref)
if (labelScore.isInfinite) {
logger.warn("problem with unary: " + (label, ref) + " " + span)
}
case tree =>
val labelScore = inside.bot(tree.span.begin, tree.span.end, anchoring.topology.labelIndex(tree.label._1), tree.label._2)
if (labelScore.isInfinite) {
logger.warn("problem with other: " + t.label + " " + tree.span)
}
}
this
}
def checkForSimpleTree(tree: BinarizedTree[L]) = {
for (t <- tree.allChildren) t match {
case UnaryTree( label, _, _, span) =>
val labelScore = breeze.linalg.softmax(inside.top.decodedLabelScores(span.begin, span.end, anchoring.topology.labelIndex(label)))
if (labelScore.isInfinite) {
logger.warn("problem with unary: " + (label) + " " + span)
}
case tree =>
val labelScore = breeze.linalg.softmax(inside.bot.decodedLabelScores(tree.begin, tree.end, anchoring.topology.labelIndex(tree.label)))
if (labelScore.isInfinite) {
logger.warn("problem with other: " + t.label + " " + tree.span)
}
}
this
}
def checkForTreeOutside(tree: BinarizedTree[(L, Int)]) {
for (t <- tree.allChildren) t match {
case tree@UnaryTree( (label, ref), _, _, span) =>
val ai: Int = anchoring.topology.labelIndex(label)
val labelScore = outside.top(span.begin, span.end, ai, ref)
if (labelScore.isInfinite) {
RefinedChartMarginal.synchronized {
logger.warn("problem with top: " + (label, ref) + " " + span)
logger.warn(s"problem with outside other: ${t.label} ${tree.span} ${outside.top.enteredLabelIndexes(tree.span.begin, tree.span.end)(ai)} $words ${outside.top.decodedLabelScores(tree.span.begin,tree.span.end)}")
logger.warn(ai + " " + outside.top.enteredLabels(TriangularArray.index(tree.span.begin, tree.span.end)))
logger.warn("Constraint: " + anchoring.sparsityPattern.top.isAllowedLabeledSpan(tree.begin, tree.end, ai))
logger.warn("checking for inside starting from here...")
checkForTree(t.asInstanceOf[BinarizedTree[(L, Int)]])
logger.warn("done.")
}
return
}
case tree =>
val ai: Int = anchoring.topology.labelIndex(tree.label._1)
val labelScore = outside.bot(tree.span.begin, tree.span.end, ai, tree.label._2)
if (labelScore.isInfinite) {
RefinedChartMarginal.synchronized {
logger.warn(s"problem with outside other: ${t.label} ${tree.span} ${outside.bot.enteredLabelIndexes(tree.span.begin, tree.span.end)(ai)} $words ${outside.bot.decodedLabelScores(tree.span.begin,tree.span.end)}")
logger.warn(ai + " " + outside.bot.enteredLabels(TriangularArray.index(tree.span.begin, tree.span.end)))
logger.warn("Constraint: " + anchoring.sparsityPattern.bot.isAllowedLabeledSpan(tree.begin, tree.end, ai))
logger.warn("checking for inside starting from here...")
checkForTree(t.asInstanceOf[BinarizedTree[(L, Int)]])
}
return
}
}
}
}
object RefinedChartMarginal {
def apply[L, W](grammar: Grammar[L, W], sent: IndexedSeq[W]): RefinedChartMarginal[L, W] = {
apply(grammar.anchor(sent))
}
def apply[L, W](anchoring: GrammarAnchoring[L, W]): RefinedChartMarginal[L, W] = {
apply(anchoring, false)
}
def apply[L, W](anchoring: GrammarAnchoring[L, W], maxMarginal: Boolean): RefinedChartMarginal[L, W] = {
val sent = anchoring.words
val sum = if(maxMarginal) MaxSummer else LogSummer
val inside = buildInsideChart(anchoring, sent, sum)
val logPartition = rootScore(anchoring, inside, sum)
val outside = buildOutsideChart(anchoring, inside, sum)
RefinedChartMarginal(anchoring, inside, outside, logPartition, maxMarginal)
}
private[parser] trait Summer {
def apply(a: Double, b: Double):Double
def apply(a: Array[Double], length: Int):Double
}
private[parser] object LogSummer extends Summer {
def apply(a: Double, b: Double): Double = softmax(a,b)
def apply(a: Array[Double], length: Int): Double = softmax.array(a, length)
}
private[parser] object MaxSummer extends Summer {
def apply(a: Double, b: Double): Double = math.max(a,b)
def apply(a: Array[Double], length: Int): Double = if(length == 0) Double.NegativeInfinity else max.array(a, length)
}
private def rootScore[L, W](anchoring: GrammarAnchoring[L, W], inside: RefinedParseChart[L], sum: Summer): Double = {
val rootIndex: Int = anchoring.topology.labelIndex(anchoring.topology.root)
val rootScores = new Array[Double](anchoring.validLabelRefinements(0, inside.length, rootIndex).length)
var offset = 0
for(ref <- inside.top.enteredLabelRefinements(0, inside.length, rootIndex)) {
val score = inside.top.labelScore(0, inside.length, rootIndex, ref)
if(score != Double.NegativeInfinity) {
rootScores(offset) = score
offset += 1
}
}
val score = sum(rootScores, offset)
// assert(score != 0.0, rootScores.mkString(", ") + anchoring.words)
assert(!score.isNaN, rootScores.mkString(", "))
score
}
// first parse chart is the inside scores, second parse chart is span scores for spans that were computed.
private def buildInsideChart[L, W](anchoring: GrammarAnchoring[L, W],
words: IndexedSeq[W], sum: Summer): RefinedParseChart[L] = {
val inside = RefinedParseChart(anchoring.topology.labelIndex,
Array.tabulate(anchoring.topology.labelIndex.size)(anchoring.numValidRefinements),
words.length,
anchoring.sparsityPattern)
val tagConstraints = anchoring.tagConstraints
// handle lexical
for{i <- 0 until anchoring.words.length} {
assert(anchoring.sparsityPattern.isAllowedSpan(i,i+1), "a pos tag isn't allowed? " + anchoring.sparsityPattern)
assert(anchoring.sparsityPattern.bot.isAllowedSpan(i,i+1), "a top of a length 1 span isn't allowed?")
var foundSomething = false
for {
a <- tagConstraints.allowedTags(i) if anchoring.sparsityPattern.bot.isAllowedLabeledSpan(i, i+1, a)
ref <- anchoring.validLabelRefinements(i, i+1, a)
} {
val score:Double = anchoring.scoreSpan(i, i+1, a, ref)
if (score != Double.NegativeInfinity) {
inside.bot.enter(i, i+1, a, ref, score)
foundSomething = true
}
}
updateInsideUnaries(inside, anchoring, i, i+1, sum)
}
val scoreArray = Array.ofDim[Double](anchoring.maxLabelRefinements, 40)
val offsets = new Array[Int](anchoring.maxLabelRefinements)
// a -> bc over [begin, split, end)
for {
span <- 2 to words.length
begin:Int <- 0 to (words.length - span)
} {
val end = begin + span
for ( a <- 0 until anchoring.topology.labelIndex.size if anchoring.sparsityPattern.bot.isAllowedLabeledSpan(begin, end, a)) {
val numValidLabelRefs = anchoring.numValidRefinements(a)
java.util.Arrays.fill(offsets, 0)
val rules = anchoring.topology.indexedBinaryRulesWithParent(a)
var ruleIndex = 0
// into rules
while(ruleIndex < rules.length) {
val r = rules(ruleIndex)
val b = anchoring.topology.leftChild(r)
val c = anchoring.topology.rightChild(r)
ruleIndex += 1
val feasibleCoarseRange = inside.top.feasibleSplitPoints(begin, end, b, c)
if(feasibleCoarseRange.nonEmpty) {
val validA = anchoring.validParentRefinementsGivenRule(begin, feasibleCoarseRange.begin, feasibleCoarseRange.end, end, r)
var ai = 0
while(ai < validA.length) {
val refA = validA(ai)
ai += 1
val spanScore = anchoring.scoreSpan(begin, end, a, refA)
if(!spanScore.isInfinite) {
val refinements = anchoring.validRuleRefinementsGivenParent(begin, end, r, refA)
var ruleRefIndex = 0
while(ruleRefIndex < refinements.length) {
val refR = refinements(ruleRefIndex)
ruleRefIndex += 1
val refB = anchoring.leftChildRefinement(r, refR)
val refC = anchoring.rightChildRefinement(r, refR)
val feasibleSplitRange = inside.top.feasibleSplitPoints(begin, end, b, refB, c, refC)
var split = feasibleSplitRange.begin
val endSplit = feasibleSplitRange.end
while(split < endSplit) {
val bScore = inside.top.labelScore(begin, split, b, refB)
val cScore = inside.top.labelScore(split, end, c, refC)
val withoutRule = bScore + cScore + spanScore
if(withoutRule != Double.NegativeInfinity) {
val prob = withoutRule + anchoring.scoreBinaryRule(begin, split, end, r, refR)
assert(!prob.isNaN, s"$withoutRule ${anchoring.scoreBinaryRule(begin, split, end, r, refR)} $bScore $cScore $spanScore")
if(prob != Double.NegativeInfinity) {
scoreArray(refA)(offsets(refA)) = prob
offsets(refA) += 1
// buffer full
if(offsets(refA) == scoreArray(refA).length) {
scoreArray(refA)(0) = sum(scoreArray(refA), offsets(refA))
offsets(refA) = 1
}
}
}
split += 1
}
}
}
} // end a refinement
} // end canBuildThisRule
} // end rules
enterScoresForLabelRefinements(sum, scoreArray, offsets, inside.bot, begin, end, a, numValidLabelRefs)
// assert(rootScore(anchoring, inside, sum) != 0.0, (begin, end, a))
// if(!foundSomething && refined.sparsityPattern != ChartConstraints.noSparsity) {
// logger.warn(s"Failed to replicate a span in ($begin, $end) of ${anchoring.words}. Label is ${anchoring.grammar.labelIndex.get(a)}")
//
// }
}
updateInsideUnaries(inside, anchoring, begin, end, sum)
}
inside
}
private def enterScoresForLabelRefinements[L](sum: Summer, scoreArray: Array[Array[Double]], offsets: Array[Int], bot: RefinedParseChart[L]#ChartScores, begin: Int, end: Int, parent: Int, numValidLabelRefs: Int) {
var foundSomething = false
var ai = 0
while (ai < numValidLabelRefs) {
// done updating vector, do an enter:
if (offsets(ai) > 0) {
val score = sum(scoreArray(ai), offsets(ai))
assert(!score.isNaN, scoreArray(ai).take(offsets(ai)).toIndexedSeq)
bot.enter(begin, end, parent, ai, score)
foundSomething = true
}
ai += 1
}
}
private def buildOutsideChart[L, W](anchoring: GrammarAnchoring[L, W],
inside: RefinedParseChart[L], sum: Summer):RefinedParseChart[L] = {
val refined = anchoring
val grammar = anchoring.topology
val rootIndex = grammar.labelIndex(grammar.root)
val length = inside.length
val outside = RefinedParseChart(grammar.labelIndex,
Array.tabulate(grammar.labelIndex.size)(refined.numValidRefinements),
length,
refined.sparsityPattern)
for(refRoot <- refined.validLabelRefinements(0, inside.length, rootIndex)) {
outside.top.enter(0, inside.length, rootIndex, refRoot, 0.0)
}
updateOutsideUnaries(outside, inside, anchoring, 0, inside.length, sum)
val scoreArray = Array.ofDim[Double](anchoring.maxLabelRefinements, 80)
val offsets = new Array[Int](anchoring.maxLabelRefinements)
for {
span <- (length-1) until 0 by (-1)
begin <- 0 to (length-span)
} {
val end = begin + span
val enteredTop = inside.top.enteredLabelIndexes(begin, end)
var a = 0
while(a < grammar.labelIndex.size) {
// we're going to populate a by looking at rules p -> a rc, p -> lc a
if (enteredTop.contains(a)) {
java.util.Arrays.fill(offsets, 0)
doOutsideLeftCompletionUpdates(inside, outside, anchoring, begin, end, a, scoreArray, offsets, sum)
doOutsideRightCompletionUpdates(inside, outside, anchoring, begin, end, a, scoreArray, offsets, sum)
val numValidLabelRefs = anchoring.numValidRefinements(a)
enterScoresForLabelRefinements(sum, scoreArray, offsets, outside.top, begin, end, a, numValidLabelRefs)
}
a += 1
}
updateOutsideUnaries(outside, inside, anchoring, begin, end, sum)
}
outside
}
private def doOutsideLeftCompletionUpdates[W, L](inside: RefinedParseChart[L], outside: RefinedParseChart[L],
anchoring: GrammarAnchoring[L, W],
begin: Int, end: Int,
label: Int,
scoreArray: Array[Array[Double]], offsets: Array[Int], sum: Summer) {
val refined = anchoring
val grammar = refined.topology
val rules = anchoring.topology.indexedBinaryRulesWithLeftChild(label)
var br = 0
while (br < rules.length) {
val r = rules(br)
val p = grammar.parent(r)
val rc = grammar.rightChild(r)
br += 1
// can I possibly build any refinement of this rule?
val coarseCompletionSpan = feasibleSpanForCoarseLeftCompletion(begin, end, p, rc, inside)
val coarseCompletionBegin = coarseCompletionSpan.begin
val coarseCompletionEnd = coarseCompletionSpan.end
val canBuildThisRule = coarseCompletionBegin <= coarseCompletionEnd
if (canBuildThisRule) {
val enteredRefTop = inside.top.enteredLabelRefinements(begin, end, label)
val compatibleRefinements = refined.validLeftChildRefinementsGivenRule(begin, end, coarseCompletionBegin, coarseCompletionEnd, r)
var refai = 0
while (refai < compatibleRefinements.length) {
val refA = compatibleRefinements(refai)
if (enteredRefTop.contains(refA)) {
val ruleRefinements = refined.validRuleRefinementsGivenLeftChild(begin, end, coarseCompletionBegin, coarseCompletionEnd, r, refA)
var rfI = 0
while (rfI < ruleRefinements.length) {
val refR = ruleRefinements(rfI)
rfI += 1
val refP = refined.parentRefinement(r, refR)
val refC = refined.rightChildRefinement(r, refR)
val splitSpan = feasibleSpanForLeftCompletion(begin, end, p, refP, rc, refC, inside)
var completion = splitSpan.begin
while (completion <= splitSpan.end) {
val pOutside = outside.bot.labelScore(begin, completion, p, refP) + anchoring.scoreSpan(begin, completion, p, refP)
val cInside = inside.top.labelScore(end, completion, rc, refC)
if (cInside != Double.NegativeInfinity && pOutside != Double.NegativeInfinity) {
val ruleScore = refined.scoreBinaryRule(begin, end, completion, r, refR)
val score = cInside + ruleScore + pOutside
if(score != Double.NegativeInfinity) {
scoreArray(refA)(offsets(refA)) = score
offsets(refA) += 1
// buffer full
if (offsets(refA) == scoreArray(refA).length) {
scoreArray(refA)(0) = sum(scoreArray(refA), offsets(refA))
offsets(refA) = 1
}
}
}
completion += 1
}
}
}
refai += 1
}
}
}
}
private def feasibleSpanForLeftCompletion[L, W](begin: Int, end: Int, p: Int, refP: Int, rc: Int, refC: Int, inside: RefinedParseChart[L]) = {
val parentMinCompletion = inside.bot.leftMostEndForBegin(begin)(p)(refP)
val rcMinCompletion = inside.top.leftMostEndForBegin(end)(rc)(refC)
val parentMaxCompletion = inside.bot.rightMostEndForBegin(begin)(p)(refP)
val rcMaxCompletion = inside.top.rightMostEndForBegin(end)(rc)(refC)
val completionBegin = math.max(math.max(parentMinCompletion, rcMinCompletion), end + 1)
val completionEnd = math.min(parentMaxCompletion, rcMaxCompletion)
Span(completionBegin, completionEnd)
}
private def feasibleSpanForCoarseLeftCompletion[L, W](begin: Int, end: Int, p: Int, rc: Int, inside: RefinedParseChart[L]) = {
val parentMinCompletion = inside.bot.coarseLeftMostEndForBegin(begin)(p)
val rcMinCompletion = inside.top.coarseLeftMostEndForBegin(end)(rc)
val parentMaxCompletion = inside.bot.coarseRightMostEndForBegin(begin)(p)
val rcMaxCompletion = inside.top.coarseRightMostEndForBegin(end)(rc)
val completionBegin = math.max(math.max(parentMinCompletion, rcMinCompletion), end + 1)
val completionEnd = math.min(parentMaxCompletion, rcMaxCompletion)
Span(completionBegin, completionEnd)
}
private def doOutsideRightCompletionUpdates[W, L](inside: RefinedParseChart[L], outside: RefinedParseChart[L],
anchoring: GrammarAnchoring[L, W],
begin: Int, end: Int,
label: Int,
scoreArray: Array[Array[Double]],
offsets: Array[Int], sum: Summer) {
val refined = anchoring
val grammar = refined.topology
val rules = anchoring.topology.indexedBinaryRulesWithRightChild(label)
var br = 0
while (br < rules.length) {
val r = rules(br)
val p = grammar.parent(r)
val lc = grammar.leftChild(r)
br += 1
// can I possibly build any refinement of this rule?
val coarseCompletionSpan = feasibleSpanForCoarseRightCompletion(begin, end, p, lc, inside)
val coarseCompletionBegin = coarseCompletionSpan.begin
val coarseCompletionEnd = coarseCompletionSpan.end
val canBuildThisRule = coarseCompletionBegin <= coarseCompletionEnd
if (canBuildThisRule) {
val enteredRefTop = inside.top.enteredLabelRefinements(begin, end, label)
val compatibleRefinements = refined.validRightChildRefinementsGivenRule(coarseCompletionBegin, coarseCompletionEnd, begin, end, r)
var refai = 0
while (refai < compatibleRefinements.length) {
val refA = compatibleRefinements(refai)
if (enteredRefTop.contains(refA)) {
val ruleRefinements = refined.validRuleRefinementsGivenRightChild(coarseCompletionBegin, coarseCompletionEnd, begin, end, r, refA)
var rfI = 0
while (rfI < ruleRefinements.length) {
val refR = ruleRefinements(rfI)
rfI += 1
val refP = refined.parentRefinement(r, refR)
val refB = refined.leftChildRefinement(r, refR)
val completionSpan = feasibleSpanForRightCompletion(begin, end, p, refP, lc, refB, inside)
var completion = completionSpan.begin
while (completion <= completionSpan.end) {
val pOutside = outside.bot.labelScore(completion, end, p, refP) + anchoring.scoreSpan(completion, end, p, refP)
val bInside = inside.top.labelScore(completion, begin, lc, refB)
if (bInside != Double.NegativeInfinity && pOutside != Double.NegativeInfinity) {
val ruleScore = refined.scoreBinaryRule(completion, begin, end, r, refR)
val score = bInside + ruleScore + pOutside
if(score != Double.NegativeInfinity) {
scoreArray(refA)(offsets(refA)) = score
offsets(refA) += 1
// buffer full
if (offsets(refA) == scoreArray(refA).length) {
scoreArray(refA)(0) = sum(scoreArray(refA), offsets(refA))
offsets(refA) = 1
}
}
}
completion += 1
}
}
}
refai += 1
}
}
}
}
private def feasibleSpanForRightCompletion[L, W](begin: Int, end: Int, p: Int, refP: Int, lc: Int, refB: Int, inside: RefinedParseChart[L]) = {
val parentMinCompletion = inside.bot.leftMostBeginForEnd(end)(p)(refP)
val rcMinCompletion = inside.top.leftMostBeginForEnd(begin)(lc)(refB)
val parentMaxCompletion = inside.bot.rightMostBeginForEnd(end)(p)(refP)
val rcMaxCompletion = inside.top.rightMostBeginForEnd(begin)(lc)(refB)
val completionBegin = math.max(parentMinCompletion, rcMinCompletion)
val completionEnd = math.min(begin, math.min(parentMaxCompletion, rcMaxCompletion))
Span(completionBegin, completionEnd)
}
private def feasibleSpanForCoarseRightCompletion[L, W](begin: Int, end: Int, p: Int, lc: Int, inside: RefinedParseChart[L]) = {
val parentMinCompletion = inside.bot.coarseLeftMostBeginForEnd(end)(p)
val rcMinCompletion = inside.top.coarseLeftMostBeginForEnd(begin)(lc)
val parentMaxCompletion = inside.bot.coarseRightMostBeginForEnd(end)(p)
val rcMaxCompletion = inside.top.coarseRightMostBeginForEnd(begin)(lc)
val completionBegin = math.max(parentMinCompletion, rcMinCompletion)
val completionEnd = math.min(begin, math.min(parentMaxCompletion, rcMaxCompletion))
Span(completionBegin, completionEnd)
}
private def updateInsideUnaries[L, W](chart: RefinedParseChart[L],
anchoring: GrammarAnchoring[L, W],
begin: Int, end: Int, sum: Summer) = {
val refined = anchoring
val grammar = anchoring.topology
for(bi <- chart.bot.enteredLabelIndexes(begin, end); refB <- chart.bot.enteredLabelRefinements(begin, end, bi)) {
val b = bi
val bScore = chart.bot.labelScore(begin, end, b, refB)
if(bScore != Double.NegativeInfinity) {
val rules = grammar.indexedUnaryRulesWithChild(b)
var j = 0
while(j < rules.length) {
val r = rules(j)
val a = grammar.parent(r)
if(refined.sparsityPattern.top.isAllowedLabeledSpan(begin, end, a)) {
for (refR <- refined.validUnaryRuleRefinementsGivenChild(begin, end, r, refB)) {
val refA = refined.parentRefinement(r, refR)
val ruleScore: Double = refined.scoreUnaryRule(begin, end, r, refR)
val prob: Double = bScore + ruleScore
assert(!prob.isNaN, s"$ruleScore $bScore")
if (prob != Double.NegativeInfinity) {
chart.top.enter(begin, end, a, refA, sum(chart.top.labelScore(begin, end, a, refA), prob))
}
}
}
j += 1
}
}
}
}
private def updateOutsideUnaries[L, W](chart: RefinedParseChart[L],
inside: RefinedParseChart[L],
anchoring: GrammarAnchoring[L, W],
begin: Int, end: Int, sum: Summer) = {
val refined = anchoring
val grammar = anchoring.topology
for(ai <- inside.top.enteredLabelIndexes(begin, end); refA <- inside.top.enteredLabelRefinements(begin, end, ai)) {
val a = ai
val bScore = chart.top.labelScore(begin, end, a, refA)
val rules = grammar.indexedUnaryRulesWithParent(a)
var j = 0
while(j < rules.length) {
val r = rules(j)
val b = grammar.child(r)
if(inside.bot.isLabelEntered(begin, end, b))
for(refR <- refined.validRuleRefinementsGivenParent(begin, end, rules(j), refA)) {
val refB = refined.childRefinement(rules(j), refR)
val ruleScore: Double = refined.scoreUnaryRule(begin, end, rules(j), refR)
val prob: Double = bScore + ruleScore
if(prob != Double.NegativeInfinity) {
chart.bot.enter(begin, end, b, refB, sum(chart.bot.labelScore(begin, end, b, refB), prob))
}
}
j += 1
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy