|    237   case SEQ(r1, r2) =>  1 + size_faulty(r1) + size_faulty(r2) |    237   case SEQ(r1, r2) =>  1 + size_faulty(r1) + size_faulty(r2) | 
|    238   case STAR(r) => 1 + size_faulty(r) - range(0, 2).generate |    238   case STAR(r) => 1 + size_faulty(r) - range(0, 2).generate | 
|    239 } |    239 } | 
|    240  |    240  | 
|    241  |    241  | 
|    242     |    242  | 
|    243 // some convenience for typing in regular expressions |    243 // some convenience for typing in regular expressions | 
|    244  |    244  | 
|    245 def charlist2rexp(s : List[Char]): Rexp = s match { |    245 def charlist2rexp(s : List[Char]): Rexp = s match { | 
|    246   case Nil => ONE |    246   case Nil => ONE | 
|    247   case c::Nil => CHAR(c) |    247   case c::Nil => CHAR(c) | 
|    248   case c::s => SEQ(CHAR(c), charlist2rexp(s)) |    248   case c::s => SEQ(CHAR(c), charlist2rexp(s)) | 
|    249 } |    249 } | 
|    250 implicit def string2rexp(s : String) : Rexp =  |    250 implicit def string2rexp(s : String) : Rexp =  | 
|    251   charlist2rexp(s.toList) |    251   charlist2rexp(s.toList) | 
|    252  |    252  | 
|    253 implicit def RexpOps(r: Rexp) = new { |    253   implicit def RexpOps(r: Rexp) = new { | 
|    254   def | (s: Rexp) = ALTS(r, s) |    254     def | (s: Rexp) = ALTS(r, s) | 
|    255   def % = STAR(r) |    255     def % = STAR(r) | 
|    256   def ~ (s: Rexp) = SEQ(r, s) |    256     def ~ (s: Rexp) = SEQ(r, s) | 
|    257 } |    257   } | 
|    258  |    258  | 
|    259 implicit def stringOps(s: String) = new { |    259   implicit def stringOps(s: String) = new { | 
|    260   def | (r: Rexp) = ALTS(s, r) |    260     def | (r: Rexp) = ALTS(s, r) | 
|    261   def | (r: String) = ALTS(s, r) |    261     def | (r: String) = ALTS(s, r) | 
|    262   def % = STAR(s) |    262     def % = STAR(s) | 
|    263   def ~ (r: Rexp) = SEQ(s, r) |    263     def ~ (r: Rexp) = SEQ(s, r) | 
|    264   def ~ (r: String) = SEQ(s, r) |    264     def ~ (r: String) = SEQ(s, r) | 
|    265   def $ (r: Rexp) = RECD(s, r) |    265     def $ (r: Rexp) = RECD(s, r) | 
|    266 } |    266   } | 
|    267  |    267  | 
|    268 def nullable(r: Rexp) : Boolean = r match { |    268   def nullable(r: Rexp) : Boolean = r match { | 
|    269   case ZERO => false |    269     case ZERO => false | 
|    270   case ONE => true |    270     case ONE => true | 
|    271   case CHAR(_) => false |    271     case CHAR(_) => false | 
|    272   case ANYCHAR => false |    272     case ANYCHAR => false | 
|    273   case ALTS(r1, r2) => nullable(r1) || nullable(r2) |    273     case ALTS(r1, r2) => nullable(r1) || nullable(r2) | 
|    274   case ALTSS(rs) => rs.exists(nullable) |    274     case ALTSS(rs) => rs.exists(nullable) | 
|    275   case SEQ(r1, r2) => nullable(r1) && nullable(r2) |    275     case SEQ(r1, r2) => nullable(r1) && nullable(r2) | 
|    276   case STAR(_) => true |    276     case STAR(_) => true | 
|    277   case RECD(_, r1) => nullable(r1) |    277     case RECD(_, r1) => nullable(r1) | 
|    278   case NTIMES(n, r) => if (n == 0) true else nullable(r) |    278     case NTIMES(n, r) => if (n == 0) true else nullable(r) | 
|    279   case OPTIONAL(r) => true |    279     case OPTIONAL(r) => true | 
|    280   case NOT(r) => !nullable(r) |    280     case NOT(r) => !nullable(r) | 
|    281 } |    281   } | 
|    282  |    282  | 
|    283 def der(c: Char, r: Rexp) : Rexp = r match { |    283   def der(c: Char, r: Rexp) : Rexp = r match { | 
|    284   case ZERO => ZERO |    284     case ZERO => ZERO | 
|    285   case ONE => ZERO |    285     case ONE => ZERO | 
|    286   case CHAR(d) => if (c == d) ONE else ZERO |    286     case CHAR(d) => if (c == d) ONE else ZERO | 
|    287   case ANYCHAR => ONE  |    287     case ANYCHAR => ONE  | 
|    288   case ALTS(r1, r2) => ALTS(der(c, r1), der(c, r2)) |    288     case ALTS(r1, r2) => ALTS(der(c, r1), der(c, r2)) | 
|    289   case ALTSS(rs) => ALTSS(rs.map(der(c, _))) |    289     case ALTSS(rs) => ALTSS(rs.map(der(c, _))) | 
|    290   case SEQ(r1, r2) =>  |    290     case SEQ(r1, r2) =>  | 
|    291     if (nullable(r1)) ALTS(SEQ(der(c, r1), r2), der(c, r2)) |    291       if (nullable(r1)) ALTS(SEQ(der(c, r1), r2), der(c, r2)) | 
|    292     else SEQ(der(c, r1), r2) |    292       else SEQ(der(c, r1), r2) | 
|    293   case STAR(r) => SEQ(der(c, r), STAR(r)) |    293     case STAR(r) => SEQ(der(c, r), STAR(r)) | 
|    294   case RECD(_, r1) => der(c, r1) |    294     case RECD(_, r1) => der(c, r1) | 
|    295   case NTIMES(n, r) => if(n > 0) SEQ(der(c, r), NTIMES(n - 1, r)) else ZERO |    295     case NTIMES(n, r) => if(n > 0) SEQ(der(c, r), NTIMES(n - 1, r)) else ZERO | 
|    296   case OPTIONAL(r) => der(c, r) |    296     case OPTIONAL(r) => der(c, r) | 
|    297   case NOT(r) =>  NOT(der(c, r)) |    297     case NOT(r) =>  NOT(der(c, r)) | 
|    298 } |    298   } | 
|    299  |    299  | 
|    300 def ders(s: List[Char], r: Rexp) : Rexp = s match { |    300   def ders(s: List[Char], r: Rexp) : Rexp = s match { | 
|    301   case Nil => r |    301     case Nil => r | 
|    302   case c :: cs => ders(cs, der(c, r)) |    302     case c :: cs => ders(cs, der(c, r)) | 
|    303 } |    303   } | 
|    304  |    304  | 
|    305 def ders_simp(s: List[Char], r: Rexp) : Rexp = s match { |    305   def ders_simp(s: List[Char], r: Rexp) : Rexp = s match { | 
|    306   case Nil => simp(r) |    306     case Nil => simp(r) | 
|    307   case c :: cs => ders_simp(cs, simp(der(c, r))) |    307     case c :: cs => ders_simp(cs, simp(der(c, r))) | 
|    308 } |    308   } | 
|    309  |    309  | 
|    310  |    310  | 
|    311 def simp2(r: Rexp) : Rexp = r match { |    311   def simp2(r: Rexp) : Rexp = r match { | 
|    312   case SEQ(r1, r2) =>  |    312     case SEQ(r1, r2) =>  | 
|    313     (simp2(r1), simp2(r2)) match { |    313       (simp2(r1), simp2(r2)) match { | 
|    314       case (ZERO, _) => ZERO |    314         case (ZERO, _) => ZERO | 
|    315       case (_, ZERO) => ZERO |    315         case (_, ZERO) => ZERO | 
|    316       case (ONE, r2s) => r2s |    316         case (ONE, r2s) => r2s | 
|    317       case (r1s, ONE) => r1s |    317         case (r1s, ONE) => r1s | 
|    318       case (r1s, r2s) =>  |    318         case (r1s, r2s) =>  | 
|    319         SEQ(r1s, r2s) |    319           SEQ(r1s, r2s) | 
|    320     } |    320       } | 
|    321   case ALTS(r1, r2) =>  |    321         case ALTS(r1, r2) =>  | 
|    322     val r1r2s = fltsplain(simp2(r1) :: simp2(r2) :: Nil).distinct  |    322           val r1r2s = fltsplain(simp2(r1) :: simp2(r2) :: Nil).distinct  | 
|    323     r1r2s match { |    323           r1r2s match { | 
|    324       case Nil => ZERO |    324             case Nil => ZERO | 
|    325       case r :: Nil => r |    325             case r :: Nil => r | 
|    326       case r1 :: r2 :: rs =>  |    326             case r1 :: r2 :: rs =>  | 
|    327         ALTSS(r1 :: r2 :: rs) |    327               ALTSS(r1 :: r2 :: rs) | 
|    328     } |    328           } | 
|    329   case ALTSS(rs) =>  |    329             case ALTSS(rs) =>  | 
|    330     // println(rs) |    330               // println(rs) | 
|    331     (fltsplain(rs.map(simp2))).distinct match { |    331               (fltsplain(rs.map(simp2))).distinct match { | 
|    332       case Nil => ZERO |    332                 case Nil => ZERO | 
|    333       case r :: Nil => r |    333                 case r :: Nil => r | 
|    334       case r1 :: r2 :: rs => |    334                 case r1 :: r2 :: rs => | 
|    335         ALTSS(r1 :: r2 :: rs) |    335                   ALTSS(r1 :: r2 :: rs) | 
|    336     } |    336               } | 
|    337   case r => r |    337                 case r => r | 
|    338 } |    338   } | 
|    339  |    339  | 
|    340  |    340  | 
|    341 def simp(r: Rexp) : Rexp = r match { |    341   def simp(r: Rexp) : Rexp = r match { | 
|    342   case SEQ(r1, r2) =>  |    342     case SEQ(r1, r2) =>  | 
|    343     (simp(r1), simp(r2)) match { |    343       (simp(r1), simp(r2)) match { | 
|    344       case (ZERO, _) => ZERO |    344         case (ZERO, _) => ZERO | 
|    345       case (_, ZERO) => ZERO |    345         case (_, ZERO) => ZERO | 
|    346       case (ONE, r2s) => r2s |    346         case (ONE, r2s) => r2s | 
|    347       case (r1s, ONE) => r1s |    347         case (r1s, ONE) => r1s | 
|    348       case (r1s, r2s) => SEQ(r1s, r2s) |    348         case (r1s, r2s) => SEQ(r1s, r2s) | 
|    349     } |    349       } | 
|    350   case ALTS(r1, r2) => { |    350         case ALTS(r1, r2) => { | 
|    351     (simp(r1), simp(r2)) match { |    351           (simp(r1), simp(r2)) match { | 
|    352       case (ZERO, r2s) => r2s |    352             case (ZERO, r2s) => r2s | 
|    353       case (r1s, ZERO) => r1s |    353             case (r1s, ZERO) => r1s | 
|    354       case (r1s, r2s) => |    354             case (r1s, r2s) => | 
|    355         if(r1s == r2s) r1s else ALTS(r1s, r2s) |    355               if(r1s == r2s) r1s else ALTS(r1s, r2s) | 
|    356     } |    356           } | 
|    357   } |    357         } | 
|    358   case r => r |    358             case r => r | 
|    359 } |    359   } | 
|    360  |    360  | 
|    361 def fltsplain(rs: List[Rexp]) : List[Rexp] = rs match { |    361   def fltsplain(rs: List[Rexp]) : List[Rexp] = rs match { | 
|    362   case Nil => Nil |    362     case Nil => Nil | 
|    363   case ZERO :: rs => fltsplain(rs) |    363     case ZERO :: rs => fltsplain(rs) | 
|    364   case ALTS(r1, r2) :: rs => r1 :: r2 :: fltsplain(rs)  |    364     case ALTS(r1, r2) :: rs => r1 :: r2 :: fltsplain(rs)  | 
|    365   case ALTSS(rs) :: rs1 => rs ::: fltsplain(rs1) |    365     case ALTSS(rs) :: rs1 => rs ::: fltsplain(rs1) | 
|    366   case r :: rs => r :: fltsplain(rs) |    366     case r :: rs => r :: fltsplain(rs) | 
|    367 } |    367   } | 
|    368  |    368  | 
|    369  |    369  | 
|    370  |    370  | 
|    371  |    371  | 
|    372 def matcher(s: String, r: Rexp) : Boolean =  |    372   def matcher(s: String, r: Rexp) : Boolean =  | 
|    373   nullable(ders(s.toList, r)) |    373     nullable(ders(s.toList, r)) | 
|    374  |    374  | 
|    375 def simp_matcher(s: String, r: Rexp) : Boolean =  |    375   def simp_matcher(s: String, r: Rexp) : Boolean =  | 
|    376   nullable(ders_simp(s.toList, r)) |    376     nullable(ders_simp(s.toList, r)) | 
|    377  |    377  | 
|    378  |    378  | 
|    379 // extracts a string from a value |    379   // extracts a string from a value | 
|    380 def flatten(v: Val) : String = v match { |    380   def flatten(v: Val) : String = v match { | 
|    381   case Empty => "" |    381     case Empty => "" | 
|    382   case Chr(c) => c.toString |    382     case Chr(c) => c.toString | 
|    383   case Left(v) => flatten(v) |    383     case Left(v) => flatten(v) | 
|    384   case Right(v) => flatten(v) |    384     case Right(v) => flatten(v) | 
|    385   case Sequ(v1, v2) => flatten(v1) ++ flatten(v2) |    385     case Sequ(v1, v2) => flatten(v1) ++ flatten(v2) | 
|    386   case Stars(vs) => vs.map(flatten).mkString |    386     case Stars(vs) => vs.map(flatten).mkString | 
|    387   case Ntime(vs) => vs.map(flatten).mkString |    387     case Ntime(vs) => vs.map(flatten).mkString | 
|    388   case Optionall(v) => flatten(v) |    388     case Optionall(v) => flatten(v) | 
|    389   case Rec(_, v) => flatten(v) |    389     case Rec(_, v) => flatten(v) | 
|    390 } |    390   } | 
|    391  |    391  | 
|    392  |    392  | 
|    393 // extracts an environment from a value; |    393   // extracts an environment from a value; | 
|    394 // used for tokenising a string |    394   // used for tokenising a string | 
|    395 def env(v: Val) : List[(String, String)] = v match { |    395   def env(v: Val) : List[(String, String)] = v match { | 
|    396   case Empty => Nil |    396     case Empty => Nil | 
|    397   case Chr(c) => Nil |    397     case Chr(c) => Nil | 
|    398   case Left(v) => env(v) |    398     case Left(v) => env(v) | 
|    399   case Right(v) => env(v) |    399     case Right(v) => env(v) | 
|    400   case Sequ(v1, v2) => env(v1) ::: env(v2) |    400     case Sequ(v1, v2) => env(v1) ::: env(v2) | 
|    401   case Stars(vs) => vs.flatMap(env) |    401     case Stars(vs) => vs.flatMap(env) | 
|    402   case Ntime(vs) => vs.flatMap(env) |    402     case Ntime(vs) => vs.flatMap(env) | 
|    403   case Rec(x, v) => (x, flatten(v))::env(v) |    403     case Rec(x, v) => (x, flatten(v))::env(v) | 
|    404   case Optionall(v) => env(v) |    404     case Optionall(v) => env(v) | 
|    405   case Nots(s) => ("Negative", s) :: Nil |    405     case Nots(s) => ("Negative", s) :: Nil | 
|    406 } |    406   } | 
|    407  |    407  | 
|    408  |    408  | 
|    409 // The injection and mkeps part of the lexer |    409   // The injection and mkeps part of the lexer | 
|    410 //=========================================== |    410   //=========================================== | 
|    411  |    411  | 
|    412 def mkeps(r: Rexp) : Val = r match { |    412   def mkeps(r: Rexp) : Val = r match { | 
|    413   case ONE => Empty |    413     case ONE => Empty | 
|    414   case ALTS(r1, r2) =>  |    414     case ALTS(r1, r2) =>  | 
|    415     if (nullable(r1)) Left(mkeps(r1)) else Right(mkeps(r2)) |    415       if (nullable(r1)) Left(mkeps(r1)) else Right(mkeps(r2)) | 
|    416   case SEQ(r1, r2) => Sequ(mkeps(r1), mkeps(r2)) |    416     case SEQ(r1, r2) => Sequ(mkeps(r1), mkeps(r2)) | 
|    417   case STAR(r) => Stars(Nil) |    417     case STAR(r) => Stars(Nil) | 
|    418   case RECD(x, r) => Rec(x, mkeps(r)) |    418     case RECD(x, r) => Rec(x, mkeps(r)) | 
|    419   case NTIMES(n, r) => Ntime(List.fill(n)(mkeps(r))) |    419     case NTIMES(n, r) => Ntime(List.fill(n)(mkeps(r))) | 
|    420   case OPTIONAL(r) => Optionall(Empty) |    420     case OPTIONAL(r) => Optionall(Empty) | 
|    421   case NOT(rInner) => if(nullable(rInner)) throw new Exception("error")   |    421     case NOT(rInner) => if(nullable(rInner)) throw new Exception("error")   | 
|    422                          else Nots("")//Nots(s.reverse.toString) |    422     else Nots("")//Nots(s.reverse.toString) | 
|    423 //   case NOT(ZERO) => Empty |    423     //   case NOT(ZERO) => Empty | 
|    424 //   case NOT(CHAR(c)) => Empty |    424     //   case NOT(CHAR(c)) => Empty | 
|    425 //   case NOT(SEQ(r1, r2)) => Sequ(mkeps(NOT(r1)), mkeps(NOT(r2))) |    425     //   case NOT(SEQ(r1, r2)) => Sequ(mkeps(NOT(r1)), mkeps(NOT(r2))) | 
|    426 //   case NOT(ALTS(r1, r2)) => if(!nullable(r1)) Left(mkeps(NOT(r1))) else Right(mkeps(NOT(r2))) |    426     //   case NOT(ALTS(r1, r2)) => if(!nullable(r1)) Left(mkeps(NOT(r1))) else Right(mkeps(NOT(r2))) | 
|    427 //   case NOT(STAR(r)) => Stars(Nil)  |    427     //   case NOT(STAR(r)) => Stars(Nil)  | 
|    428  |    428  | 
|    429 } |    429   } | 
|    430  |    430  | 
|    431 def inj(r: Rexp, c: Char, v: Val) : Val = (r, v) match { |    431   def inj(r: Rexp, c: Char, v: Val) : Val = (r, v) match { | 
|    432   case (STAR(r), Sequ(v1, Stars(vs))) => Stars(inj(r, c, v1)::vs) |    432     case (STAR(r), Sequ(v1, Stars(vs))) => Stars(inj(r, c, v1)::vs) | 
|    433   case (SEQ(r1, r2), Sequ(v1, v2)) => Sequ(inj(r1, c, v1), v2) |    433     case (SEQ(r1, r2), Sequ(v1, v2)) => Sequ(inj(r1, c, v1), v2) | 
|    434   case (SEQ(r1, r2), Left(Sequ(v1, v2))) => Sequ(inj(r1, c, v1), v2) |    434     case (SEQ(r1, r2), Left(Sequ(v1, v2))) => Sequ(inj(r1, c, v1), v2) | 
|    435   case (SEQ(r1, r2), Right(v2)) => Sequ(mkeps(r1), inj(r2, c, v2)) |    435     case (SEQ(r1, r2), Right(v2)) => Sequ(mkeps(r1), inj(r2, c, v2)) | 
|    436   case (ALTS(r1, r2), Left(v1)) => Left(inj(r1, c, v1)) |    436     case (ALTS(r1, r2), Left(v1)) => Left(inj(r1, c, v1)) | 
|    437   case (ALTS(r1, r2), Right(v2)) => Right(inj(r2, c, v2)) |    437     case (ALTS(r1, r2), Right(v2)) => Right(inj(r2, c, v2)) | 
|    438   case (CHAR(d), Empty) => Chr(c)  |    438     case (CHAR(d), Empty) => Chr(c)  | 
|    439   case (RECD(x, r1), _) => Rec(x, inj(r1, c, v)) |    439     case (RECD(x, r1), _) => Rec(x, inj(r1, c, v)) | 
|    440   case (NTIMES(n, r), Sequ(v1, Ntime(vs))) => Ntime(inj(r, c, v1)::vs) |    440     case (NTIMES(n, r), Sequ(v1, Ntime(vs))) => Ntime(inj(r, c, v1)::vs) | 
|    441   case (OPTIONAL(r), v) => Optionall(inj(r, c, v)) |    441     case (OPTIONAL(r), v) => Optionall(inj(r, c, v)) | 
|    442   case (NOT(r), Nots(s)) => Nots(c.toString ++ s) |    442     case (NOT(r), Nots(s)) => Nots(c.toString ++ s) | 
|    443   case (ANYCHAR, Empty) => Chr(c) |    443     case (ANYCHAR, Empty) => Chr(c) | 
|    444 } |    444   } | 
|    445  |    445  | 
|    446 // some "rectification" functions for simplification |    446   // some "rectification" functions for simplification | 
|    447  |    447  | 
|    448  |    448  | 
|    449  |    449  | 
|    450  |    450  | 
|    451 // The Lexing Rules for the WHILE Language |    451   // The Lexing Rules for the WHILE Language | 
|    452  |    452  | 
|    453   // bnullable function: tests whether the aregular  |    453   // bnullable function: tests whether the aregular  | 
|    454   // expression can recognise the empty string |    454   // expression can recognise the empty string | 
|    455 def bnullable (r: ARexp) : Boolean = r match { |    455   def bnullable (r: ARexp) : Boolean = r match { | 
|    456     case AZERO => false |    456     case AZERO => false | 
|    457     case AONE(_) => true |    457     case AONE(_) => true | 
|    458     case ACHAR(_,_) => false |    458     case ACHAR(_,_) => false | 
|    459     case AALTS(_, rs) => rs.exists(bnullable) |    459     case AALTS(_, rs) => rs.exists(bnullable) | 
|    460     case ASEQ(_, r1, r2) => bnullable(r1) && bnullable(r2) |    460     case ASEQ(_, r1, r2) => bnullable(r1) && bnullable(r2) | 
|    461     case ASTAR(_, _) => true |    461     case ASTAR(_, _) => true | 
|    462     case ANOT(_, rn) => !bnullable(rn) |    462     case ANOT(_, rn) => !bnullable(rn) | 
|    463   } |    463   } | 
|    464  |    464  | 
|    465 def mkepsBC(r: ARexp) : Bits = r match { |    465   def mkepsBC(r: ARexp) : Bits = r match { | 
|    466     case AONE(bs) => bs |    466     case AONE(bs) => bs | 
|    467     case AALTS(bs, rs) => { |    467     case AALTS(bs, rs) => { | 
|    468       val n = rs.indexWhere(bnullable) |    468       val n = rs.indexWhere(bnullable) | 
|    469       bs ++ mkepsBC(rs(n)) |    469       bs ++ mkepsBC(rs(n)) | 
|    470     } |    470     } | 
|    587           (dist_res) match { |    587           (dist_res) match { | 
|    588             case Nil => AZERO |    588             case Nil => AZERO | 
|    589             case s :: Nil => fuse(bs1, s) |    589             case s :: Nil => fuse(bs1, s) | 
|    590             case rs => AALTS(bs1, rs)   |    590             case rs => AALTS(bs1, rs)   | 
|    591           } |    591           } | 
|    592     } |    592         } | 
|    593     case r => r |    593             case r => r | 
|    594   } |    594     } | 
|    595 } |    595   } | 
|    596  |    596  | 
|    597 def strongBsimp6(r: ARexp): ARexp = |    597   def strongBsimp6(r: ARexp): ARexp = | 
|    598 { |    598   { | 
|    599   // println("was this called?") |    599     // println("was this called?") | 
|    600   r match { |    600     r match { | 
|    601     case ASEQ(bs1, r1, r2) => (strongBsimp6(r1), strongBsimp6(r2)) match { |    601       case ASEQ(bs1, r1, r2) => (strongBsimp6(r1), strongBsimp6(r2)) match { | 
|    602         case (AZERO, _) => AZERO |    602         case (AZERO, _) => AZERO | 
|    603         case (_, AZERO) => AZERO |    603         case (_, AZERO) => AZERO | 
|    604         case (AONE(bs2), r2s) => fuse(bs1 ++ bs2, r2s) |    604         case (AONE(bs2), r2s) => fuse(bs1 ++ bs2, r2s) | 
|    605         case (r1s, AONE(bs2)) => fuse(bs1, r1s) //asserted bs2 == Nil |    605         case (r1s, AONE(bs2)) => fuse(bs1, r1s) //asserted bs2 == Nil | 
|    606         //case (r1s, r2s) if(isOne(erase(r1s))) => fuse(bs1 ++ mkepsBC(r1s), r2s) |    606         //case (r1s, r2s) if(isOne(erase(r1s))) => fuse(bs1 ++ mkepsBC(r1s), r2s) | 
|    607         case (r1s, r2s) => ASEQ(bs1, r1s, r2s) |    607         case (r1s, r2s) => ASEQ(bs1, r1s, r2s) | 
|    608     } |    608       } | 
|    609     case AALTS(bs1, rs) => { |    609         case AALTS(bs1, rs) => { | 
|    610         // println("alts case") |    610           // println("alts case") | 
|    611           val rs_simp = rs.map(strongBsimp6(_)) |    611           val rs_simp = rs.map(strongBsimp6(_)) | 
|    612           val flat_res = flats(rs_simp) |    612           val flat_res = flats(rs_simp) | 
|    613           var dist_res = distinctBy6(flat_res)//distinctBy(flat_res, erase) |    613           var dist_res = distinctBy6(flat_res)//distinctBy(flat_res, erase) | 
|    614           (dist_res) match { |    614           (dist_res) match { | 
|    615             case Nil => AZERO |    615             case Nil => AZERO | 
|    616             case s :: Nil => fuse(bs1, s) |    616             case s :: Nil => fuse(bs1, s) | 
|    617             case rs => AALTS(bs1, rs)   |    617             case rs => AALTS(bs1, rs)   | 
|    618           } |    618           } | 
|    619     } |    619         } | 
|    620     //(erase(r0))) => AONE(bs) |    620         //(erase(r0))) => AONE(bs) | 
|    621     case r => r |    621             case r => r | 
|    622   } |    622     } | 
|    623 } |    623   } | 
|    624  |    624  | 
|    625 def distinctWith(rs: List[ARexp],  |    625  | 
|    626                 pruneFunction: (ARexp, Set[Rexp]) => ARexp,  |    626     def atMostEmpty(r: Rexp) : Boolean = r match { | 
|    627                 acc: Set[Rexp] = Set()) : List[ARexp] =  |    627       case ZERO => true | 
|    628   rs match{ |    628       case ONE => true | 
|    629     case Nil => Nil |    629       case STAR(r) => atMostEmpty(r) | 
|    630     case r :: rs =>  |    630       case SEQ(r1, r2) => atMostEmpty(r1) && atMostEmpty(r2) | 
|    631       if(acc(erase(r))) |    631       case ALTS(r1, r2) => atMostEmpty(r1) && atMostEmpty(r2) | 
|    632         distinctWith(rs, pruneFunction, acc) |    632       case CHAR(_) => false | 
|    633       else { |    633     } | 
|    634         val pruned_r = pruneFunction(r, acc) |    634  | 
|    635         pruned_r ::  |    635  | 
|    636         distinctWith(rs,  |    636     def isOne(r: Rexp) : Boolean = r match { | 
|    637           pruneFunction,  |    637       case ONE => true | 
|    638           turnIntoTerms(erase(pruned_r)) ++: acc |    638       case SEQ(r1, r2) => isOne(r1) && isOne(r2) | 
|    639         ) |    639       case ALTS(r1, r2) => (isOne(r1) || isOne(r2)) && (atMostEmpty(r1) && atMostEmpty(r2))//rs.forall(atMostEmpty) && rs.exists(isOne) | 
|    640       } |    640       case STAR(r0) => atMostEmpty(r0) | 
|    641   } |    641       case CHAR(c) => false | 
|    642  |    642       case ZERO => false | 
|    643 // def distinctByPlus(rs: List[ARexp], acc: Set[Rexp] = Set()) :  |    643     } | 
|    644 // List[ARexp] =  rs match { |    644  | 
|    645 //   case Nil => Nil |    645   def distinctWith(rs: List[ARexp],  | 
|    646 //   case r :: rs => |    646     pruneFunction: (ARexp, Set[Rexp]) => ARexp,  | 
|    647 //     if(acc.contains(erase(r))) |    647     acc: Set[Rexp] = Set()) : List[ARexp] =  | 
|    648 //       distinctByPlus(rs, acc) |    648       rs match{ | 
|    649 //     else  |    649         case Nil => Nil | 
|    650 //       prune(r, acc) :: distinctByPlus(rs, prune(r, acc) +: acc) |    650         case r :: rs =>  | 
|    651 // } |    651           if(acc(erase(r))) | 
|    652  |    652             distinctWith(rs, pruneFunction, acc) | 
|    653 //r = r' ~ tail => returns r' |    653           else { | 
|    654 def removeSeqTail(r: Rexp, tail: Rexp) : Rexp = r match { |    654             val pruned_r = pruneFunction(r, acc) | 
|    655   case SEQ(r1, r2) =>  |    655             pruned_r ::  | 
|    656     if(r2 == tail)  |    656             distinctWith(rs,  | 
|    657       r1 |    657               pruneFunction,  | 
|    658     else |    658               turnIntoTerms(erase(pruned_r)) ++: acc | 
|    659       ZERO |    659               ) | 
|    660   case r => ZERO |    660           } | 
|    661 } |    661       } | 
|    662  |    662  | 
|    663 def prune7(r: ARexp, acc: Set[Rexp]) : ARexp = r match{ |    663     //r = r' ~ tail' : If tail' matches tail => returns r' | 
|    664   case AALTS(bs, rs) => rs.map(r => prune7(r, acc)).filter(_ != ZERO) match |    664     def removeSeqTail(r: Rexp, tail: Rexp) : Rexp = r match { | 
|    665   { |    665       case SEQ(r1, r2) =>  | 
|    666     case Nil => AZERO |    666         if(r2 == tail)  | 
|    667     case r::Nil => fuse(bs, r) |    667           r1 | 
|    668     case rs1 => AALTS(bs, rs1) |    668         else | 
|    669   } |    669           ZERO | 
|    670   case ASEQ(bs, r1, r2) => prune7(r1, acc.map(r => removeSeqTail(r, erase(r2)))) match { |    670       case r => ZERO | 
|    671     case AZERO => AZERO |    671     } | 
|    672     case r1p if(isOne(erase(r1p))) => fuse(bs ++ mkepsBC(r1p), r2) |    672  | 
|    673     case r1p => ASEQ(bs, r1p, r2) |    673     def prune(r: ARexp, acc: Set[Rexp]) : ARexp = r match{ | 
|    674   } |    674       case AALTS(bs, rs) => rs.map(r => prune(r, acc)).filter(_ != ZERO) match | 
|    675   case r => if(acc(erase(r))) AZERO else r |    675       { | 
|    676 } |    676         //all components have been removed, meaning this is effectively a duplicate | 
|    677  |    677         //flats will take care of removing this AZERO  | 
|    678 def strongBsimp7(r: ARexp): ARexp = |    678         case Nil => AZERO | 
|    679 { |    679         case r::Nil => fuse(bs, r) | 
|    680   r match { |    680         case rs1 => AALTS(bs, rs1) | 
|    681     case ASEQ(bs1, r1, r2) => (strongBsimp7(r1), strongBsimp7(r2)) match { |    681       } | 
|         |    682       case ASEQ(bs, r1, r2) =>  | 
|         |    683         //remove the r2 in (ra + rb)r2 to identify the duplicate contents of r1 | 
|         |    684         prune(r1, acc.map(r => removeSeqTail(r, erase(r2)))) match { | 
|         |    685           //after pruning, returns 0 | 
|         |    686           case AZERO => AZERO | 
|         |    687           //after pruning, got r1'.r2, where r1' is equal to 1 | 
|         |    688           case r1p if(isOne(erase(r1p))) => fuse(bs ++ mkepsBC(r1p), r2) | 
|         |    689           //assemble the pruned head r1p with r2 | 
|         |    690           case r1p => ASEQ(bs, r1p, r2) | 
|         |    691         } | 
|         |    692         //this does the duplicate component removal task | 
|         |    693       case r => if(acc(erase(r))) AZERO else r | 
|         |    694     } | 
|         |    695  | 
|         |    696     //a stronger version of simp | 
|         |    697     def bsimpStrong(r: ARexp): ARexp = | 
|         |    698     { | 
|         |    699       r match { | 
|         |    700         case ASEQ(bs1, r1, r2) => (bsimpStrong(r1), bsimpStrong(r2)) match { | 
|         |    701           //normal clauses same as simp | 
|    682         case (AZERO, _) => AZERO |    702         case (AZERO, _) => AZERO | 
|    683         case (_, AZERO) => AZERO |    703         case (_, AZERO) => AZERO | 
|    684         case (AONE(bs2), r2s) => fuse(bs1 ++ bs2, r2s) |    704         case (AONE(bs2), r2s) => fuse(bs1 ++ bs2, r2s) | 
|    685         case (r1s, AONE(bs2)) => fuse(bs1, r1s) //asserted bs2 == Nil |    705         //bs2 can be discarded | 
|    686         //case (r1s, r2s) if(isOne(erase(r1s))) => fuse(bs1 ++ mkepsBC(r1s), r2s) |    706         case (r1s, AONE(bs2)) => fuse(bs1, r1s) //assert bs2 == Nil | 
|    687         case (r1s, r2s) => ASEQ(bs1, r1s, r2s) |    707         case (r1s, r2s) => ASEQ(bs1, r1s, r2s) | 
|    688     } |    708         } | 
|    689     case AALTS(bs1, rs) => { |    709         case AALTS(bs1, rs) => { | 
|    690         // println("alts case") |    710           //distinctBy(flat_res, erase) | 
|    691           val rs_simp = rs.map(strongBsimp7(_)) |    711           distinctWith(flats(rs.map(bsimpStrong(_))), prune) match { | 
|    692           val flat_res = flats(rs_simp) |         | 
|    693           var dist_res = distinctWith(flat_res, prune7)//distinctBy(flat_res, erase) |         | 
|    694           (dist_res) match { |         | 
|    695             case Nil => AZERO |    712             case Nil => AZERO | 
|    696             case s :: Nil => fuse(bs1, s) |    713             case s :: Nil => fuse(bs1, s) | 
|    697             case rs => AALTS(bs1, rs)   |    714             case rs => AALTS(bs1, rs)   | 
|    698           } |    715           } | 
|    699     } |    716         } | 
|    700     case ASTAR(bs, r0) if(atMostEmpty(erase(r0))) => AONE(bs) |    717         //stars that can be treated as 1 | 
|    701     case r => r |    718         case ASTAR(bs, r0) if(atMostEmpty(erase(r0))) => AONE(bs) | 
|    702   } |    719         case r => r | 
|    703 } |    720       } | 
|    704  |    721     } | 
|    705  |    722  | 
|    706 def bders (s: List[Char], r: ARexp) : ARexp = s match { |    723  | 
|    707   case Nil => r |    724     def bders (s: List[Char], r: ARexp) : ARexp = s match { | 
|    708   case c::s => bders(s, bder(c, r)) |    725       case Nil => r | 
|    709 } |    726       case c::s => bders(s, bder(c, r)) | 
|    710  |    727     } | 
|    711 def flats(rs: List[ARexp]): List[ARexp] = rs match { |    728  | 
|    712     case Nil => Nil |    729     def flats(rs: List[ARexp]): List[ARexp] = rs match { | 
|    713     case AZERO :: rs1 => flats(rs1) |    730       case Nil => Nil | 
|    714     case AALTS(bs, rs1) :: rs2 => rs1.map(fuse(bs, _)) ::: flats(rs2) |    731       case AZERO :: rs1 => flats(rs1) | 
|    715     case r1 :: rs2 => r1 :: flats(rs2) |    732       case AALTS(bs, rs1) :: rs2 => rs1.map(fuse(bs, _)) ::: flats(rs2) | 
|    716   } |    733       case r1 :: rs2 => r1 :: flats(rs2) | 
|    717  |    734     } | 
|    718 def distinctBy[B, C](xs: List[B], f: B => C, acc: List[C] = Nil): List[B] = xs match { |    735  | 
|    719   case Nil => Nil |    736     def distinctBy[B, C](xs: List[B], f: B => C, acc: List[C] = Nil): List[B] = xs match { | 
|    720   case (x::xs) => { |    737       case Nil => Nil | 
|    721     val res = f(x) |    738       case (x::xs) => { | 
|    722     if (acc.contains(res)) distinctBy(xs, f, acc)   |    739         val res = f(x) | 
|    723     else x::distinctBy(xs, f, res::acc) |    740         if (acc.contains(res)) distinctBy(xs, f, acc)   | 
|    724   } |    741         else x::distinctBy(xs, f, res::acc) | 
|    725 }  |    742       } | 
|    726  |    743     }  | 
|    727  |    744  | 
|    728 def pruneRexp(r: ARexp, allowableTerms: List[Rexp]) : ARexp = { |    745  | 
|    729   r match { |    746     def pruneRexp(r: ARexp, allowableTerms: List[Rexp]) : ARexp = { | 
|    730     case ASEQ(bs, r1, r2) =>  |    747       r match { | 
|    731       val termsTruncated = allowableTerms.collect(rt => rt match { |    748         case ASEQ(bs, r1, r2) =>  | 
|    732         case SEQ(r1p, r2p) if(r2p == erase(r2)) => r1p//if(r2p == erase(r2))  |    749           val termsTruncated = allowableTerms.collect(rt => rt match { | 
|         |    750             case SEQ(r1p, r2p) if(r2p == erase(r2)) => r1p//if(r2p == erase(r2))  | 
|         |    751           }) | 
|         |    752           val pruned : ARexp = pruneRexp(r1, termsTruncated) | 
|         |    753           pruned match { | 
|         |    754             case AZERO => AZERO | 
|         |    755             case AONE(bs1) => fuse(bs ++ bs1, r2) | 
|         |    756             case pruned1 => ASEQ(bs, pruned1, r2) | 
|         |    757           } | 
|         |    758  | 
|         |    759             case AALTS(bs, rs) =>  | 
|         |    760               //allowableTerms.foreach(a => println(shortRexpOutput(a)))         | 
|         |    761               val rsp = rs.map(r =>  | 
|         |    762                   pruneRexp(r, allowableTerms) | 
|         |    763                   ) | 
|         |    764                     .filter(r => r != AZERO) | 
|         |    765                     rsp match { | 
|         |    766                       case Nil => AZERO | 
|         |    767                       case r1::Nil => fuse(bs, r1) | 
|         |    768                       case rs1 => AALTS(bs, rs1) | 
|         |    769                     } | 
|         |    770                       case r =>  | 
|         |    771                         if(allowableTerms.contains(erase(r))) r else AZERO //assert(r != AZERO) | 
|         |    772       } | 
|         |    773     } | 
|         |    774  | 
|         |    775     def oneSimp(r: Rexp) : Rexp = r match { | 
|         |    776       case SEQ(ONE, r) => r | 
|         |    777       case SEQ(r1, r2) => SEQ(oneSimp(r1), r2) | 
|         |    778       case r => r//assert r != 0  | 
|         |    779  | 
|         |    780     } | 
|         |    781  | 
|         |    782  | 
|         |    783     def distinctBy4(xs: List[ARexp], acc: List[Rexp] = Nil) : List[ARexp] = xs match { | 
|         |    784       case Nil => Nil | 
|         |    785       case x :: xs => | 
|         |    786         //assert(acc.distinct == acc) | 
|         |    787         val erased = erase(x) | 
|         |    788         if(acc.contains(erased)) | 
|         |    789           distinctBy4(xs, acc) | 
|         |    790         else{ | 
|         |    791           val addToAcc =  breakIntoTerms(erased).filter(r => !acc.contains(oneSimp(r))) | 
|         |    792           //val xp = pruneRexp(x, addToAcc) | 
|         |    793           pruneRexp(x, addToAcc) match { | 
|         |    794             case AZERO => distinctBy4(xs, addToAcc.map(oneSimp(_)) ::: acc) | 
|         |    795             case xPrime => xPrime :: distinctBy4(xs, addToAcc.map(oneSimp(_)) ::: acc) | 
|         |    796           } | 
|         |    797         } | 
|         |    798     } | 
|         |    799  | 
|         |    800     // fun pAKC_aux :: "arexp list ⇒ arexp ⇒ rexp ⇒ arexp" | 
|         |    801     //   where | 
|         |    802     // "pAKC_aux rsa r ctx = (if (seqFold (SEQ (erase r) ( ctx) )) ⊆ (seqFold (erase (AALTs [] rsa))) then AZERO else | 
|         |    803     //                           case r of (ASEQ bs r1 r2) ⇒  | 
|         |    804     //                             bsimp_ASEQ bs (pAKC_aux rsa r1 (SEQ  (erase r2) ( ctx) )) r2   | | 
|         |    805     //                                     (AALTs bs rs) ⇒  | 
|         |    806     //                             bsimp_AALTs bs (flts (map (λr. pAKC_aux rsa r ( ctx) ) rs) )    | | 
|         |    807     //                                     r             ⇒ r | 
|         |    808  | 
|         |    809     // def canonicalSeq(rs: List[Rexp], acc: Rexp) = rs match { | 
|         |    810     //   case r::Nil => SEQ(r, acc) | 
|         |    811     //   case Nil => acc | 
|         |    812     //   case r1::r2::Nil => SEQ(SEQ(r1, r2), acc) | 
|         |    813     // } | 
|         |    814  | 
|         |    815  | 
|         |    816     //the "fake" Language interpretation: just concatenates! | 
|         |    817     def seqFold(acc: Rexp, rs: List[Rexp]) : Rexp = rs match { | 
|         |    818       case Nil => acc | 
|         |    819       case r :: rs1 =>  | 
|         |    820         // if(acc == ONE)  | 
|         |    821         //   seqFold(r, rs1)  | 
|         |    822         // else | 
|         |    823         seqFold(SEQ(acc, r), rs1) | 
|         |    824     } | 
|         |    825  | 
|         |    826     def rprint(r: Rexp) : Unit = println(shortRexpOutput(r)) | 
|         |    827     def rsprint(rs: Iterable[Rexp]) = rs.foreach(r => println(shortRexpOutput(r))) | 
|         |    828  | 
|         |    829     def aprint(a: ARexp) = println(shortRexpOutput(erase(a))) | 
|         |    830     def asprint(as: List[ARexp]) = as.foreach(a => println(shortRexpOutput(erase(a)))) | 
|         |    831  | 
|         |    832     def pAKC(acc: List[Rexp], r: ARexp, ctx: List[Rexp]) : ARexp = { | 
|         |    833       // println("pakc") | 
|         |    834       // println(shortRexpOutput(erase(r))) | 
|         |    835       // println("acc") | 
|         |    836       // rsprint(acc) | 
|         |    837       // println("ctx---------") | 
|         |    838       // rsprint(ctx) | 
|         |    839       // println("ctx---------end") | 
|         |    840       // rsprint(breakIntoTerms(seqFold(erase(r), ctx)).map(oneSimp)) | 
|         |    841  | 
|         |    842       if (breakIntoTerms(seqFold(erase(r), ctx)).map(oneSimp).forall(acc.contains)) {//acc.flatMap(breakIntoTerms | 
|         |    843         AZERO | 
|         |    844       } | 
|         |    845       else{ | 
|         |    846         r match { | 
|         |    847           case ASEQ(bs, r1, r2) =>  | 
|         |    848             (pAKC(acc, r1, erase(r2) :: ctx)) match{ | 
|         |    849               case AZERO =>  | 
|         |    850                 AZERO | 
|         |    851               case AONE(bs1) =>  | 
|         |    852                 fuse(bs1, r2) | 
|         |    853               case r1p =>  | 
|         |    854                 ASEQ(bs, r1p, r2) | 
|         |    855             } | 
|         |    856               case AALTS(bs, rs0) =>  | 
|         |    857                 // println("before pruning") | 
|         |    858                 // println(s"ctx is ") | 
|         |    859                 // ctx.foreach(r => println(shortRexpOutput(r))) | 
|         |    860                 // println(s"rs0 is ") | 
|         |    861                 // rs0.foreach(r => println(shortRexpOutput(erase(r)))) | 
|         |    862                 // println(s"acc is ") | 
|         |    863                 // acc.foreach(r => println(shortRexpOutput(r))) | 
|         |    864                 rs0.map(r => pAKC(acc, r, ctx)).filter(_ != AZERO) match { | 
|         |    865                   case Nil =>  | 
|         |    866                     // println("after pruning Nil") | 
|         |    867                     AZERO | 
|         |    868                   case r :: Nil =>  | 
|         |    869                     // println("after pruning singleton") | 
|         |    870                     // println(shortRexpOutput(erase(r))) | 
|         |    871                     r  | 
|         |    872                   case rs0p =>  | 
|         |    873                     // println("after pruning non-singleton") | 
|         |    874                     AALTS(bs, rs0p) | 
|         |    875                 } | 
|         |    876                   case r => r | 
|         |    877         } | 
|         |    878       } | 
|         |    879     } | 
|         |    880  | 
|         |    881     def distinctBy5(xs: List[ARexp], acc: List[Rexp] = Nil) : List[ARexp] = xs match { | 
|         |    882       case Nil =>  | 
|         |    883         Nil | 
|         |    884       case x :: xs => { | 
|         |    885         val erased = erase(x) | 
|         |    886         if(acc.contains(erased)){ | 
|         |    887           distinctBy5(xs, acc) | 
|         |    888         } | 
|         |    889         else{ | 
|         |    890           val pruned = pAKC(acc, x, Nil) | 
|         |    891           val newTerms = breakIntoTerms(erase(pruned)) | 
|         |    892           pruned match { | 
|         |    893             case AZERO =>  | 
|         |    894               distinctBy5(xs, acc) | 
|         |    895             case xPrime =>  | 
|         |    896               xPrime :: distinctBy5(xs, newTerms.map(oneSimp) ::: acc)//distinctBy5(xs, addToAcc.map(oneSimp(_)) ::: acc) | 
|         |    897           } | 
|         |    898         } | 
|         |    899       } | 
|         |    900     } | 
|         |    901  | 
|         |    902  | 
|         |    903     def isOne1(r: Rexp) : Boolean = r match { | 
|         |    904       case ONE => true | 
|         |    905       case SEQ(r1, r2) => false//isOne1(r1) && isOne1(r2) | 
|         |    906       case ALTS(r1, r2) => false//(isOne1(r1) || isOne1(r2)) && (atMostEmpty(r1) && atMostEmpty(r2))//rs.forall(atMostEmpty) && rs.exists(isOne) | 
|         |    907       case STAR(r0) => false//atMostEmpty(r0) | 
|         |    908       case CHAR(c) => false | 
|         |    909       case ZERO => false | 
|         |    910  | 
|         |    911     } | 
|         |    912  | 
|         |    913     def turnIntoTerms(r: Rexp): List[Rexp] = r match { | 
|         |    914       case SEQ(r1, r2)  => if(isOne1(r1))  | 
|         |    915       turnIntoTerms(r2)  | 
|         |    916     else  | 
|         |    917       turnIntoTerms(r1).flatMap(r11 => furtherSEQ(r11, r2)) | 
|         |    918       case ALTS(r1, r2) => turnIntoTerms(r1) ::: turnIntoTerms(r2) | 
|         |    919       case ZERO => Nil | 
|         |    920       case _ => r :: Nil | 
|         |    921     } | 
|         |    922  | 
|         |    923     def furtherSEQ(r11: Rexp, r2: Rexp) : List[Rexp] = { | 
|         |    924       if(r11 == ONE) | 
|         |    925         turnIntoTerms(r2) | 
|         |    926       else | 
|         |    927         SEQ(r11, r2) :: Nil | 
|         |    928     } | 
|         |    929  | 
|         |    930     def attachCtx(r: ARexp, ctx: List[Rexp]) : Set[Rexp] = { | 
|         |    931       turnIntoTerms((seqFold(erase(r), ctx))) | 
|         |    932         .toSet | 
|         |    933     } | 
|         |    934  | 
|         |    935     def attachCtxcc(r: Rexp, ctx: List[Rexp]) : Set[Rexp] = | 
|         |    936       turnIntoTerms(seqFold(r, ctx)).toSet | 
|         |    937  | 
|         |    938     def ABIncludedByC[A, B, C](a: A, b: B, c: C, f: (A, B) => C,  | 
|         |    939       subseteqPred: (C, C) => Boolean) : Boolean = { | 
|         |    940         subseteqPred(f(a, b), c) | 
|         |    941     } | 
|         |    942       def rs1_subseteq_rs2(rs1: Set[Rexp], rs2: Set[Rexp]) : Boolean =  | 
|         |    943         //rs1 \subseteq rs2 | 
|         |    944       rs1.forall(rs2.contains) | 
|         |    945  | 
|         |    946       def prune6(acc: Set[Rexp], r: ARexp, ctx: List[Rexp] = Nil) : ARexp = { | 
|         |    947         if (ABIncludedByC(a = r, b = ctx, c = acc,  | 
|         |    948           f = attachCtx, subseteqPred = rs1_subseteq_rs2))  | 
|         |    949           { | 
|         |    950             AZERO | 
|         |    951           } | 
|         |    952           else{ | 
|         |    953             r match { | 
|         |    954               case ASEQ(bs, r1, r2) => (prune6(acc, r1, erase(r2) :: ctx)) match{ | 
|         |    955                 case AZERO =>  | 
|         |    956                   AZERO | 
|         |    957                 case AONE(bs1) => //when r1 becomes 1, chances to further prune r2 | 
|         |    958                   prune6(acc, fuse(bs1, r2), ctx) | 
|         |    959                 case r1p =>  | 
|         |    960                   ASEQ(bs, r1p, r2) | 
|         |    961               } | 
|         |    962                 case AALTS(bs, rs0) =>  | 
|         |    963                   rs0.map(r => prune6(acc, r, ctx)).filter(_ != AZERO) match { | 
|         |    964                     case Nil =>  | 
|         |    965                       AZERO | 
|         |    966                     case r :: Nil =>  | 
|         |    967                       fuse(bs, r)  | 
|         |    968                     case rs0p =>  | 
|         |    969                       AALTS(bs, rs0p) | 
|         |    970                   } | 
|         |    971                     case r => r | 
|         |    972             } | 
|         |    973           } | 
|         |    974       } | 
|         |    975  | 
|         |    976       def prune6cc(acc: Set[Rexp], r: Rexp, ctx: List[Rexp]) : Rexp = { | 
|         |    977         if (ABIncludedByC(a = r, b = ctx, c = acc,  | 
|         |    978           f = attachCtxcc, subseteqPred = rs1_subseteq_rs2))  | 
|         |    979           {//acc.flatMap(breakIntoTerms | 
|         |    980             ZERO | 
|         |    981           } | 
|         |    982           else{ | 
|         |    983             r match { | 
|         |    984               case SEQ(r1, r2) =>  | 
|         |    985                 (prune6cc(acc, r1, r2 :: ctx)) match{ | 
|         |    986                   case ZERO =>  | 
|         |    987                     ZERO | 
|         |    988                   case ONE =>  | 
|         |    989                     r2 | 
|         |    990                   case r1p =>  | 
|         |    991                     SEQ(r1p, r2) | 
|         |    992                 } | 
|         |    993                   case ALTS(r1, r2) =>  | 
|         |    994                     List(r1, r2).map(r => prune6cc(acc, r, ctx)).filter(_ != AZERO) match { | 
|         |    995                       case Nil =>  | 
|         |    996                         ZERO | 
|         |    997                       case r :: Nil =>  | 
|         |    998                         r  | 
|         |    999                       case ra :: rb :: Nil =>  | 
|         |   1000                         ALTS(ra, rb) | 
|         |   1001                     } | 
|         |   1002                       case r => r | 
|         |   1003             } | 
|         |   1004           } | 
|         |   1005       } | 
|         |   1006  | 
|         |   1007       def distinctBy6(xs: List[ARexp], acc: Set[Rexp] = Set()) :  | 
|         |   1008       List[ARexp] = xs match { | 
|         |   1009         case Nil =>  | 
|         |   1010           Nil | 
|         |   1011         case x :: xs => { | 
|         |   1012           val erased = erase(x) | 
|         |   1013           if(acc.contains(erased)){ | 
|         |   1014             distinctBy6(xs, acc) | 
|         |   1015           } | 
|         |   1016           else{ | 
|         |   1017             val pruned = prune6(acc, x) | 
|         |   1018             val newTerms = turnIntoTerms(erase(pruned)) | 
|         |   1019             pruned match { | 
|         |   1020               case AZERO =>  | 
|         |   1021                 distinctBy6(xs, acc) | 
|         |   1022               case xPrime =>  | 
|         |   1023                 xPrime :: distinctBy6(xs, newTerms ++: acc)//distinctBy5(xs, addToAcc.map(oneSimp(_)) ::: acc) | 
|         |   1024             } | 
|         |   1025           } | 
|         |   1026         } | 
|         |   1027       } | 
|         |   1028  | 
|         |   1029       def distinctByacc(xs: List[Rexp], acc: Set[Rexp] = Set()) : Set[Rexp] = xs match { | 
|         |   1030         case Nil =>  | 
|         |   1031           acc | 
|         |   1032         case x :: xs => { | 
|         |   1033           if(acc.contains(x)){ | 
|         |   1034             distinctByacc(xs, acc) | 
|         |   1035           } | 
|         |   1036           else{ | 
|         |   1037             val pruned = prune6cc(acc, x, Nil) | 
|         |   1038             val newTerms = turnIntoTerms(pruned) | 
|         |   1039             pruned match { | 
|         |   1040               case ZERO =>  | 
|         |   1041                 distinctByacc(xs, acc) | 
|         |   1042               case xPrime =>  | 
|         |   1043                 distinctByacc(xs, newTerms.map(oneSimp) ++: acc)//distinctBy5(xs, addToAcc.map(oneSimp(_)) ::: acc) | 
|         |   1044             } | 
|         |   1045           } | 
|         |   1046         } | 
|         |   1047       } | 
|         |   1048  | 
|         |   1049       def breakIntoTerms(r: Rexp) : List[Rexp] = r match { | 
|         |   1050         case SEQ(r1, r2)  => breakIntoTerms(r1).map(r11 => SEQ(r11, r2)) | 
|         |   1051         case ALTS(r1, r2) => breakIntoTerms(r1) ::: breakIntoTerms(r2) | 
|         |   1052         case ZERO => Nil | 
|         |   1053         case _ => r::Nil | 
|         |   1054       } | 
|         |   1055  | 
|         |   1056       def flatsIntoTerms(r: Rexp) : List[Rexp] = r match { | 
|         |   1057         //case SEQ(r1, r2)  => flatsIntoTerms(r1).map(r11 => SEQ(r11, r2)) | 
|         |   1058         case ALTS(r1, r2) => flatsIntoTerms(r1) ::: flatsIntoTerms(r2) | 
|         |   1059         case ZERO => Nil | 
|         |   1060         case _ => r::Nil | 
|         |   1061       } | 
|         |   1062  | 
|         |   1063  | 
|         |   1064       def decode_aux(r: Rexp, bs: Bits) : (Val, Bits) = (r, bs) match { | 
|         |   1065         case (ONE, bs) => (Empty, bs) | 
|         |   1066         case (CHAR(f), bs) => (Chr(f), bs) | 
|         |   1067         case (ALTS(r1, r2), Z::bs1) => { | 
|         |   1068           val (v, bs2) = decode_aux(r1, bs1) | 
|         |   1069           (Left(v), bs2) | 
|         |   1070         } | 
|         |   1071         case (ALTS(r1, r2), S::bs1) => { | 
|         |   1072           val (v, bs2) = decode_aux(r2, bs1) | 
|         |   1073           (Right(v), bs2) | 
|         |   1074         } | 
|         |   1075         case (SEQ(r1, r2), bs) => { | 
|         |   1076           val (v1, bs1) = decode_aux(r1, bs) | 
|         |   1077           val (v2, bs2) = decode_aux(r2, bs1) | 
|         |   1078           (Sequ(v1, v2), bs2) | 
|         |   1079         } | 
|         |   1080         case (STAR(r1), S::bs) => { | 
|         |   1081           val (v, bs1) = decode_aux(r1, bs) | 
|         |   1082           //(v) | 
|         |   1083           val (Stars(vs), bs2) = decode_aux(STAR(r1), bs1) | 
|         |   1084           (Stars(v::vs), bs2) | 
|         |   1085         } | 
|         |   1086         case (STAR(_), Z::bs) => (Stars(Nil), bs) | 
|         |   1087         case (RECD(x, r1), bs) => { | 
|         |   1088           val (v, bs1) = decode_aux(r1, bs) | 
|         |   1089           (Rec(x, v), bs1) | 
|         |   1090         } | 
|         |   1091         case (NOT(r), bs) => (Nots(r.toString), bs) | 
|         |   1092       } | 
|         |   1093  | 
|         |   1094       def decode(r: Rexp, bs: Bits) = decode_aux(r, bs) match { | 
|         |   1095         case (v, Nil) => v | 
|         |   1096         case _ => throw new Exception("Not decodable") | 
|         |   1097       } | 
|         |   1098  | 
|         |   1099  | 
|         |   1100  | 
|         |   1101       def blexing_simp(r: Rexp, s: String) : Val = { | 
|         |   1102         val bit_code = blex_simp(internalise(r), s.toList) | 
|         |   1103         decode(r, bit_code) | 
|         |   1104       } | 
|         |   1105       def simpBlexer(r: Rexp, s: String) : Val = { | 
|         |   1106         Try(blexing_simp(r, s)).getOrElse(Failure) | 
|         |   1107       } | 
|         |   1108  | 
|         |   1109       def strong_blexing_simp(r: Rexp, s: String) : Val = { | 
|         |   1110         decode(r, strong_blex_simp(internalise(r), s.toList)) | 
|         |   1111       } | 
|         |   1112  | 
|         |   1113       def strong_blexing_simp5(r: Rexp, s: String) : Val = { | 
|         |   1114         decode(r, strong_blex_simp5(internalise(r), s.toList)) | 
|         |   1115       } | 
|         |   1116  | 
|         |   1117  | 
|         |   1118  | 
|         |   1119  | 
|         |   1120       //def blexerStrong(r: ARexp, s: String) : Val = { | 
|         |   1121       //  Try(strong_blexing_simp(r, s)).getOrElse(Failure) | 
|         |   1122       //} | 
|         |   1123       def strongBlexer5(r: Rexp, s: String): Val = { | 
|         |   1124         Try(strong_blexing_simp5(r, s)).getOrElse(Failure) | 
|         |   1125       } | 
|         |   1126  | 
|         |   1127       def strongBlexer(r: Rexp, s: String) : Option[Val] = { | 
|         |   1128         Try(Some(decode(r, strong_blex_simp(internalise(r), s.toList)))).getOrElse(None) | 
|         |   1129       } | 
|         |   1130       def strong_blex_simp(r: ARexp, s: List[Char]) : Bits = s match { | 
|         |   1131         case Nil => { | 
|         |   1132           if (bnullable(r)) { | 
|         |   1133             mkepsBC(r) | 
|         |   1134           } | 
|         |   1135           else  | 
|         |   1136             throw new Exception("Not matched") | 
|         |   1137         } | 
|         |   1138         case c::cs => { | 
|         |   1139           strong_blex_simp(strongBsimp(bder(c, r)), cs)       | 
|         |   1140         } | 
|         |   1141       } | 
|         |   1142  | 
|         |   1143       def strong_blex_simp5(r: ARexp, s: List[Char]) : Bits = s match { | 
|         |   1144         case Nil => { | 
|         |   1145           if (bnullable(r)) { | 
|         |   1146             val bits = mkepsBC(r) | 
|         |   1147             bits | 
|         |   1148           } | 
|         |   1149           else  | 
|         |   1150             throw new Exception("Not matched") | 
|         |   1151         } | 
|         |   1152         case c::cs => { | 
|         |   1153           val der_res = bder(c,r) | 
|         |   1154           val simp_res = strongBsimp5(der_res)   | 
|         |   1155           strong_blex_simp5(simp_res, cs)       | 
|         |   1156         } | 
|         |   1157       } | 
|         |   1158  | 
|         |   1159  | 
|         |   1160       def bders_simp(s: List[Char], r: ARexp) : ARexp = s match { | 
|         |   1161         case Nil => r | 
|         |   1162         case c::s =>  | 
|         |   1163           //println(erase(r)) | 
|         |   1164           bders_simp(s, bsimp(bder(c, r))) | 
|         |   1165       } | 
|         |   1166  | 
|         |   1167       def bdersStrong5(s: List[Char], r: ARexp) : ARexp = s match { | 
|         |   1168         case Nil => r | 
|         |   1169         case c::s => bdersStrong5(s, strongBsimp5(bder(c, r))) | 
|         |   1170       } | 
|         |   1171       def bdersStrong6(s: List[Char], r: ARexp) : ARexp = s match { | 
|         |   1172         case Nil => r | 
|         |   1173         case c::s => bdersStrong6(s, strongBsimp6(bder(c, r))) | 
|         |   1174       } | 
|         |   1175       //Conjecture: [| bdersStrong(s, r) |] = O([| r |]^3) | 
|         |   1176       def bdersStrong(s: List[Char], r: ARexp) : ARexp = s match { | 
|         |   1177         case Nil => r | 
|         |   1178         case c::s => bdersStrong(s, bsimpStrong(bder(c, r))) | 
|         |   1179       } | 
|         |   1180       def bdersSimp(s: String, r: Rexp) : ARexp = bders_simp(s.toList, internalise(r)) | 
|         |   1181  | 
|         |   1182       //def bdersStrong(s: List[Char], r: ARexp) : ARexp = s match { | 
|         |   1183       //  case Nil => r  | 
|         |   1184       //  case c::s => bdersStrong(s, strongBsimp(bder(c, r))) | 
|         |   1185       //} | 
|         |   1186  | 
|         |   1187       def bdersStrongRexp(s: String, r: Rexp) : ARexp = bdersStrong(s.toList, internalise(r)) | 
|         |   1188  | 
|         |   1189       def erase(r:ARexp): Rexp = r match{ | 
|         |   1190         case AZERO => ZERO | 
|         |   1191         case AONE(_) => ONE | 
|         |   1192         case ACHAR(bs, c) => CHAR(c) | 
|         |   1193         case AALTS(bs, Nil) => ZERO | 
|         |   1194         case AALTS(bs, a::Nil) => erase(a) | 
|         |   1195         case AALTS(bs, a::as) => ALTS(erase(a), erase(AALTS(bs, as))) | 
|         |   1196         case ASEQ(bs, r1, r2) => SEQ (erase(r1), erase(r2)) | 
|         |   1197         case ASTAR(cs, r)=> STAR(erase(r)) | 
|         |   1198         case ANOT(bs, r) => NOT(erase(r)) | 
|         |   1199         case AANYCHAR(bs) => ANYCHAR | 
|         |   1200       } | 
|         |   1201  | 
|         |   1202  | 
|         |   1203       def allCharSeq(r: Rexp) : Boolean = r match { | 
|         |   1204         case CHAR(c) => true | 
|         |   1205         case SEQ(r1, r2) => allCharSeq(r1) && allCharSeq(r2) | 
|         |   1206         case _ => false | 
|         |   1207       } | 
|         |   1208  | 
|         |   1209       def flattenSeq(r: Rexp) : String = r match { | 
|         |   1210         case CHAR(c) => c.toString | 
|         |   1211         case SEQ(r1, r2) => flattenSeq(r1) ++ flattenSeq(r2) | 
|         |   1212         case _ => throw new Error("flatten unflattenable rexp") | 
|         |   1213       }  | 
|         |   1214  | 
|         |   1215       def shortRexpOutput(r: Rexp) : String = r match { | 
|         |   1216         case CHAR(c) => c.toString | 
|         |   1217         case ONE => "1" | 
|         |   1218         case ZERO => "0" | 
|         |   1219         case SEQ(r1, r2) if(allCharSeq(r)) => flattenSeq(r)//"[" ++ shortRexpOutput(r1) ++ "~" ++ shortRexpOutput(r2) ++ "]" | 
|         |   1220         case SEQ(r1, r2) => "[" ++ shortRexpOutput(r1) ++ "~" ++ shortRexpOutput(r2) ++ "]" | 
|         |   1221         case ALTS(r1, r2) => "(" ++ shortRexpOutput(r1) ++ "+" ++ shortRexpOutput(r2) ++ ")" | 
|         |   1222         case STAR(STAR(r)) => "(..)*"// ++ shortRexpOutput(r) ++ "]*" | 
|         |   1223         case STAR(r) => "STAR(" ++ shortRexpOutput(r) ++ ")" | 
|         |   1224         //case RTOP => "RTOP" | 
|         |   1225       } | 
|         |   1226  | 
|         |   1227  | 
|         |   1228       def blex_simp(r: ARexp, s: List[Char]) : Bits = s match { | 
|         |   1229         case Nil => { | 
|         |   1230           if (bnullable(r)) { | 
|         |   1231             val bits = mkepsBC(r) | 
|         |   1232             bits | 
|         |   1233           } | 
|         |   1234           else  | 
|         |   1235             throw new Exception("Not matched") | 
|         |   1236         } | 
|         |   1237         case c::cs => { | 
|         |   1238           val der_res = bder(c,r) | 
|         |   1239           val simp_res = bsimp(der_res)   | 
|         |   1240           blex_simp(simp_res, cs)       | 
|         |   1241         } | 
|         |   1242       } | 
|         |   1243  | 
|         |   1244  | 
|         |   1245  | 
|         |   1246  | 
|         |   1247       def size(r: Rexp) : Int = r match { | 
|         |   1248         case ZERO => 1 | 
|         |   1249         case ONE => 1 | 
|         |   1250         case CHAR(_) => 1 | 
|         |   1251         case ANYCHAR => 1 | 
|         |   1252         case NOT(r0) => 1 + size(r0) | 
|         |   1253         case SEQ(r1, r2) => 1 + size(r1) + size(r2) | 
|         |   1254         case ALTS(r1, r2) => 1 + List(r1, r2).map(size).sum | 
|         |   1255         case STAR(r) => 1 + size(r) | 
|         |   1256       } | 
|         |   1257  | 
|         |   1258       def asize(a: ARexp) = size(erase(a)) | 
|         |   1259  | 
|         |   1260       //pder related | 
|         |   1261       type Mon = (Char, Rexp) | 
|         |   1262       type Lin = Set[Mon] | 
|         |   1263  | 
|         |   1264       def dot_prod(rs: Set[Rexp], r: Rexp): Set[Rexp] = r match { | 
|         |   1265         case ZERO => Set() | 
|         |   1266         case ONE => rs | 
|         |   1267         case r => rs.map((re) => if (re == ONE) r else SEQ(re, r)  )    | 
|         |   1268       } | 
|         |   1269       def cir_prod(l: Lin, t: Rexp): Lin = t match {//remember this Lin is different from the Lin in Antimirov's paper. Here it does not mean the set of all subsets of linear forms that does not contain zero, but rather the type a set of linear forms | 
|         |   1270         case ZERO => Set() | 
|         |   1271         // case ONE => l | 
|         |   1272         case t => l.map( m => m._2 match  | 
|         |   1273         { | 
|         |   1274           case ZERO => m  | 
|         |   1275           case ONE => (m._1, t)  | 
|         |   1276           case p => (m._1, SEQ(p, t))  | 
|         |   1277         }   | 
|         |   1278  | 
|         |   1279         ) | 
|         |   1280       } | 
|         |   1281       def cir_prodList(l : List[Mon], t: Rexp): List[Mon] = t match { | 
|         |   1282         case ZERO => Nil | 
|         |   1283         case ONE => l | 
|         |   1284         case t => l.map(m => m._2 match | 
|         |   1285         { | 
|         |   1286           case ZERO => m | 
|         |   1287           case ONE => (m._1, t) | 
|         |   1288           case p => (m._1, SEQ(p, t)) | 
|         |   1289         } | 
|         |   1290         ) | 
|         |   1291  | 
|         |   1292       } | 
|         |   1293       def lfList(r: Rexp) : List[Mon] = r match { | 
|         |   1294         case ZERO => Nil | 
|         |   1295         case ONE => Nil | 
|         |   1296         case CHAR(f) => { | 
|         |   1297           (f, ONE) :: Nil | 
|         |   1298         } | 
|         |   1299         case ALTS(r1, r2) => { | 
|         |   1300           lfList(r1) ++ lfList(r2) | 
|         |   1301         } | 
|         |   1302         case STAR(r1) => cir_prodList(lfList(r1), STAR(r1)) | 
|         |   1303         case SEQ(r1, r2) => { | 
|         |   1304           if(nullable(r1)) | 
|         |   1305             cir_prodList(lfList(r1), r2) ++ lfList(r2) | 
|         |   1306           else | 
|         |   1307             cir_prodList(lfList(r1), r2) | 
|         |   1308         } | 
|         |   1309       } | 
|         |   1310       def lfprint(ls: Lin) = ls.foreach(m =>{ | 
|         |   1311         println(m._1) | 
|         |   1312         rprint(m._2) | 
|    733       }) |   1313       }) | 
|    734       val pruned : ARexp = pruneRexp(r1, termsTruncated) |   1314     def lf(r: Rexp): Lin = r match { | 
|    735       pruned match { |   1315       case ZERO => Set() | 
|    736         case AZERO => AZERO |   1316       case ONE => Set() | 
|    737         case AONE(bs1) => fuse(bs ++ bs1, r2) |   1317       case CHAR(f) => { | 
|    738         case pruned1 => ASEQ(bs, pruned1, r2) |   1318         //val Some(c) = alphabet.find(f)  | 
|    739       } |   1319         Set((f, ONE)) | 
|    740  |   1320       } | 
|    741     case AALTS(bs, rs) =>  |   1321       case ALTS(r1, r2) => { | 
|    742       //allowableTerms.foreach(a => println(shortRexpOutput(a)))         |   1322         lf(r1 ) ++ lf(r2) | 
|    743       val rsp = rs.map(r =>  |   1323       } | 
|    744                     pruneRexp(r, allowableTerms) |   1324       case STAR(r1) => cir_prod(lf(r1), STAR(r1)) //may try infix notation later...... | 
|    745                   ) |   1325       case SEQ(r1, r2) =>{ | 
|    746                   .filter(r => r != AZERO) |   1326         if (nullable(r1)) | 
|    747       rsp match { |   1327           cir_prod(lf(r1), r2) ++ lf(r2) | 
|    748         case Nil => AZERO |   1328         else | 
|    749         case r1::Nil => fuse(bs, r1) |   1329           cir_prod(lf(r1), r2)  | 
|    750         case rs1 => AALTS(bs, rs1) |   1330       } | 
|    751       } |   1331     } | 
|    752     case r =>  |   1332     def lfs(r: Set[Rexp]): Lin = { | 
|    753       if(allowableTerms.contains(erase(r))) r else AZERO //assert(r != AZERO) |   1333       r.foldLeft(Set[Mon]())((acc, r) => acc ++ lf(r)) | 
|    754   } |   1334     } | 
|    755 } |   1335  | 
|    756  |   1336     def pder(x: Char, t: Rexp): Set[Rexp] = { | 
|    757 def oneSimp(r: Rexp) : Rexp = r match { |   1337       val lft = lf(t) | 
|    758   case SEQ(ONE, r) => r |   1338       (lft.filter(mon => if(mon._1 == x) true else false)).map(mon => mon._2) | 
|    759   case SEQ(r1, r2) => SEQ(oneSimp(r1), r2) |   1339     } | 
|    760   case r => r//assert r != 0  |   1340     def pders_single(s: List[Char], t: Rexp) : Set[Rexp] = s match { | 
|    761      |   1341       case x::xs => pders(xs, pder(x, t)) | 
|    762 } |   1342       case Nil => Set(t) | 
|    763  |   1343     } | 
|    764  |   1344     def pders(s: List[Char], ts: Set[Rexp]) : Set[Rexp] = s match { | 
|    765 def distinctBy4(xs: List[ARexp], acc: List[Rexp] = Nil) : List[ARexp] = xs match { |   1345       case x::xs => pders(xs, ts.foldLeft(Set[Rexp]())((acc, t) => acc ++ pder(x, t))) | 
|    766   case Nil => Nil |   1346       case Nil => ts  | 
|    767   case x :: xs => |   1347     } | 
|    768     //assert(acc.distinct == acc) |   1348     def pderss(ss: List[List[Char]], t: Rexp): Set[Rexp] =  | 
|    769     val erased = erase(x) |   1349       ss.foldLeft( Set[Rexp]() )( (acc, s) => pders_single(s, t) ++ acc ) | 
|    770     if(acc.contains(erased)) |   1350     def pdera(t: Rexp): Set[Rexp] = lf(t).map(mon => mon._2) | 
|    771       distinctBy4(xs, acc) |   1351     //all implementation of partial derivatives that involve set union are potentially buggy | 
|    772     else{ |   1352     //because they don't include the original regular term before they are pdered. | 
|    773       val addToAcc =  breakIntoTerms(erased).filter(r => !acc.contains(oneSimp(r))) |   1353     //now only pderas is fixed. | 
|    774       //val xp = pruneRexp(x, addToAcc) |   1354     def pderas(t: Set[Rexp], d: Int): Set[Rexp] =  | 
|    775       pruneRexp(x, addToAcc) match { |   1355       if(d > 0)  | 
|    776         case AZERO => distinctBy4(xs, addToAcc.map(oneSimp(_)) ::: acc) |   1356         pderas(lfs(t).map(mon => mon._2), d - 1) ++ t  | 
|    777         case xPrime => xPrime :: distinctBy4(xs, addToAcc.map(oneSimp(_)) ::: acc) |   1357       else  | 
|    778       } |   1358         lfs(t).map(mon => mon._2) ++ t//repeated application of pderas over the newest set of pders. | 
|    779     } |         | 
|    780 } |         | 
|    781  |         | 
|    782 // fun pAKC_aux :: "arexp list ⇒ arexp ⇒ rexp ⇒ arexp" |         | 
|    783 //   where |         | 
|    784 // "pAKC_aux rsa r ctx = (if (seqFold (SEQ (erase r) ( ctx) )) ⊆ (seqFold (erase (AALTs [] rsa))) then AZERO else |         | 
|    785 //                           case r of (ASEQ bs r1 r2) ⇒  |         | 
|    786 //                             bsimp_ASEQ bs (pAKC_aux rsa r1 (SEQ  (erase r2) ( ctx) )) r2   | |         | 
|    787 //                                     (AALTs bs rs) ⇒  |         | 
|    788 //                             bsimp_AALTs bs (flts (map (λr. pAKC_aux rsa r ( ctx) ) rs) )    | |         | 
|    789 //                                     r             ⇒ r |         | 
|    790  |         | 
|    791 // def canonicalSeq(rs: List[Rexp], acc: Rexp) = rs match { |         | 
|    792 //   case r::Nil => SEQ(r, acc) |         | 
|    793 //   case Nil => acc |         | 
|    794 //   case r1::r2::Nil => SEQ(SEQ(r1, r2), acc) |         | 
|    795 // } |         | 
|    796  |         | 
|    797  |         | 
|    798 //the "fake" Language interpretation: just concatenates! |         | 
|    799 def seqFold(acc: Rexp, rs: List[Rexp]) : Rexp = rs match { |         | 
|    800   case Nil => acc |         | 
|    801   case r :: rs1 =>  |         | 
|    802     // if(acc == ONE)  |         | 
|    803     //   seqFold(r, rs1)  |         | 
|    804     // else |         | 
|    805       seqFold(SEQ(acc, r), rs1) |         | 
|    806 } |         | 
|    807  |         | 
|    808 def rprint(r: Rexp) : Unit = println(shortRexpOutput(r)) |         | 
|    809 def rsprint(rs: Iterable[Rexp]) = rs.foreach(r => println(shortRexpOutput(r))) |         | 
|    810  |         | 
|    811 def aprint(a: ARexp) = println(shortRexpOutput(erase(a))) |         | 
|    812 def asprint(as: List[ARexp]) = as.foreach(a => println(shortRexpOutput(erase(a)))) |         | 
|    813  |         | 
|    814 def pAKC(acc: List[Rexp], r: ARexp, ctx: List[Rexp]) : ARexp = { |         | 
|    815   // println("pakc") |         | 
|    816   // println(shortRexpOutput(erase(r))) |         | 
|    817   // println("acc") |         | 
|    818   // rsprint(acc) |         | 
|    819   // println("ctx---------") |         | 
|    820   // rsprint(ctx) |         | 
|    821   // println("ctx---------end") |         | 
|    822   // rsprint(breakIntoTerms(seqFold(erase(r), ctx)).map(oneSimp)) |         | 
|    823  |         | 
|    824   if (breakIntoTerms(seqFold(erase(r), ctx)).map(oneSimp).forall(acc.contains)) {//acc.flatMap(breakIntoTerms |         | 
|    825     AZERO |         | 
|    826   } |         | 
|    827   else{ |         | 
|    828     r match { |         | 
|    829       case ASEQ(bs, r1, r2) =>  |         | 
|    830       (pAKC(acc, r1, erase(r2) :: ctx)) match{ |         | 
|    831         case AZERO =>  |         | 
|    832           AZERO |         | 
|    833         case AONE(bs1) =>  |         | 
|    834           fuse(bs1, r2) |         | 
|    835         case r1p =>  |         | 
|    836           ASEQ(bs, r1p, r2) |         | 
|    837       } |         | 
|    838       case AALTS(bs, rs0) =>  |         | 
|    839         // println("before pruning") |         | 
|    840         // println(s"ctx is ") |         | 
|    841         // ctx.foreach(r => println(shortRexpOutput(r))) |         | 
|    842         // println(s"rs0 is ") |         | 
|    843         // rs0.foreach(r => println(shortRexpOutput(erase(r)))) |         | 
|    844         // println(s"acc is ") |         | 
|    845         // acc.foreach(r => println(shortRexpOutput(r))) |         | 
|    846         rs0.map(r => pAKC(acc, r, ctx)).filter(_ != AZERO) match { |         | 
|    847           case Nil =>  |         | 
|    848             // println("after pruning Nil") |         | 
|    849             AZERO |         | 
|    850           case r :: Nil =>  |         | 
|    851             // println("after pruning singleton") |         | 
|    852             // println(shortRexpOutput(erase(r))) |         | 
|    853             r  |         | 
|    854           case rs0p =>  |         | 
|    855           // println("after pruning non-singleton") |         | 
|    856             AALTS(bs, rs0p) |         | 
|    857         } |         | 
|    858       case r => r |         | 
|    859     } |         | 
|    860   } |         | 
|    861 } |         | 
|    862  |         | 
|    863 def distinctBy5(xs: List[ARexp], acc: List[Rexp] = Nil) : List[ARexp] = xs match { |         | 
|    864   case Nil =>  |         | 
|    865     Nil |         | 
|    866   case x :: xs => { |         | 
|    867     val erased = erase(x) |         | 
|    868     if(acc.contains(erased)){ |         | 
|    869       distinctBy5(xs, acc) |         | 
|    870     } |         | 
|    871     else{ |         | 
|    872       val pruned = pAKC(acc, x, Nil) |         | 
|    873       val newTerms = breakIntoTerms(erase(pruned)) |         | 
|    874       pruned match { |         | 
|    875         case AZERO =>  |         | 
|    876           distinctBy5(xs, acc) |         | 
|    877         case xPrime =>  |         | 
|    878           xPrime :: distinctBy5(xs, newTerms.map(oneSimp) ::: acc)//distinctBy5(xs, addToAcc.map(oneSimp(_)) ::: acc) |         | 
|    879       } |         | 
|    880     } |         | 
|    881   } |         | 
|    882 } |         | 
|    883  |         | 
|    884 def atMostEmpty(r: Rexp) : Boolean = r match { |         | 
|    885   case ZERO => true |         | 
|    886   case ONE => true |         | 
|    887   case STAR(r) => atMostEmpty(r) |         | 
|    888   case SEQ(r1, r2) => atMostEmpty(r1) && atMostEmpty(r2) |         | 
|    889   case ALTS(r1, r2) => atMostEmpty(r1) && atMostEmpty(r2) |         | 
|    890   case CHAR(_) => false |         | 
|    891 } |         | 
|    892  |         | 
|    893 def isOne(r: Rexp) : Boolean = r match { |         | 
|    894   case ONE => true |         | 
|    895   case SEQ(r1, r2) => isOne(r1) && isOne(r2) |         | 
|    896   case ALTS(r1, r2) => (isOne(r1) || isOne(r2)) && (atMostEmpty(r1) && atMostEmpty(r2))//rs.forall(atMostEmpty) && rs.exists(isOne) |         | 
|    897   case STAR(r0) => atMostEmpty(r0) |         | 
|    898   case CHAR(c) => false |         | 
|    899   case ZERO => false |         | 
|    900  |         | 
|    901 } |         | 
|    902  |         | 
|    903 def isOne1(r: Rexp) : Boolean = r match { |         | 
|    904   case ONE => true |         | 
|    905   case SEQ(r1, r2) => false//isOne1(r1) && isOne1(r2) |         | 
|    906   case ALTS(r1, r2) => false//(isOne1(r1) || isOne1(r2)) && (atMostEmpty(r1) && atMostEmpty(r2))//rs.forall(atMostEmpty) && rs.exists(isOne) |         | 
|    907   case STAR(r0) => false//atMostEmpty(r0) |         | 
|    908   case CHAR(c) => false |         | 
|    909   case ZERO => false |         | 
|    910  |         | 
|    911 } |         | 
|    912  |         | 
|    913 def turnIntoTerms(r: Rexp): List[Rexp] = r match { |         | 
|    914   case SEQ(r1, r2)  => if(isOne1(r1))  |         | 
|    915                           turnIntoTerms(r2)  |         | 
|    916                        else  |         | 
|    917                           turnIntoTerms(r1).flatMap(r11 => furtherSEQ(r11, r2)) |         | 
|    918   case ALTS(r1, r2) => turnIntoTerms(r1) ::: turnIntoTerms(r2) |         | 
|    919   case ZERO => Nil |         | 
|    920   case _ => r :: Nil |         | 
|    921 } |         | 
|    922  |         | 
|    923 def furtherSEQ(r11: Rexp, r2: Rexp) : List[Rexp] = { |         | 
|    924   if(r11 == ONE) |         | 
|    925     turnIntoTerms(r2) |         | 
|    926   else |         | 
|    927     SEQ(r11, r2) :: Nil |         | 
|    928 } |         | 
|    929  |         | 
|    930 def attachCtx(r: ARexp, ctx: List[Rexp]) : Set[Rexp] = { |         | 
|    931   turnIntoTerms((seqFold(erase(r), ctx))) |         | 
|    932     .toSet |         | 
|    933 } |         | 
|    934  |         | 
|    935 def attachCtxcc(r: Rexp, ctx: List[Rexp]) : Set[Rexp] = |         | 
|    936   turnIntoTerms(seqFold(r, ctx)).toSet |         | 
|    937  |         | 
|    938 def ABIncludedByC[A, B, C](a: A, b: B, c: C, f: (A, B) => C,  |         | 
|    939 subseteqPred: (C, C) => Boolean) : Boolean = { |         | 
|    940   subseteqPred(f(a, b), c) |         | 
|    941 } |         | 
|    942 def rs1_subseteq_rs2(rs1: Set[Rexp], rs2: Set[Rexp]) : Boolean =  |         | 
|    943   //rs1 \subseteq rs2 |         | 
|    944   rs1.forall(rs2.contains) |         | 
|    945  |         | 
|    946 def prune6(acc: Set[Rexp], r: ARexp, ctx: List[Rexp] = Nil) : ARexp = { |         | 
|    947   if (ABIncludedByC(a = r, b = ctx, c = acc,  |         | 
|    948                     f = attachCtx, subseteqPred = rs1_subseteq_rs2))  |         | 
|    949   { |         | 
|    950     AZERO |         | 
|    951   } |         | 
|    952   else{ |         | 
|    953     r match { |         | 
|    954       case ASEQ(bs, r1, r2) => (prune6(acc, r1, erase(r2) :: ctx)) match{ |         | 
|    955         case AZERO =>  |         | 
|    956           AZERO |         | 
|    957         case AONE(bs1) => //when r1 becomes 1, chances to further prune r2 |         | 
|    958           prune6(acc, fuse(bs1, r2), ctx) |         | 
|    959         case r1p =>  |         | 
|    960           ASEQ(bs, r1p, r2) |         | 
|    961       } |         | 
|    962       case AALTS(bs, rs0) =>  |         | 
|    963         rs0.map(r => prune6(acc, r, ctx)).filter(_ != AZERO) match { |         | 
|    964           case Nil =>  |         | 
|    965             AZERO |         | 
|    966           case r :: Nil =>  |         | 
|    967             fuse(bs, r)  |         | 
|    968           case rs0p =>  |         | 
|    969             AALTS(bs, rs0p) |         | 
|    970         } |         | 
|    971       case r => r |         | 
|    972     } |         | 
|    973   } |         | 
|    974 } |         | 
|    975  |         | 
|    976 def prune6cc(acc: Set[Rexp], r: Rexp, ctx: List[Rexp]) : Rexp = { |         | 
|    977   if (ABIncludedByC(a = r, b = ctx, c = acc,  |         | 
|    978                     f = attachCtxcc, subseteqPred = rs1_subseteq_rs2))  |         | 
|    979   {//acc.flatMap(breakIntoTerms |         | 
|    980     ZERO |         | 
|    981   } |         | 
|    982   else{ |         | 
|    983     r match { |         | 
|    984       case SEQ(r1, r2) =>  |         | 
|    985       (prune6cc(acc, r1, r2 :: ctx)) match{ |         | 
|    986         case ZERO =>  |         | 
|    987           ZERO |         | 
|    988         case ONE =>  |         | 
|    989           r2 |         | 
|    990         case r1p =>  |         | 
|    991           SEQ(r1p, r2) |         | 
|    992       } |         | 
|    993       case ALTS(r1, r2) =>  |         | 
|    994         List(r1, r2).map(r => prune6cc(acc, r, ctx)).filter(_ != AZERO) match { |         | 
|    995           case Nil =>  |         | 
|    996             ZERO |         | 
|    997           case r :: Nil =>  |         | 
|    998             r  |         | 
|    999           case ra :: rb :: Nil =>  |         | 
|   1000             ALTS(ra, rb) |         | 
|   1001         } |         | 
|   1002       case r => r |         | 
|   1003     } |         | 
|   1004   } |         | 
|   1005 } |         | 
|   1006  |         | 
|   1007 def distinctBy6(xs: List[ARexp], acc: Set[Rexp] = Set()) :  |         | 
|   1008 List[ARexp] = xs match { |         | 
|   1009   case Nil =>  |         | 
|   1010     Nil |         | 
|   1011   case x :: xs => { |         | 
|   1012     val erased = erase(x) |         | 
|   1013     if(acc.contains(erased)){ |         | 
|   1014       distinctBy6(xs, acc) |         | 
|   1015     } |         | 
|   1016     else{ |         | 
|   1017       val pruned = prune6(acc, x) |         | 
|   1018       val newTerms = turnIntoTerms(erase(pruned)) |         | 
|   1019       pruned match { |         | 
|   1020         case AZERO =>  |         | 
|   1021           distinctBy6(xs, acc) |         | 
|   1022         case xPrime =>  |         | 
|   1023           xPrime :: distinctBy6(xs, newTerms ++: acc)//distinctBy5(xs, addToAcc.map(oneSimp(_)) ::: acc) |         | 
|   1024       } |         | 
|   1025     } |         | 
|   1026   } |         | 
|   1027 } |         | 
|   1028  |         | 
|   1029 def distinctByacc(xs: List[Rexp], acc: Set[Rexp] = Set()) : Set[Rexp] = xs match { |         | 
|   1030   case Nil =>  |         | 
|   1031     acc |         | 
|   1032   case x :: xs => { |         | 
|   1033     if(acc.contains(x)){ |         | 
|   1034       distinctByacc(xs, acc) |         | 
|   1035     } |         | 
|   1036     else{ |         | 
|   1037       val pruned = prune6cc(acc, x, Nil) |         | 
|   1038       val newTerms = turnIntoTerms(pruned) |         | 
|   1039       pruned match { |         | 
|   1040         case ZERO =>  |         | 
|   1041           distinctByacc(xs, acc) |         | 
|   1042         case xPrime =>  |         | 
|   1043           distinctByacc(xs, newTerms.map(oneSimp) ++: acc)//distinctBy5(xs, addToAcc.map(oneSimp(_)) ::: acc) |         | 
|   1044       } |         | 
|   1045     } |         | 
|   1046   } |         | 
|   1047 } |         | 
|   1048  |         | 
|   1049 def breakIntoTerms(r: Rexp) : List[Rexp] = r match { |         | 
|   1050   case SEQ(r1, r2)  => breakIntoTerms(r1).map(r11 => SEQ(r11, r2)) |         | 
|   1051   case ALTS(r1, r2) => breakIntoTerms(r1) ::: breakIntoTerms(r2) |         | 
|   1052   case ZERO => Nil |         | 
|   1053   case _ => r::Nil |         | 
|   1054 } |         | 
|   1055  |         | 
|   1056 def flatsIntoTerms(r: Rexp) : List[Rexp] = r match { |         | 
|   1057   //case SEQ(r1, r2)  => flatsIntoTerms(r1).map(r11 => SEQ(r11, r2)) |         | 
|   1058   case ALTS(r1, r2) => flatsIntoTerms(r1) ::: flatsIntoTerms(r2) |         | 
|   1059   case ZERO => Nil |         | 
|   1060   case _ => r::Nil |         | 
|   1061 } |         | 
|   1062  |         | 
|   1063  |         | 
|   1064 def decode_aux(r: Rexp, bs: Bits) : (Val, Bits) = (r, bs) match { |         | 
|   1065   case (ONE, bs) => (Empty, bs) |         | 
|   1066   case (CHAR(f), bs) => (Chr(f), bs) |         | 
|   1067   case (ALTS(r1, r2), Z::bs1) => { |         | 
|   1068       val (v, bs2) = decode_aux(r1, bs1) |         | 
|   1069       (Left(v), bs2) |         | 
|   1070   } |         | 
|   1071   case (ALTS(r1, r2), S::bs1) => { |         | 
|   1072       val (v, bs2) = decode_aux(r2, bs1) |         | 
|   1073       (Right(v), bs2) |         | 
|   1074   } |         | 
|   1075   case (SEQ(r1, r2), bs) => { |         | 
|   1076     val (v1, bs1) = decode_aux(r1, bs) |         | 
|   1077     val (v2, bs2) = decode_aux(r2, bs1) |         | 
|   1078     (Sequ(v1, v2), bs2) |         | 
|   1079   } |         | 
|   1080   case (STAR(r1), S::bs) => { |         | 
|   1081     val (v, bs1) = decode_aux(r1, bs) |         | 
|   1082     //(v) |         | 
|   1083     val (Stars(vs), bs2) = decode_aux(STAR(r1), bs1) |         | 
|   1084     (Stars(v::vs), bs2) |         | 
|   1085   } |         | 
|   1086   case (STAR(_), Z::bs) => (Stars(Nil), bs) |         | 
|   1087   case (RECD(x, r1), bs) => { |         | 
|   1088     val (v, bs1) = decode_aux(r1, bs) |         | 
|   1089     (Rec(x, v), bs1) |         | 
|   1090   } |         | 
|   1091   case (NOT(r), bs) => (Nots(r.toString), bs) |         | 
|   1092 } |         | 
|   1093  |         | 
|   1094 def decode(r: Rexp, bs: Bits) = decode_aux(r, bs) match { |         | 
|   1095   case (v, Nil) => v |         | 
|   1096   case _ => throw new Exception("Not decodable") |         | 
|   1097 } |         | 
|   1098  |         | 
|   1099  |         | 
|   1100  |         | 
|   1101 def blexing_simp(r: Rexp, s: String) : Val = { |         | 
|   1102     val bit_code = blex_simp(internalise(r), s.toList) |         | 
|   1103     decode(r, bit_code) |         | 
|   1104 } |         | 
|   1105 def simpBlexer(r: Rexp, s: String) : Val = { |         | 
|   1106   Try(blexing_simp(r, s)).getOrElse(Failure) |         | 
|   1107 } |         | 
|   1108  |         | 
|   1109 def strong_blexing_simp(r: Rexp, s: String) : Val = { |         | 
|   1110   decode(r, strong_blex_simp(internalise(r), s.toList)) |         | 
|   1111 } |         | 
|   1112  |         | 
|   1113 def strong_blexing_simp5(r: Rexp, s: String) : Val = { |         | 
|   1114   decode(r, strong_blex_simp5(internalise(r), s.toList)) |         | 
|   1115 } |         | 
|   1116  |         | 
|   1117  |         | 
|   1118 def strongBlexer(r: Rexp, s: String) : Val = { |         | 
|   1119   Try(strong_blexing_simp(r, s)).getOrElse(Failure) |         | 
|   1120 } |         | 
|   1121  |         | 
|   1122 def strongBlexer5(r: Rexp, s: String): Val = { |         | 
|   1123   Try(strong_blexing_simp5(r, s)).getOrElse(Failure) |         | 
|   1124 } |         | 
|   1125  |         | 
|   1126 def strong_blex_simp(r: ARexp, s: List[Char]) : Bits = s match { |         | 
|   1127   case Nil => { |         | 
|   1128     if (bnullable(r)) { |         | 
|   1129       //println(asize(r)) |         | 
|   1130       val bits = mkepsBC(r) |         | 
|   1131       bits |         | 
|   1132     } |         | 
|   1133     else  |         | 
|   1134       throw new Exception("Not matched") |         | 
|   1135   } |         | 
|   1136   case c::cs => { |         | 
|   1137     val der_res = bder(c,r) |         | 
|   1138     val simp_res = strongBsimp(der_res)   |         | 
|   1139     strong_blex_simp(simp_res, cs)       |         | 
|   1140   } |         | 
|   1141 } |         | 
|   1142  |         | 
|   1143 def strong_blex_simp5(r: ARexp, s: List[Char]) : Bits = s match { |         | 
|   1144   case Nil => { |         | 
|   1145     if (bnullable(r)) { |         | 
|   1146       val bits = mkepsBC(r) |         | 
|   1147       bits |         | 
|   1148     } |         | 
|   1149     else  |         | 
|   1150       throw new Exception("Not matched") |         | 
|   1151   } |         | 
|   1152   case c::cs => { |         | 
|   1153     val der_res = bder(c,r) |         | 
|   1154     val simp_res = strongBsimp5(der_res)   |         | 
|   1155     strong_blex_simp5(simp_res, cs)       |         | 
|   1156   } |         | 
|   1157 } |         | 
|   1158  |         | 
|   1159  |         | 
|   1160   def bders_simp(s: List[Char], r: ARexp) : ARexp = s match { |         | 
|   1161     case Nil => r |         | 
|   1162     case c::s =>  |         | 
|   1163       //println(erase(r)) |         | 
|   1164       bders_simp(s, bsimp(bder(c, r))) |         | 
|   1165   } |         | 
|   1166    |         | 
|   1167   def bdersStrong5(s: List[Char], r: ARexp) : ARexp = s match { |         | 
|   1168     case Nil => r |         | 
|   1169     case c::s => bdersStrong5(s, strongBsimp5(bder(c, r))) |         | 
|   1170   } |         | 
|   1171   def bdersStrong6(s: List[Char], r: ARexp) : ARexp = s match { |         | 
|   1172     case Nil => r |         | 
|   1173     case c::s => bdersStrong6(s, strongBsimp6(bder(c, r))) |         | 
|   1174   } |         | 
|   1175   def bdersStrong7(s: List[Char], r: ARexp) : ARexp = s match { |         | 
|   1176     case Nil => r |         | 
|   1177     case c::s => bdersStrong7(s, strongBsimp7(bder(c, r))) |         | 
|   1178   } |         | 
|   1179   def bdersSimp(s: String, r: Rexp) : ARexp = bders_simp(s.toList, internalise(r)) |         | 
|   1180  |         | 
|   1181   def bdersStrong(s: List[Char], r: ARexp) : ARexp = s match { |         | 
|   1182     case Nil => r  |         | 
|   1183     case c::s => bdersStrong(s, strongBsimp(bder(c, r))) |         | 
|   1184   } |         | 
|   1185  |         | 
|   1186   def bdersStrongRexp(s: String, r: Rexp) : ARexp = bdersStrong(s.toList, internalise(r)) |         | 
|   1187  |         | 
|   1188   def erase(r:ARexp): Rexp = r match{ |         | 
|   1189     case AZERO => ZERO |         | 
|   1190     case AONE(_) => ONE |         | 
|   1191     case ACHAR(bs, c) => CHAR(c) |         | 
|   1192     case AALTS(bs, Nil) => ZERO |         | 
|   1193     case AALTS(bs, a::Nil) => erase(a) |         | 
|   1194     case AALTS(bs, a::as) => ALTS(erase(a), erase(AALTS(bs, as))) |         | 
|   1195     case ASEQ(bs, r1, r2) => SEQ (erase(r1), erase(r2)) |         | 
|   1196     case ASTAR(cs, r)=> STAR(erase(r)) |         | 
|   1197     case ANOT(bs, r) => NOT(erase(r)) |         | 
|   1198     case AANYCHAR(bs) => ANYCHAR |         | 
|   1199   } |         | 
|   1200  |         | 
|   1201  |         | 
|   1202   def allCharSeq(r: Rexp) : Boolean = r match { |         | 
|   1203     case CHAR(c) => true |         | 
|   1204     case SEQ(r1, r2) => allCharSeq(r1) && allCharSeq(r2) |         | 
|   1205     case _ => false |         | 
|   1206   } |         | 
|   1207  |         | 
|   1208   def flattenSeq(r: Rexp) : String = r match { |         | 
|   1209     case CHAR(c) => c.toString |         | 
|   1210     case SEQ(r1, r2) => flattenSeq(r1) ++ flattenSeq(r2) |         | 
|   1211     case _ => throw new Error("flatten unflattenable rexp") |         | 
|   1212   }  |         | 
|   1213  |         | 
|   1214   def shortRexpOutput(r: Rexp) : String = r match { |         | 
|   1215       case CHAR(c) => c.toString |         | 
|   1216       case ONE => "1" |         | 
|   1217       case ZERO => "0" |         | 
|   1218       case SEQ(r1, r2) if(allCharSeq(r)) => flattenSeq(r)//"[" ++ shortRexpOutput(r1) ++ "~" ++ shortRexpOutput(r2) ++ "]" |         | 
|   1219       case SEQ(r1, r2) => "[" ++ shortRexpOutput(r1) ++ "~" ++ shortRexpOutput(r2) ++ "]" |         | 
|   1220       case ALTS(r1, r2) => "(" ++ shortRexpOutput(r1) ++ "+" ++ shortRexpOutput(r2) ++ ")" |         | 
|   1221       case STAR(STAR(r)) => "(..)*"// ++ shortRexpOutput(r) ++ "]*" |         | 
|   1222       case STAR(r) => "STAR(" ++ shortRexpOutput(r) ++ ")" |         | 
|   1223       //case RTOP => "RTOP" |         | 
|   1224     } |         | 
|   1225  |         | 
|   1226  |         | 
|   1227   def blex_simp(r: ARexp, s: List[Char]) : Bits = s match { |         | 
|   1228       case Nil => { |         | 
|   1229         if (bnullable(r)) { |         | 
|   1230           val bits = mkepsBC(r) |         | 
|   1231           bits |         | 
|   1232         } |         | 
|   1233         else  |         | 
|   1234           throw new Exception("Not matched") |         | 
|   1235       } |         | 
|   1236       case c::cs => { |         | 
|   1237         val der_res = bder(c,r) |         | 
|   1238         val simp_res = bsimp(der_res)   |         | 
|   1239         blex_simp(simp_res, cs)       |         | 
|   1240       } |         | 
|   1241   } |         | 
|   1242  |         | 
|   1243  |         | 
|   1244  |         | 
|   1245  |         | 
|   1246     def size(r: Rexp) : Int = r match { |         | 
|   1247       case ZERO => 1 |         | 
|   1248       case ONE => 1 |         | 
|   1249       case CHAR(_) => 1 |         | 
|   1250       case ANYCHAR => 1 |         | 
|   1251       case NOT(r0) => 1 + size(r0) |         | 
|   1252       case SEQ(r1, r2) => 1 + size(r1) + size(r2) |         | 
|   1253       case ALTS(r1, r2) => 1 + List(r1, r2).map(size).sum |         | 
|   1254       case STAR(r) => 1 + size(r) |         | 
|   1255     } |         | 
|   1256  |         | 
|   1257     def asize(a: ARexp) = size(erase(a)) |         | 
|   1258  |         | 
|   1259 //pder related |         | 
|   1260 type Mon = (Char, Rexp) |         | 
|   1261 type Lin = Set[Mon] |         | 
|   1262  |         | 
|   1263 def dot_prod(rs: Set[Rexp], r: Rexp): Set[Rexp] = r match { |         | 
|   1264     case ZERO => Set() |         | 
|   1265     case ONE => rs |         | 
|   1266     case r => rs.map((re) => if (re == ONE) r else SEQ(re, r)  )    |         | 
|   1267   } |         | 
|   1268   def cir_prod(l: Lin, t: Rexp): Lin = t match {//remember this Lin is different from the Lin in Antimirov's paper. Here it does not mean the set of all subsets of linear forms that does not contain zero, but rather the type a set of linear forms |         | 
|   1269     case ZERO => Set() |         | 
|   1270     // case ONE => l |         | 
|   1271     case t => l.map( m => m._2 match  |         | 
|   1272       { |         | 
|   1273         case ZERO => m  |         | 
|   1274         case ONE => (m._1, t)  |         | 
|   1275         case p => (m._1, SEQ(p, t))  |         | 
|   1276       }   |         | 
|   1277      |         | 
|   1278     ) |         | 
|   1279   } |         | 
|   1280   def cir_prodList(l : List[Mon], t: Rexp): List[Mon] = t match { |         | 
|   1281     case ZERO => Nil |         | 
|   1282     case ONE => l |         | 
|   1283     case t => l.map(m => m._2 match |         | 
|   1284       { |         | 
|   1285         case ZERO => m |         | 
|   1286         case ONE => (m._1, t) |         | 
|   1287         case p => (m._1, SEQ(p, t)) |         | 
|   1288       } |         | 
|   1289     ) |         | 
|   1290  |         | 
|   1291   } |         | 
|   1292   def lfList(r: Rexp) : List[Mon] = r match { |         | 
|   1293     case ZERO => Nil |         | 
|   1294     case ONE => Nil |         | 
|   1295     case CHAR(f) => { |         | 
|   1296       (f, ONE) :: Nil |         | 
|   1297     } |         | 
|   1298     case ALTS(r1, r2) => { |         | 
|   1299       lfList(r1) ++ lfList(r2) |         | 
|   1300     } |         | 
|   1301     case STAR(r1) => cir_prodList(lfList(r1), STAR(r1)) |         | 
|   1302     case SEQ(r1, r2) => { |         | 
|   1303       if(nullable(r1)) |         | 
|   1304         cir_prodList(lfList(r1), r2) ++ lfList(r2) |         | 
|   1305       else |         | 
|   1306         cir_prodList(lfList(r1), r2) |         | 
|   1307     } |         | 
|   1308   } |         | 
|   1309   def lfprint(ls: Lin) = ls.foreach(m =>{ |         | 
|   1310     println(m._1) |         | 
|   1311     rprint(m._2) |         | 
|   1312     }) |         | 
|   1313   def lf(r: Rexp): Lin = r match { |         | 
|   1314     case ZERO => Set() |         | 
|   1315     case ONE => Set() |         | 
|   1316     case CHAR(f) => { |         | 
|   1317       //val Some(c) = alphabet.find(f)  |         | 
|   1318       Set((f, ONE)) |         | 
|   1319     } |         | 
|   1320     case ALTS(r1, r2) => { |         | 
|   1321       lf(r1 ) ++ lf(r2) |         | 
|   1322     } |         | 
|   1323     case STAR(r1) => cir_prod(lf(r1), STAR(r1)) //may try infix notation later...... |         | 
|   1324     case SEQ(r1, r2) =>{ |         | 
|   1325       if (nullable(r1)) |         | 
|   1326         cir_prod(lf(r1), r2) ++ lf(r2) |         | 
|   1327       else |         | 
|   1328         cir_prod(lf(r1), r2)  |         | 
|   1329     } |         | 
|   1330   } |         | 
|   1331   def lfs(r: Set[Rexp]): Lin = { |         | 
|   1332     r.foldLeft(Set[Mon]())((acc, r) => acc ++ lf(r)) |         | 
|   1333   } |         | 
|   1334  |         | 
|   1335   def pder(x: Char, t: Rexp): Set[Rexp] = { |         | 
|   1336     val lft = lf(t) |         | 
|   1337     (lft.filter(mon => if(mon._1 == x) true else false)).map(mon => mon._2) |         | 
|   1338   } |         | 
|   1339   def pders_single(s: List[Char], t: Rexp) : Set[Rexp] = s match { |         | 
|   1340     case x::xs => pders(xs, pder(x, t)) |         | 
|   1341     case Nil => Set(t) |         | 
|   1342   } |         | 
|   1343   def pders(s: List[Char], ts: Set[Rexp]) : Set[Rexp] = s match { |         | 
|   1344     case x::xs => pders(xs, ts.foldLeft(Set[Rexp]())((acc, t) => acc ++ pder(x, t))) |         | 
|   1345     case Nil => ts  |         | 
|   1346   } |         | 
|   1347   def pderss(ss: List[List[Char]], t: Rexp): Set[Rexp] =  |         | 
|   1348     ss.foldLeft( Set[Rexp]() )( (acc, s) => pders_single(s, t) ++ acc ) |         | 
|   1349   def pdera(t: Rexp): Set[Rexp] = lf(t).map(mon => mon._2) |         | 
|   1350   //all implementation of partial derivatives that involve set union are potentially buggy |         | 
|   1351   //because they don't include the original regular term before they are pdered. |         | 
|   1352   //now only pderas is fixed. |         | 
|   1353   def pderas(t: Set[Rexp], d: Int): Set[Rexp] =  |         | 
|   1354     if(d > 0)  |         | 
|   1355       pderas(lfs(t).map(mon => mon._2), d - 1) ++ t  |         | 
|   1356     else  |         | 
|   1357       lfs(t).map(mon => mon._2) ++ t//repeated application of pderas over the newest set of pders. |         | 
|   1358   def pderUNIV(r: Rexp) : Set[Rexp] = pderas(Set(r), awidth(r) + 1) |   1359   def pderUNIV(r: Rexp) : Set[Rexp] = pderas(Set(r), awidth(r) + 1) | 
|   1359   def awidth(r: Rexp) : Int = r match { |   1360   def awidth(r: Rexp) : Int = r match { | 
|   1360     case CHAR(c) => 1 |   1361     case CHAR(c) => 1 | 
|   1361     case SEQ(r1, r2) => awidth(r1) + awidth(r2) |   1362     case SEQ(r1, r2) => awidth(r1) + awidth(r2) | 
|   1362     case ALTS(r1, r2) => awidth(r1) + awidth(r2) |   1363     case ALTS(r1, r2) => awidth(r1) + awidth(r2) | 
|   1382   } |   1383   } | 
|   1383   def pdpss(ss: List[List[Char]], t: Rexp): Set[Rexp] = ss.foldLeft( Set[Rexp]())((acc, s) => pdps(s, Set(t)) ++ acc) |   1384   def pdpss(ss: List[List[Char]], t: Rexp): Set[Rexp] = ss.foldLeft( Set[Rexp]())((acc, s) => pdps(s, Set(t)) ++ acc) | 
|   1384  |   1385  | 
|   1385  |   1386  | 
|   1386  |   1387  | 
|   1387 def starPrint(r: Rexp) : Unit = r match { |   1388   def starPrint(r: Rexp) : Unit = r match { | 
|   1388          |   1389  | 
|   1389           case SEQ(head, rstar) => |   1390     case SEQ(head, rstar) => | 
|   1390             println(shortRexpOutput(head) ++ "~STARREG") |   1391       println(shortRexpOutput(head) ++ "~STARREG") | 
|   1391           case STAR(rstar) => |   1392     case STAR(rstar) => | 
|   1392             println("STARREG") |   1393       println("STARREG") | 
|   1393           case ALTS(r1, r2) =>   |   1394     case ALTS(r1, r2) =>   | 
|   1394             println("(") |   1395       println("(") | 
|   1395             starPrint(r1) |   1396       starPrint(r1) | 
|   1396             println("+") |   1397       println("+") | 
|   1397             starPrint(r2) |   1398       starPrint(r2) | 
|   1398             println(")") |   1399       println(")") | 
|   1399           case ZERO => println("0") |   1400     case ZERO => println("0") | 
|   1400       } |   1401   } | 
|   1401  |   1402  | 
|   1402 // @arg(doc = "small tests") |   1403   // @arg(doc = "small tests") | 
|   1403 def n_astar_list(d: Int) : Rexp = { |   1404   def n_astar_list(d: Int) : Rexp = { | 
|   1404   if(d == 0) STAR("a")  |   1405     if(d == 0) STAR("a")  | 
|   1405   else ALTS(STAR("a" * d), n_astar_list(d - 1)) |   1406     else ALTS(STAR("a" * d), n_astar_list(d - 1)) | 
|   1406 } |   1407   } | 
|   1407 def n_astar_alts(d: Int) : Rexp = d match { |   1408   def n_astar_alts(d: Int) : Rexp = d match { | 
|   1408   case 0 => n_astar_list(0) |   1409     case 0 => n_astar_list(0) | 
|   1409   case d => STAR(n_astar_list(d)) |   1410     case d => STAR(n_astar_list(d)) | 
|   1410   } |   1411   } | 
|   1411 def n_astar_alts2(d: Int) : Rexp = d match { |   1412   def n_astar_alts2(d: Int) : Rexp = d match { | 
|   1412   case 0 => n_astar_list(0) |   1413     case 0 => n_astar_list(0) | 
|   1413   case d => STAR(STAR(n_astar_list(d))) |   1414     case d => STAR(STAR(n_astar_list(d))) | 
|   1414   } |   1415   } | 
|   1415 def n_astar_aux(d: Int) = { |   1416   def n_astar_aux(d: Int) = { | 
|   1416   if(d == 0) n_astar_alts(0) |   1417     if(d == 0) n_astar_alts(0) | 
|   1417   else ALTS(n_astar_alts(d), n_astar_alts(d - 1)) |   1418     else ALTS(n_astar_alts(d), n_astar_alts(d - 1)) | 
|   1418 } |   1419   } | 
|   1419  |   1420  | 
|   1420 def n_astar(d: Int) : Rexp = STAR(n_astar_aux(d)) |   1421   def n_astar(d: Int) : Rexp = STAR(n_astar_aux(d)) | 
|   1421 //val STARREG = n_astar(3) |   1422   //val STARREG = n_astar(3) | 
|   1422 // ( STAR("a") |  |   1423   // ( STAR("a") |  | 
|   1423 //                  ("a" | "aa").% |  |   1424   //                  ("a" | "aa").% |  | 
|   1424 //                 ( "a" | "aa" | "aaa").%  |   1425   //                 ( "a" | "aa" | "aaa").%  | 
|   1425 //                 ).% |   1426   //                 ).% | 
|   1426                 //( "a" | "aa" | "aaa" | "aaaa").% | |   1427   //( "a" | "aa" | "aaa" | "aaaa").% | | 
|   1427                 //( "a" | "aa" | "aaa" | "aaaa" | "aaaaa").%  |   1428   //( "a" | "aa" | "aaa" | "aaaa" | "aaaaa").%  | 
|   1428 (((STAR("a") | ( STAR("aaa")) | STAR("aaaaa"| ( STAR("aaaaaaa")) | STAR("aaaaaaaaaaa"))).%).%).% |   1429   (((STAR("a") | ( STAR("aaa")) | STAR("aaaaa"| ( STAR("aaaaaaa")) | STAR("aaaaaaaaaaa"))).%).%).% | 
|   1429  |   1430  | 
|   1430 // @main |   1431   // @main | 
|   1431  |   1432  | 
|   1432 def lcm(list: Seq[Int]):Int=list.foldLeft(1:Int){ |   1433   def lcm(list: Seq[Int]):Int=list.foldLeft(1:Int){ | 
|   1433   (a, b) => b * a / |   1434     (a, b) => b * a / | 
|   1434   Stream.iterate((a,b)){case (x,y) => (y, x%y)}.dropWhile(_._2 != 0).head._1.abs |   1435     Stream.iterate((a,b)){case (x,y) => (y, x%y)}.dropWhile(_._2 != 0).head._1.abs | 
|   1435 } |   1436   } | 
|   1436  |   1437  | 
|   1437 def small() = { |   1438   def small() = { | 
|   1438   //val pderSTAR = pderUNIV(STARREG) |   1439     //val pderSTAR = pderUNIV(STARREG) | 
|   1439  |   1440  | 
|   1440   //val refSize = pderSTAR.map(size(_)).sum |   1441     //val refSize = pderSTAR.map(size(_)).sum | 
|   1441   for(n <- 5 to 5){ |   1442     for(n <- 5 to 5){ | 
|   1442     val STARREG = n_astar_alts2(n) |   1443       val STARREG = n_astar_alts2(n) | 
|   1443     val iMax = (lcm((1 to n).toList)) |   1444       val iMax = (lcm((1 to n).toList)) | 
|   1444     for(i <- 0 to iMax ){// 100, 400, 800, 840, 841, 900  |   1445       for(i <- 0 to iMax ){// 100, 400, 800, 840, 841, 900  | 
|   1445       val prog0 = "a" * i |   1446         val prog0 = "a" * i | 
|   1446       //println(s"test: $prog0") |   1447         //println(s"test: $prog0") | 
|   1447       print(i) |   1448         print(i) | 
|   1448       print(" ") |   1449         print(" ") | 
|   1449       // print(i) |   1450         // print(i) | 
|   1450       // print(" ") |   1451         // print(" ") | 
|   1451       println(asize(bders_simp(prog0.toList, internalise(STARREG)))) |   1452         println(asize(bders_simp(prog0.toList, internalise(STARREG)))) | 
|   1452       // println(asize(bdersStrong7(prog0.toList, internalise(STARREG)))) |   1453         // println(asize(bdersStrong(prog0.toList, internalise(STARREG)))) | 
|   1453     } |   1454       } | 
|   1454      |   1455  | 
|   1455   } |   1456     } | 
|   1456 } |   1457   } | 
|   1457 // small() |   1458   // small() | 
|   1458  |   1459  | 
|   1459 def aaa_star() = { |   1460   def aaa_star() = { | 
|   1460   val r = STAR(("a" | "aa")) |   1461     val r = STAR(("a" | "aa")) | 
|   1461   for(i <- 0 to 20) { |   1462     for(i <- 0 to 20) { | 
|   1462     val prog = "a" * i |   1463       val prog = "a" * i | 
|   1463     print(i+" ") |   1464       print(i+" ") | 
|   1464     println(asize(bders_simp(prog.toList, internalise(r)))) |   1465       println(asize(bders_simp(prog.toList, internalise(r)))) | 
|   1465     //println(size(ders_simp(prog.toList, r))) |   1466       //println(size(ders_simp(prog.toList, r))) | 
|   1466   } |   1467     } | 
|   1467 } |   1468   } | 
|   1468 // aaa_star() |   1469   // aaa_star() | 
|   1469  |   1470  | 
|   1470 def matching_ways_counting(n: Int): Int =  |   1471   def matching_ways_counting(n: Int): Int =  | 
|   1471   { |   1472   { | 
|   1472     if(n == 0) 1 |   1473     if(n == 0) 1 | 
|   1473     else if(n == 1) 2 |   1474     else if(n == 1) 2 | 
|   1474     else (for(i <- 1 to n - 1)  |   1475     else (for(i <- 1 to n - 1)  | 
|   1475       yield matching_ways_counting(i) * matching_ways_counting(n - i) ).sum + (n + 1) |   1476       yield matching_ways_counting(i) * matching_ways_counting(n - i) ).sum + (n + 1) | 
|   1476   } |   1477   } | 
|   1477 def naive_matcher() { |   1478   def naive_matcher() { | 
|   1478   val r = STAR(STAR("a") ~ STAR("a")) |   1479     val r = STAR(STAR("a") ~ STAR("a")) | 
|   1479  |   1480  | 
|   1480   // for(i <- 0 to 10) { |   1481     // for(i <- 0 to 10) { | 
|   1481   //   val s = "a" * i  |   1482     //   val s = "a" * i  | 
|   1482   //   val t1 = System.nanoTime |   1483     //   val t1 = System.nanoTime | 
|   1483   //   matcher(s, r) |   1484     //   matcher(s, r) | 
|   1484   //   val duration = (System.nanoTime - t1) / 1e9d |   1485     //   val duration = (System.nanoTime - t1) / 1e9d | 
|   1485   //   print(i) |   1486     //   print(i) | 
|   1486   //   print(" ") |   1487     //   print(" ") | 
|   1487   //   // print(duration) |   1488     //   // print(duration) | 
|   1488   //   // print(" ") |   1489     //   // print(" ") | 
|   1489   //   (aprint(bders_simp(s.toList, internalise(r)))) |   1490     //   (aprint(bders_simp(s.toList, internalise(r)))) | 
|   1490   //   //print(size(ders_simp(s.toList, r))) |   1491     //   //print(size(ders_simp(s.toList, r))) | 
|   1491   //   println() |   1492     //   println() | 
|   1492   // } |   1493     // } | 
|   1493   for(i <- 1 to 3) { |   1494     for(i <- 1 to 3) { | 
|   1494     val s = "a" * i |   1495       val s = "a" * i | 
|   1495     val t1 = System.nanoTime |   1496       val t1 = System.nanoTime | 
|   1496     val derssimp_result = ders_simp(s.toList, r) |   1497       val derssimp_result = ders_simp(s.toList, r) | 
|   1497     println(i) |   1498       println(i) | 
|   1498     println(matching_ways_counting(i)) |   1499       println(matching_ways_counting(i)) | 
|   1499     println(size(derssimp_result)) |   1500       println(size(derssimp_result)) | 
|   1500     rprint(derssimp_result) |   1501       rprint(derssimp_result) | 
|   1501   } |   1502     } | 
|   1502    |   1503  | 
|   1503 } |   1504   } | 
|   1504 naive_matcher() |   1505   naive_matcher() | 
|   1505 //single(SEQ(SEQ(STAR(CHAR('b')),STAR(STAR(SEQ(CHAR('a'),CHAR('b'))))), |   1506   //single(SEQ(SEQ(STAR(CHAR('b')),STAR(STAR(SEQ(CHAR('a'),CHAR('b'))))), | 
|   1506 //  SEQ(SEQ(CHAR('b'),STAR(ALTS(CHAR('a'),ONE))),ONE))) |   1507   //  SEQ(SEQ(CHAR('b'),STAR(ALTS(CHAR('a'),ONE))),ONE))) | 
|   1507  |   1508  | 
|   1508  |   1509  | 
|   1509 //STAR(SEQ(ALTS(CHAR(b),STAR(CHAR(b))),ALTS(ALTS(ONE,CHAR(b)),SEQ(CHAR(c),ONE)))) |   1510   //STAR(SEQ(ALTS(CHAR(b),STAR(CHAR(b))),ALTS(ALTS(ONE,CHAR(b)),SEQ(CHAR(c),ONE)))) | 
|   1510 def generator_test() { |   1511   def generator_test() { | 
|   1511  |   1512  | 
|   1512   test(single(STAR(SEQ(ALTS(STAR(CHAR('b')),ALTS(CHAR('b'),CHAR('a'))),ALTS(ALTS(CHAR('b'),CHAR('c')),STAR(ZERO))))), 1) { (r: Rexp) =>  |   1513     test(single(STAR(SEQ(ALTS(STAR(CHAR('b')),ALTS(CHAR('b'),CHAR('a'))),ALTS(ALTS(CHAR('b'),CHAR('c')),STAR(ZERO))))), 1) { (r: Rexp) =>  | 
|   1513   // ALTS(SEQ(SEQ(ONE,CHAR('a')),STAR(CHAR('a'))),SEQ(ALTS(CHAR('c'),ONE),STAR(ZERO))))))), 1) { (r: Rexp) =>  |   1514       // ALTS(SEQ(SEQ(ONE,CHAR('a')),STAR(CHAR('a'))),SEQ(ALTS(CHAR('c'),ONE),STAR(ZERO))))))), 1) { (r: Rexp) =>  | 
|   1514     val ss = Set("ab")//stringsFromRexp(r) |   1515       val ss = Set("ab")//stringsFromRexp(r) | 
|   1515     val boolList = ss.map(s => { |   1516       val boolList = ss.map(s => { | 
|   1516       //val bdStrong = bdersStrong(s.toList, internalise(r)) |   1517         //val bdStrong = bdersStrong(s.toList, internalise(r)) | 
|   1517       val bdStrong6 = bdersStrong6(s.toList, internalise(r)) |   1518         val bdStrong6 = bdersStrong6(s.toList, internalise(r)) | 
|   1518       val bdStrong6Set = breakIntoTerms(erase(bdStrong6)) |   1519         val bdStrong6Set = breakIntoTerms(erase(bdStrong6)) | 
|   1519       val pdersSet = pderUNIV(r)//.flatMap(r => turnIntoTerms(r)) |   1520         val pdersSet = pderUNIV(r)//.flatMap(r => turnIntoTerms(r)) | 
|   1520       val pdersSetBroken = pdersSet.flatMap(r => turnIntoTerms(r)) |   1521         val pdersSetBroken = pdersSet.flatMap(r => turnIntoTerms(r)) | 
|   1521       (rs1_subseteq_rs2(bdStrong6Set.toSet, distinctByacc(pdersSet.toList)) || |   1522         (rs1_subseteq_rs2(bdStrong6Set.toSet, distinctByacc(pdersSet.toList)) || | 
|   1522       bdStrong6Set.size <= pdersSet.size || bdStrong6Set.size <= pdersSetBroken.size || |   1523           bdStrong6Set.size <= pdersSet.size || bdStrong6Set.size <= pdersSetBroken.size || | 
|   1523       rs1_subseteq_rs2(bdStrong6Set.toSet, pdersSet union pdersSetBroken))//|| bdStrong6Set.size <= pdersSetBroken.size |   1524           rs1_subseteq_rs2(bdStrong6Set.toSet, pdersSet union pdersSetBroken))//|| bdStrong6Set.size <= pdersSetBroken.size | 
|   1524        |   1525  | 
|   1525     }) |   1526       }) | 
|   1526     //!boolList.exists(b => b == false) |   1527       //!boolList.exists(b => b == false) | 
|   1527     !boolList.exists(b => b == false) |   1528       !boolList.exists(b => b == false) | 
|   1528   } |   1529       } | 
|   1529 } |   1530     } | 
|   1530 // small() |   1531     // small() | 
|   1531 // generator_test() |   1532     // generator_test() | 
|   1532  |   1533  | 
|   1533  |   1534  | 
|   1534    |   1535  | 
|   1535   //STAR(STAR(STAR(SEQ(SEQ(ALTS(STAR(ALTS(ONE,CHAR('c'))), |   1536     //STAR(STAR(STAR(SEQ(SEQ(ALTS(STAR(ALTS(ONE,CHAR('c'))), | 
|   1536           //  CHAR('c')),ALTS(CHAR('a'),ALTS(STAR(CHAR('b')),ALTS(CHAR('a'),ZERO)))), |   1537     //  CHAR('c')),ALTS(CHAR('a'),ALTS(STAR(CHAR('b')),ALTS(CHAR('a'),ZERO)))), | 
|   1537           //  CHAR('c')))))//SEQ(STAR(CHAR('c')),STAR(SEQ(STAR(CHAR('c')),ONE)))//STAR(SEQ(ALTS(STAR(CHAR('c')),CHAR('c')),SEQ(ALTS(CHAR('c'),ONE),ONE))) |   1538     //  CHAR('c')))))//SEQ(STAR(CHAR('c')),STAR(SEQ(STAR(CHAR('c')),ONE)))//STAR(SEQ(ALTS(STAR(CHAR('c')),CHAR('c')),SEQ(ALTS(CHAR('c'),ONE),ONE))) | 
|   1538 //counterexample1: STAR(SEQ(ALTS(STAR(ZERO),ALTS(CHAR(a),CHAR(b))),SEQ(ONE,ALTS(CHAR(a),CHAR(b))))) |   1539     //counterexample1: STAR(SEQ(ALTS(STAR(ZERO),ALTS(CHAR(a),CHAR(b))),SEQ(ONE,ALTS(CHAR(a),CHAR(b))))) | 
|   1539 //counterexample2: SEQ(ALTS(SEQ(CHAR(a),STAR(ONE)),STAR(ONE)),ALTS(CHAR(a),SEQ(ALTS(CHAR(c),CHAR(a)),CHAR(b)))) |   1540     //counterexample2: SEQ(ALTS(SEQ(CHAR(a),STAR(ONE)),STAR(ONE)),ALTS(CHAR(a),SEQ(ALTS(CHAR(c),CHAR(a)),CHAR(b)))) | 
|   1540  |   1541  | 
|   1541 //new ce1 : STAR(SEQ(ALTS(ALTS(ONE,CHAR(a)),SEQ(ONE,CHAR(b))),ALTS(CHAR(a),ALTS(CHAR(b),CHAR(a))))) |   1542     //new ce1 : STAR(SEQ(ALTS(ALTS(ONE,CHAR(a)),SEQ(ONE,CHAR(b))),ALTS(CHAR(a),ALTS(CHAR(b),CHAR(a))))) | 
|   1542 //new ce2 : ALTS(CHAR(b),SEQ(ALTS(ZERO,ALTS(CHAR(b),CHAR(b))),ALTS(ALTS(CHAR(a),CHAR(b)),SEQ(CHAR(c),ONE)))) |   1543     //new ce2 : ALTS(CHAR(b),SEQ(ALTS(ZERO,ALTS(CHAR(b),CHAR(b))),ALTS(ALTS(CHAR(a),CHAR(b)),SEQ(CHAR(c),ONE)))) | 
|   1543 //new ce3 : SEQ(CHAR(b),ALTS(ALTS(ALTS(ONE,CHAR(a)),SEQ(CHAR(c),ONE)),SEQ(STAR(ZERO),SEQ(ONE,CHAR(b))))) |   1544     //new ce3 : SEQ(CHAR(b),ALTS(ALTS(ALTS(ONE,CHAR(a)),SEQ(CHAR(c),ONE)),SEQ(STAR(ZERO),SEQ(ONE,CHAR(b))))) | 
|   1544 //circular double-nullable STAR(SEQ((STAR("b") | "a" | "b"), ("b" | ONE))) |   1545     //circular double-nullable STAR(SEQ((STAR("b") | "a" | "b"), ("b" | ONE))) | 
|   1545 def counterexample_check() { |   1546     def counterexample_check() { | 
|   1546   val r = STAR(SEQ(ALTS(STAR(CHAR('b')),ALTS(CHAR('b'),CHAR('a'))), |   1547       val r = STAR(SEQ(ALTS(STAR(CHAR('b')),ALTS(CHAR('b'),CHAR('a'))), | 
|   1547     ALTS(ALTS(CHAR('b'),CHAR('c')),STAR(ZERO))))//SEQ(SEQ(STAR(ALTS(CHAR('a'),CHAR('b'))), |   1548         ALTS(ALTS(CHAR('b'),CHAR('c')),STAR(ZERO))))//SEQ(SEQ(STAR(ALTS(CHAR('a'),CHAR('b'))), | 
|   1548     //ALTS(ALTS(CHAR('c'),CHAR('b')),STAR(ONE))),STAR(CHAR('b'))) |   1549       //ALTS(ALTS(CHAR('c'),CHAR('b')),STAR(ONE))),STAR(CHAR('b'))) | 
|   1549   val s = "ab" |   1550       val s = "ab" | 
|   1550   val bdStrong5 = bdersStrong6(s.toList, internalise(r)) |   1551       val bdStrong5 = bdersStrong6(s.toList, internalise(r)) | 
|   1551   val bdStrong5Set = breakIntoTerms(erase(bdStrong5)) |   1552       val bdStrong5Set = breakIntoTerms(erase(bdStrong5)) | 
|   1552   val pdersSet = pderUNIV(r)//.map(r => erase(bsimp(internalise(r))))//.flatMap(r => turnIntoTerms(r))//.map(oneSimp).flatMap(r => breakIntoTerms(r)) |   1553       val pdersSet = pderUNIV(r)//.map(r => erase(bsimp(internalise(r))))//.flatMap(r => turnIntoTerms(r))//.map(oneSimp).flatMap(r => breakIntoTerms(r)) | 
|   1553   val apdersSet = pdersSet.map(internalise) |   1554       val apdersSet = pdersSet.map(internalise) | 
|   1554   println("original regex ") |   1555       println("original regex ") | 
|   1555   rprint(r) |         | 
|   1556   println("after strong bsimp") |         | 
|   1557   aprint(bdStrong5) |         | 
|   1558   println("turned into a set %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%   ") |         | 
|   1559   rsprint(bdStrong5Set) |         | 
|   1560   println("after pderUNIV") |         | 
|   1561   rsprint(pdersSet.toList) |         | 
|   1562   println("pderUNIV distinctBy6") |         | 
|   1563   //asprint(distinctBy6(apdersSet.toList)) |         | 
|   1564   rsprint((pdersSet.toList).flatMap(turnIntoTerms)) |         | 
|   1565   // rsprint(turnIntoTerms(pdersSet.toList(3))) |         | 
|   1566   // println("NO 3 not into terms") |         | 
|   1567   // rprint((pdersSet.toList())) |         | 
|   1568   // println("after pderUNIV broken") |         | 
|   1569   // rsprint(pdersSet.flatMap(r => turnIntoTerms(r)).toList) |         | 
|   1570  |         | 
|   1571 } |         | 
|   1572  |         | 
|   1573 // counterexample_check() |         | 
|   1574  |         | 
|   1575 def lf_display() { |         | 
|   1576   val r = STAR(SEQ(ALTS(STAR(CHAR('b')),ALTS(CHAR('b'),CHAR('a'))), |         | 
|   1577     ALTS(ALTS(CHAR('b'),CHAR('c')),STAR(ZERO))))//SEQ(SEQ(STAR(ALTS(CHAR('a'),CHAR('b'))), |         | 
|   1578     //ALTS(ALTS(CHAR('c'),CHAR('b')),STAR(ONE))),STAR(CHAR('b'))) |         | 
|   1579   val s = "ab" |         | 
|   1580   val bdStrong5 = bdersStrong6(s.toList, internalise(r)) |         | 
|   1581   val bdStrong5Set = breakIntoTerms(erase(bdStrong5)) |         | 
|   1582   val pdersSet = pderUNIV(r)//.map(r => erase(bsimp(internalise(r))))//.flatMap(r => turnIntoTerms(r))//.map(oneSimp).flatMap(r => breakIntoTerms(r)) |         | 
|   1583   val apdersSet = pdersSet.map(internalise) |         | 
|   1584   lfprint(lf(r)) |         | 
|   1585  |         | 
|   1586 } |         | 
|   1587  |         | 
|   1588 lf_display() |         | 
|   1589  |         | 
|   1590 def breakable(r: Rexp) : Boolean = r match { |         | 
|   1591   case SEQ(ALTS(_, _), _) => true |         | 
|   1592   case SEQ(r1, r2) => breakable(r1) |         | 
|   1593   case _ => false |         | 
|   1594 } |         | 
|   1595  |         | 
|   1596 def linform_test() { |         | 
|   1597   val r = STAR(SEQ(STAR(CHAR('c')),ONE))//SEQ(STAR(CHAR('c')),STAR(SEQ(STAR(CHAR('c')),ONE))) // |         | 
|   1598   val r_linforms = lf(r) |         | 
|   1599   println(r_linforms.size) |         | 
|   1600   val pderuniv = pderUNIV(r) |         | 
|   1601   println(pderuniv.size) |         | 
|   1602 } |         | 
|   1603 // linform_test() |         | 
|   1604 // 1 |         | 
|   1605 def newStrong_test() { |         | 
|   1606   val r2 = (CHAR('b') | ONE) |         | 
|   1607   val r0 = CHAR('d') |         | 
|   1608   val r1 = (ONE | CHAR('c')) |         | 
|   1609   val expRexp = (SEQ(r2, r0) | SEQ(SEQ(r1, r2), r0)) |         | 
|   1610   println(s"original regex is: ") |         | 
|   1611   rprint(expRexp) |         | 
|   1612   val expSimp5 = strongBsimp5(internalise(expRexp)) |         | 
|   1613   val expSimp6 = strongBsimp6(internalise(expRexp)) |         | 
|   1614   aprint(expSimp5) |         | 
|   1615   aprint(expSimp6) |         | 
|   1616 } |         | 
|   1617 // newStrong_test() |         | 
|   1618 // SEQ(SEQ(SEQ(ONE,CHAR('b')),STAR(CHAR('b'))), |         | 
|   1619 // SEQ(ALTS(ALTS(ZERO,STAR(CHAR('b'))), |         | 
|   1620 // STAR(ALTS(CHAR('a'),SEQ(SEQ(STAR(ALTS(STAR(CHAR('c')),CHAR('a'))), |         | 
|   1621 // SEQ(CHAR('a'),SEQ(ALTS(CHAR('b'),ZERO),SEQ(ONE,CHAR('b'))))),ONE)))),ONE)) |         | 
|   1622  |         | 
|   1623  |         | 
|   1624 // Sequ(Sequ(Sequ(Empty,Chr(b)),Stars(List(Chr(b), Chr(b)))),Sequ(Right(Stars(List(Right(Sequ(Sequ(Stars(List(Right(Chr(a)), Right(Chr(a)))),Sequ(Chr(a),Sequ(Left(Chr(b)),Sequ(Empty,Chr(b))))),Empty)), Right(Sequ(Sequ(Stars(List(Right(Chr(a)), Right(Chr(a)))),Sequ(Chr(a),Sequ(Left(Chr(b)),Sequ(Empty,Chr(b))))),Empty))))),Empty)) |         | 
|   1625 // Sequ(Sequ(Sequ(Empty,Chr(b)),Stars(List(Chr(b), Chr(b)))),Sequ(Right(Stars(List(Right(Sequ(Sequ(Stars(List(Right(Chr(a)), Right(Chr(a)))),Sequ(Chr(a),Sequ(Left(Chr(b)),Sequ(Empty,Chr(b))))),Empty)), Right(Sequ(Sequ(Stars(List(Right(Chr(a)), Right(Chr(a)))),Sequ(Chr(a),Sequ(Left(Chr(b)),Sequ(Empty,Chr(b))))),Empty))))),Empty)) |         | 
|   1626  |         | 
|   1627  |         | 
|   1628  |         | 
|   1629  |         | 
|   1630  |         | 
|   1631 def bders_bderssimp() { |         | 
|   1632  |         | 
|   1633   test(single(SEQ(ALTS(ONE,CHAR('c')), |         | 
|   1634   SEQ(SEQ(CHAR('a'),CHAR('a')),ALTS(ONE,CHAR('c'))))), 1) { (r: Rexp) =>  |         | 
|   1635   // ALTS(SEQ(SEQ(ONE,CHAR('a')),STAR(CHAR('a'))),SEQ(ALTS(CHAR('c'),ONE),STAR(ZERO))))))), 1) { (r: Rexp) =>  |         | 
|   1636     val ss = Set("aa")//stringsFromRexp(r) |         | 
|   1637     val boolList = ss.map(s => { |         | 
|   1638       //val bdStrong = bdersStrong(s.toList, internalise(r)) |         | 
|   1639       val bds = bsimp(bders(s.toList, internalise(r))) |         | 
|   1640       val bdssimp = bsimp(bders_simp(s.toList, internalise(r))) |         | 
|   1641       //val pdersSet = pderUNIV(r)//.flatMap(r => turnIntoTerms(r)) |         | 
|   1642       //val pdersSetBroken = pdersSet.flatMap(r => turnIntoTerms(r)) |         | 
|   1643       //rs1_subseteq_rs2(bdStrong6Set.toSet, distinctByacc(pdersSet.toList)) |         | 
|   1644       //bdStrong6Set.size <= pdersSet.size || bdStrong6Set.size <= pdersSetBroken.size || |         | 
|   1645       //rs1_subseteq_rs2(bdStrong6Set.toSet, pdersSet union pdersSetBroken)//|| bdStrong6Set.size <= pdersSetBroken.size |         | 
|   1646       rprint(r) |   1556       rprint(r) | 
|   1647       println(bds) |   1557       println("after strong bsimp") | 
|   1648       println(bdssimp) |   1558       aprint(bdStrong5) | 
|   1649       bds == bdssimp |   1559       println("turned into a set %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%   ") | 
|   1650     }) |   1560       rsprint(bdStrong5Set) | 
|   1651     //!boolList.exists(b => b == false) |   1561       println("after pderUNIV") | 
|   1652     !boolList.exists(b => b == false) |   1562       rsprint(pdersSet.toList) | 
|   1653   } |   1563       println("pderUNIV distinctBy6") | 
|   1654 } |   1564       //asprint(distinctBy6(apdersSet.toList)) | 
|   1655 //  bders_bderssimp() |   1565       rsprint((pdersSet.toList).flatMap(turnIntoTerms)) | 
|   1656    |   1566       // rsprint(turnIntoTerms(pdersSet.toList(3))) | 
|   1657  |   1567       // println("NO 3 not into terms") | 
|   1658  |   1568       // rprint((pdersSet.toList())) | 
|         |   1569       // println("after pderUNIV broken") | 
|         |   1570       // rsprint(pdersSet.flatMap(r => turnIntoTerms(r)).toList) | 
|         |   1571  | 
|         |   1572     } | 
|         |   1573  | 
|         |   1574     // counterexample_check() | 
|         |   1575  | 
|         |   1576     def lf_display() { | 
|         |   1577       val r = STAR(SEQ(ALTS(STAR(CHAR('b')),ALTS(CHAR('b'),CHAR('a'))), | 
|         |   1578         ALTS(ALTS(CHAR('b'),CHAR('c')),STAR(ZERO))))//SEQ(SEQ(STAR(ALTS(CHAR('a'),CHAR('b'))), | 
|         |   1579       //ALTS(ALTS(CHAR('c'),CHAR('b')),STAR(ONE))),STAR(CHAR('b'))) | 
|         |   1580       val s = "ab" | 
|         |   1581       val bdStrong5 = bdersStrong6(s.toList, internalise(r)) | 
|         |   1582       val bdStrong5Set = breakIntoTerms(erase(bdStrong5)) | 
|         |   1583       val pdersSet = pderUNIV(r)//.map(r => erase(bsimp(internalise(r))))//.flatMap(r => turnIntoTerms(r))//.map(oneSimp).flatMap(r => breakIntoTerms(r)) | 
|         |   1584       val apdersSet = pdersSet.map(internalise) | 
|         |   1585       lfprint(lf(r)) | 
|         |   1586  | 
|         |   1587     } | 
|         |   1588  | 
|         |   1589     lf_display() | 
|         |   1590  | 
|         |   1591     def breakable(r: Rexp) : Boolean = r match { | 
|         |   1592       case SEQ(ALTS(_, _), _) => true | 
|         |   1593       case SEQ(r1, r2) => breakable(r1) | 
|         |   1594       case _ => false | 
|         |   1595     } | 
|         |   1596  | 
|         |   1597     def linform_test() { | 
|         |   1598       val r = STAR(SEQ(STAR(CHAR('c')),ONE))//SEQ(STAR(CHAR('c')),STAR(SEQ(STAR(CHAR('c')),ONE))) // | 
|         |   1599       val r_linforms = lf(r) | 
|         |   1600       println(r_linforms.size) | 
|         |   1601       val pderuniv = pderUNIV(r) | 
|         |   1602       println(pderuniv.size) | 
|         |   1603     } | 
|         |   1604     // linform_test() | 
|         |   1605     // 1 | 
|         |   1606     def newStrong_test() { | 
|         |   1607       val r2 = (CHAR('b') | ONE) | 
|         |   1608       val r0 = CHAR('d') | 
|         |   1609       val r1 = (ONE | CHAR('c')) | 
|         |   1610       val expRexp = (SEQ(r2, r0) | SEQ(SEQ(r1, r2), r0)) | 
|         |   1611       println(s"original regex is: ") | 
|         |   1612       rprint(expRexp) | 
|         |   1613       val expSimp5 = strongBsimp5(internalise(expRexp)) | 
|         |   1614       val expSimp6 = strongBsimp6(internalise(expRexp)) | 
|         |   1615       aprint(expSimp5) | 
|         |   1616       aprint(expSimp6) | 
|         |   1617     } | 
|         |   1618     // newStrong_test() | 
|         |   1619     // SEQ(SEQ(SEQ(ONE,CHAR('b')),STAR(CHAR('b'))), | 
|         |   1620     // SEQ(ALTS(ALTS(ZERO,STAR(CHAR('b'))), | 
|         |   1621     // STAR(ALTS(CHAR('a'),SEQ(SEQ(STAR(ALTS(STAR(CHAR('c')),CHAR('a'))), | 
|         |   1622     // SEQ(CHAR('a'),SEQ(ALTS(CHAR('b'),ZERO),SEQ(ONE,CHAR('b'))))),ONE)))),ONE)) | 
|         |   1623  | 
|         |   1624  | 
|         |   1625     // Sequ(Sequ(Sequ(Empty,Chr(b)),Stars(List(Chr(b), Chr(b)))),Sequ(Right(Stars(List(Right(Sequ(Sequ(Stars(List(Right(Chr(a)), Right(Chr(a)))),Sequ(Chr(a),Sequ(Left(Chr(b)),Sequ(Empty,Chr(b))))),Empty)), Right(Sequ(Sequ(Stars(List(Right(Chr(a)), Right(Chr(a)))),Sequ(Chr(a),Sequ(Left(Chr(b)),Sequ(Empty,Chr(b))))),Empty))))),Empty)) | 
|         |   1626     // Sequ(Sequ(Sequ(Empty,Chr(b)),Stars(List(Chr(b), Chr(b)))),Sequ(Right(Stars(List(Right(Sequ(Sequ(Stars(List(Right(Chr(a)), Right(Chr(a)))),Sequ(Chr(a),Sequ(Left(Chr(b)),Sequ(Empty,Chr(b))))),Empty)), Right(Sequ(Sequ(Stars(List(Right(Chr(a)), Right(Chr(a)))),Sequ(Chr(a),Sequ(Left(Chr(b)),Sequ(Empty,Chr(b))))),Empty))))),Empty)) | 
|         |   1627  | 
|         |   1628  | 
|         |   1629  | 
|         |   1630  | 
|         |   1631  | 
|         |   1632     def bders_bderssimp() { | 
|         |   1633  | 
|         |   1634       test(single(SEQ(ALTS(ONE,CHAR('c')), | 
|         |   1635         SEQ(SEQ(CHAR('a'),CHAR('a')),ALTS(ONE,CHAR('c'))))), 1) { (r: Rexp) =>  | 
|         |   1636           // ALTS(SEQ(SEQ(ONE,CHAR('a')),STAR(CHAR('a'))),SEQ(ALTS(CHAR('c'),ONE),STAR(ZERO))))))), 1) { (r: Rexp) =>  | 
|         |   1637           val ss = Set("aa")//stringsFromRexp(r) | 
|         |   1638           val boolList = ss.map(s => { | 
|         |   1639             //val bdStrong = bdersStrong(s.toList, internalise(r)) | 
|         |   1640             val bds = bsimp(bders(s.toList, internalise(r))) | 
|         |   1641             val bdssimp = bsimp(bders_simp(s.toList, internalise(r))) | 
|         |   1642             //val pdersSet = pderUNIV(r)//.flatMap(r => turnIntoTerms(r)) | 
|         |   1643             //val pdersSetBroken = pdersSet.flatMap(r => turnIntoTerms(r)) | 
|         |   1644             //rs1_subseteq_rs2(bdStrong6Set.toSet, distinctByacc(pdersSet.toList)) | 
|         |   1645             //bdStrong6Set.size <= pdersSet.size || bdStrong6Set.size <= pdersSetBroken.size || | 
|         |   1646             //rs1_subseteq_rs2(bdStrong6Set.toSet, pdersSet union pdersSetBroken)//|| bdStrong6Set.size <= pdersSetBroken.size | 
|         |   1647             rprint(r) | 
|         |   1648             println(bds) | 
|         |   1649             println(bdssimp) | 
|         |   1650             bds == bdssimp | 
|         |   1651           }) | 
|         |   1652           //!boolList.exists(b => b == false) | 
|         |   1653           !boolList.exists(b => b == false) | 
|         |   1654           } | 
|         |   1655         } | 
|         |   1656         //  bders_bderssimp() | 
|         |   1657  | 
|         |   1658  | 
|         |   1659  |