--- a/progs/re4.scala Fri Jul 15 10:54:09 2016 +0100
+++ b/progs/re4.scala Sun Aug 21 00:37:27 2016 +0100
@@ -4,46 +4,46 @@
def simp : Rexp = this
}
-case object NULL extends Rexp
-case object EMPTY extends Rexp
+case object ZERO extends Rexp
+case object ONE extends Rexp
case class CHAR(c: Char) extends Rexp
case class ALT(r1: Rexp, r2: Rexp) extends Rexp {
override def simp = (r1.simp, r2.simp) match {
- case (NULL, r) => r
- case (r, NULL) => r
- case (r, EMPTY) => if (nullable(r)) r else ALT(r, EMPTY)
- case (EMPTY, r) => if (nullable(r)) r else ALT(r, EMPTY)
+ case (ZERO, r) => r
+ case (r, ZERO) => r
+ case (r, ONE) => if (nullable(r)) r else ALT(r, ONE)
+ case (ONE, r) => if (nullable(r)) r else ALT(r, ONE)
case (r1, r2) => if (r1 == r2) r1 else ALT(r1, r2)
}
}
case class SEQ(r1: Rexp, r2: Rexp) extends Rexp {
override def simp = (r1.simp, r2.simp) match {
- case (NULL, _) => NULL
- case (_, NULL) => NULL
- case (EMPTY, r) => r
- case (r, EMPTY) => r
+ case (ZERO, _) => ZERO
+ case (_, ZERO) => ZERO
+ case (ONE, r) => r
+ case (r, ONE) => r
case (r1, r2) => SEQ(r1, r2)
}
}
case class STAR(r: Rexp) extends Rexp {
override def simp = r.simp match {
- case NULL => EMPTY
- case EMPTY => EMPTY
+ case ZERO => ONE
+ case ONE => ONE
case r => STAR(r)
}
}
case class NTIMES(r: Rexp, n: Int) extends Rexp {
- override def simp = if (n == 0) EMPTY else
+ override def simp = if (n == 0) ONE else
r.simp match {
- case NULL => NULL
- case EMPTY => EMPTY
+ case ZERO => ZERO
+ case ONE => ONE
case r => NTIMES(r, n)
}
}
// some convenience for typing in regular expressions
def charlist2rexp(s : List[Char]) : Rexp = s match {
- case Nil => EMPTY
+ case Nil => ONE
case c::Nil => CHAR(c)
case c::s => SEQ(CHAR(c), charlist2rexp(s))
}
@@ -53,8 +53,8 @@
// nullable function: tests whether the regular
// expression can recognise the empty string
def nullable (r: Rexp) : Boolean = r match {
- case NULL => false
- case EMPTY => true
+ case ZERO => false
+ case ONE => true
case CHAR(_) => false
case ALT(r1, r2) => nullable(r1) || nullable(r2)
case SEQ(r1, r2) => nullable(r1) && nullable(r2)
@@ -64,16 +64,16 @@
// derivative of a regular expression w.r.t. a character
def der (c: Char, r: Rexp) : Rexp = r match {
- case NULL => NULL
- case EMPTY => NULL
- case CHAR(d) => if (c == d) EMPTY else NULL
+ case ZERO => ZERO
+ case ONE => ZERO
+ case CHAR(d) => if (c == d) ONE else ZERO
case ALT(r1, r2) => ALT(der(c, r1), der(c, r2))
case SEQ(r1, r2) =>
if (nullable(r1)) ALT(SEQ(der(c, r1), r2), der(c, r2))
else SEQ(der(c, r1), r2)
case STAR(r) => SEQ(der(c, r), STAR(r))
case NTIMES(r, i) =>
- if (i == 0) NULL else SEQ(der(c, r), NTIMES(r, i - 1))
+ if (i == 0) ZERO else SEQ(der(c, r), NTIMES(r, i - 1))
}
// derivative w.r.t. a string (iterates der)
@@ -83,12 +83,23 @@
case c::s => ders(s, der(c, r).simp)
}
+
+def ders2 (s: List[Char], r: Rexp) : Rexp = (s, r) match {
+ case (Nil, r) => r
+ case (s, ZERO) => ZERO
+ case (s, ONE) => if (s == Nil) ONE else ZERO
+ case (s, CHAR(c)) => if (s == List(c)) ONE else
+ if (s == Nil) CHAR(c) else ZERO
+ case (s, ALT(r1, r2)) => ALT(ders2(s, r2), ders2(s, r2))
+ case (c::s, r) => ders2(s, der(c, r).simp)
+}
+
// main matcher function
-def matcher(r: Rexp, s: String) : Boolean = nullable(ders(s.toList, r))
+def matcher(r: Rexp, s: String) : Boolean = nullable(ders2(s.toList, r))
//one or zero
-def OPT(r: Rexp) = ALT(r, EMPTY)
+def OPT(r: Rexp) = ALT(r, ONE)
def EVIL(n: Int) = SEQ(NTIMES(OPT("a"), n), NTIMES("a", n))
@@ -99,9 +110,11 @@
(end - start)/(i * 1.0e9)
}
+val i = 5000000
+println(i + " " + "%.5f".format(time_needed(10, matcher(EVIL(i), "a" * i))))
-for (i <- 1 to 12001 by 500) {
- println(i + " " + "%.5f".format(time_needed(1, matcher(EVIL(i), "a" * i))))
+for (i <- 1 to 800001 by 10000) {
+ println(i + " " + "%.5f".format(time_needed(10, matcher(EVIL(i), "a" * i))))
}