EditionDistance always returns 0 distance [message #1819682] |
Tue, 21 January 2020 09:55 |
Magnus Marthinsen Messages: 9 Registered: January 2020 |
Junior Member |
|
|
Hi!
I am working on a project that takes a broken model and repairs it. I am trying to calculate the editing distance between the original model and the repaired version. To do this I am using the org.eclipse.emf.compare.match.eobject.EditionDistance-class.
I am using EMFCompare to find the differenes, and passes the Comparison to the distance-function. Even though there are differences listed in the comparison, the distance is still 0 and the areIdentic-method returns true. Am I using it wrong?
This is the code I am using:
public double calculateDistanceFromOriginal() {
URI originalUri = URI.createFileURI(getOriginal().getAbsolutePath());
URI modelUri = URI.createFileURI(getModel().getAbsolutePath());
ResourceSet originalResourceSet = new ResourceSetImpl();
ResourceSet modelResourceSet = new ResourceSetImpl();
originalResourceSet.getResource(originalUri, true);
modelResourceSet.getResource(modelUri, true);
IComparisonScope scope = new DefaultComparisonScope(originalResourceSet, modelResourceSet, null);
Comparison comparison = EMFCompare.builder().build().compare(scope);
EList<Diff> diff = comparison.getDifferences();
Resource orignalResource = originalResourceSet.getResource(originalUri, false);
Resource modelResource = modelResourceSet.getResource(modelUri, false);
WeightProvider weightProvider = new EcoreWeightProvider();
EditionDistance distanceCalculator = EditionDistance.builder().weightProvider(weightProvider).build();
double totalDistance = 0;
for(int i = 0; i < orignalResource.getContents().size(); i++) {
EObject originalObject = orignalResource.getContents().get(i);
EObject newObject = modelResource.getContents().get(i);
totalDistance += distanceCalculator.distance(comparison, originalObject, newObject);
}
return totalDistance; // distanceCalculator.distance(comparison, originalModel, newModel);
To view the full code, look here.
|
|
|
Re: EditionDistance always returns 0 distance [message #1820699 is a reply to message #1819682] |
Mon, 27 January 2020 08:36 |
|
Hello,
Unfortunately I don't have the specifics on how the EditionDistance works under the hood in memory. You might want to look at how it is used internally by EMF Compare when computing the differences for models with no ID and try to reproduce that.
I'm pretty sure that the EditionDistance.Builder is not used internally, we construct our EditionDistance instances with both a WeightProvider registry and an EqualityHelperExtensionProvider registry (see org.eclipse.emf.compare.match.DefaultMatchEngine.createDefaultEObjectMatcher(UseIdentifiers, Registry, Registry), you can use EqualityHelperExtensionProviderDescriptorRegistryImpl.createStandaloneInstance() as the second of those registries ). Further than that, I am not sure that you can give a completed comparison to the EditionDistance. I believe objects with a Match already present in that comparison will be reported as identic. The comparison has to be an "in progress" one. I do not think we have implemented a use case that directly calls the EditionDistance on our side to date.
Why exactly are you trying to compute the distance between the models, shouldn't the comparison then merging be enough to repair your models?
Laurent Goubet
Obeo
|
|
|
Re: EditionDistance always returns 0 distance [message #1820896 is a reply to message #1820699] |
Fri, 31 January 2020 08:15 |
Magnus Marthinsen Messages: 9 Registered: January 2020 |
Junior Member |
|
|
Thank you so much for the response :)
You're right, the builder is not used. Like you said you construct it with a WeightProvider registry and an EqualityHelperExtensionProvider registry.
From org.eclipse.emf.compare.match.DefaultMatchEngine:
public static IEObjectMatcher createDefaultEObjectMatcher(UseIdentifiers useIDs,
WeightProvider.Descriptor.Registry weightProviderRegistry,
EqualityHelperExtensionProvider.Descriptor.Registry equalityHelperExtensionProviderRegistry) {
final IEObjectMatcher matcher;
final EditionDistance editionDistance = new EditionDistance(weightProviderRegistry,
equalityHelperExtensionProviderRegistry);
final CachingDistance cachedDistance = new CachingDistance(editionDistance);
switch (useIDs) {
case NEVER:
matcher = new ProximityEObjectMatcher(cachedDistance);
break;
.
.
.
}
As we can see, CachingDistance is used. The ProximityEObjectMatcher passes this to a ByTypeIndex, ant the ByTypeIndex passes it to a ProximityIndex. When looking at the ProximityIndexTest I found this:
Comparison comp = CompareFactory.eINSTANCE.createComparison();
for (EObject leftElement : index.getValuesStillThere(Side.LEFT)) {
assertNull("With a distance which always return Double.MAX_VALUE we should never find a closest.",
index.findClosests(comp, leftElement, Side.LEFT));
}
The findClosest calls the private method findTheClosest(), that is the closest I can find to comparing two models.
I have tried implementing this:
Comparison comparison = CompareFactory.eINSTANCE.createComparison();
EditionDistance editionDistance = new EditionDistance(WeightProviderDescriptorRegistryImpl.createStandaloneInstance(), EqualityHelperExtensionProviderDescriptorRegistryImpl.createStandaloneInstance());
CachingDistance cachingDistance = new CachingDistance(editionDistance);
double distance = cachingDistance.distance(comparison, orignalResource.getContents().get(0), modelResource.getContents().get(0));
System.out.println("Distance: "+ distance);
...but still no luck. The distance is still 0.0, and the models are not equal. Any ideas?
Quote:Why exactly are you trying to compute the distance between the models, shouldn't the comparison then merging be enough to repair your models?
I have already repaired the models, the EditingDistance is just to see how much the models have changed :)
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.04810 seconds