@@ -194,3 +194,44 @@ Gvn toGvn(ControlFlowElement cfe) {
194
194
result = TListGvn ( l )
195
195
)
196
196
}
197
+
198
+ /**
199
+ * A configuration for performing structural comparisons of program elements
200
+ * (expressions and statements).
201
+ *
202
+ * The predicate `candidate()` must be overridden, in order to identify the
203
+ * elements for which to perform structural comparison.
204
+ *
205
+ * Each use of the library is identified by a unique string value.
206
+ */
207
+ abstract class StructuralComparisonConfiguration extends string {
208
+ bindingset [ this ]
209
+ StructuralComparisonConfiguration ( ) { any ( ) }
210
+
211
+ /**
212
+ * Holds if elements `x` and `y` are candidates for testing structural
213
+ * equality.
214
+ *
215
+ * Subclasses are expected to override this predicate to identify the
216
+ * top-level elements which they want to compare. Care should be
217
+ * taken to avoid identifying too many pairs of elements, as in general
218
+ * there are very many structurally equal subtrees in a program, and
219
+ * in order to keep the computation feasible we must focus attention.
220
+ *
221
+ * Note that this relation is not expected to be symmetric -- it's
222
+ * fine to include a pair `(x, y)` but not `(y, x)`.
223
+ * In fact, not including the symmetrically implied fact will save
224
+ * half the computation time on the structural comparison.
225
+ */
226
+ abstract predicate candidate ( ControlFlowElement x , ControlFlowElement y ) ;
227
+
228
+ /**
229
+ * Holds if elements `x` and `y` structurally equal. `x` and `y` must be
230
+ * flagged as candidates for structural equality, that is,
231
+ * `candidate(x, y)` must hold.
232
+ */
233
+ predicate same ( ControlFlowElement x , ControlFlowElement y ) {
234
+ candidate ( x , y ) and
235
+ toGvn ( x ) = toGvn ( y )
236
+ }
237
+ }
0 commit comments