Assignment In Control Of Rewriting
Pt
Assignment
In Section 7.6 the idiom of `staged cascading transformations' is
described as a sequence of innermost normalizations:
simplify =
innermost(A1 + ... + Ak)
; innermost(B1 + ... + Bl)
; ...
; innermost(C1 + ... + Cm)
Use this idiom to implement the 'sequence of canonical forms'
transformation style of TAMPR described in Section 7.4. In particular,
write a set of rewrite rules for achieving the polynomial reordering
described in that section, for Tiger expressions. Thus, the Tiger
polynomial in
y
(x**2 + 2 * x + 1) * y**2 + (x**2 - 9) * y - (20*x**2 + 18*x - 18)
should be turned into the following polynomial in
x:
(y**2 + y - 20) * x**2 + (2*y**2 - 18)*x + (y**2 - 9*y + 18)
Transformation Setup
This should be achieved by means of the following program:
------------------------------------------------
module factorout
imports lib Tiger
strategies
main =
io-wrap(factorout-options,
factorout(|<get-config>"--factor")
)
factorout-options =
ArgOption("--factor"
, <set-config>("--factor", <id>)
,"--factor")
factorout(|x) =
sum-of-monomonials
; commute-right(|x)
; collect-by-power(|x)
; factor-out(|x)
sum-of-monomonials =
innermost(RulesA)
commute-right(|x) =
innermost(RulesB)
collect-by-power(|x) =
innermost(RulesC)
factor-out(|x) =
innermost(RulesD)
------------------------------------------------
This program should be extended with appropriate sets of rewrite
rules for
RulesA to
RulesD.
Note that some of the definitions are parameterized with a term
argument
x which represents the name of the variable to be factored
out.
Use concrete syntax to define the rewrite rules.
Applying the transformation
The transformation should be applied in the following pipeline (add slashes at the
end of the lines):
parse-tiger -i $<
| Tiger-Desugar
| Tiger-Rename
| ./factorout --factor x
| TAS-Format
| Tiger-Ensugar
| pp-tiger -o $@
It should be possible to select a different variable to factor out.
Submission
Submit the following files
- Makefile
- factout.str : the transformation program
- polynomial%.tig : Tiger expressions to test the transformation
- polynomial%.exp : expected outputs
The makefile should implement the following targets
- factorout : compilation of the program
- %.fou : applies transformation to a Tiger program
- clean
- check : checks transformation for several example expressions
Tips
Levels of Complexity
As usual it is not necessary to submit a complete solution, but the
more cases your transformation can handle, the higher your grade.
Make sure your transformation is always correct.
Write a set of example Tiger expressions with growing complexity.
Only try to deal with the next level if you can completely deal
with the previous level.
Rules with Term Arguments
Rewrite rules can be parameterized with term arguments. In this way you
can specify a transformation only for specific terms. For instance, the
following rule commutes an addition if the left-argument is the argument
x:
L(|x) : |[ +(x, e) ]| -> |[ +(e, x) ]|
Due to a problem in the compiler you should compile with optimization turned off, i.e.,
strc -O 0
Useful tests
The following tests can be used in conditions of rules:
strategies
atomic = Var(id) + Int(id) + Real(id) + String(id)
commutative = PLUS + MUL
associative = PLUS + MUL
The
commutative and
associative tests allow you to write more generic transformation rules that apply to all commutative (associative) operators.
Recall: an operator bo is associative if
bo(e1, bo(e2, e3)) = bo(bo(e1, e2), e3)
and commutative if
bo(e1, e2) = bo(e2, e1)
Is it a factor?
The following test determines whether an expression is
x or a power of
x.
is-factor(|x) = ?|[ x ]| + ?|[ **(x, i) ]|
Factor of
Disect an expression of the general form *(e, **(x, i)) into the coefficient
e and the exponent
i.
factor-of(|x) : |[ *(e, **(x, i)) ]| -> (|[ e ]|, |[ i ]|)
factor-of(|x) : |[ *(e, x) ]| -> (|[ e ]|, |[ 1 ]|)
factor-of(|x) : |[ **(x, i) ]| -> (|[ 1 ]|, |[ i ]|)
factor-of(|x) : |[ x ]| -> (|[ 1 ]|, |[ 1 ]|)
Exponent of
The following strategy produces the exponent in
x of an expression:
exponent-of(|x) = factor-of(|x); Snd; ?Int(<id>) <+ !"0"
Then you can test whether the exponent of expressions
e2 is greater
than the exponent of expression
e1 as follows:
<gtS>(<exponent-of(|x)> e2, <exponent-of(|x)> e1)