package org.jactr.tools.analysis.production.relationships;
/*
* default logging
*/
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import org.antlr.runtime.tree.CommonTree;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jactr.io.antlr3.builder.JACTRBuilder;
import org.jactr.tools.analysis.production.endstates.BufferEndState;
import org.jactr.tools.analysis.production.endstates.BufferEndStates;
public class GeneralRelationshipComputer implements IRelationshipComputer
{
/**
* Logger definition
*/
static private final transient Log LOGGER = LogFactory
.getLog(GeneralRelationshipComputer.class);
public IRelationship computeRelationship(BufferEndStates headEndStates,
BufferEndStates tailEndStates)
{
Map<String, CommonTree> conditions = tailEndStates
.getMapOfTrees(JACTRBuilder.MATCH_CONDITION);
Map<String, CommonTree> queries = tailEndStates
.getMapOfTrees(JACTRBuilder.QUERY_CONDITION);
Map<String, Collection<IPair>> positiveConditions = new TreeMap<String, Collection<IPair>>();
Map<String, Collection<IPair>> ambiguousConditions = new TreeMap<String, Collection<IPair>>();
Map<String, Collection<IPair>> negativeConditions = new TreeMap<String, Collection<IPair>>();
Set<String> buffers = new TreeSet<String>(conditions.keySet());
buffers.addAll(queries.keySet());
Map<String, Collection<BufferEndState>> endStateMap = headEndStates
.getEndStates();
DefaultRelationship relationship = new DefaultRelationship(headEndStates
.getProduction(), tailEndStates.getProduction());
for (String bufferName : buffers)
{
Collection<IPair> positive = new ArrayList<IPair>();
positiveConditions.put(bufferName, positive);
Collection<IPair> ambiguous = new ArrayList<IPair>();
ambiguousConditions.put(bufferName, ambiguous);
Collection<IPair> negative = new ArrayList<IPair>();
negativeConditions.put(bufferName, negative);
CommonTree condition = conditions.get(bufferName);
if (condition != null)
evaluateEndStates(bufferName, endStateMap.get(bufferName), condition,
positive, ambiguous, negative);
CommonTree query = queries.get(bufferName);
if (query != null)
evaluateEndStates(bufferName, endStateMap.get(bufferName), query,
positive, ambiguous, negative);
// minimum positive is the minim number of positive pairs for a potential
// match
double minimumPositive = 1;
double divisor = 1;
double score = 0;
if (endStateMap.containsKey(bufferName))
divisor = endStateMap.get(bufferName).size();
if (query != null && condition != null) minimumPositive = 2;
if (positive.size() >= minimumPositive)
score = positive.size() / divisor;
else
{
double ambigDivisor = Math.max(1, ambiguous.size());
score = - negative.size() / ambigDivisor
/ divisor;
}
if (LOGGER.isDebugEnabled()) LOGGER.debug("Computed "+bufferName+" score = "+score);
relationship.setScore(bufferName, score);
relationship.setAmbiguousRelationships(bufferName, ambiguous);
relationship.setNegativeRelationships(bufferName, negative);
relationship.setPositiveRelationships(bufferName, positive);
}
return relationship;
}
private void evaluateEndStates(String bufferName,
Collection<BufferEndState> headEndStates, CommonTree check,
Collection<IPair> positive, Collection<IPair> ambiguous,
Collection<IPair> negative)
{
/*
* the head production had no operations on the current buffer
*/
if (headEndStates == null) return;
boolean isQuery = check.getType() == JACTRBuilder.QUERY_CONDITION;
for (BufferEndState endState : headEndStates)
if ((endState.isQuery() && isQuery) || (!endState.isQuery() && !isQuery))
{
int rel = endState.computeRelationship(check);
IPair pair = new DefaultPair(endState, check);
if (rel > 0)
positive.add(pair);
else if (rel < 0)
negative.add(pair);
else
ambiguous.add(pair);
}
}
}