-
Notifications
You must be signed in to change notification settings - Fork 1
/
MiniCon.java.old
631 lines (517 loc) · 19.7 KB
/
MiniCon.java.old
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
/*
* MiniCon.java
* -------------
* Implements the MiniCon algorithm.
* $Id: MiniCon.java,v 1.33 2000/11/17 01:35:39 chenli Exp $
*
*/
import java.util.*;
class MiniCon {
public static double timeFormMCD;
public static double timeCombineMCD;
public static int numMCDs;
public static int numRews;
public static Prof prof;
// calls the MiniCon algorithm to generate rewritings for the query
static HashSet genPlan(Query query, Vector views) {
long startTime = 0;
long endTime = 0;
prof = new Prof("MCDs");
prof.start();
HashSet mcds = formMCDs(query, views);
prof.stop();
HashSet rewritings = new HashSet();
//HashSet rewritings = combineMCDs(query, mcds);
prof.stop2();
timeFormMCD = (prof.stopcputime - prof.startcputime)/1000000000.0;
timeCombineMCD = (prof.stopcputime2 - prof.stopcputime) /1000000000.0;
//minimizeRews();
numMCDs = mcds.size();
numRews = rewritings.size();
return rewritings;
}
// generates all MCDs for a query and views
static HashSet formMCDs(Query query, Vector views) {
UserLib.myprintln("calling formMCDs()...");
HashSet mcds = new HashSet();
for (int i = 0; i < views.size(); i ++) {
Query view = (Query) views.elementAt(i);
mcds.addAll(formMCDs(query, view));
}
return mcds;
}
// generates all MCDs for a query and views
static HashSet formMCDs(Query query, Query view) {
UserLib.myprintln("calling formMCDs(), view = " + view);
HashSet mcds = new HashSet();
Vector querySubgoals = (Vector) query.getBody();
// generates all subsets of the query subgoals except the given one
HashSet querySubsets = UserLib.genSubsets(querySubgoals);
// scans the subsets from the smallest one to the largest one
for (int i = 1; i <= querySubgoals.size(); i ++)
{
for (Iterator iter = querySubsets.iterator(); iter.hasNext();)
{
// for this "i"^th around, we consider only subsets with size i
HashSet querySubgoalSubset = (HashSet) iter.next();
if (querySubgoalSubset.size() != i)
continue;
//System.out.println("query-subgoal subset = " + querySubgoalSubset);
// tries to extend this subset ONLY IF it is not a superset of
// another existing subset in the found MCDs
if (containsQuerySubgoalSubset(mcds, querySubgoalSubset))
continue;
// we should rename the view and adjust the PhiHH
Query renamedView = view.rename();
//System.out.println("after renaming, view = " + renamedView);
HashSet newMCDs = extend(query, querySubgoalSubset, renamedView);
// it IS extendable. finally, we got some mcds
mcds.addAll(newMCDs);
}
}
return mcds;
}
/**
* Given a query subgoal and a view subguoa, tries to find an HH of the
* view, under which there is a mapping phi from the query subgoal to
* the view subgoal.
*/
private static PhiHH unifiable(Query query, int querySubgoalIndex,
Query view, int viewSubgoalIndex) {
Subgoal querySubgoal = query.getSubgoal(querySubgoalIndex);
Subgoal viewSubgoal = view.getSubgoal(viewSubgoalIndex);
// they must use the same name
if (!querySubgoal.isSameName(viewSubgoal))
return null;
Vector queryArgs = querySubgoal.getArgs();
Vector viewArgs = viewSubgoal.getArgs();
if (queryArgs.size() != viewArgs.size())
UserLib.myerror("MiniCon.unifiable(), wrong args!");
Mapping phi = new Mapping();
Mapping hh = new Mapping();
// checks if a query arg is unifiable with the corresponding view arg
for (int i = 0; i < queryArgs.size(); i ++) {
Argument queryArg = (Argument) queryArgs.elementAt(i);
Argument viewArg = (Argument) viewArgs.elementAt(i);
if (!queryArg.unifiable(viewArg, phi, hh, view.getDistVars()))
return null;
}
return (new PhiHH(phi, hh));
}
// for (i = 1; i < number of query's subgoals; i ++)
// {
// for each superset querySuperset of {querySubgoal} with size i
// {
// if querySuperset can be mapped to some view subgoals while
// the mapping is consistent with phihh, and the mapping satisfies
// the PROPERTY
// {
// if this superset is not a superset of another existing
// superset in moreMCDs
// {
// form an MCD and add
// }
// }
// }
// }
/**
* checks if a subset of query's subgoals can be mapped to some view
* subgoals while the mapping is consistent with a given phihh from a
* given query subgoal to a given view subgoal, and the mapping
* satisfies the PROPERTY.
* If so, returns the set of new MCDs.
*/
private static HashSet extend(Query query, HashSet querySubgoalSubset,
Query view) {
HashSet mcds = new HashSet();
// translates the querySubgoalSubset to a vector
Vector querySubgoalSeq = new Vector();
for (Iterator iter = querySubgoalSubset.iterator(); iter.hasNext();) {
querySubgoalSeq.add(iter.next());
}
// clones the view's body
Vector viewSubgoals = (Vector) view.getBody();
// generates all subsets of the view subgoals except the given one
HashSet viewSubsets = UserLib.genSubsets(viewSubgoals);
//System.out.println("viewSubsets = " + viewSubsets);
// scans the subsets from the smallest one to the largest one
for (int i = 1; i <= viewSubgoals.size(); i ++)
{
if (i > querySubgoalSubset.size())
break;
for (Iterator iter = viewSubsets.iterator(); iter.hasNext();)
{
// for this "i"^th around, we consider only subsets with size i
HashSet viewSubgoalSubset = (HashSet) iter.next();
if (viewSubgoalSubset.size() != i)
continue;
//System.out.println("view-subgoal subset = " + viewSubgoalSubset);
// tries to extend the view-subgoal subset ONLY IF it is not a
// superset of another existing view-subgoal subset in the found MCDs
if (containsViewSubgoalSubset(mcds, viewSubgoalSubset)) continue;
// considers this pair of query-subgoal subset and view-subgoal subset
MCD mcd = formOneMCD(query, querySubgoalSeq,
view, viewSubgoalSubset);
if (mcd != null) mcds.add(mcd);
}
}
return mcds;
}
/**
* checks if one query-subgoal subset is a superset of another existing
* query-subgoal subset in a given set of MCDs.
*/
private static boolean containsQuerySubgoalSubset(HashSet mcds,
HashSet querySubgoals) {
for (Iterator iter = mcds.iterator(); iter.hasNext();) {
MCD mcd = (MCD) iter.next();
HashSet mcdQuerySubgoals = mcd.getMappedQuerySubgoals();
// checks if the given set of subgoals is a super set of the
// subgoals in this MCD. !!! make sure the sets are using references
// to the same set of query subgoals
if (querySubgoals.containsAll(mcdQuerySubgoals))
return true;
}
return false;
}
/**
* checks if one query-subgoal subset is a superset of another existing
* query-subgoal subset in a given set of MCDs.
*/
private static boolean containsViewSubgoalSubset(HashSet mcds,
HashSet viewSubgoals) {
for (Iterator iter = mcds.iterator(); iter.hasNext();) {
MCD mcd = (MCD) iter.next();
HashSet mcdViewSubgoals = mcd.getViewSubgoals();
// checks if the given set of subgoals is a super set of the
// subgoals in this MCD. !!! make sure the sets are using references
// to the same set of query subgoals
if (viewSubgoals.containsAll(mcdViewSubgoals)) // <== !!! renamed
return true;
}
return false;
}
/**
* Given a pair of query-subgoal subset and view-subgoal subset,
* tries to extend them to form an MCD. Note that ALL the subgoals in
* the two subsets must be used.
*/
private static MCD formOneMCD(Query query,
Vector querySubgoalSeq,
Query view,
HashSet viewSubgoalSubset) {
/*System.out.println("formOneMCD(): querySubgoalSeq = " +
querySubgoalSeq + " viewSubgoalSubset " +
viewSubgoalSubset);*/
// the view-subgoal subest cannot have more subgoals than the
// query-subgoal subset
if (viewSubgoalSubset.size() > querySubgoalSeq.size())
return null;
// generates all the sequences of length querySubgoalSubset.size() for
// the view subgoals which each view subgoal should appear at least
// once.
Vector viewSubgoalSeqs =
UserLib.getAllSeqs(viewSubgoalSubset, querySubgoalSeq.size());
//System.out.println("formOneMCD(): viewSubgoalSeqs = " + viewSubgoalSeqs);
if (viewSubgoalSeqs == null) return null;
for (int i = 0; i < viewSubgoalSeqs.size(); i ++) {
// tries to create an MCD for this pair of sequences of query
// subgoals and view subgoals
Vector viewSubgoalSeq = (Vector) viewSubgoalSeqs.elementAt(i);
MCD mcd = buildMCD(query, querySubgoalSeq, view, viewSubgoalSeq);
// returns once if we find one MCD
if (mcd != null) return mcd;
}
return null;
}
private static MCD buildMCD(Query query,
Vector querySubgoalSeq,
Query view,
Vector viewSubgoalSeq) {
// two vectors should have the same size
if (querySubgoalSeq.size() != viewSubgoalSeq.size())
UserLib.myerror("MiniCon.buildMCD(): error. The two " +
"vectors should have the same size.");
// clones a new phihh
Mapping phi = new Mapping();
Mapping hh = new Mapping();
// scans the subgoals to match
for (int i = 0; i < querySubgoalSeq.size(); i ++) {
Subgoal querySubgoal = (Subgoal) querySubgoalSeq.elementAt(i);
Subgoal viewSubgoal = (Subgoal) viewSubgoalSeq.elementAt(i);
// they should have the same name
// !!! make sure "equals" works
if (!querySubgoal.getName().equals(viewSubgoal.getName()))
return null;
Vector queryArgs = querySubgoal.getArgs();
Vector viewArgs = viewSubgoal.getArgs();
// they should have the same number of subgoals
if (viewArgs.size() != queryArgs.size())
UserLib.myerror("MiniCon.buildmCD(): error. The two " +
"subgoals should have the same size.");
// checks if a query arg is unifiable with the corresponding view arg
for (int j = 0; j < queryArgs.size(); j ++) {
Argument queryArg = (Argument) queryArgs.elementAt(j);
Argument viewArg = (Argument) viewArgs.elementAt(j);
if (!queryArg.unifiable(viewArg, phi, hh, view.getDistVars()))
return null;
}
}
// transforms vectors to sets
HashSet querySubgoalSubset = new HashSet(querySubgoalSeq);
HashSet viewSubgoalSubset = new HashSet(viewSubgoalSeq);
// checks if the mapping satisfies the PROPERTY
if (satisfyProperty(phi, hh, query, querySubgoalSubset, view))
{ // finally we got one!
MCD mcd = new MCD(query,
querySubgoalSubset,
hh.apply(view), // applies hh here!
viewSubgoalSubset,
phi, hh); // hh has been extended
UserLib.myprintln("WE FOUND ONE MCD! ==> \n" + mcd);
return mcd;
}
return null;
}
/**
* Checks if a mapping satisfies the PROPERTY.
*/
private static boolean satisfyProperty(Mapping phi, Mapping hh,
Query query,
HashSet querySubgoalSubset,
Query view) {
/*System.out.println("In satisfyProperty()!");
System.out.println("phi = " + phi + "\n" + " hh = " + hh +
"query = " + query + "\n" +
"querySubgoalSubset = " + querySubgoalSubset + "\n" +
"view = " + view);*/
Map map = phi.getMap();
Set entrySet = (Set) map.entrySet();
for (Iterator iter = entrySet.iterator(); iter.hasNext();) {
Map.Entry mapEntry = (Map.Entry) iter.next();
Argument queryArg = (Argument) mapEntry.getKey();
Argument viewArg = (Argument) mapEntry.getValue();
/*System.out.println("queryArg = " + queryArg +
" viewArg = " + viewArg );*/
// it's OK if the view arg is distinguished
if (view.isDistVar(viewArg)) continue;
// the view arg is not distinguished,
// then the query arg must be distinguished
if (query.isDistVar(queryArg)) {
UserLib.myprintln("Case 1 failed.");
return false;
}
// queryArg is not distinguished, and viewArg is not either, then
// all the query subgoals that use this var should be mapped, i.e.,
// they are in querySubgoalSubset
for (int i = 0; i < query.getSubgoalNum(); i ++) {
Subgoal querySubgoal = query.getSubgoal(i);
if (querySubgoal.contains(queryArg) // this subgoal uses this var
&& !querySubgoalSubset.contains(querySubgoal)) {
UserLib.myprintln("Case 2 failed.");
UserLib.myprintln("querySubgoal = " + querySubgoal +
"querySubgoalSubset = " + querySubgoalSubset);
return false;
}
}
}
return true;
}
/*
for each subgoal g in Q
For view V in \V and every subgoal v_i in V
Let h be the least restrictive head homomorphism on V
such that there exists a mapping \phi, s.t., \phi(g) = h(v).
If h and \phi exist, then add to C any new MCD C
that can be constructed where:
(a) \phi_C (resp. h_C) is an extension of \phi (res. h);
(b) G_C is the minimal subset of subgoals of Q such that
G_C,\phi)C and h_C satisfy Peoperty I, and
(c) it is not possible to extend \phi and h to an MCD that
covers fewer subgoals than G_C.
Return C.
*/
/**
* Step 2: combines MCDs to generate rewritings.
*/
/* static HashSet combineMCDs(Query query, HashSet mcds) {
// computes the EC function
Mapping ec = new Mapping();
for (Iterator iter = mcds.iterator(); iter.hasNext();) {
MCD mcd = (MCD) iter.next();
Mapping ec = computeECPsi(ec, mcd);
}
return genRewritings(query, mcds, ec);
}
*/
/**
* Given a set of MCDs (with their psi functions computed) and an EC,
* generates rewritings by trying all possible combinations of these MCDs.
*/
static HashSet combineMCDs(Query query, HashSet mcds) {
UserLib.myprintln("calling combineMCDs()...");
HashSet rewritings = new HashSet();
HashSet mcdSubsets = UserLib.genSubsets(mcds);
// scans the subsets from the smallest one to the largest one
for (int i = 1; i <= mcds.size(); i ++)
{
for (Iterator iter = mcdSubsets.iterator(); iter.hasNext();)
{
HashSet oneMCDSubset = (HashSet) iter.next();
if (oneMCDSubset.size() != i) continue;
// tries to build an MCD ONLY IF it is not a superset of
// another existing subset in the found rewritings
if (containsMCDSubset(rewritings, oneMCDSubset))
continue;
Mapping ec = computeEC(oneMCDSubset); // computes the EC
Rewriting rewriting = buildRewriting(query, oneMCDSubset, ec);
if (rewriting != null) rewritings.add(rewriting);
}
}
return rewritings;
}
/**
* computes the EC function for the query and the psi function for a set
* of MCDs.
*/
static Mapping computeEC(HashSet mcdSubset) {
Mapping ec = new Mapping();
for (Iterator iter = mcdSubset.iterator(); iter.hasNext();) {
MCD mcd = (MCD) iter.next();
computeECPsi(ec, mcd);
}
// in the case of X1->Y1, Y1->Y2, we need to propogate the mappings to
// the tail
Mapping pec = new Mapping();
Set keySet = (Set) ec.getMap().keySet();
for (Iterator iter = keySet.iterator(); iter.hasNext();) {
Argument headArg = (Argument) iter.next();
Argument tailArg = ec.getTail(headArg); // finds the tail for this srcArg
pec.put(headArg, tailArg);
}
return pec; // returns the propogated EC
}
/**
* computes the EC function for the query and the psi function for the
* MCD given an MCD
*/
static void computeECPsi(Mapping ec, MCD mcd) {
// sets the psi
/*System.out.println("WWWWW: in computeECPsi()");
System.out.println("WWWWW: ec = " + ec + " mcd = " + mcd);*/
Mapping phi = mcd.getPhi();
Query view = mcd.getView(); // applies the HH on the view
Mapping psi = new Mapping();
// scans the args in phi
Set entrySet = phi.getMap().entrySet();
for (Iterator iter = entrySet.iterator(); iter.hasNext();) {
Map.Entry mapEntry = (Map.Entry) iter.next();
Argument queryArg = (Argument) mapEntry.getKey();
Argument viewArg = (Argument) mapEntry.getValue();
// this view arg should exist in the view
viewArg = mcd.getHH().applyTryIdentity(viewArg);
if (!view.containsArg(viewArg))
UserLib.myerror("MiniCon.computeECPsi(), didn't find viewArg " +
viewArg);
Argument oldQueryArg = psi.apply(viewArg);
if (oldQueryArg == null) {
// this view arg hasn't been mapped.
// puts a pair in psi by reversing this pair
psi.put(viewArg, queryArg);
} else {
// this view arg already mapped. extends the ec
// oldQueryArg queryArg
// \ |
// \ |
// viewArg
/*if (ec.get(queryArg) == null)
ec.put(queryArg, oldQueryArg);*/
if (queryArg.equals(oldQueryArg)) continue; // identical
if (ec.apply(queryArg) != null) continue; // already mapped
ec.put(queryArg, oldQueryArg);
}
}
// sets the psi
//System.out.println("WWWWW: computed psi = " + psi);
mcd.setPsi(psi);
}
/**
* Given a set of MCDs and an EC, build a rewriting
*/
static Rewriting buildRewriting(Query query, HashSet oneMCDSubset,
Mapping ec) {
HashSet coveredQuerySubgoals = new HashSet();
for (Iterator iter = oneMCDSubset.iterator(); iter.hasNext();) {
MCD mcd = (MCD) iter.next();
HashSet querySubgoals = mcd.getMappedQuerySubgoals();
// all the subgoals in the MCDs should be disjoint
if (!UserLib.disjoint(coveredQuerySubgoals, querySubgoals))
return null;
// adds these new subgoals to the whole subgoals
coveredQuerySubgoals.addAll(querySubgoals);
}
// all subgoal subgoals should be covered
if (!coveredQuerySubgoals.containsAll(query.getBody()))
return null;
return createRewriting(query, oneMCDSubset, ec);
}
/**
* creates a rewriting.
*/
static Rewriting createRewriting(Query query, HashSet oneMCDSubset,
Mapping ec) {
/*System.out.println("forming a rewriting using MCDs\n " +
oneMCDSubset);*/
int id = 0;
String name = query.getName();
Subgoal head = ec.apply(query.getHead()); // head
Vector body = new Vector(); // body
for (Iterator iter = oneMCDSubset.iterator(); iter.hasNext();) {
MCD mcd = (MCD) iter.next();
Query view = mcd.getView(); // already applies HH !
Mapping psi = mcd.getPsi();
Subgoal subgoal = ec.apply(psi.apply(view.getHead()));
body.add(subgoal);
}
Query rew = new Query(name, head, body);
return new Rewriting(rew, oneMCDSubset, ec);
}
/**
* checks if a mcd subset is a superset of another existing
* mcd set in a given set of rewritings.
*/
private static boolean containsMCDSubset(HashSet rewritings,
HashSet oneMCDSubset) {
for (Iterator iter = rewritings.iterator(); iter.hasNext();) {
Rewriting rewriting = (Rewriting) iter.next();
HashSet mcds = rewriting.getMCDs();
if (oneMCDSubset.containsAll(mcds))
return true;
}
return false;
}
// minimizes the rwritings
static void minimizeRews() {
}
static class Prof extends JCProf {
String me;
long starttime, startcputime;
long stoptime, stopcputime;
long stoptime2, stopcputime2;
Prof(String name) {
me = name;
}
void start() {
startcputime = getCpuTime();
// starttime = System.currentTimeMillis();
}
void stop() {
stopcputime = getCpuTime();
//stoptime = System.currentTimeMillis();
}
void stop2() {
stopcputime2 = getCpuTime();
//stoptime2 = System.currentTimeMillis();
}
}
}