[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [mdt-ocl.dev] Overload resolution and dynamic dispatch patch

Hi Axel

I can't answer your question because it doesn't make sense to me.

It seems we now agree that we have to be able to find the opposites. Once you have those it's easy, you just use the type-specific selections in the style of a dependency analysis. The new CachedTypeChecker.getDynamicOperation(dynamicType, staticOperation) does precisely the body discovery you need.

    Regards

        Ed Willink




On 08/05/2012 08:10, Axel Uhl wrote:
a) is ugly but unavoidable if we want to maintain the current, otherwise well-working approach; b) and c) are already encapsulated by the OppositeEndFinder which does exactly that and offers a way to plug different ways of repository query capabilities.

I suppose it may be best to extend OppositeEndFinder such that it also encapsulates how to obtain the body expressions of any overriding method for a given method. Like the default for hidden opposite navigation which is based on the state of the loaded resources only, the default for discovering overrides would also only be based on loaded metamodel state and as such be consistent with the default hidden opposite navigation.

If someone (such as the query2 folks) may want to provide an OppositeEndFinder implementation using their richer query capabilities on a well-defined universe, they may as well define what the metamodel universe looks like and offer a way to discover the overriding method bodies.

Let me know what you think and I can work on a corresponding extension of OppositeEndFinder.

Best,
-- Axel

On 5/8/2012 7:59 AM, Ed Willink wrote:
Hi Axel

Ok, so we misunderstood the application domain.

The IA is targetted at huge models of which only large sub-models are
loaded in memory.

This now makes sense of your 'what are all the meta-models' questions.
If the loaded submodels consist of A objects and the unloaded submodels
might contain X objects, you need to known whether an X::a relationship
exists, so that when an A changes you can propagate impact to an X. This
has three problems:
a) you need to know all the meta-models of all the unloaded parts of the
models to discover that there is an X::a relationship
b) you need to be able to identify all X objects in the unloaded submodels
c) you need to identify which X objects have an X::a relationship
targetting the impacted A object


a) is soluble by requiring a closed universe of declared meta-models
b) is only soluble with some collaboration; if the unloaded objects are
in a repository, the repository may partition by class and so may be
able to support allInstances() without a total scan since the result of
allInstances() is cached as repository control state
c) is similarly soluble via a repository's allInstances() cache - but
only via an inefficient large scan for a huge model

If the repository maintains an allInstances() cache, the the repository
can certainly provide an allClasses()/allPackages() response to enable
all meta-models to be identified for a).

I see no way of doing hidden opposites from unloaded resources without
cached state resulting from a transient load of the whole model.

The problem of dynamic dispatch is much the same as hidden opposites.
Any function computes using modeled state, so the source type is
deducible whenever the function uses fully navigable relationships. The
problem is that if the function uses forward relationships, then you
cannot follow in reverse. This is the hidden opposites impact problem.

----

So if we have a large partial model in memory, in order to propagate
impact to the unloaded part, there are three options:
a) don't - it is an unsupported capability
b) use a type-based allInstances() search of those objects that might be
hidden opposites
c) use an instance-based cache that supports navigation of the hidden
opposite relationships

a) is easy and useful for large loadable models.

Both b) and c) rely on cached knowledge of the whole system, so if
you're going to have cached knowledge surely you should provide the
cache that supports efficient instance-based navigation rather than
dubiously scalable type-based searches?

The instance-based cache could take a variety of forms. To support huge
unloaded models, it is probably a good idea for objects to have
co-objects that contain their hidden opposites. The co-objects can be
unloaded and maintained in the repository, so the in-memory cost is
proportional to the size of the in-memory model and the number of actual
hidden opposites per object. Whenever impact spreads, you can load the
impacted objects and their co-objects. The IA can of course maintain the
co-object relationships automatically.

Some classes, such as OCLExpression, have a large number of hidden
opposites, so the 'coOCLExpression' probably wants to use a list of
(feature,object) pairs for the typically one hidden opposite that
actually exists.

-----

Once co-objects support navigation of all relationships of all loaded
objects, the active system consists of unloaded (co-)objects and loaded
(co-)objects, some of which are on the boundary because they have one or
more relationships to unloaded objects. To prime the impact propagation,
dependency analysis from all loaded objects populates the notifier
chain. If at run-time an impact reaches a border object, the dynamic
types of the unloaded neighbours are examined to see if impact
propagation is possible and if necessary, neighbouring objects are
loaded, analyzed for dependencies, notifiers installed, and the impact
continues to propagate, loading only impacted unloaded objects and
co-objects.

