blob: 2e8ed4bf925d714b9255123993815ee1715c6686 [file] [log] [blame]
/*******************************************************************************
* 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.viatra2.gtasm.patternmatcher.incremental.simple;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;
import org.eclipse.viatra2.gtasm.patternmatcher.incremental.adapters.GTASMBuildable;
import org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.construction.RetePatternBuildException;
import org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.construction.Stub;
import org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.construction.psystem.PVariable;
import org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.construction.psystem.basicdeferred.BaseTypeSafePredicateCheck;
import org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.tuple.FlatTuple;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.terms.FunctionInvocation;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.terms.GTPatternCall;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.terms.ModelElementQuery;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.terms.Term;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.terms.VariableReference;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.gt.GTPattern;
/**
* @author Bergmann Gábor
*
*/
public class GTASMCheckConditionPConstraint<StubHandle> extends
BaseTypeSafePredicateCheck<GTPattern, StubHandle> {
private Term topTerm;
private GTPatternBodyToPSystem<StubHandle, ?> pGraph;
private GTASMBuildable<StubHandle, ?> gtBuildable;
/**
* @param pSystem
* @param affectedVariables
* @throws RetePatternBuildException
*/
public GTASMCheckConditionPConstraint(
GTPatternBodyToPSystem<StubHandle, ?> pGraph, GTASMBuildable<StubHandle, ?> gtBuildable,
Term topTerm) throws RetePatternBuildException {
super(pGraph.pSystem, extractAffectedVariables(pGraph, topTerm));
this.pGraph = pGraph;
this.topTerm = topTerm;
this.gtBuildable = gtBuildable;
}
/* (non-Javadoc)
* @see org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.construction.psystem.DeferredPConstraint#doCheckOn(org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.construction.Stub)
*/
@Override
protected Stub<StubHandle> doCheckOn(Stub<StubHandle> stub)
throws RetePatternBuildException {
Map<String, Integer> variableIndices = new HashMap<String, Integer>();
Map<String, String> variableEquivalence = new HashMap<String, String>();
Set<String> variableNames = extractAffectedVariableNames(pGraph, topTerm);
for (String name : variableNames) {
PVariable pNode = pGraph.getPNode(name);
variableEquivalence.put(name, pNode.getName());
variableIndices.put(pNode.getName(), stub.getVariablesIndex().get(pNode));
}
return gtBuildable.buildGTASMTermChecker(topTerm, variableIndices, variableEquivalence, null, stub);
}
/* (non-Javadoc)
* @see org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.construction.psystem.BasePConstraint#toStringRest()
*/
@Override
protected String toStringRest() {
return new FlatTuple(new ArrayList<PVariable>(getAffectedVariables()).toArray()).toString() + "|=" + topTerm.toString();
}
/* (non-Javadoc)
* @see org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.construction.psystem.BasePConstraint#doReplaceVariable(org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.construction.psystem.PVariable, org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.construction.psystem.PVariable)
*/
@Override
protected void doReplaceVariable(PVariable obsolete, PVariable replacement) {}
private static <StubHandle> Set<PVariable> extractAffectedVariables(GTPatternBodyToPSystem<StubHandle, ?> pGraph, Term topTerm)
throws RetePatternBuildException
{
HashSet<PVariable> affected = new HashSet<PVariable>();
Set<String> variableNames = extractAffectedVariableNames(pGraph, topTerm);
for (String name : variableNames) {
PVariable termNode = pGraph.getPNode(name);
affected.add(termNode);
}
return affected;
}
private static <StubHandle> Set<String> extractAffectedVariableNames(GTPatternBodyToPSystem<StubHandle, ?> pGraph, Term topTerm)
throws RetePatternBuildException
{
HashSet<String> affected = new HashSet<String>();
LinkedList<Term> termQueue = new LinkedList<Term>();
termQueue.add(topTerm);
while (termQueue.size() > 0) {
Term term = termQueue.removeFirst();
if (term instanceof VariableReference) {
VariableReference termVar = (VariableReference) term;
affected.add(termVar.getVariable().getName());
} else if (term instanceof FunctionInvocation) {
FunctionInvocation fi = (FunctionInvocation) term;
for (Term paramTerm : fi.getActualParameters()) {
termQueue.addFirst(paramTerm);
}
} else if (term instanceof ModelElementQuery) {
ModelElementQuery meq = (ModelElementQuery) term;
termQueue.addFirst(meq.getArgument());
} else if (term instanceof GTPatternCall) {
GTPatternCall pc = (GTPatternCall) term;
String[] errorData = {pc.getCalledPattern().getFqn(), pGraph.gtPattern.getFqn()};
String message =
"Offending call to pattern {1} in enclosing pattern {2}. " +
"The incremental pattern matcher does not support GT Pattern calls in checks and expressions embedded into GT Patterns;" +
" please use a 'find' clause directly in the pattern body.";
//pGraph.builder.logger.error(message);
throw new RetePatternBuildException(message, errorData, pGraph.gtPattern);
// If we did want to handle this case
// for (Object o : pc.getActualParameters()) {
// termQueue.addFirst((Term) o);
// }
}
}
return affected;
}
}