3 # This is an implementation of the algorithm described in
5 # [ACI10] C. Ancourt, F. Coelho and F. Irigoin, A modular static analysis
6 # approach to affine loop invariants detection (2010), pp. 3 - 16, NSAD 2010.
8 # to compute the transitive closure of an affine transformer. A refined version
9 # of this algorithm is implemented in PIPS.
16 def __new__(cls
, polyhedron
, range_symbols
, domain_symbols
):
17 self
= object().__new
__(cls
)
18 self
.polyhedron
= polyhedron
19 self
.range_symbols
= range_symbols
20 self
.domain_symbols
= domain_symbols
25 return self
.range_symbols
+ self
.domain_symbols
28 delta_symbols
= [symbol
.asdummy() for symbol
in self
.range_symbols
]
30 polyhedron
= self
.polyhedron
31 for x
, xprime
, dx
in zip(self
.range_symbols
, self
.domain_symbols
, delta_symbols
):
32 polyhedron
&= Eq(dx
, xprime
- x
)
33 polyhedron
= polyhedron
.project(self
.symbols
)
34 equalities
, inequalities
= [], []
35 for equality
in polyhedron
.equalities
:
36 equality
+= (k
-1) * equality
.constant
37 equalities
.append(equality
)
38 for inequality
in polyhedron
.inequalities
:
39 inequality
+= (k
-1) * inequality
.constant
40 inequalities
.append(inequality
)
41 polyhedron
= Polyhedron(equalities
, inequalities
) & Ge(k
, 0)
42 polyhedron
= polyhedron
.project([k
])
43 for x
, xprime
, dx
in zip(self
.range_symbols
, self
.domain_symbols
, delta_symbols
):
44 polyhedron
&= Eq(dx
, xprime
- x
)
45 polyhedron
= polyhedron
.project(delta_symbols
)
46 return Transformer(polyhedron
, self
.range_symbols
, self
.domain_symbols
)
49 if __name__
== '__main__':
50 i0
, i
, j0
, j
= symbols('i0 i j0 j')
51 transformer
= Transformer(Eq(i
, i0
+ 2) & Eq(j
, j0
+ 1),
53 print('T =', transformer
.polyhedron
)
54 print('T* =', transformer
.star().polyhedron
)