/*******************************************************************************
* Copyright (c) 2004-2010 Gabor Bergmann and Daniel Varro
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Gabor Bergmann - initial API and implementation
*******************************************************************************/
package org.eclipse.incquery.runtime.rete.construction.basiclinear;
import java.util.Collections;
import java.util.Set;
import org.eclipse.incquery.runtime.rete.collections.CollectionsFactory;
import org.eclipse.incquery.runtime.rete.construction.Buildable;
import org.eclipse.incquery.runtime.rete.construction.IReteLayoutStrategy;
import org.eclipse.incquery.runtime.rete.construction.RetePatternBuildException;
import org.eclipse.incquery.runtime.rete.construction.Stub;
import org.eclipse.incquery.runtime.rete.construction.helpers.BuildHelper;
import org.eclipse.incquery.runtime.rete.construction.helpers.LayoutHelper;
import org.eclipse.incquery.runtime.rete.construction.psystem.DeferredPConstraint;
import org.eclipse.incquery.runtime.rete.construction.psystem.EnumerablePConstraint;
import org.eclipse.incquery.runtime.rete.construction.psystem.PConstraint;
import org.eclipse.incquery.runtime.rete.construction.psystem.PSystem;
import org.eclipse.incquery.runtime.rete.matcher.IPatternMatcherContext;
import org.eclipse.incquery.runtime.rete.util.Options;
/**
* Basic layout that builds a linear RETE net based on a heuristic ordering of constraints.
*
* @author Bergmann Gábor
*
*/
public class BasicLinearLayout<PatternDescription, StubHandle, Collector> implements
IReteLayoutStrategy<PatternDescription, StubHandle, Collector> {
@Override
public Stub<StubHandle> layout(final PSystem<PatternDescription, StubHandle, Collector> pSystem)
throws RetePatternBuildException {
PatternDescription pattern = pSystem.getPattern();
IPatternMatcherContext<PatternDescription> context = pSystem.getContext();
Buildable<PatternDescription, StubHandle, Collector> buildable = pSystem.getBuildable();
try {
context.logDebug(getClass().getSimpleName() + ": patternbody build started");
// UNIFICATION AND WEAK INEQUALITY ELMINATION
LayoutHelper.unifyVariablesAlongEqualities(pSystem);
LayoutHelper.eliminateWeakInequalities(pSystem);
// UNARY ELIMINATION WITH TYPE INFERENCE
if (Options.calcImpliedTypes) {
LayoutHelper.eliminateInferrableUnaryTypes(pSystem, context);
}
// PREVENTIVE CHECKS
LayoutHelper.checkSanity(pSystem);
// STARTING THE LINE
Stub<StubHandle> stub = buildable.buildStartStub(new Object[] {}, new Object[] {});
// Set<ConstantValue> constants = pSystem.getConstraintsOfType(ConstantValue.class);
// for (ConstantValue<PatternDescription, StubHandle> pConstraint : constants) {
// Stub<StubHandle> sideStub = pConstraint.doCreateStub();
// stub = BuildHelper.naturalJoin(buildable, stub, sideStub);
// }
Set<PConstraint> pQueue = CollectionsFactory.getSet();//new HashSet<PConstraint>(pSystem.getConstraints()); // TreeSet<PConstraint>(new
// OrderingHeuristics());
// pQueue.addAll(pSystem.getConstraintsOfType(EnumerablePConstraint.class));
// pQueue.addAll(pSystem.getConstraintsOfType(DeferredPConstraint.class));
// // omitted: symbolic & equality -- not anymore
// MAIN LOOP
while (!pQueue.isEmpty()) {
PConstraint pConstraint = Collections.min(pQueue,
new OrderingHeuristics<PatternDescription, StubHandle, Collector>(stub)); // pQueue.iterator().next();
pQueue.remove(pConstraint);
if (pConstraint instanceof EnumerablePConstraint<?, ?>) {
EnumerablePConstraint<PatternDescription, StubHandle> enumerable = (EnumerablePConstraint<PatternDescription, StubHandle>) pConstraint;
Stub<StubHandle> sideStub = enumerable.getStub();
stub = BuildHelper.naturalJoin(buildable, stub, sideStub);
} else {
DeferredPConstraint<PatternDescription, StubHandle> deferred = (DeferredPConstraint<PatternDescription, StubHandle>) pConstraint;
if (deferred.isReadyAt(stub)) {
stub = deferred.checkOn(stub);
} else {
deferred.raiseForeverDeferredError(stub);
}
}
}
// FINAL CHECK, whether all exported variables are present
LayoutHelper.finalCheck(pSystem, stub);
// // output
// int paramNum = patternScaffold.gtPattern.getSymParameters().size();
// int[] tI = new int[paramNum];
// int tiW = stub.getVariablesTuple().getSize();
// for (int i = 0; i < paramNum; i++) {
// PatternVariable variable = patternScaffold.gtPattern.getSymParameters().get(i);
// // for (Object o : variable.getElementInPattern()) // in all bodies
// // {
// PatternNodeBase pNode = pGraph.getPNode(variable);
// // if (stub.calibrationIndex.containsKey(pNode))
// tI[i] = stub.getVariablesIndex().get(pNode);
// // }
// }
// TupleMask trim = new TupleMask(tI, tiW);
// Stub<StubHandle> trimmer = buildable.buildTrimmer(stub, trim);
// buildable.buildConnection(trimmer, collector);
context.logDebug(getClass().getSimpleName() + ": patternbody build concluded");
return stub;
} catch (RetePatternBuildException ex) {
ex.setPatternDescription(pattern);
throw ex;
}
}
}