package org.aksw.jena_sparql_api.concept_cache.combinatorics; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.aksw.commons.collections.MapUtils; import org.aksw.jena_sparql_api.utils.QuadUtils; import org.apache.commons.math3.util.CombinatoricsUtils; import org.apache.jena.graph.Node; import org.apache.jena.sparql.core.Quad; import org.apache.jena.sparql.core.Var; import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; import com.google.common.collect.Sets; public class Utils2 { // public static int getCombinationCount(long n, long k) { // if(k > n) { // result = 0; // } else { // result = (int)(CombinatoricsUtils.factorial(n) / CombinatoricsUtils.factorial(n - k)); // } // } public static int getNumMatches(Entry<? extends Collection<?>, ? extends Collection<?>> quadGroup) { int result; int c = quadGroup.getKey().size(); int q = quadGroup.getValue().size(); if(c > q) { // If there are more candidates quads than query quads, we can't map all of them result = 0; } else { result = (int)(CombinatoricsUtils.factorial(q) / CombinatoricsUtils.factorial(q - c)); } return result; } public static Set<Var> getCooccurrentVars(Set<Var> vars, Iterable<Quad> quads) { Set<Var> result = new HashSet<Var>(); for(Quad quad : quads) { Set<Var> quadVars = QuadUtils.getVarsMentioned(quad); Set<Var> intersection = Sets.intersection(vars, quadVars); //Set<Var> diff = Sets.difference(quadVars, vars); if(!intersection.isEmpty()) { result.addAll(quadVars); } } return result; } // TODO Reflexive or not? Right now its irreflexive - i.e. a var cannot co-occur with itself public static Multimap<Var, Var> getCooccurrentVarMap(Set<Var> vars, Iterable<Quad> quads) { //Set<Var> result = new HashSet<Var>(); Multimap<Var, Var> result = HashMultimap.create(); for(Quad quad : quads) { Set<Var> quadVars = QuadUtils.getVarsMentioned(quad); Set<Var> intersection = Sets.intersection(vars, quadVars); for(Var v : intersection) { Set<Var> diff = Sets.difference(quadVars, Collections.singleton(v)); result.putAll(v, diff); } // if(!intersection.isEmpty()) { // result.addAll(quadVars); // } } return result; } /** * Note: if we assigned variables to integers, we could use arrays rather than maps * * @param source * @param target * @return */ public static Map<Var, Var> createVarMap(Quad source, Quad target) { Map<Var, Var> result = new HashMap<Var, Var>(); for(int i = 0; i < 4; ++i) { Node x = QuadUtils.getNode(source, i); Node y = QuadUtils.getNode(target, i); // Skip non-variable components if(!x.isVariable()) { if(!x.equals(y)) { result = null; break; } else { continue; } } Var s = (Var)x; // TODO Make sure y is a variable Var t = (Var)y; Map<Var, Var> cand = Collections.singletonMap(s, t); boolean isCompatible = MapUtils.isPartiallyCompatible(cand, result); if(!isCompatible) { result = null; break; } else { result.put(s, t); } } return result; } }