
scala.xml.dtd.impl.SubsetConstruction.scala Maven / Gradle / Ivy
/* __ *\
** ________ ___ / / ___ Scala API **
** / __/ __// _ | / / / _ | (c) 2003-2020, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | (c) 2011-2020, Lightbend, Inc. **
** /____/\___/_/ |_/____/_/ | | http://scala-lang.org/ **
** |/ **
\* */
package scala
package xml.dtd.impl
import scala.collection.{ mutable, immutable }
// TODO: still used in ContentModel -- @deprecated("This class will be removed", "2.10.0")
private[dtd] class SubsetConstruction[T <: AnyRef](val nfa: NondetWordAutom[T]) {
import nfa.labels
def selectTag(Q: immutable.BitSet, finals: Array[Int]) =
(Q map finals filter (_ > 0)).min
def determinize: DetWordAutom[T] = {
// for assigning numbers to bitsets
val indexMap = mutable.Map[immutable.BitSet, Int]()
val invIndexMap = mutable.Map[Int, immutable.BitSet]()
var ix = 0
// we compute the dfa with states = bitsets
val q0 = immutable.BitSet(0) // the set { 0 }
val sink = immutable.BitSet.empty // the set { }
var states = Set(q0, sink) // initial set of sets
val delta = new mutable.HashMap[immutable.BitSet, mutable.HashMap[T, immutable.BitSet]]
val deftrans = mutable.Map(q0 -> sink, sink -> sink) // initial transitions
val finals: mutable.Map[immutable.BitSet, Int] = mutable.Map()
var rest = immutable.List.empty[immutable.BitSet]
rest = q0 :: sink :: rest
def addFinal(q: immutable.BitSet): Unit = {
if (nfa containsFinal q)
finals(q) = selectTag(q, nfa.finals)
}
def add(Q: immutable.BitSet): Unit = {
if (!states(Q)) {
states += Q
rest = Q :: rest
addFinal(Q)
}
}
addFinal(q0) // initial state may also be a final state
while (!rest.isEmpty) {
val P = rest.head
rest = rest.tail
// assign a number to this bitset
indexMap(P) = ix
invIndexMap(ix) = P
ix += 1
// make transition map
val Pdelta = new mutable.HashMap[T, immutable.BitSet]
delta.update(P, Pdelta)
labels foreach { label =>
val Q = nfa.next(P, label)
Pdelta.update(label, Q)
add(Q)
}
// collect default transitions
val Pdef = nfa nextDefault P
deftrans(P) = Pdef
add(Pdef)
}
// create DetWordAutom, using indices instead of sets
val nstatesR = states.size
val deltaR = new Array[mutable.Map[T, Int]](nstatesR)
val defaultR = new Array[Int](nstatesR)
val finalsR = new Array[Int](nstatesR)
for (Q <- states) {
val q = indexMap(Q)
val trans = delta(Q)
val transDef = deftrans(Q)
val qDef = indexMap(transDef)
val ntrans = new mutable.HashMap[T, Int]()
for ((label, value) <- trans) {
val p = indexMap(value)
if (p != qDef)
ntrans.update(label, p)
}
deltaR(q) = ntrans
defaultR(q) = qDef
}
finals foreach { case (k, v) => finalsR(indexMap(k)) = v }
new DetWordAutom[T] {
val nstates = nstatesR
val delta = deltaR
val default = defaultR
val finals = finalsR
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy