/******************************************************************************* | |
* Copyright (c) 2004-2008 Akos Horvath, Gergely Varro 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: | |
* Akos Horvath, Gergely Varro - initial API and implementation | |
*******************************************************************************/ | |
package org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.rgg; | |
import java.util.Collection; | |
import java.util.HashMap; | |
import java.util.Iterator; | |
import java.util.LinkedList; | |
import java.util.List; | |
import java.util.Map; | |
import java.util.Queue; | |
import java.util.Vector; | |
import org.eclipse.viatra2.gtasm.interpreter.exception.ViatraTransformationException; | |
import org.eclipse.viatra2.gtasm.patternmatcher.ExecutionMode; | |
import org.eclipse.viatra2.gtasm.patternmatcher.IMatching; | |
import org.eclipse.viatra2.gtasm.patternmatcher.ParameterMode; | |
import org.eclipse.viatra2.gtasm.patternmatcher.PatternCallSignature; | |
import org.eclipse.viatra2.gtasm.patternmatcher.Scope; | |
import org.eclipse.viatra2.gtasm.patternmatcher.exceptions.PatternMatcherRuntimeException; | |
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.MatchingFrame; | |
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.MatchingKey; | |
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.callgraph.PatternNode; | |
import org.eclipse.viatra2.gtasm.patternmatcher.patterns.IPatternMatcher; | |
public class RemoteGoalIncremental extends RemoteGoal { | |
private IPatternMatcher patternMatcher; | |
private boolean isFirstTimeSync,isFirstTimeDelta; | |
private Map<MatchingKey, List<IMatching>> mapWithAdornedIndex; | |
private Map<MatchingKey, List<IMatching>> map; | |
private Collection<IMatching> matchings; | |
public RemoteGoalIncremental(PatternNode pattern, Boolean[] adornment, IPatternMatcher patternMatcher) { | |
super(pattern, adornment); | |
isFirstTimeSync = true; | |
isFirstTimeDelta = true; | |
this.patternMatcher = patternMatcher; | |
mapWithAdornedIndex = new HashMap<MatchingKey, List<IMatching>>(); | |
map = new HashMap<MatchingKey, List<IMatching>>(); | |
} | |
public void calculateAllDeltas(IndexedRule parent, Queue<MatchingFrame> output) throws PatternMatcherRuntimeException { | |
// ---> | |
// left |><| right | |
//debug | |
//System.out.println("Pre CaclutaeDelta: "); | |
//this.debug(); | |
Queue<MatchingFrame> input = parent.getQueue(); | |
for (Iterator<MatchingFrame> i = input.iterator(); i.hasNext();) { | |
MatchingFrame leftFrame = i.next(); | |
MatchingKey keyForLeftFrame = parent.getBoundHeader(leftFrame); | |
List<IMatching> list = mapWithAdornedIndex.get(keyForLeftFrame); | |
if (list != null) { | |
for (IMatching rightFrame : list) { | |
MatchingFrame newFrame = (MatchingFrame) leftFrame.clone(); | |
parent.merge(newFrame, rightFrame); | |
output.offer(newFrame); | |
} | |
} | |
ms.addArray(keyForLeftFrame); | |
i.remove(); | |
} | |
// <--- | |
// left |><| right will have to evaluate only once at the first run! | |
if(isFirstTimeDelta && matchings != null) | |
{isFirstTimeDelta = false; | |
for(List<IMatching> matchings:map.values()) | |
for(IMatching rightFrame :matchings){ | |
//IMatching rightFrame = j.next(); | |
Vector<Object> v = new Vector<Object>(); | |
int size = 0; | |
for (int i = 0; i < adornment.length; i++) { | |
if (adornment[i]) { | |
v.add(rightFrame.lookup(i)); | |
size++; | |
} | |
} | |
final Object[] key = new Object[size]; | |
v.toArray(key); | |
HistoryList<MatchingKey, MatchingFrame> queue = | |
parent.getQueue(); | |
List<MatchingFrame> list = queue.get(new MatchingKey(key)); | |
if (list != null) | |
{ | |
for (MatchingFrame leftFrame : list) { | |
MatchingFrame newFrame = (MatchingFrame) leftFrame.clone(); | |
parent.merge(newFrame, rightFrame); | |
output.offer(newFrame); | |
} | |
} | |
} | |
} | |
//debug | |
//System.out.println("Post CaclutaeDelta: "); | |
//this.debug(); | |
} | |
public boolean synchronize() throws ViatraTransformationException { | |
//System.out.println("Pre Synch: "); | |
this.debug(); | |
boolean result = false; | |
//have to be activated the first time when the matchings are available and only once then | |
if(isFirstTimeSync | |
//&& matchings != null | |
) | |
{isFirstTimeSync = false; | |
//if(matchings == null){ | |
Object[] inputMapping = new Object[adornment.length]; | |
Integer[] quantificationOrder = new Integer[adornment.length]; | |
PatternCallSignature[] signature = new PatternCallSignature[adornment.length]; | |
for(int i= 0; i<signature.length; i++){ | |
PatternCallSignature _p = new PatternCallSignature(); | |
_p.setExecutionMode(ExecutionMode.MULTIPLE_RESULTS); | |
_p.setParameterMode(ParameterMode.OUTPUT); | |
_p.setParameterScope(new Scope()); | |
signature[i] = _p; | |
} | |
try { | |
matchings = patternMatcher.matchAll(inputMapping, signature, quantificationOrder); | |
//for(IMatching matching:matchings){ | |
//MatchingKey keyforFrame = adornedKeyGenerator.calculateKey(matching); | |
//after the first match all elements are present in the ms | |
//ms.addArray(keyforFrame); | |
// } | |
} catch (ViatraTransformationException e) { | |
throw e.addNewStackElement(this.pattern.getPattern()); | |
} | |
for(IMatching matching: matchings){ | |
MatchingKey keyForFrameAdorned = adornedKeyGenerator.calculateKey(matching); | |
List<IMatching> currentList = | |
mapWithAdornedIndex.get(keyForFrameAdorned); | |
if (currentList == null) { | |
currentList = new LinkedList<IMatching>(); | |
} | |
currentList.add(matching); | |
mapWithAdornedIndex.put(keyForFrameAdorned, currentList); | |
ms.addArray(keyForFrameAdorned); | |
MatchingKey keyForFrame = keyGenerator.calculateKey(matching); | |
currentList = map.get(keyForFrame); | |
if (currentList == null) { | |
currentList = new LinkedList<IMatching>(); | |
//newFrames.add(frame); | |
result = true; | |
} | |
currentList.add(matching); | |
map.put(keyForFrame, currentList); | |
} | |
} | |
// for (Iterator<MatchingFrame> i = newFrames.iterator(); i.hasNext();) { | |
// MatchingFrame frame = i.next(); | |
// MatchingKey keyForFrame = adornedKeyGenerator.calculateKey(frame); | |
// List<IMatching> currentList = | |
// mapWithAdornedIndex.get(keyForFrame); | |
// if (currentList == null) { | |
// currentList = new LinkedList<IMatching>(); | |
// } | |
// currentList.add(frame); | |
// mapWithAdornedIndex.put(keyForFrame, currentList); | |
// i.remove(); | |
// } | |
// assert newFrames.isEmpty(); | |
// //for (Queue<MatchingFrame> queue : queues) { | |
// //for (Iterator<MatchingFrame> i = queue.iterator(); i.hasNext();) { | |
// //MatchingFrame frame = i.next(); | |
// MatchingFrame frame = null; | |
// MatchingKey keyForFrame = keyGenerator.calculateKey(frame); | |
// List<IMatching> currentList = map.get(keyForFrame); | |
// if (currentList == null) { | |
// currentList = new LinkedList<IMatching>(); | |
// newFrames.add(frame); | |
// result = true; | |
// } | |
// currentList.add(frame); | |
// map.put(keyForFrame, currentList); | |
// i.remove(); | |
// } | |
// } | |
//for (Rule rule : children) { | |
// rule.synchronize(); | |
//} | |
//debug | |
//will have to evaluate that are we ready or there are new matches avvailable | |
//System.out.println("Post Synch: "); | |
//this.debug(); | |
return (ms.synchronizeFromGoal() ? true : result); | |
} | |
public void init() { | |
ms.init(); | |
map.clear(); | |
matchings = null; | |
mapWithAdornedIndex.clear(); | |
isFirstTimeSync = true; | |
isFirstTimeDelta = true; | |
//for (Queue<MatchingFrame> queue : queues) { | |
// queue.clear(); | |
//} | |
// newFrames.clear(); | |
} | |
/* | |
public MatchingFrame match(PatternCallSignature[] signature, Vector<Integer> freeVariables) throws PatternMatcherRuntimeException { | |
// init(); | |
assert children.size() == queues.size(); | |
for (int i = 0; i < children.size(); i++) { | |
Rule rule = children.get(i); | |
MatchingFrame template = new MatchingFrame(rule.pattern); | |
MatchingFrame frame = rule.traverse(queues.get(i), template); | |
for (Integer varID : freeVariables) { | |
Scope s = signature[varID].getParameterScope(); | |
if (s.getContainmentMode() == ContainmentMode.IN && | |
!((IEntity) s.getParent()).getContents().contains(frame.getValue(varID)) || | |
s.getContainmentMode() == ContainmentMode.BELOW && | |
!((IEntity) s.getParent()).getAllComponents().contains(frame.getValue(varID))) { | |
break; | |
} | |
return frame; | |
} | |
} | |
return null; | |
} | |
*/ | |
public void matchAll() throws PatternMatcherRuntimeException { | |
//TODO: can only be invoked from the PatternMatcher -> exception | |
//throw new PatternMatcherRuntimeException(PatternMatcherRuntimeException.INTERNAL_PATTERNMATCHER_INCREMENTALWITHREMOTEGOAL_MATCHALL_ERROR); | |
// init(); | |
//assert children.size() == queues.size(); | |
//for (int i = 0; i < children.size(); i++) { | |
// Rule rule = children.get(i); | |
// MatchingFrame template = new MatchingFrame(rule.pattern); | |
// rule.traverseAll(queues.get(i), template); | |
//first call of the matchall after an init | |
} | |
@Override | |
public void debug() { | |
//this. | |
} | |
} | |