blob: 280c2944c64e594149c441b6eb9f7bcf1ea493a5 [file] [log] [blame]
/*******************************************************************************
* 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.
}
}