org.aksw.jena_sparql_api.views.EquiMap Maven / Gradle / Ivy
The newest version!
package org.aksw.jena_sparql_api.views;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.aksw.commons.collections.multimaps.BiHashMultimap;
import org.aksw.commons.collections.multimaps.IBiSetMultimap;
import org.aksw.commons.collections.multimaps.MultimapUtils;
import com.google.common.collect.Sets;
/**
* A map where keys can be stated as equivalent.
*
* Provides methods for checking consistency (the map gets inconsistent
* as soon as a key maps to multiple non-equal values)
*
*
* TODO Not sure if a conflict resultion strategy for the case that
* values are not directly equal but not contradictory should go here.
* For instance if a key x maps to {A, B} and y maps to {A} one resolution stragtegy
* might be to map both to A.
*
* Essentially I have the ValueSets in mind to quickly reject inconsistent bindings.
*
* @author raven
*
* @param
* @param
*/
public class EquiMap
{
private IBiSetMultimap equivalences = new BiHashMultimap();
private Map keyToValue = new HashMap();
/**
*
* @return A view of all keys
*/
public Set keySet() {
return Sets.union(equivalences.asMap().keySet(), keyToValue.keySet());
}
public void clear()
{
equivalences.clear();
keyToValue.clear();
}
public boolean isEqual(K a, K b) {
return get(a).contains(b);
}
public boolean areAllEqual(Collection set) {
if(set.isEmpty()) {
return true; // Is that sane? Should it be false?
}
return get(set.iterator().next()).containsAll(set);
}
public boolean isConsistentInsertEquiv(K a, K b)
{
return isConsistentSet(Sets.union(get(a), get(b)));
}
public boolean isConsistentSet(Set set)
{
return set.size() <= 1;
}
public boolean isConsistentInsertValue(K a, V b)
{
Set values = get(a);
if(values.isEmpty()) {
return true;
} else if(values.size() == 1 && values.contains(b)) {
return true;
} else if(values.size() > 1) {
throw new RuntimeException("Should not happen");
}
return false;
}
public boolean isSelfConsistent()
{
Set open = new HashSet(keyToValue.keySet());
while(!open.isEmpty()) {
K key = open.iterator().next();
open.remove(key);
Set keys = getEquivalences(key, false);
open.removeAll(keys);
Set values = get(keys);
if(!isConsistentSet(values)) {
return false;
}
}
return true;
}
public EquiMap()
{
}
public EquiMap(EquiMap other)
{
for(Map.Entry> entry : equivalences.asMap().entrySet()) {
for(K value : entry.getValue()) {
this.equivalences.put(entry.getKey(), value);
}
}
this.keyToValue.putAll(other.keyToValue);
}
public IBiSetMultimap getEquivalences()
{
return equivalences;
}
public Map getKeyToValue()
{
return keyToValue;
}
public void put(K key, V value)
{
keyToValue.put(key, value);
}
public Set getAll(Set> keys)
{
Set result = new HashSet();
for(Object key : keys) {
if(keyToValue.containsKey(key)) {
result.add(keyToValue.get(key));
}
}
return result;
}
public Set getEquivalences(Object key, boolean reflexiv)
{
Set result = MultimapUtils.transitiveGetBoth(equivalences, key);
if(reflexiv) {
result.add((K)key);
}
return result;
}
public Set getAllEquivalences(Collection> keys, boolean reflexiv)
{
Set result = new HashSet();
Set