initial
[prop.git] / app / willard / paige.cc
blob5f631e796951c5f84da5fdb5b3bc67af83bd3fe8
1 ///////////////////////////////////////////////////////////////////////////////
2 // This file is generated automatically using Prop (version 2.3.5),
3 // last updated on Jun 18, 1997.
4 // The original source file is "paige.pcc".
5 ///////////////////////////////////////////////////////////////////////////////
7 #define PROP_REWRITING_USED
8 #define PROP_STRCMP_USED
9 #define PROP_QUARK_USED
10 #define PROP_TUPLE2_USED
11 #include <propdefs.h>
12 #line 1 "paige.pcc"
13 #include <assert.h>
14 #include <iostream.h>
15 #include <fstream.h>
16 #include <AD/pretty/postream.h>
17 #include "paige.h"
18 #include "willard-ast.h"
20 ///////////////////////////////////////////////////////////////////////////////
22 // Constructor for the Paige/Goyal query transformer
24 ///////////////////////////////////////////////////////////////////////////////
25 PaigeGoyal::PaigeGoyal() : log(*new ofstream), errlog(cerr)
26 { True = LIT(BOOL(true));
27 False = LIT(BOOL(false));
28 Zero = LIT(INT(0));
29 One = LIT(INT(1));
30 Two = LIT(INT(2));
31 EmptySet = GENERATOR(
32 #line 19 "paige.pcc"
33 #line 19 "paige.pcc"
34 nil_1_
35 #line 19 "paige.pcc"
36 #line 19 "paige.pcc"
38 #line 19 "paige.pcc"
39 #line 19 "paige.pcc"
40 nil_1_
41 #line 19 "paige.pcc"
42 #line 19 "paige.pcc"
43 ,Zero);
44 new_name = 0;
45 subquery_names =
46 #line 21 "paige.pcc"
47 #line 21 "paige.pcc"
48 nil_1_
49 #line 21 "paige.pcc"
50 #line 21 "paige.pcc"
52 subqueries =
53 #line 22 "paige.pcc"
54 #line 22 "paige.pcc"
55 nil_1_
56 #line 22 "paige.pcc"
57 #line 22 "paige.pcc"
61 ///////////////////////////////////////////////////////////////////////////////
63 // Destructor for the Paige/Goyal query transformer
65 ///////////////////////////////////////////////////////////////////////////////
66 PaigeGoyal::~PaigeGoyal()
70 ///////////////////////////////////////////////////////////////////////////////
72 // Method to add a subquery
74 ///////////////////////////////////////////////////////////////////////////////
75 void PaigeGoyal::add_subquery(Id x, Exp e)
76 { // PrettyOStream S;
77 // S << "Subquery: " << x << '=' << e << '\n';
78 subquery_names =
79 #line 42 "paige.pcc"
80 #line 42 "paige.pcc"
81 list_1_(x,subquery_names)
82 #line 42 "paige.pcc"
83 #line 42 "paige.pcc"
85 subqueries =
86 #line 43 "paige.pcc"
87 #line 43 "paige.pcc"
88 list_1_(e,subqueries)
89 #line 43 "paige.pcc"
90 #line 43 "paige.pcc"
93 Bool PaigeGoyal::has_subqueries() const { return subqueries !=
94 #line 45 "paige.pcc"
95 #line 45 "paige.pcc"
96 nil_1_
97 #line 45 "paige.pcc"
98 #line 45 "paige.pcc"
99 ; }
101 ///////////////////////////////////////////////////////////////////////////////
103 // Method to collect subqueries into a LET
105 ///////////////////////////////////////////////////////////////////////////////
106 Exp PaigeGoyal::collect_subqueries(Exp exp)
107 { exp = make_let(subquery_names, subqueries, exp);
108 subquery_names =
109 #line 54 "paige.pcc"
110 #line 54 "paige.pcc"
111 nil_1_
112 #line 54 "paige.pcc"
113 #line 54 "paige.pcc"
115 subqueries =
116 #line 55 "paige.pcc"
117 #line 55 "paige.pcc"
118 nil_1_
119 #line 55 "paige.pcc"
120 #line 55 "paige.pcc"
122 return exp;
125 ///////////////////////////////////////////////////////////////////////////////
127 // Method to make a nested LET
129 ///////////////////////////////////////////////////////////////////////////////
130 Exp PaigeGoyal::make_let(Ids xs, Exps es, Exp exp)
132 #line 65 "paige.pcc"
133 #line 71 "paige.pcc"
135 for (;;) {
136 if (xs) {
137 if (es) {
138 #line 67 "paige.pcc"
139 Id x = xs->_1;
140 Exp e = es->_1;
141 exp = LET(x,e,exp);
142 xs = xs->_2; es = es->_2;
144 #line 71 "paige.pcc"
145 } else { goto L1; }
146 } else { goto L1; }
148 L1:;
150 #line 72 "paige.pcc"
151 #line 72 "paige.pcc"
153 return exp;
156 ///////////////////////////////////////////////////////////////////////////////
158 // Methods to define/lookup the range of a variable
160 ///////////////////////////////////////////////////////////////////////////////
161 void PaigeGoyal::define_range(Id x, Exp e) { var_range.insert(x,e); }
162 void PaigeGoyal::define_range(Ids xs, Exps es)
163 { Ids ids = xs;
164 Exps exps = es;
166 #line 85 "paige.pcc"
167 #line 86 "paige.pcc"
169 for (;;) {
170 if (ids) {
171 if (exps) {
172 #line 86 "paige.pcc"
173 define_range(ids->_1,exps->_1); ids = ids->_2; exps = exps->_2;
174 #line 86 "paige.pcc"
175 } else { goto L2; }
176 } else { goto L2; }
178 L2:;
180 #line 87 "paige.pcc"
181 #line 87 "paige.pcc"
183 if (ids !=
184 #line 88 "paige.pcc"
185 #line 88 "paige.pcc"
186 nil_1_
187 #line 88 "paige.pcc"
188 #line 88 "paige.pcc"
189 || exps !=
190 #line 88 "paige.pcc"
191 #line 88 "paige.pcc"
192 nil_1_
193 #line 88 "paige.pcc"
194 #line 88 "paige.pcc"
196 errlog << "Arity mismatch in " << xs << "in" << es << ::newline;
199 Exp PaigeGoyal::range_of(Id x)
200 { assert(var_range.contains(x));
201 return var_range[x];
204 ///////////////////////////////////////////////////////////////////////////////
206 // Method to print messages
208 ///////////////////////////////////////////////////////////////////////////////
209 void PaigeGoyal::message(const char * msg, Exp e)
210 { log << ::indent << e << ::newline << ::newline << ::unindent
211 << '[' << msg << ']' << ::newline << ::newline;
214 void PaigeGoyal::error(const char * msg, Exp e)
215 { errlog << '[' << "ERROR:" << msg << ']' << ::newline << ::indent
216 << e << ::newline << ::unindent;
219 void PaigeGoyal::set_log(ostream& f) { log.set_stream(f); }
220 void PaigeGoyal::set_error(ostream& f) { errlog.set_stream(f); }
222 ///////////////////////////////////////////////////////////////////////////////
224 // Method to add an edge into the query graph
226 ///////////////////////////////////////////////////////////////////////////////
227 void PaigeGoyal::add_edge(Id x, Id y)
228 { if (parent.contains(y))
229 { Id z = parent[y];
230 if (x != z)
231 errlog << "Edge: " << x << "->" << y << "conflicts with"
232 << z << "->" << y << "in the query graph\n";
234 parent.insert(y,x);
237 Bool PaigeGoyal::has_edge(Id x, Id y) const
238 { if (! parent.contains(y)) return false;
239 return parent[y] == x;
242 void PaigeGoyal::add_edge_query(Id x, Id y, Exp q)
244 edge_queries.insert(
245 #line 137 "paige.pcc"
246 #line 137 "paige.pcc"
247 mkTuple2(x,y)
248 #line 137 "paige.pcc"
249 #line 137 "paige.pcc"
250 ,q);
253 ///////////////////////////////////////////////////////////////////////////////
255 // Method to compute the transitive closure of the query graph
257 ///////////////////////////////////////////////////////////////////////////////
258 void PaigeGoyal::compute_transitive_closure()
259 { foreach (i,parent)
260 { parent_closure.insert(parent.key(i),parent.value(i));
264 ///////////////////////////////////////////////////////////////////////////////
266 // Methods to push/pop from the quantifier stack
268 ///////////////////////////////////////////////////////////////////////////////
269 void PaigeGoyal::push_quantifier(Id x) { quantifier_vars.push(x); }
270 void PaigeGoyal::push_quantifier(Ids xs)
272 #line 158 "paige.pcc"
273 #line 158 "paige.pcc"
275 for (;;) {
276 if (xs) {
277 #line 158 "paige.pcc"
278 push_quantifier(xs->_1); xs = xs->_2;
279 #line 158 "paige.pcc"
280 } else { goto L3; }
282 L3:;
284 #line 158 "paige.pcc"
285 #line 158 "paige.pcc"
287 void PaigeGoyal::pop_quantifier(Id x) { quantifier_vars.pop(); }
288 void PaigeGoyal::pop_quantifier(Ids xs)
290 #line 161 "paige.pcc"
291 #line 161 "paige.pcc"
293 for (;;) {
294 if (xs) {
295 #line 161 "paige.pcc"
296 pop_quantifier(xs->_1); xs = xs->_2;
297 #line 161 "paige.pcc"
298 } else { goto L4; }
300 L4:;
302 #line 161 "paige.pcc"
303 #line 161 "paige.pcc"
306 ///////////////////////////////////////////////////////////////////////////////
308 // Method to print the query graph
310 ///////////////////////////////////////////////////////////////////////////////
311 void PaigeGoyal::print_query_graph()
312 { log << ::tab << "[Query Graph]" << ::newline << ::indent;
313 foreach (i,parent)
314 { Id x = parent.value(i);
315 Id y = parent.key(i);
316 log << ::tab << "edge" << x << "->" << y;
317 if (edge_queries.contains(
318 #line 174 "paige.pcc"
319 #line 174 "paige.pcc"
320 mkTuple2(x,y)
321 #line 174 "paige.pcc"
322 #line 174 "paige.pcc"
324 log << '\t' << edge_queries[
325 #line 175 "paige.pcc"
326 #line 175 "paige.pcc"
327 mkTuple2(x,y)
328 #line 175 "paige.pcc"
329 #line 175 "paige.pcc"
331 log << ::newline;
333 log << ::unindent;
336 ///////////////////////////////////////////////////////////////////////////////
338 // Main method to decompose a query
340 ///////////////////////////////////////////////////////////////////////////////
341 Exp PaigeGoyal::decompose(Exp e)
342 { subqueries =
343 #line 187 "paige.pcc"
344 #line 187 "paige.pcc"
345 nil_1_
346 #line 187 "paige.pcc"
347 #line 187 "paige.pcc"
349 do {
350 changed = false;
351 e = remove_duplicate_names(e);
352 e = phase1(e); // DNF construction
353 e = construct_query_graph(e); // query graph construction
354 e = phase2(e); // quantifier elimination
355 e = phase3(e); // disjunction removal
356 e = phase4(e); // conjunction removal
357 e = projection_recognition(e);
358 e = phase5(e);
359 if (changed) message("Reiterating the transformation",e);
360 } while (changed);
361 return e;
363 #line 202 "paige.pcc"
365 ------------------------------- Statistics -------------------------------
366 Merge matching rules = yes
367 Number of DFA nodes merged = 8
368 Number of ifs generated = 6
369 Number of switches generated = 0
370 Number of labels = 0
371 Number of gotos = 0
372 Adaptive matching = disabled
373 Fast string matching = disabled
374 Inline downcasts = disabled
375 --------------------------------------------------------------------------