Permalink
Browse files

Fix automatons for union/intersection

  • Loading branch information...
1 parent 120a17d commit aa4ae1889ee464017aa275ee640b7af0d2a1532f @colder committed Jun 14, 2012
Showing with 63 additions and 4 deletions.
  1. +23 −0 src/insane/alias/PointToAnalysis.scala
  2. +40 −4 src/insane/utils/Automatons.scala
@@ -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")
+
}
}
}
@@ -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)) {
@@ -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])])
@@ -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)

0 comments on commit aa4ae18

Please sign in to comment.