blob: f0c35756e491fdfaed707ba8c962e8d39ca36cbd [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004-2008 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.rete.index;
import java.util.Collection;
import org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.network.Direction;
import org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.network.ReteContainer;
import org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.tuple.Tuple;
/**
* Propagates all substitutions arriving at the PRIMARY slot if and only if (a
* matching substitution on the SECONDARY is present) xor (NEGATIVE).
*
* The negative parameter specifies whether this node checks for existence or
* non-existence.
*
* @author Gabor Bergmann
*/
public class ExistenceNode extends DualInputNode {
protected boolean negative;
/**
* @param reteContainer
* @param primarySlot
* @param secondarySlot
* @param negative
* if false, act as axistence checker, otherwise a
* nonexistence-checker
*/
public ExistenceNode(ReteContainer reteContainer, IterableIndexer primarySlot,
Indexer secondarySlot, boolean negative) {
super(reteContainer, primarySlot, secondarySlot, null);
this.negative = negative;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.index.DualInputNode#calibrate(org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.tuple.Tuple,
* org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.tuple.Tuple)
*/
@Override
public Tuple calibrate(Tuple primary, Tuple secondary) {
return primary;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.index.DualInputNode#notifyUpdate(org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.index.DualInputNode.Side,
* org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.network.Direction, org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.tuple.Tuple, org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.tuple.Tuple, boolean)
*/
@Override
public void notifyUpdate(Side side, Direction direction,
Tuple updateElement, Tuple signature, boolean change) {
switch (side) {
case PRIMARY:
if ((retrieveOpposites(side, signature) != null) ^ negative)
propagateUpdate(direction, updateElement);
break;
case SECONDARY:
if (change) {
Collection<Tuple> opposites = retrieveOpposites(side, signature);
if (opposites != null)
for (Tuple opposite : opposites) {
propagateUpdate((negative ? direction.opposite()
: direction), opposite);
}
}
break;
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.network.Supplier#pullInto(org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.network.Receiver)
*/
public void pullInto(Collection<Tuple> collector) {
reteContainer.flushUpdates();
for (Tuple signature : primarySlot.getSignatures()) {
Collection<Tuple> primaries = primarySlot.get(signature); // not null due to the contract of IterableIndex.getSignatures()
Collection<Tuple> opposites = secondarySlot.get(signature);
if ((opposites != null) ^ negative)
collector.addAll(primaries);
}
}
}