1 ///////////////////////////////////////////////////////////////////////////////
3 // This is the main partial evaluation routines.
5 ///////////////////////////////////////////////////////////////////////////////
18 ///////////////////////////////////////////////////////////////////////////////
22 ///////////////////////////////////////////////////////////////////////////////
23 typedef TreeAutomaton::Functor Functor;
24 typedef TreeAutomaton::State State;
25 typedef TreeAutomaton::Rule Rule;
27 ///////////////////////////////////////////////////////////////////////////////
29 // Method for partial evaluating the trs
31 ///////////////////////////////////////////////////////////////////////////////
33 { for (Rule r = 0; r < number_of_rules; r++)
38 ///////////////////////////////////////////////////////////////////////////////
40 // Method for partial evaluating one rule
42 ///////////////////////////////////////////////////////////////////////////////
48 ///////////////////////////////////////////////////////////////////////////////
50 // Method for partial evaluting one rule, using 0-strategy.
52 ///////////////////////////////////////////////////////////////////////////////
53 void TRS::mix_0(Rule r)
54 { int arity = num_var_map[r];
55 for (int i = 0; i < arity; i++) states[i] = 0;
56 // msg("0-Partial evaluating %r ", rule_map[r]) << rhs_map[r] << '\n';
57 Term rhs = copy(rhs_map[r]);
59 State new_state = normalize(rhs,reductions);
61 { print_residue(r,rhs);
62 make_rhs(r,optimized_map[r] = make_exp(rhs));
66 ///////////////////////////////////////////////////////////////////////////////
68 // Method for partial evaluting one rule, using 1-strategy.
70 ///////////////////////////////////////////////////////////////////////////////
71 void TRS::mix_1(Rule r)
72 { int arity = num_var_map[r];
73 int number_of_states = treeauto.number_of_states();
74 // msg("1-Partial evaluating %r ", rule_map[r]) << rhs_map[r] << '\n';
75 for (int i = 0; i < arity; i++)
76 { // If the variable does not have an index we can't do anything
78 if (! compiler.has_index(var_pat_map[r][i]->ty)) continue;
79 for (int j = 0; j < arity; j++) states[j] = 0;
80 for (State s = 1; s < number_of_states; s++)
81 { // skip accept states
83 if (treeauto.is_accept_state(s)) continue;
84 if (! is_relevant(r)) continue;
86 Term rhs = copy(rhs_map[r]);
87 State new_state = normalize(rhs,reductions);
89 { generate_residue(r,i,s,rhs); }
94 ///////////////////////////////////////////////////////////////////////////////
96 // Method to check that a particular specialization is relevant
98 ///////////////////////////////////////////////////////////////////////////////
99 Bool TRS::is_relevant(Rule r)
100 { int redex_count = 0;
102 State s = normalize(lhs_map[r],redex_count);
104 // cerr << lhs_map[r] << " has " << redex_count << " redexes\n";
105 if (redex_count > 1) return false;
106 if (treeauto.accept1_rule(s) != r) return false;
110 ///////////////////////////////////////////////////////////////////////////////
112 // Method to normalize a rule
114 ///////////////////////////////////////////////////////////////////////////////
115 TRS::State TRS::normalize(Term& term, int& reductions)
121 { CONSterm(f,_,n,args):
123 for (int i = 0; i < n; i++)
124 { State s = normalize(args[i],reductions);
125 mu[i] = treeauto.index_map(f,i,s);
127 new_state = treeauto.get_delta(f,mu);
129 if (treeauto.is_accept_state(new_state))
134 term = reduce(term,new_state,reductions,changed);
137 | VARterm(v,_,_): { return states[v]; }
144 ///////////////////////////////////////////////////////////////////////////////
146 // Method to reduce a rule during accepting
148 ///////////////////////////////////////////////////////////////////////////////
149 Term TRS::reduce(Term term, State state, int& reductions, Bool& changed)
151 // Test for conditional rules
152 // For each rule that can accept, check the guard associated
153 // with the rule. Evaluate the guard if possible.
154 // We'll not reduce if we are not guaranteed that the reduction
156 const BitSet& accept = treeauto.accept_rules(state);
157 for (Rule r = 0; r <= number_of_rules; r++)
159 { Exp guard = guard_map[r];
160 EvalResult result = SUCCESS;
161 if (guard == NOexp) result = SUCCESS;
162 else result = eval_guard(guard);
165 { Term rule_rhs = rhs_map[r];
167 Term new_rhs = subst(rule_rhs,term,ok);
168 if (! ok) return term; // no reduction
173 case UNKNOWN: return term; // no reduction
174 case FAILURE: break; // try next rule
178 return term; // no reduction
181 ///////////////////////////////////////////////////////////////////////////////
185 ///////////////////////////////////////////////////////////////////////////////
186 Term TRS::subst(Term rhs, Term redex, Bool& ok)
188 { CONSterm(f,c,n,args):
189 { return CONSterm(f,c,n,subst(n,args,redex,ok)); }
191 { return proj(exp,redex,ok); }
193 { return proj(exp,redex,ok); }
194 | _: { bug("TRS::subst"); return redex; }
198 ///////////////////////////////////////////////////////////////////////////////
202 ///////////////////////////////////////////////////////////////////////////////
203 Term * TRS::subst(int n, Term * rhs, Term redex, Bool& ok)
204 { Term * args = (Term*)mem_pool.m_alloc(sizeof(Term) * n);
205 for (int i = 0; i < n; i++)
206 args[i] = subst(rhs[i],redex,ok);
210 ///////////////////////////////////////////////////////////////////////////////
212 // Perform projection a rule
214 ///////////////////////////////////////////////////////////////////////////////
215 Term TRS::proj(Exp exp, Term redex, Bool& ok)
217 match (exp) and (redex)
218 { IDexp "redex", redex: { return redex; }
219 | DOTexp(SELECTORexp(e,c1,ty),ith), redex:
220 { match (proj(e,redex,ok))
221 { CONSterm(_,c2,n,args) |
222 c1 == c2 && ((nth = atol(ith+1)-1), nth < n):
223 { return args[nth]; }
224 | CODEterm(e): { return CODEterm(DOTexp(SELECTORexp(e,c1,ty),ith)); }
226 { return CODEterm(DOTexp(SELECTORexp(e,c1,ty),ith)); }
227 | redex as CONSterm(_,c2,n,args):
228 { // msg("1 Can't project %e %i %i", exp,nth,n);
229 // print(msg(""),redex); msg("\n");
234 { // msg("1 Can't project %e", exp);
235 // print(msg(""),redex); msg("\n");
241 | SELECTORexp(e,c1,ty), redex:
242 { match (proj(e,redex,ok))
243 { CONSterm(_,c2,n,args) | c1 == c2:
245 | CODEterm(e): { return CODEterm(SELECTORexp(e,c1,ty)); }
246 | VARterm(_,_,e): { return CODEterm(SELECTORexp(e,c1,ty)); }
248 { // msg("2 Can't project %e ", exp);
249 // print(msg(""),redex); msg("\n");
256 { // msg("3 Can't project %e ", exp);
257 // print(msg(""),redex); msg("\n");
259 return CODEterm(NOexp);
264 ///////////////////////////////////////////////////////////////////////////////
266 // Compose two projection expression
268 ///////////////////////////////////////////////////////////////////////////////
269 Exp TRS::proj(Exp e1, Exp e2, Bool& ok)
271 { IDexp "redex": { return e2; }
272 | SELECTORexp(e,c,ty): { return SELECTORexp(proj(e,e2,ok),c,ty); }
273 | DOTexp(e,id): { return DOTexp(proj(e,e2,ok),id); }
274 | _: { msg("Can't project %e %e\n", e1, e2); return NOexp; }
278 ///////////////////////////////////////////////////////////////////////////////
282 ///////////////////////////////////////////////////////////////////////////////
283 Term TRS::copy(Term rhs)
285 { CONSterm(f,c,n,args):
286 { return CONSterm(f,c,n,copy(n,args)); }
291 ///////////////////////////////////////////////////////////////////////////////
295 ///////////////////////////////////////////////////////////////////////////////
296 Term * TRS::copy(int n, Term rhs [])
297 { Term * args = (Term*)mem_pool.m_alloc(sizeof(Term) * n);
298 for (int i = 0; i < n; i++)
299 args[i] = copy(rhs[i]);
303 ///////////////////////////////////////////////////////////////////////////////
305 // Method to evaluate a guard expression
307 ///////////////////////////////////////////////////////////////////////////////
308 TRS::EvalResult TRS::eval_guard(Exp exp)
312 ///////////////////////////////////////////////////////////////////////////////
314 // Method to print out the residue.
316 ///////////////////////////////////////////////////////////////////////////////
317 void TRS::print_residue(Rule r, Term rhs_residue) const
318 { std::ostream& log = open_logfile();
319 MatchRule rule = rule_map[r];
320 log << "line " << rule->begin_line << ": "
321 << rule_map[r] << ' ';
322 print(log, rhs_map[r]); log << '\n';
323 for (int i = 0; i < num_var_map[r]; i++)
324 { if (states[i] != 0)
325 { log << "\twhen " << var_pat_map[r][i] << " is in state:\n";
326 treeauto.print_state(log,states[i]);
329 log << "\toptimize rhs to ";
330 print(log,rhs_residue);