Regards

Ed Willink

On 07/05/2012 20:44, Axel Uhl wrote:
Ok, understood. This conflicts with the way the current IA approach
works. It is geared towards non-loaded resources and large, scalable
repositories. The design assumes that it's impractical to load all
relevant resources into memory, analyze and then memorize all
dependencies for all OCL expressions for all context elements.
Instead, it is analyzing the expression structure up-front, then
deriving the change listeners which obviously need to be registered
only on objects loaded into memory because only for those changes can
be detected at all. Once a change occurs, the change is analyzed by
traversing the element graph "backwards" using the expression
structure. This also works for even the largest repositories because
the memory required for backwards traversal doesn't grow with
repository size.

It would be good if we knew which classes were generally available in
the scope of a ResourceSet so as to scan their operations during
backwards traversal ("traceback"). For the "traceback" approach this
would consider all operations known/loaded at that time. The
NavigationStep approach which is pre-computing the traceback paths
would not work this way because it wouldn't know operations loaded
through metamodels that become available after the IA has pre-computed
the navigation steps.

What would be a good way to scan all existing operations and be
notified when new subclasses with redefinitions / overrides become
available? Wasn't there an open EMF bug requesting a notification
mechanism for EPackage loads?

Best,
-- Axel

On 5/7/2012 9:06 PM, Ed Willink wrote:
Hi


a) unloaded Resources

In your earlier example with resource Y (unloaded) so that propagation
of 42 through resource X failed to impact:


Using my dependency analysis perspective, if the Y resource is not
loaded, I don't analyze it, I don't detect any dependencies, so I
don't
install any listeners/notifiers to cause the Y resource elements to
react to changes. So I agree that it doesn't work. It's nothing to do
with EMF-based; it's just common sense.

not so common sense after all if a reference path leads through Y back
to X. Which resources from a repository an editor loads into a
ResourceSet is fairly random. JDT wouldn't be the same if errors in
Java resources not currently open in an editor remained undetected
until the resource is loaded.

Exactly. JDT knows how to open all files, and in order to report errors
it either loads everything or exploits some sort of memento of previous
results.


It seems to be mandatory to load all resources for which any form of
analysis is to be performed. (It may be that they are unloaded retaining
only a memento, but they must be loaded to create the memento.)

Consider a doctor's patient list and the impact of a policy change to
invite all patients over 50 rather than over 60 to have a free flu
vaccination for the winter. The derived property of the number of
required injections can only be determined by examining each patients
records. If a patient's record is not loaded into the system/looked at
by a human, the accurate answer cannot be determined. It seems
unreasonable to expect to have impact or dependencies for unloaded
resources.


b) polymorphic calls

It seems that your traceback does not use the source object and so
needs
to consider all possible operations. This seems inefficient and may
lead
to fat notifications that can be filtered. The dependency perspective
knows the source object and so need only consider the relevant
operation.

I don't understand your "dependency perspective." Maybe you can explain using the example I gave earlier?

For the derived property

context X::derivedProperty : Integer = self.m().i

on y1:Y, which is loaded so its dependencies are analyzed.
- it is a Y, so Y::m() which is self.b.a so depends on
-- the object identity at self.b, which is currently a B
-- the object value at self.b, which is b.a, so depends on
--- the object identity at self.b.a, which is currently an A
--- the object value at self.b.a which is i, so depends on
[---- the object identity i is not relevant since it is a data type]
---- the datatype value i

Each of the dependencies needs a direct or transitive notifier chain to
cause the change to propagate and in the case of identity changes, the
notifier chain to be adjusted.


Regards

Ed

_______________________________________________
mdt-ocl.dev mailing list
mdt-ocl.dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/mdt-ocl.dev


_______________________________________________
mdt-ocl.dev mailing list
mdt-ocl.dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/mdt-ocl.dev


-----
No virus found in this message.
Checked by AVG - www.avg.com
Version: 2012.0.2171 / Virus Database: 2425/4983 - Release Date: 05/07/12




_______________________________________________ mdt-ocl.dev mailing list mdt-ocl.dev@xxxxxxxxxxx https://dev.eclipse.org/mailman/listinfo/mdt-ocl.dev


_______________________________________________
mdt-ocl.dev mailing list
mdt-ocl.dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/mdt-ocl.dev


----- No virus found in this message. Checked by AVG - www.avg.com Version: 2012.0.2171 / Virus Database: 2425/4983 - Release Date: 05/07/12