390
|
1 |
// package zre
|
|
2 |
//Zre5: eliminated mems table
|
|
3 |
|
|
4 |
|
|
5 |
|
|
6 |
import scala.collection.mutable.{Map => MMap}
|
|
7 |
import scala.collection.mutable.{ArrayBuffer => MList}
|
|
8 |
//import pprint._
|
|
9 |
|
|
10 |
import scala.util.Try
|
|
11 |
|
|
12 |
|
|
13 |
|
|
14 |
abstract class Val
|
|
15 |
case object Empty extends Val
|
|
16 |
case class Chr(c: Char) extends Val
|
|
17 |
case class Sequ(v1: Val, v2: Val) extends Val
|
|
18 |
case class Left(v: Val) extends Val
|
|
19 |
case class Right(v: Val) extends Val
|
|
20 |
case class Stars(vs: List[Val]) extends Val
|
|
21 |
case object DummyFilling extends Val
|
|
22 |
|
|
23 |
|
|
24 |
// abstract class Rexp {
|
|
25 |
// def equals(other: Rexp) : Boolean = this.eq(other)
|
|
26 |
// }
|
|
27 |
abstract class Rexp
|
|
28 |
case object ZERO extends Rexp // matches nothing
|
|
29 |
case object ONE extends Rexp // matches an empty string
|
|
30 |
case class CHAR(c: Char) extends Rexp // matches a character c
|
|
31 |
case class ALT(r1: Rexp, r2: Rexp) extends Rexp // alternative
|
|
32 |
case class AL1(r1: Rexp) extends Rexp
|
|
33 |
case class SEQ(r1: Rexp, r2: Rexp) extends Rexp // sequence
|
|
34 |
case class STAR(r: Rexp) extends Rexp
|
|
35 |
case object RTOP extends Rexp
|
|
36 |
|
|
37 |
|
|
38 |
//Seq a b --> Seq Seqa Seqb
|
|
39 |
//Seq a b --> Sequ chra chrb
|
|
40 |
//ALT r1 r2 --> mALT
|
|
41 |
// AltC L AltC R
|
|
42 |
var cyclicPreventionList : Set[Int]= Set()
|
|
43 |
abstract class Ctx
|
|
44 |
case object RootC extends Ctx
|
|
45 |
case class SeqC( mForMyself: Mem, processedSibling: List[Val], unpSibling: List[Rexp]) extends Ctx
|
|
46 |
case class AltC( mForMyself: Mem, wrapper: Val => Val) extends Ctx
|
|
47 |
case class StarC(mForMyself: Mem, vs: List[Val], inside: Rexp) extends Ctx
|
|
48 |
|
|
49 |
case class Mem(var parents: List[Ctx], var result : MList[(Int, Val)])
|
|
50 |
|
|
51 |
//AltC(Mem(RootC::Nil, Map()))
|
|
52 |
|
|
53 |
|
|
54 |
|
|
55 |
type Zipper = (Val, Mem)
|
|
56 |
|
|
57 |
var mems : MMap[(Int, Rexp), Mem] = MMap()
|
|
58 |
//start pos, original regex --> result entry
|
|
59 |
|
|
60 |
|
|
61 |
var pos : Int = 0
|
|
62 |
|
|
63 |
|
|
64 |
|
|
65 |
//input ..................
|
|
66 |
// ^ ^
|
|
67 |
// p q
|
|
68 |
// r
|
|
69 |
|
|
70 |
//parse r[p...q] --> v
|
|
71 |
|
|
72 |
|
|
73 |
def check_before_down(c: Ctx, r: Rexp, d: Int = 0) : List[Zipper] = {
|
|
74 |
mems.get((pos, r)) match {
|
|
75 |
case Some(m) =>
|
|
76 |
m.parents = c::Nil//c::m.parents
|
|
77 |
m.result.find(tup2 => tup2._1 == pos) match {
|
|
78 |
// case Some((i, v)) =>
|
|
79 |
// original_up(v, c, d)
|
|
80 |
case None =>
|
|
81 |
List()
|
|
82 |
}
|
|
83 |
case None =>
|
|
84 |
val m = Mem(c::Nil, MList.empty[(Int, Val)])
|
|
85 |
mems = mems + ((pos, r) -> m)
|
|
86 |
original_down(r, m, d)
|
|
87 |
}
|
|
88 |
}
|
|
89 |
|
|
90 |
|
|
91 |
|
|
92 |
def mem_up(vres: Val, m: Mem, rec_depth : Int = 0) : List[Zipper] = {
|
|
93 |
m.result += (pos -> vres)
|
|
94 |
m.parents.flatMap((c: Ctx) =>
|
|
95 |
original_up(vres, c, rec_depth)
|
|
96 |
)
|
|
97 |
}
|
|
98 |
|
|
99 |
def original_down(r: Rexp, m: Mem, d: Int = 0) : List[Zipper] = (r, m) match {
|
|
100 |
case (CHAR(b), m) => {
|
|
101 |
if (input(pos) == b) {
|
|
102 |
List((Chr(b), m))
|
|
103 |
}
|
|
104 |
else
|
|
105 |
Nil
|
|
106 |
}
|
|
107 |
case (ONE, m) => mem_up(Empty, m, d + 1)
|
|
108 |
case (SEQ(r1, r2), m) =>
|
|
109 |
|
|
110 |
val mprime = Mem(AltC(m, x => x )::Nil, MList.empty[(Int, Val)])
|
|
111 |
|
|
112 |
check_before_down(SeqC(mprime, Nil, List(r2)), r1, d)
|
|
113 |
case (ALT(r1, r2), m) =>
|
|
114 |
|
|
115 |
check_before_down(AltC(m, Left(_)), r1, d) :::
|
|
116 |
check_before_down(AltC(m, Right(_)), r2, d)
|
|
117 |
case (STAR(r0), m) =>
|
|
118 |
|
|
119 |
check_before_down(StarC(m, Nil, r0), r0, d)
|
|
120 |
case (_, _) => throw new Exception("original down unexpected r or m")
|
|
121 |
}
|
|
122 |
|
|
123 |
def original_up(v: Val, c: Ctx, d: Int = 0) : List[Zipper] =
|
|
124 |
{
|
|
125 |
|
|
126 |
(v, c) match {
|
|
127 |
case (v, SeqC(m, v1::Nil, Nil)) =>
|
|
128 |
mem_up(Sequ(v1, v), m, d + 1)
|
|
129 |
case (v, SeqC(m, Nil, u1::Nil)) =>
|
|
130 |
check_before_down(SeqC(m, v::Nil, Nil), u1, d)
|
|
131 |
case (v, AltC(m, wrap)) => m.result.find(tup2 => tup2._1 == pos) match {
|
|
132 |
case Some( (i, vPrime) ) =>
|
|
133 |
m.result += (i -> wrap(v))
|
|
134 |
Nil
|
|
135 |
case None =>
|
|
136 |
mem_up(wrap(v), m, d + 1)
|
|
137 |
} //mem_up(AL1(r), par)
|
|
138 |
//case (v, StarC(m, vs, r0)) => throw new Exception("why not hit starC")
|
|
139 |
|
|
140 |
case (v, RootC) =>
|
|
141 |
Nil
|
|
142 |
case (v, StarC(m, vs, r0) ) => mem_up(Stars(v::vs), m, d + 1) :::
|
|
143 |
check_before_down(StarC(m, v::vs, r0), r0, d)
|
|
144 |
case (_, _) => throw new Exception("hit unexpected context")
|
|
145 |
}
|
|
146 |
|
|
147 |
}
|
|
148 |
|
|
149 |
|
|
150 |
def derive(p: Int, z: Zipper) : List[Zipper] = {
|
|
151 |
pos = p
|
|
152 |
z match {
|
|
153 |
case (v, m) => mem_up(v, m)
|
|
154 |
case _ => throw new Exception("error")
|
|
155 |
}
|
|
156 |
}
|
|
157 |
//let e' = Seq([]) in
|
|
158 |
//
|
|
159 |
def init_zipper(r: Rexp) : Zipper = {
|
|
160 |
val m_top = Mem(RootC::Nil, MList.empty[(Int, Val)])
|
|
161 |
val c_top = SeqC(m_top, Nil, r::Nil)
|
|
162 |
val m_r = Mem(c_top::Nil, MList.empty[(Int, Val)])
|
|
163 |
println(s"initial zipper is (ZERO, $m_r)")
|
|
164 |
(Empty, m_r)//TODO: which val should we start with? Maybe Empty, maybe doesn't matter
|
|
165 |
// val dummyRexp = ONE
|
|
166 |
// val dummyMem = Mem()
|
|
167 |
|
|
168 |
}
|
|
169 |
|
|
170 |
|
|
171 |
def plug_convert(v: Val, c: Ctx) : List[Val] =
|
|
172 |
{
|
|
173 |
|
|
174 |
c match {
|
|
175 |
case RootC => List(v)
|
|
176 |
//TODO: non-binary Seq requires ps.rev
|
|
177 |
case SeqC(m, ps::Nil, Nil) =>
|
|
178 |
plug_mem(Sequ(ps, v), m)
|
|
179 |
|
|
180 |
//TODO: un not nullable--partial values?
|
|
181 |
case SeqC(m, Nil, un::Nil) =>
|
|
182 |
if(nullable(un))
|
|
183 |
plug_mem(Sequ(v, mkeps(un)), m)
|
|
184 |
else
|
|
185 |
Nil
|
|
186 |
|
|
187 |
//TODO: when multiple results stored in m, which one to choose?
|
|
188 |
case AltC(m, wrap) =>
|
|
189 |
plug_mem(wrap(v), m)
|
|
190 |
case StarC(m, vs, r0) => plug_mem(Stars(v::vs), m)
|
|
191 |
}
|
|
192 |
|
|
193 |
}
|
|
194 |
|
|
195 |
|
|
196 |
var cnt = 0;
|
|
197 |
def plug_mem(v: Val, m: Mem) : List[Val] = {
|
|
198 |
m.result += (pos -> v)
|
|
199 |
m.parents.flatMap({c =>
|
|
200 |
plug_convert(v, c)
|
|
201 |
}
|
|
202 |
)
|
|
203 |
}
|
|
204 |
|
|
205 |
def plug_all(zs: List[Zipper]) : List[Val] = {
|
|
206 |
zs.flatMap(z => plug_mem(z._1, z._2))
|
|
207 |
}
|
|
208 |
|
|
209 |
|
|
210 |
def mkeps(r: Rexp) : Val = r match {
|
|
211 |
case ONE => Empty
|
|
212 |
case ALT(r1, r2) =>
|
|
213 |
if (nullable(r1)) Left(mkeps(r1)) else Right(mkeps(r2))
|
|
214 |
case SEQ(r1, r2) => Sequ(mkeps(r1), mkeps(r2))
|
|
215 |
case _ => DummyFilling
|
|
216 |
}
|
|
217 |
|
|
218 |
def nullable(r: Rexp) : Boolean = r match {
|
|
219 |
case ZERO => false
|
|
220 |
case ONE => true
|
|
221 |
case CHAR(_) => false
|
|
222 |
case ALT(r1, r2) => nullable(r1) || nullable(r2)
|
|
223 |
case SEQ(r1, r2) => nullable(r1) && nullable(r2)
|
|
224 |
case _ => false
|
|
225 |
}
|
|
226 |
|
|
227 |
|
|
228 |
val tokList : List[Char] = "aab".toList
|
|
229 |
var input : List[Char] = tokList
|
|
230 |
|
|
231 |
|
|
232 |
|
|
233 |
|
|
234 |
|
|
235 |
|
|
236 |
|
|
237 |
def lexRecurse(zs: List[Zipper], index: Int) : List[Zipper] = {
|
|
238 |
if(index < input.length )
|
|
239 |
lexRecurse(zs.flatMap(z => derive(index, z) ), index + 1)
|
|
240 |
else
|
|
241 |
zs
|
|
242 |
}
|
|
243 |
|
|
244 |
def lex(r: Rexp, s: String) : List[Zipper] = {
|
|
245 |
input = s.toList
|
|
246 |
|
|
247 |
lexRecurse(init_zipper(r)::Nil, 0)
|
|
248 |
}
|
|
249 |
|
|
250 |
|
|
251 |
|
|
252 |
implicit def charlist2rexp(s: List[Char]): Rexp = s match {
|
|
253 |
case Nil => ONE
|
|
254 |
case c::Nil => CHAR(c)
|
|
255 |
case c::cs => SEQ(CHAR(c), charlist2rexp(cs))
|
|
256 |
}
|
|
257 |
implicit def string2Rexp(s: String) : Rexp = charlist2rexp(s.toList)
|
|
258 |
|
|
259 |
implicit def RexpOps(r: Rexp) = new {
|
|
260 |
def | (s: Rexp) = ALT(r, s)
|
|
261 |
def ~ (s: Rexp) = SEQ(r, s)
|
|
262 |
def % = STAR(r)
|
|
263 |
}
|
|
264 |
|
|
265 |
implicit def stringOps(s: String) = new {
|
|
266 |
def | (r: Rexp) = ALT(s, r)
|
|
267 |
def | (r: String) = ALT(s, r)
|
|
268 |
def ~ (r: Rexp) = SEQ(s, r)
|
|
269 |
def ~ (r: String) = SEQ(s, r)
|
|
270 |
def % = STAR(s)
|
|
271 |
|
|
272 |
}
|
|
273 |
|
|
274 |
//derive(0, init_zipper(re0))
|
|
275 |
|
|
276 |
// println(re1s.length)
|
|
277 |
// mems.foreach(a => println(a))
|
|
278 |
// val re1sPlugged = plug_all(re1s)
|
|
279 |
// re1sPlugged.foreach(zipper => {
|
|
280 |
// println(zipper);
|
|
281 |
// println("delimit")
|
|
282 |
// })
|
|
283 |
|
|
284 |
// mems.clear()
|
|
285 |
// println(mems)
|
|
286 |
// println(re0)
|
|
287 |
// val re2s = lex(re0, "aab")
|
|
288 |
// val re2sPlugged = plug_all(re2s)
|
|
289 |
// re2sPlugged.foreach(v => {
|
|
290 |
// val Sequ(Empty, vp) = v
|
|
291 |
// println(vp)
|
|
292 |
// }
|
|
293 |
// )
|
|
294 |
// val re0 = SEQ(ALT(CHAR('a'), SEQ(CHAR('a'),CHAR('a'))),
|
|
295 |
// ALT(SEQ(CHAR('a'), CHAR('b')), SEQ(CHAR('b'), CHAR('c')) )
|
|
296 |
// )
|
|
297 |
|
|
298 |
// val (rgraph, re0root) = makeGraphFromObject(re0)
|
|
299 |
// val asciir = GraphLayout.renderGraph(rgraph)
|
|
300 |
// println("printing out re0")
|
|
301 |
// println(asciir)
|
|
302 |
// val re1s = lex(re0, "aabc")
|
|
303 |
|
|
304 |
def actualZipperSize(zs: List[Zipper]) : Int = zs match {
|
|
305 |
case Nil => 0
|
|
306 |
case z::zs1 => countParents(z._2) + actualZipperSize(zs1)
|
|
307 |
}
|
|
308 |
|
|
309 |
def countParents(m: Mem) : Int = {
|
|
310 |
m.parents.map(c => countGrandParents(c)).sum
|
|
311 |
}
|
|
312 |
|
|
313 |
def countGrandParents(c: Ctx) : Int = {
|
|
314 |
c match {
|
|
315 |
case RootC => 1
|
|
316 |
case SeqC(m, pr, unp) => countParents(m)
|
|
317 |
case AltC(m, w) => countParents(m)
|
|
318 |
case StarC(m, _, _) => countParents(m)
|
|
319 |
}
|
|
320 |
}
|
|
321 |
|
|
322 |
def zipperSimp(zs: List[Zipper]) : List[Zipper] = {
|
|
323 |
zs.distinctBy(z => zipBackMem(z._2))
|
|
324 |
}
|
|
325 |
|
|
326 |
def zipBackToRegex(c: Ctx, r: Rexp = ONE) : List[Rexp] = {
|
|
327 |
c match {
|
|
328 |
case RootC => r::Nil
|
|
329 |
case SeqC(m, pr, Nil) => zipBackMem(m, r)
|
|
330 |
case SeqC(m, pr, unp::Nil) => zipBackMem(m, SEQ(r, unp))
|
|
331 |
case AltC(m, w) => zipBackMem(m, r)
|
|
332 |
case StarC(m, vs, r0) => zipBackMem(m, SEQ(r, STAR(r0)))
|
|
333 |
}
|
|
334 |
}
|
|
335 |
|
|
336 |
def zipBackMem(m: Mem, r: Rexp = ONE) : List[Rexp] = {
|
|
337 |
m.parents.flatMap(c => zipBackToRegex(c, r))
|
|
338 |
}
|
|
339 |
|
|
340 |
//def crystalizeZipper
|
|
341 |
|
|
342 |
mems.clear()
|
|
343 |
val re1 = ("a" | "aa").%
|
|
344 |
val re1ss = lex(re1, "aa")
|
|
345 |
|
|
346 |
// drawZippers(re1ss)
|
|
347 |
// println(actualZipperSize(re1ss))
|
|
348 |
// println(re1ss)
|
|
349 |
//val re1S = zipperSimp(re1ss)
|
|
350 |
//println(actualZipperSize(re1S))
|
|
351 |
|
|
352 |
|
|
353 |
val re2 = SEQ(ONE, "a")
|
|
354 |
val re2res = lex(re2, "a")
|
|
355 |
//lex(1~a, "a") --> lexRecurse((1v, m (SeqC(m (RootC, Nil) ))))
|
|
356 |
|
|
357 |
|
|
358 |
println(re2res)
|
|
359 |
|
|
360 |
val re2resPlugged = plug_all(re2res)
|
|
361 |
re2resPlugged.foreach(v => {
|
|
362 |
val Sequ(Empty, vp) = v
|
|
363 |
println(vp)
|
|
364 |
}
|
|
365 |
)
|
|
366 |
|
|
367 |
// println("remaining regex")
|
|
368 |
// println(re1ss.flatMap(z => zipBackMem(z._2)))
|
|
369 |
|
|
370 |
|
|
371 |
// val re1ssPlugged = plug_all(re1ss)
|
|
372 |
// println("each of the values")
|
|
373 |
// re1ssPlugged.foreach(v => {
|
|
374 |
// //val Sequ(Empty, vp) = v
|
|
375 |
// //println(vp)
|
|
376 |
// println(v)
|
|
377 |
// }
|
|
378 |
// )
|
|
379 |
// println(mems.size)
|
|
380 |
//println(mems)
|
|
381 |
//mems.map({case (ir, m) => if (ir._1 == 1 && ir._2 == CHAR('b')) println(printMem(m)) })
|
|
382 |
// println("Mkeps + inj:")
|
|
383 |
// println(
|
|
384 |
// mems.get((0, re1)) match {
|
|
385 |
// case Some(m) => printMem(m)
|
|
386 |
// case None => ""
|
|
387 |
// }
|
|
388 |
// )
|
|
389 |
|
|
390 |
// println(re1sPlugged)
|
|
391 |
//drawZippers(re1s, plugOrNot = false)
|
|
392 |
// re1s.foreach{
|
|
393 |
// re1 =>
|
|
394 |
// {
|
|
395 |
|
|
396 |
// drawZippers(derive(1, re1), plugOrNot = true)
|
|
397 |
|
|
398 |
// }
|
|
399 |
// }
|
|
400 |
|
|
401 |
|