1 ///////////////////////////////////////////////////////////////////////////////
3 // These are the routines for building the data structure
4 // for partial evaluting a TRS
6 ///////////////////////////////////////////////////////////////////////////////
20 ///////////////////////////////////////////////////////////////////////////////
22 // Constructors for represents a term
24 ///////////////////////////////////////////////////////////////////////////////
25 instantiate datatype Term;
27 ///////////////////////////////////////////////////////////////////////////////
29 // Constructor for TRS
31 ///////////////////////////////////////////////////////////////////////////////
32 TRS::TRS(RewritingCompiler& C)
33 : compiler(C), Fmap(*C.Fmap), treeauto(*C.Fmap->tree_gen),
36 MatchRules rules = Fmap.bottomup_rules;
37 number_of_rules = length(rules);
38 rule_map = new MatchRule [number_of_rules];
39 guard_map = new Exp [number_of_rules];
40 lhs_map = new Term [number_of_rules];
41 rhs_map = new Term [number_of_rules];
42 num_var_map = new int [number_of_rules];
43 var_map = new Exp * [number_of_rules];
44 var_pat_map = new Pat * [number_of_rules];
45 residue_map = new Residues *[number_of_rules];
46 literal_map = new Literal [Fmap.G.functors()];
47 optimized_map = new Exp [number_of_rules];
52 for_each(MatchRule, r, rules)
54 { MATCHrule(_,pat,guard,exp,action):
55 { if (r->rule_number != i) bug("%LTRS::TRS()");
60 { #[MARKEDdecl(_,REPLACEMENTdecl(exp,_))]: { make_rhs(i,exp); }
61 | _: { rhs_map[i] = OPAQUEterm(action); }
69 ///////////////////////////////////////////////////////////////////////////////
73 ///////////////////////////////////////////////////////////////////////////////
79 delete [] num_var_map;
81 delete [] var_pat_map;
82 delete [] residue_map;
83 delete [] literal_map;
84 delete [] optimized_map;
87 ///////////////////////////////////////////////////////////////////////////////
89 // Method to determine if any expression is a pattern variable.
91 ///////////////////////////////////////////////////////////////////////////////
92 Bool is_pattern_var(Exp exp)
94 { SELECTORexp(IDexp "redex",_,_): { return true; }
95 | DOTexp(SELECTORexp(IDexp "redex",_,_),_): { return true; }
96 | DOTexp(SELECTORexp(e,_,_),_): { exp = e; }
97 | SELECTORexp(e,_,_): { exp = e; }
98 | _: { return false; }
102 ///////////////////////////////////////////////////////////////////////////////
104 // Method to create the lhs
106 ///////////////////////////////////////////////////////////////////////////////
107 void TRS::make_lhs(Rule r, Pat pat)
109 lhs_map[r] = make_term(pat);
111 num_var_map[r] = num_vars;
112 var_map[r] = (Exp*)mem_pool.m_alloc(sizeof(Exp)*num_vars);
113 var_pat_map[r] = (Pat*)mem_pool.m_alloc(sizeof(Pat)*num_vars);
114 residue_map[r] = (Residues*)mem_pool.c_alloc(sizeof(Residues)*num_vars);
115 optimized_map[r] = NOexp;
117 memcpy(var_map[r], vars, sizeof(Exp)*num_vars);
118 memcpy(var_pat_map[r],var_pats,sizeof(Pat)*num_vars);
121 ///////////////////////////////////////////////////////////////////////////////
123 // Method to create the lhs for rule r
125 ///////////////////////////////////////////////////////////////////////////////
126 Term TRS::make_term(Pat pat)
128 { MARKEDpat(_,p): { pat = p; }
129 | ASpat(_,p,_,_): { pat = p; }
130 | IDpat _: { return make_term_var(pat,pat->selector); }
131 | APPpat(CONSpat C, TUPLEpat ps): { return make_term(pat,C,ps); }
132 | APPpat(CONSpat C, p): { return make_term(pat,C,#[p]); }
133 | CONSpat C: { return make_term(pat,C,#[]); }
134 | LISTpat { cons, nil, head = #[], tail = NOpat }:
135 { return make_term(pat,nil,#[]); }
136 | LISTpat { cons, nil, head = #[], tail }:
138 | LISTpat { cons, nil, head = #[h ... t], tail }:
139 { Pat tl_pat = LISTpat'{cons = cons, nil = nil, head = t, tail = tail};
140 tl_pat->ty = pat->ty;
141 return make_term(pat,cons,#[h,tl_pat]);
143 | LITERALpat l | Fmap.literal_map.contains(l):
144 { Functor f = Fmap.literal_map[l];
146 return CONSterm(f,NOcons,0,0);
148 | pat: { return PATterm(pat); }
152 ///////////////////////////////////////////////////////////////////////////////
154 // Method to create the lhs for rule r
156 ///////////////////////////////////////////////////////////////////////////////
157 Term TRS::make_term(Pat pat, Cons cons, Pats pats)
158 { int n = length(pats);
159 FunctorTable::Entry * E = Fmap.type_map.lookup(pat->ty);
160 if (E == 0) { return PATterm(pat); }
162 { DATATYPEty ({ unit ... }, _):
163 { Functor f = Fmap.type_map.value(E) + cons->tag +
164 (cons->ty == NOty ? 0 : unit);
165 return CONSterm(f,cons,n,make_term(pats));
167 | _: { bug("TRS::make_term"); return PATterm(pat); }
171 ///////////////////////////////////////////////////////////////////////////////
173 // Method to create the lhs for rule r
175 ///////////////////////////////////////////////////////////////////////////////
176 Term * TRS::make_term(Pats pats)
177 { int n = length(pats);
178 Term * args = (Term *)mem_pool.m_alloc(sizeof(Term) * n);
180 for_each(Pat, p, pats) args[i++] = make_term(p);
184 ///////////////////////////////////////////////////////////////////////////////
186 // Return the type of an expression
188 ///////////////////////////////////////////////////////////////////////////////
189 Ty type_of(Exp e) { return type_of(e,Env()); }
191 ///////////////////////////////////////////////////////////////////////////////
193 // Method to create the rhs for rule r
195 ///////////////////////////////////////////////////////////////////////////////
196 void TRS::make_rhs(Rule r, Exp exp)
198 rhs_map[r] = make_term(exp);
201 ///////////////////////////////////////////////////////////////////////////////
203 // Method to create the rhs
205 ///////////////////////////////////////////////////////////////////////////////
206 Term TRS::make_term(Exp exp)
209 { MARKEDexp(_,e): { exp = e; }
210 | IDexp id: { return make_term(exp,id,#[]); }
211 | CONSexp(cons,#[],NOexp):
212 { return make_term(exp,cons->name,#[]); }
213 | CONSexp(cons,#[],TUPLEexp es):
214 { return make_term(exp,cons->name,es); }
215 | CONSexp(cons,#[],e):
216 { return make_term(exp,cons->name,#[e]); }
217 | LISTexp(cons, nil, #[h], t):
218 { Exp nil_exp = t == NOexp ? CONSexp(nil,#[],NOexp) : t;
219 nil_exp->ty = exp->ty;
220 return make_term(exp,cons->name,#[h,nil_exp]);
222 | LISTexp(cons, nil, #[h ... t], tail):
223 { Exp e2 = LISTexp(cons, nil, t, tail);
225 return make_term(exp,cons->name,#[h,e2]);
227 | APPexp(IDexp id,TUPLEexp es):
228 { law_exp = DatatypeCompiler::lookup_law(id,es);
229 if (law_exp == NOexp) return make_term(exp,id,es);
233 | APPexp(IDexp id,e):
234 { law_exp = DatatypeCompiler::lookup_law(id,#[e]);
235 if (law_exp == NOexp) return make_term(exp,id,#[e]);
239 | LITERALexp l | Fmap.literal_map.contains(l):
240 { return CONSterm(Fmap.literal_map[l],0,0,0); }
241 | exp | is_pattern_var(exp): { return make_term_var(NOpat,exp); }
242 | exp: { return CODEterm(exp); }
246 ///////////////////////////////////////////////////////////////////////////////
248 // Method to create the rhs
250 ///////////////////////////////////////////////////////////////////////////////
251 Term TRS::make_term(Exp exp, Id id, Exps exps)
252 { int n = length(exps);
253 Cons cons = find_cons(id);
254 if (cons == NOcons) { return CODEterm(exp); }
255 FunctorTable::Entry * E = Fmap.type_map.lookup(exp->ty);
256 if (E == 0) { return CODEterm(exp); }
258 { DATATYPEty({ unit ... },_):
259 { Functor f = Fmap.type_map.value(E) + cons->tag +
260 (cons->ty == NOty ? 0 : unit);
261 return CONSterm(f,cons,n,make_term(exps));
263 | _: { bug("TRS::make_term"); return CODEterm(exp); }
267 ///////////////////////////////////////////////////////////////////////////////
269 // Method to create the term variable
271 ///////////////////////////////////////////////////////////////////////////////
272 Term TRS::make_term_var(Pat pat, Exp exp)
273 { for (int i = 0; i < num_vars; i++)
274 { if (equal(exp,vars[i])) return VARterm(i,var_pats[i],vars[i]); }
275 if (pat == NOpat) { return CODEterm(exp); }
276 if (num_vars == MAX_VARS)
277 bug("%LTRS::make_term_var() too many variables");
278 vars[num_vars] = exp;
279 var_pats[num_vars] = pat;
280 return VARterm(num_vars++,pat,exp);
283 ///////////////////////////////////////////////////////////////////////////////
285 // Method to create the term from a list of expressions
287 ///////////////////////////////////////////////////////////////////////////////
288 Term * TRS::make_term(Exps exps)
289 { int n = length(exps);
290 Term * args = (Term *)mem_pool.m_alloc(sizeof(Term) * n);
292 for_each(Exp, e, exps) args[i++] = make_term(e);
296 /////////////////////////////////////////////////////////////////////////////// //
298 // Method to print a term
300 ///////////////////////////////////////////////////////////////////////////////
301 void TRS::print (std::ostream& s, Term term) const
303 { CONSterm(f,cons,2,args) | is_list_constructor(cons):
304 { s << '#' << cons->name[1];
308 { CONSterm(g,cons2,2,args) | g == f:
309 { s << comma; print(s,args[0]); t = args[1]; comma = ", "; }
312 { CONSterm(g,nil,0,args)
313 | cons && is_list_constructor(nil): // skip
314 | _: { s << comma; print(s,t); }
318 | CONSterm(f,cons,arity,args):
319 { s << (cons != NOcons ? cons->name : Fmap.G.functor_name(f));
322 for (int i = 0; i < arity; i++)
324 if (i < arity - 1) s << ", ";
329 | VARterm(v,pat,_): { s << pat; }
330 | CODEterm(exp): { Bool save = pretty_print_exp;
331 pretty_print_exp = true;
332 s << "[[" << exp << "]]";
333 pretty_print_exp = save;
335 | OPAQUEterm _: { s << "..."; }
336 | PATterm pat: { s << "[[" << pat << "]]"; }
340 ///////////////////////////////////////////////////////////////////////////////
342 // Method to print a TRS
344 ///////////////////////////////////////////////////////////////////////////////
345 void TRS::print (std::ostream& s) const
346 { s << "\n\nBottom-up term rewriting system:\n";
347 Bool save = pretty_print_exp;
348 pretty_print_exp = true;
349 for (Rule r = 0; r < number_of_rules; r++)
350 { MatchRule rule = rule_map[r];
351 s << "line " << rule->begin_line << ": ";
353 if (guard_map[r] != NOexp) s << " | " << guard_map[r];
354 s << ":\n\t"; print(s,rhs_map[r]); s << '\n';
355 for (int i = 0; i < num_var_map[r]; i++)
356 { Pat pat_var = var_pat_map[r][i];
357 Ty pat_ty = pat_var->ty;
358 s << "\tvariable " << pat_var << " : " << pat_ty;
359 if (! compiler.has_index(pat_ty)) s << " has no index";
365 pretty_print_exp = save;