Skip to content

Commit

Permalink
Fix automatons for union/intersection
Browse files Browse the repository at this point in the history
  • Loading branch information
colder committed Jun 14, 2012
1 parent 120a17d commit aa4ae18
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 4 deletions.
23 changes: 23 additions & 0 deletions src/insane/alias/PointToAnalysis.scala
Expand Up @@ -2033,6 +2033,29 @@ trait PointToAnalysis extends PointToGraphsDefs with PointToEnvs with PointToLat
reporter.info(" - No simple effects")
}
}

val r1 = "a.b*.a";
val r2 = "a.b.b.a";

import utils.RegularExpressions._

val nfa1 = RegexHelpers.regexToNFA(RegexParser.parseString(r1).get)
val nfa2 = RegexHelpers.regexToNFA(RegexParser.parseString(r2).get)

dumpFA(nfa1, "nfa1.dot")
dumpFA(nfa2, "nfa2.dot")

val dfa1 = nfa1.determinize
val dfa2 = nfa2.determinize

dumpFA(dfa1, "dfa1.dot")
dumpFA(dfa2, "dfa2.dot")

val dfau = dfa1 union dfa2
val dfai = dfa1 intersection dfa2
dumpFA(dfau, "dfau.dot")
dumpFA(dfai, "dfai.dot")

}
}
}
Expand Down
44 changes: 40 additions & 4 deletions src/insane/utils/Automatons.scala
Expand Up @@ -44,12 +44,13 @@ object Automatons {
}

def removeStates(sts: Iterable[State]): Automaton[L] = {
assert(!sts.toSet.apply(entry), "Trying to remove entry state!")
assert(!sts.toSet.apply(entry), "Trying to remove entry state!")
assert(!(finals -- sts.toSet).isEmpty, "Removing every final states!")
copy(finals = finals -- sts, graph = graph -- sts)
}

def removeDeadPaths: Automaton[L] = {
var markedStates = Set[State](entry) ++ finals
var markedStates = Set[State](entry)

def visit(s: State, from: Set[State]): Unit = {
for (in <- graph.ins(s)) {
Expand Down Expand Up @@ -121,12 +122,46 @@ object Automatons {
new Automaton[L](dStates, dTransitions, dEntry, dFinals)
}

def constructSync(that: Automaton[L]): (Map[(State, State), State], Automaton[L]) = {

var newTransitions = Set[Transition[L]]()
val errorState = newState
var newStates = Map[(State, State), State]()

for (s1 <- this.states; s2 <- that.states) {
val s = newState()
newStates += (s1, s2) -> s
}

for (s1 <- this.states; s2 <- that.states) {
val outs1 = this.graph.outs(s1).groupBy(_.label)
val outs2 = that.graph.outs(s2).groupBy(_.label)

val s = newStates(s1, s2)

for (a <- outs1.keySet ++ outs2.keySet) {
val v21 = outs1.get(a).map(_.head.v2).getOrElse(errorState)
val v22 = outs2.get(a).map(_.head.v2).getOrElse(errorState)

newTransitions += Transition(newStates.getOrElse((s1, s2), errorState), a, newStates.getOrElse((v21, v22), errorState))
}
}

(newStates, new Automaton[L](Set(errorState) ++ newStates.values, newTransitions, newStates((this.entry, that.entry)), Set()))
}

def union(that: Automaton[L]): Automaton[L] = {
this
val (statesMap, atm) = constructSync(that)

val finals = statesMap.collect{ case ((s1, s2), s) if this.finals(s1) || that.finals(s2) => s}
atm.copy(finals = finals.toSet).removeDeadPaths
}

def intersection(that: Automaton[L]): Automaton[L] = {
this
val (statesMap, atm) = constructSync(that)

val finals = statesMap.collect{ case ((s1, s2), s) if this.finals(s1) && that.finals(s2) => s}
atm.copy(finals = finals.toSet).removeDeadPaths
}

case class StateSig(ins: Set[(State, Option[L])], outs: Set[(State, Option[L])])
Expand All @@ -137,6 +172,7 @@ object Automatons {
graph.outs(s).map(t => (t.v2, t.label)).toSet)
}
}

def collapseSimilarStates: Automaton[L] = {
// Keep the head of each kind, remove the rest
val toRemove = states.groupBy(StateSig.fromState _).values.flatMap(_.tail)
Expand Down

0 comments on commit aa4ae18

Please sign in to comment.