use of ai.grakn.graql.internal.reasoner.utils.Pair in project grakn by graknlabs.
the class ReasonerAtomicQuery method queryStateIterator.
@Override
public Pair<Iterator<ResolutionState>, MultiUnifier> queryStateIterator(QueryStateBase parent, Set<ReasonerAtomicQuery> visitedSubGoals, QueryCache<ReasonerAtomicQuery> cache) {
Pair<Stream<Answer>, MultiUnifier> cacheEntry = cache.getAnswerStreamWithUnifier(this);
MultiUnifier cacheUnifier = cacheEntry.getValue().inverse();
Iterator<AnswerState> dbIterator = cacheEntry.getKey().map(a -> a.explain(a.getExplanation().setQuery(this))).map(ans -> new AnswerState(ans, parent.getUnifier(), parent)).iterator();
Iterator<ResolutionState> subGoalIterator;
// if this is ground and exists in the db then do not resolve further
if (visitedSubGoals.contains(this) || (this.isGround() && dbIterator.hasNext())) {
subGoalIterator = Collections.emptyIterator();
} else {
visitedSubGoals.add(this);
subGoalIterator = this.getRuleStream().map(rulePair -> rulePair.getKey().subGoal(this.getAtom(), rulePair.getValue(), parent, visitedSubGoals, cache)).iterator();
}
return new Pair<>(Iterators.concat(dbIterator, subGoalIterator), cacheUnifier);
}
use of ai.grakn.graql.internal.reasoner.utils.Pair in project grakn by graknlabs.
the class QueryCache method getAnswerStreamWithUnifier.
@Override
public Pair<Stream<Answer>, MultiUnifier> getAnswerStreamWithUnifier(Q query) {
CacheEntry<Q, QueryAnswers> match = this.getEntry(query);
if (match != null) {
Q equivalentQuery = match.query();
QueryAnswers answers = match.cachedElement();
MultiUnifier multiUnifier = equivalentQuery.getMultiUnifier(query);
// lazy version would be answers.stream().flatMap(ans -> ans.unify(multiUnifier))
return new Pair<>(answers.unify(multiUnifier).stream(), multiUnifier);
}
return new Pair<>(structuralCache().get(query), new MultiUnifierImpl());
}
use of ai.grakn.graql.internal.reasoner.utils.Pair in project grakn by graknlabs.
the class LazyQueryCache method getAnswersWithUnifier.
@Override
public Pair<LazyAnswerIterator, MultiUnifier> getAnswersWithUnifier(Q query) {
CacheEntry<Q, LazyAnswerIterator> match = this.getEntry(query);
if (match != null) {
Q equivalentQuery = match.query();
MultiUnifier multiUnifier = equivalentQuery.getMultiUnifier(query);
LazyAnswerIterator unified = match.cachedElement().unify(multiUnifier);
return new Pair<>(unified, multiUnifier);
}
Stream<Answer> answerStream = record(query, query.getQuery().stream().map(a -> a.explain(new LookupExplanation(query))));
return new Pair<>(new LazyAnswerIterator(answerStream), new MultiUnifierImpl());
}
use of ai.grakn.graql.internal.reasoner.utils.Pair in project grakn by graknlabs.
the class ReasonerQueryImpl method getVarTypeMap.
private Map<Var, Type> getVarTypeMap(Stream<IsaAtomBase> isas) {
HashMap<Var, Type> map = new HashMap<>();
isas.map(at -> new Pair<>(at.getVarName(), at.getSchemaConcept())).filter(p -> Objects.nonNull(p.getValue())).filter(p -> p.getValue().isType()).forEach(p -> {
Var var = p.getKey();
Type newType = p.getValue().asType();
Type type = map.get(var);
if (type == null)
map.put(var, newType);
else {
boolean isSubType = type.subs().anyMatch(t -> t.equals(newType));
if (isSubType)
map.put(var, newType);
}
});
return map;
}
use of ai.grakn.graql.internal.reasoner.utils.Pair in project grakn by graknlabs.
the class RelationshipAtom method getRelationPlayerMappings.
/**
* @param parentAtom reference atom defining the mapping
* @param matchType type of match to be performed
* @return set of possible COMPLETE mappings between this (child) and parent relation players
*/
private Set<List<Pair<RelationPlayer, RelationPlayer>>> getRelationPlayerMappings(RelationshipAtom parentAtom, UnifierComparison matchType) {
Multimap<Role, RelationPlayer> childRoleRPMap = this.getRoleRelationPlayerMap();
Map<Var, Type> childVarTypeMap = this.getParentQuery().getVarTypeMap();
Map<Var, Type> parentVarTypeMap = parentAtom.getParentQuery().getVarTypeMap();
// establish compatible castings for each parent casting
List<Set<Pair<RelationPlayer, RelationPlayer>>> compatibleMappingsPerParentRP = new ArrayList<>();
ReasonerQueryImpl childQuery = (ReasonerQueryImpl) getParentQuery();
Set<Role> childRoles = childRoleRPMap.keySet();
parentAtom.getRelationPlayers().stream().filter(prp -> prp.getRole().isPresent()).forEach(prp -> {
VarPatternAdmin parentRolePattern = prp.getRole().orElse(null);
if (parentRolePattern == null) {
throw GraqlQueryException.rolePatternAbsent(this);
}
Label parentRoleLabel = parentRolePattern.getTypeLabel().orElse(null);
if (parentRoleLabel != null) {
Var parentRolePlayer = prp.getRolePlayer().var();
Type parentType = parentVarTypeMap.get(parentRolePlayer);
Set<Role> compatibleRoles = compatibleRoles(tx().getSchemaConcept(parentRoleLabel), parentType, childRoles);
List<RelationPlayer> compatibleRelationPlayers = new ArrayList<>();
compatibleRoles.stream().filter(childRoleRPMap::containsKey).forEach(role -> childRoleRPMap.get(role).stream().filter(crp -> {
Var childVar = crp.getRolePlayer().var();
Type childType = childVarTypeMap.get(childVar);
return matchType.typePlayability(childQuery, childVar, parentType) && matchType.typeCompatibility(parentType, childType);
}).filter(crp -> {
IdPredicate parentId = parentAtom.getIdPredicate(prp.getRolePlayer().var());
IdPredicate childId = this.getIdPredicate(crp.getRolePlayer().var());
return matchType.atomicCompatibility(parentId, childId);
}).filter(crp -> {
ValuePredicate parentVP = parentAtom.getPredicate(prp.getRolePlayer().var(), ValuePredicate.class);
ValuePredicate childVP = this.getPredicate(crp.getRolePlayer().var(), ValuePredicate.class);
return matchType.atomicCompatibility(parentVP, childVP);
}).forEach(compatibleRelationPlayers::add));
if (!compatibleRelationPlayers.isEmpty()) {
compatibleMappingsPerParentRP.add(compatibleRelationPlayers.stream().map(crp -> new Pair<>(crp, prp)).collect(Collectors.toSet()));
}
} else {
compatibleMappingsPerParentRP.add(getRelationPlayers().stream().map(crp -> new Pair<>(crp, prp)).collect(Collectors.toSet()));
}
});
return Sets.cartesianProduct(compatibleMappingsPerParentRP).stream().filter(list -> !list.isEmpty()).filter(list -> {
List<RelationPlayer> listChildRps = list.stream().map(Pair::getKey).collect(Collectors.toList());
// NB: this preserves cardinality instead of removing all occuring instances which is what we want
return ReasonerUtils.subtract(listChildRps, this.getRelationPlayers()).isEmpty();
}).filter(list -> {
List<RelationPlayer> listParentRps = list.stream().map(Pair::getValue).collect(Collectors.toList());
return listParentRps.containsAll(parentAtom.getRelationPlayers());
}).collect(toSet());
}
Aggregations