@@ -194,3 +194,44 @@ Gvn toGvn(ControlFlowElement cfe) {
194194 result = TListGvn ( l )
195195 )
196196}
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