1 ///////////////////////////////////////////////////////////////////////////////
2 // This file is generated automatically using Prop (version 2.3.6),
3 // last updated on Nov 2, 1999.
4 // The original source file is "trs2.pcc".
5 ///////////////////////////////////////////////////////////////////////////////
7 #define PROP_STRCMP_USED
8 #define PROP_TUPLE2_USED
11 ///////////////////////////////////////////////////////////////////////////////
13 // This is the main partial evaluation routines.
15 ///////////////////////////////////////////////////////////////////////////////
28 ///////////////////////////////////////////////////////////////////////////////
32 ///////////////////////////////////////////////////////////////////////////////
33 typedef TreeAutomaton::Functor Functor
;
34 typedef TreeAutomaton::State State
;
35 typedef TreeAutomaton::Rule Rule
;
37 ///////////////////////////////////////////////////////////////////////////////
39 // Method for partial evaluating the trs
41 ///////////////////////////////////////////////////////////////////////////////
43 { for (Rule r
= 0; r
< number_of_rules
; r
++)
48 ///////////////////////////////////////////////////////////////////////////////
50 // Method for partial evaluating one rule
52 ///////////////////////////////////////////////////////////////////////////////
58 ///////////////////////////////////////////////////////////////////////////////
60 // Method for partial evaluting one rule, using 0-strategy.
62 ///////////////////////////////////////////////////////////////////////////////
63 void TRS::mix_0(Rule r
)
64 { int arity
= num_var_map
[r
];
65 for (int i
= 0; i
< arity
; i
++) states
[i
] = 0;
66 // msg("0-Partial evaluating %r ", rule_map[r]) << rhs_map[r] << '\n';
67 Term rhs
= copy(rhs_map
[r
]);
69 State new_state
= normalize(rhs
,reductions
);
71 { print_residue(r
,rhs
);
72 make_rhs(r
,optimized_map
[r
] = make_exp(rhs
));
76 ///////////////////////////////////////////////////////////////////////////////
78 // Method for partial evaluting one rule, using 1-strategy.
80 ///////////////////////////////////////////////////////////////////////////////
81 void TRS::mix_1(Rule r
)
82 { int arity
= num_var_map
[r
];
83 int number_of_states
= treeauto
.number_of_states();
84 // msg("1-Partial evaluating %r ", rule_map[r]) << rhs_map[r] << '\n';
85 for (int i
= 0; i
< arity
; i
++)
86 { // If the variable does not have an index we can't do anything
88 if (! compiler
.has_index(var_pat_map
[r
][i
]->ty
)) continue;
89 for (int j
= 0; j
< arity
; j
++) states
[j
] = 0;
90 for (State s
= 1; s
< number_of_states
; s
++)
91 { // skip accept states
93 if (treeauto
.is_accept_state(s
)) continue;
94 if (! is_relevant(r
)) continue;
96 Term rhs
= copy(rhs_map
[r
]);
97 State new_state
= normalize(rhs
,reductions
);
99 { generate_residue(r
,i
,s
,rhs
); }
104 ///////////////////////////////////////////////////////////////////////////////
106 // Method to check that a particular specialization is relevant
108 ///////////////////////////////////////////////////////////////////////////////
109 Bool
TRS::is_relevant(Rule r
)
110 { int redex_count
= 0;
112 State s
= normalize(lhs_map
[r
],redex_count
);
114 // cerr << lhs_map[r] << " has " << redex_count << " redexes\n";
115 if (redex_count
> 1) return false;
116 if (treeauto
.accept1_rule(s
) != r
) return false;
120 ///////////////////////////////////////////////////////////////////////////////
122 // Method to normalize a rule
124 ///////////////////////////////////////////////////////////////////////////////
125 TRS::State
TRS::normalize(Term
& term
, int& reductions
)
134 switch (term
->tag__
) {
135 case a_Term::tag_CONSterm
: {
138 for (int i
= 0; i
< ((Term_CONSterm
*)term
)->_3
; i
++)
139 { State s
= normalize(((Term_CONSterm
*)term
)->_4
[i
],reductions
);
140 mu
[i
] = treeauto
.index_map(((Term_CONSterm
*)term
)->_1
,i
,s
);
142 new_state
= treeauto
.get_delta(((Term_CONSterm
*)term
)->_1
,mu
);
144 if (treeauto
.is_accept_state(new_state
))
149 term
= reduce(term
,new_state
,reductions
,changed
);
154 case a_Term::tag_VARterm
: {
156 return states
[((Term_VARterm
*)term
)->_1
];
173 ///////////////////////////////////////////////////////////////////////////////
175 // Method to reduce a rule during accepting
177 ///////////////////////////////////////////////////////////////////////////////
178 Term
TRS::reduce(Term term
, State state
, int& reductions
, Bool
& changed
)
180 // Test for conditional rules
181 // For each rule that can accept, check the guard associated
182 // with the rule. Evaluate the guard if possible.
183 // We'll not reduce if we are not guaranteed that the reduction
185 const BitSet
& accept
= treeauto
.accept_rules(state
);
186 for (Rule r
= 0; r
<= number_of_rules
; r
++)
188 { Exp guard
= guard_map
[r
];
189 EvalResult result
= SUCCESS
;
190 if (guard
== NOexp
) result
= SUCCESS
;
191 else result
= eval_guard(guard
);
194 { Term rule_rhs
= rhs_map
[r
];
196 Term new_rhs
= subst(rule_rhs
,term
,ok
);
197 if (! ok
) return term
; // no reduction
202 case UNKNOWN
: return term
; // no reduction
203 case FAILURE
: break; // try next rule
207 return term
; // no reduction
210 ///////////////////////////////////////////////////////////////////////////////
214 ///////////////////////////////////////////////////////////////////////////////
215 Term
TRS::subst(Term rhs
, Term redex
, Bool
& ok
)
220 switch (rhs
->tag__
) {
221 case a_Term::tag_CONSterm
: {
223 return CONSterm(((Term_CONSterm
*)rhs
)->_1
,((Term_CONSterm
*)rhs
)->_2
,((Term_CONSterm
*)rhs
)->_3
,subst(((Term_CONSterm
*)rhs
)->_3
,((Term_CONSterm
*)rhs
)->_4
,redex
,ok
));
226 case a_Term::tag_VARterm
: {
228 return proj(((Term_VARterm
*)rhs
)->_3
,redex
,ok
);
231 case a_Term::tag_CODEterm
: {
233 return proj(((Term_CODEterm
*)rhs
)->CODEterm
,redex
,ok
);
238 bug("TRS::subst"); return redex
;
248 ///////////////////////////////////////////////////////////////////////////////
252 ///////////////////////////////////////////////////////////////////////////////
253 Term
* TRS::subst(int n
, Term
* rhs
, Term redex
, Bool
& ok
)
254 { Term
* args
= (Term
*)mem_pool
.m_alloc(sizeof(Term
) * n
);
255 for (int i
= 0; i
< n
; i
++)
256 args
[i
] = subst(rhs
[i
],redex
,ok
);
260 ///////////////////////////////////////////////////////////////////////////////
262 // Perform projection a rule
264 ///////////////////////////////////////////////////////////////////////////////
265 Term
TRS::proj(Exp exp
, Term redex
, Bool
& ok
)
272 switch (exp
->tag__
) {
273 case a_Exp::tag_IDexp
: {
274 if (_equal_string(((Exp_IDexp
*)exp
)->IDexp
,"redex")) {
282 // msg("3 Can't project %e ", exp);
283 // print(msg(""),redex); msg("\n");
285 return CODEterm(NOexp
);
290 case a_Exp::tag_DOTexp
: {
291 if (((Exp_DOTexp
*)exp
)->_1
) {
292 switch (((Exp_DOTexp
*)exp
)->_1
->tag__
) {
293 case a_Exp::tag_SELECTORexp
: {
299 Term _V1
= proj(((Exp_SELECTORexp
*)((Exp_DOTexp
*)exp
)->_1
)->_1
,redex
,ok
);
300 switch (_V1
->tag__
) {
301 case a_Term::tag_CONSterm
: {
304 ((((Exp_SELECTORexp
*)((Exp_DOTexp
*)exp
)->_1
)->_2
== ((Term_CONSterm
*)_V1
)->_2
) && (nth
= (atol((((Exp_DOTexp
*)exp
)->_2
+ 1)) - 1)),(nth
< ((Term_CONSterm
*)_V1
)->_3
))
309 return ((Term_CONSterm
*)_V1
)->_4
[nth
];
314 // msg("1 Can't project %e %i %i", exp,nth,n);
315 // print(msg(""),redex); msg("\n");
322 case a_Term::tag_VARterm
: {
324 return CODEterm(DOTexp(SELECTORexp(((Term_VARterm
*)_V1
)->_3
,((Exp_SELECTORexp
*)((Exp_DOTexp
*)exp
)->_1
)->_2
,((Exp_SELECTORexp
*)((Exp_DOTexp
*)exp
)->_1
)->_3
),((Exp_DOTexp
*)exp
)->_2
));
327 case a_Term::tag_CODEterm
: {
329 return CODEterm(DOTexp(SELECTORexp(((Term_CODEterm
*)_V1
)->CODEterm
,((Exp_SELECTORexp
*)((Exp_DOTexp
*)exp
)->_1
)->_2
,((Exp_SELECTORexp
*)((Exp_DOTexp
*)exp
)->_1
)->_3
),((Exp_DOTexp
*)exp
)->_2
));
334 // msg("1 Can't project %e", exp);
335 // print(msg(""),redex); msg("\n");
349 default: { goto L1
; } break;
353 case a_Exp::tag_SELECTORexp
: {
359 Term _V2
= proj(((Exp_SELECTORexp
*)exp
)->_1
,redex
,ok
);
360 switch (_V2
->tag__
) {
361 case a_Term::tag_CONSterm
: {
364 (((Exp_SELECTORexp
*)exp
)->_2
== ((Term_CONSterm
*)_V2
)->_2
)
369 return ((Term_CONSterm
*)_V2
)->_4
[0];
375 // msg("2 Can't project %e ", exp);
376 // print(msg(""),redex); msg("\n");
383 case a_Term::tag_VARterm
: {
385 return CODEterm(SELECTORexp(((Term_VARterm
*)_V2
)->_3
,((Exp_SELECTORexp
*)exp
)->_2
,((Exp_SELECTORexp
*)exp
)->_3
));
388 case a_Term::tag_CODEterm
: {
390 return CODEterm(SELECTORexp(((Term_CODEterm
*)_V2
)->CODEterm
,((Exp_SELECTORexp
*)exp
)->_2
,((Exp_SELECTORexp
*)exp
)->_3
));
393 default: { goto L2
; } break;
402 default: { goto L1
; } break;
411 ///////////////////////////////////////////////////////////////////////////////
413 // Compose two projection expression
415 ///////////////////////////////////////////////////////////////////////////////
416 Exp
TRS::proj(Exp e1
, Exp e2
, Bool
& ok
)
423 case a_Exp::tag_IDexp
: {
424 if (_equal_string(((Exp_IDexp
*)e1
)->IDexp
,"redex")) {
432 msg("Can't project %e %e\n", e1
, e2
); return NOexp
;
436 case a_Exp::tag_DOTexp
: {
438 return DOTexp(proj(((Exp_DOTexp
*)e1
)->_1
,e2
,ok
),((Exp_DOTexp
*)e1
)->_2
);
441 case a_Exp::tag_SELECTORexp
: {
443 return SELECTORexp(proj(((Exp_SELECTORexp
*)e1
)->_1
,e2
,ok
),((Exp_SELECTORexp
*)e1
)->_2
,((Exp_SELECTORexp
*)e1
)->_3
);
446 default: { goto L3
; } break;
455 ///////////////////////////////////////////////////////////////////////////////
459 ///////////////////////////////////////////////////////////////////////////////
460 Term
TRS::copy(Term rhs
)
465 switch (rhs
->tag__
) {
466 case a_Term::tag_CONSterm
: {
468 return CONSterm(((Term_CONSterm
*)rhs
)->_1
,((Term_CONSterm
*)rhs
)->_2
,((Term_CONSterm
*)rhs
)->_3
,copy(((Term_CONSterm
*)rhs
)->_3
,((Term_CONSterm
*)rhs
)->_4
));
483 ///////////////////////////////////////////////////////////////////////////////
487 ///////////////////////////////////////////////////////////////////////////////
488 Term
* TRS::copy(int n
, Term rhs
[])
489 { Term
* args
= (Term
*)mem_pool
.m_alloc(sizeof(Term
) * n
);
490 for (int i
= 0; i
< n
; i
++)
491 args
[i
] = copy(rhs
[i
]);
495 ///////////////////////////////////////////////////////////////////////////////
497 // Method to evaluate a guard expression
499 ///////////////////////////////////////////////////////////////////////////////
500 TRS::EvalResult
TRS::eval_guard(Exp exp
)
504 ///////////////////////////////////////////////////////////////////////////////
506 // Method to print out the residue.
508 ///////////////////////////////////////////////////////////////////////////////
509 void TRS::print_residue(Rule r
, Term rhs_residue
) const
510 { std::ostream
& log
= open_logfile();
511 MatchRule rule
= rule_map
[r
];
512 log
<< "line " << rule
->begin_line
<< ": "
513 << rule_map
[r
] << ' ';
514 print(log
, rhs_map
[r
]); log
<< '\n';
515 for (int i
= 0; i
< num_var_map
[r
]; i
++)
516 { if (states
[i
] != 0)
517 { log
<< "\twhen " << var_pat_map
[r
][i
] << " is in state:\n";
518 treeauto
.print_state(log
,states
[i
]);
521 log
<< "\toptimize rhs to ";
522 print(log
,rhs_residue
);
527 ------------------------------- Statistics -------------------------------
528 Merge matching rules = yes
529 Number of DFA nodes merged = 121
530 Number of ifs generated = 7
531 Number of switches generated = 8
534 Adaptive matching = enabled
535 Fast string matching = disabled
536 Inline downcasts = enabled
537 --------------------------------------------------------------------------