viatra / VIATRA-Generator

An efficient graph solver for generating well-formed models
Eclipse Public License 1.0
26 stars 5 forks source link

java.lang.IllegalArgumentException with patterns using EObject parameters #7

Open mayerkr opened 7 years ago

mayerkr commented 7 years ago

Description

The transformQueries method found in viatra2logic catches an IllegalArgumentException with the following query:

Query used:

pattern transitionWithoutTargetStateV1(transition:EObject) {                
    EObject(source);
    EObject(transition);
    neg find State_OutgoingTransitions(source, transition); 
    neg find stateTransition(source, transition, _);    
}

Caused by:

Only the metamodel's classes get parsed, while queries may contain generic super classes like EObject. This causes the EClassMapper's TypeofEClass method to throw a java.lang.IllegalArgumentException.

Log/Trace:

Exception in thread "main" java.lang.IllegalArgumentException: Unable to translate query "mutatedpatterns.transitionWithoutTargetStateV1".
    at hu.bme.mit.inf.dslreasoner.viatra2logic.Viatra2Logic.transformQueries(Viatra2Logic.java:105)
    at cpsgen.Run.main(Run.java:90)
Caused by: java.lang.IllegalArgumentException: Class EObject is not translated to logic!
    at hu.bme.mit.inf.dslreasoner.ecore2logic.EClassMapper_AllElementAsObject.TypeofEClass(EClassMapper_AllElementAsObject.java:63)
    at hu.bme.mit.inf.dslreasoner.ecore2logic.Ecore2Logic.TypeofEClass(Ecore2Logic.java:96)
    at hu.bme.mit.inf.dslreasoner.viatra2logic.Viatra2Logic._transformTypeReference(Viatra2Logic.java:487)
    at hu.bme.mit.inf.dslreasoner.viatra2logic.Viatra2Logic.transformTypeReference(Viatra2Logic.java:507)
    at hu.bme.mit.inf.dslreasoner.viatra2logic.Viatra2Logic.transformQueryHeader(Viatra2Logic.java:148)
    at hu.bme.mit.inf.dslreasoner.viatra2logic.Viatra2Logic.transformQueries(Viatra2Logic.java:96)
    ... 1 more
mayerkr commented 7 years ago

Tried to work around this problem by manually adding the wrappedKey of EObject to the EcoreMetamodelDescriptor.classes, as seen below.

The EcoreMetamodelDescriptor now contains the wrapper of EObject:

org.eclipse.emf.ecore.impl.EClassImpl@64bfbc86 (name: Identifiable) (instanceClassName: null) (abstract: true, interface: true)
org.eclipse.emf.ecore.impl.EClassImpl@55d56113 (name: CyberPhysicalSystem) (instanceClassName: null) (abstract: false, interface: false)
org.eclipse.emf.ecore.impl.EClassImpl@7e0b0338 (name: ApplicationType) (instanceClassName: null) (abstract: false, interface: false)
org.eclipse.emf.ecore.impl.EClassImpl@31610302 (name: HostType) (instanceClassName: null) (abstract: false, interface: false)
org.eclipse.emf.ecore.impl.EClassImpl@66480dd7 (name: ResourceRequirement) (instanceClassName: null) (abstract: false, interface: false)
org.eclipse.emf.ecore.impl.EClassImpl@4fe3c938 (name: HostInstance) (instanceClassName: null) (abstract: false, interface: false)
org.eclipse.emf.ecore.impl.EClassImpl@4e9ba398 (name: ApplicationInstance) (instanceClassName: null) (abstract: false, interface: false)
org.eclipse.emf.ecore.impl.EClassImpl@63753b6d (name: Request) (instanceClassName: null) (abstract: false, interface: false)
org.eclipse.emf.ecore.impl.EClassImpl@6536e911 (name: Requirement) (instanceClassName: null) (abstract: false, interface: false)
org.eclipse.emf.ecore.impl.EClassImpl@6f1fba17 (name: StateMachine) (instanceClassName: null) (abstract: false, interface: false)
org.eclipse.emf.ecore.impl.EClassImpl@335eadca (name: State) (instanceClassName: null) (abstract: false, interface: false)
org.eclipse.emf.ecore.impl.EClassImpl@eec5a4a (name: Transition) (instanceClassName: null) (abstract: false, interface: false)
org.eclipse.emf.ecore.impl.EClassImpl@464bee09 (name: EObject) (instanceClassName: null) (abstract: false, interface: false)

But doing so results in a java.lang.NullPointerException thrown by TypeofEClass in the EClassMapper_AllElementAsObject class.

Exception in thread "main" java.lang.NullPointerException
    at hu.bme.mit.inf.dslreasoner.ecore2logic.EClassMapper_AllElementAsObject.TypeofEClass(EClassMapper_AllElementAsObject.java:60)
    at hu.bme.mit.inf.dslreasoner.ecore2logic.Ecore2Logic.TypeofEClass(Ecore2Logic.java:96)
    at hu.bme.mit.inf.dslreasoner.viatra2logic.Viatra2Logic.getType(Viatra2Logic.java:358)
    at hu.bme.mit.inf.dslreasoner.viatra2logic.Viatra2Logic.transformBody(Viatra2Logic.java:294)
    at hu.bme.mit.inf.dslreasoner.viatra2logic.Viatra2Logic.transformQuerySpecification(Viatra2Logic.java:196)
    at hu.bme.mit.inf.dslreasoner.viatra2logic.Viatra2Logic.transformQueries(Viatra2Logic.java:113)
    at cpsgen.Run.main(Run.java:94)
mayerkr commented 7 years ago

Cause:

The previous exception was caused by the calculatecommonSubtype method found in Viatra2Logic. By filtering all the EObjects the return value was an empty set for those patterns that only contain EObject types.

Relevant part of the method:

val superClasses = allsuperClasses.filter[it!=EcorePackage.eINSTANCE.EObject]

Workaround:

If all the tpyes are EObject in a pattern, then we shouldn't filter them, and return the EObject metaclass.

Adding the following code to the beggining of the method fixed the issue:

if(allsuperClasses.forall[it == EcorePackage.eINSTANCE.EObject]){
    return allsuperClasses.head
}