blob: 21ab758b5e0fe15dab4d7c96532ac814912a33b4 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2014-2016 Akos Horvath, Abel Hegedus, Tamas Borbas, Marton Bur, Zoltan Ujhelyi, Robert Doczi, Daniel Segesdi, Peter Lunk, IncQuery Labs Ltd.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-v20.html.
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/
package org.eclipse.viatra.examples.cps.xform.m2m.launcher;
import java.util.Map;
import java.util.Optional;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.viatra.examples.cps.cyberPhysicalSystem.CyberPhysicalSystemPackage;
import org.eclipse.viatra.examples.cps.deployment.DeploymentPackage;
import org.eclipse.viatra.examples.cps.traceability.TraceabilityPackage;
import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey;
import org.eclipse.viatra.query.runtime.emf.types.EStructuralFeatureInstancesKey;
import org.eclipse.viatra.query.runtime.localsearch.matcher.integration.LocalSearchHints;
import org.eclipse.viatra.query.runtime.localsearch.planner.cost.IConstraintEvaluationContext;
import org.eclipse.viatra.query.runtime.localsearch.planner.cost.impl.StatisticsBasedConstraintCostFunction;
import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint;
import org.eclipse.viatra.query.runtime.matchers.context.IInputKey;
import org.eclipse.viatra.query.runtime.matchers.tuple.TupleMask;
import org.eclipse.viatra.query.runtime.matchers.util.Accuracy;
import org.eclipse.viatra.query.runtime.rete.matcher.ReteBackendFactory;
import com.google.common.collect.Maps;
public enum TransformationType {
BATCH_SIMPLE {
public CPSTransformationWrapper getWrapper() {return new BatchSimple();}
},
BATCH_OPTIMIZED {
public CPSTransformationWrapper getWrapper() {return new BatchOptimized();}
},
BATCH_VIATRA_QUERY_RETE {
public CPSTransformationWrapper getWrapper() {
QueryEvaluationHint hint = new QueryEvaluationHint(null, ReteBackendFactory.INSTANCE);
return new BatchQueryOnly(hint, hint);
}
},
BATCH_VIATRA_QUERY_LOCAL_SEARCH {
public CPSTransformationWrapper getWrapper() {
QueryEvaluationHint hint = LocalSearchHints.getDefaultFlatten().build();
EndOfTransformationCostFunction costFunction = new EndOfTransformationCostFunction(StatisticsBasedConstraintCostFunction.INVERSE_NAVIGATION_PENALTY_DEFAULT);
QueryEvaluationHint traceHint = LocalSearchHints.getDefaultFlatten().setCostFunction(costFunction).build();
return new BatchQueryLocalSearch(hint, traceHint);
}
},
BATCH_VIATRA_QUERY_LOCAL_SEARCH_GENERIC {
public CPSTransformationWrapper getWrapper() {
EndOfTransformationCostFunction costFunction = new EndOfTransformationCostFunction(StatisticsBasedConstraintCostFunction.INVERSE_NAVIGATION_PENALTY_GENERIC);
QueryEvaluationHint hint = LocalSearchHints.getDefaultGeneric().setCostFunction(costFunction).build();
return new BatchQueryLocalSearch(hint, hint);
}
},
BATCH_VIATRA_QUERY_LOCAL_SEARCH_WO_INDEXER {
public CPSTransformationWrapper getWrapper() {
QueryEvaluationHint hint = LocalSearchHints.getDefaultNoBase().build();
return new BatchQueryLocalSearch(hint, hint);
}
},
BATCH_VIATRA_TRANSFORMATION {
public CPSTransformationWrapper getWrapper() {return new BatchViatra();}
@Override
public boolean isDebuggable() {
return true;
}
},
INCR_VIATRA_QUERY_RESULT_TRACEABILITY {
public CPSTransformationWrapper getWrapper() {return new QueryResultTraceability();}
},
INCR_VIATRA_EXPLICIT_TRACEABILITY {
public CPSTransformationWrapper getWrapper() {return new ExplicitTraceability();}
},
INCR_VIATRA_AGGREGATED {
public CPSTransformationWrapper getWrapper() {return new PartialBatch();}
},
INCR_VIATRA_TRANSFORMATION {
public CPSTransformationWrapper getWrapper() {return new ViatraTransformation();}
@Override
public boolean isDebuggable() {
return true;
}
},
INCR_VIATRA_PUREGRATRA {
public CPSTransformationWrapper getWrapper() {return new IncrPureGraTra();}
};
private final class EndOfTransformationCostFunction extends StatisticsBasedConstraintCostFunction {
final Map<IInputKey, IInputKey> substitutions;
public EndOfTransformationCostFunction(double inverseNavigationPenalty) {
super(inverseNavigationPenalty);
substitutions = Maps.newHashMap();
substitutions.put(new EClassTransitiveInstancesKey(TraceabilityPackage.Literals.CPS2_DEPLOYMENT_TRACE), new EClassTransitiveInstancesKey(CyberPhysicalSystemPackage.Literals.IDENTIFIABLE));
substitutions.put(new EClassTransitiveInstancesKey(DeploymentPackage.Literals.DEPLOYMENT_ELEMENT), new EClassTransitiveInstancesKey(CyberPhysicalSystemPackage.Literals.IDENTIFIABLE));
substitutions.put(new EStructuralFeatureInstancesKey(TraceabilityPackage.Literals.CPS2_DEPLOYMENT_TRACE__CPS_ELEMENTS), new EClassTransitiveInstancesKey(CyberPhysicalSystemPackage.Literals.IDENTIFIABLE));
substitutions.put(new EStructuralFeatureInstancesKey(TraceabilityPackage.Literals.CPS2_DEPLOYMENT_TRACE__DEPLOYMENT_ELEMENTS), new EClassTransitiveInstancesKey(CyberPhysicalSystemPackage.Literals.IDENTIFIABLE));
substitutions.put(new EStructuralFeatureInstancesKey(TraceabilityPackage.Literals.CPS_TO_DEPLOYMENT__TRACES), new EClassTransitiveInstancesKey(CyberPhysicalSystemPackage.Literals.IDENTIFIABLE));
}
@Override
public Optional<Long> projectionSize(IConstraintEvaluationContext input, IInputKey supplierKey, TupleMask groupMask, Accuracy requiredAccuracy) {
if (supplierKey instanceof EClassTransitiveInstancesKey){
EClass eclass = ((EClassTransitiveInstancesKey) supplierKey).getEmfKey();
if (TraceabilityPackage.Literals.CPS_TO_DEPLOYMENT.equals(eclass)){
return Optional.of(1L);
}
}
if (substitutions.containsKey(supplierKey)){
IInputKey substituteType = substitutions.get(supplierKey);
if (supplierKey.getArity() == substituteType.getArity())
return input.getRuntimeContext().estimateCardinality(substituteType, groupMask, requiredAccuracy);
// problem: the original and substitute types may have different arity, difficult to interpolate masks
Optional<Long> totalCount = input.getRuntimeContext().estimateCardinality(substituteType, TupleMask.identity(substituteType.getArity()), requiredAccuracy);
Optional<Long> existence = input.getRuntimeContext().estimateCardinality(substituteType, TupleMask.empty(substituteType.getArity()), requiredAccuracy);
if (groupMask.getSize() == groupMask.sourceWidth) return totalCount;
if (groupMask.getSize() == 0) return existence;
return totalCount.flatMap((total) ->
existence.map((exists) ->
// approximate with linear map
(groupMask.getSize() * (total - exists))/groupMask.sourceWidth + exists
));
}
return input.getRuntimeContext().estimateCardinality(supplierKey, groupMask, requiredAccuracy);
}
}
public abstract CPSTransformationWrapper getWrapper();
public boolean isDebuggable() {
return false;
}
}