use of ai.grakn.graql.admin.Unifier in project grakn by graknlabs.
the class AtomicTest method exactUnification.
/**
* checks the correctness and uniqueness of an exact unifier required to unify child query with parent
* @param parentQuery parent query
* @param childQuery child query
* @param checkInverse flag specifying whether the inverse equality u^{-1}=u(parent, child) of the unifier u(child, parent) should be checked
* @param checkEquality if true the parent and child answers will be checked for equality, otherwise they are checked for containment of child answers in parent
*/
private void exactUnification(ReasonerAtomicQuery parentQuery, ReasonerAtomicQuery childQuery, boolean checkInverse, boolean checkEquality) {
Atom childAtom = childQuery.getAtom();
Atom parentAtom = parentQuery.getAtom();
Unifier unifier = childAtom.getMultiUnifier(parentAtom, UnifierType.EXACT).getUnifier();
List<Answer> childAnswers = childQuery.getQuery().execute();
List<Answer> unifiedAnswers = childAnswers.stream().map(a -> a.unify(unifier)).filter(a -> !a.isEmpty()).collect(Collectors.toList());
List<Answer> parentAnswers = parentQuery.getQuery().execute();
if (checkInverse) {
Unifier unifier2 = parentAtom.getUnifier(childAtom);
assertEquals(unifier.inverse(), unifier2);
assertEquals(unifier, unifier2.inverse());
}
assertTrue(!childAnswers.isEmpty());
assertTrue(!unifiedAnswers.isEmpty());
assertTrue(!parentAnswers.isEmpty());
if (!checkEquality) {
assertTrue(parentAnswers.containsAll(unifiedAnswers));
} else {
assertCollectionsEqual(parentAnswers, unifiedAnswers);
Unifier inverse = unifier.inverse();
List<Answer> parentToChild = parentAnswers.stream().map(a -> a.unify(inverse)).collect(Collectors.toList());
assertCollectionsEqual(parentToChild, childAnswers);
}
}
use of ai.grakn.graql.admin.Unifier in project grakn by graknlabs.
the class RelationshipAtom method getMultiUnifier.
@Override
public MultiUnifier getMultiUnifier(Atom pAtom, UnifierComparison unifierType) {
Unifier baseUnifier = super.getUnifier(pAtom);
Set<Unifier> unifiers = new HashSet<>();
if (pAtom.isRelation()) {
// This is safe due to the check above
assert (pAtom instanceof RelationshipAtom);
RelationshipAtom parentAtom = (RelationshipAtom) pAtom;
// this is important for cases like unifying ($r1: $x, $r2: $y) with itself
if (this.equals(parentAtom) && this.getPartialSubstitutions().collect(toSet()).equals(parentAtom.getPartialSubstitutions().collect(toSet())) && this.getTypeConstraints().collect(toSet()).equals(parentAtom.getTypeConstraints().collect(toSet()))) {
return new MultiUnifierImpl();
}
boolean unifyRoleVariables = parentAtom.getRelationPlayers().stream().map(RelationPlayer::getRole).flatMap(CommonUtil::optionalToStream).anyMatch(rp -> rp.var().isUserDefinedName());
getRelationPlayerMappings(parentAtom, unifierType).forEach(mappingList -> {
Multimap<Var, Var> varMappings = HashMultimap.create();
mappingList.forEach(rpm -> {
// add role player mapping
varMappings.put(rpm.getKey().getRolePlayer().var(), rpm.getValue().getRolePlayer().var());
// add role var mapping if needed
VarPattern childRolePattern = rpm.getKey().getRole().orElse(null);
VarPattern parentRolePattern = rpm.getValue().getRole().orElse(null);
if (parentRolePattern != null && childRolePattern != null && unifyRoleVariables) {
varMappings.put(childRolePattern.admin().var(), parentRolePattern.admin().var());
}
});
unifiers.add(baseUnifier.merge(new UnifierImpl(varMappings)));
});
} else {
unifiers.add(baseUnifier);
}
return new MultiUnifierImpl(unifiers);
}
use of ai.grakn.graql.admin.Unifier in project grakn by graknlabs.
the class ReasonerQueryImpl method queryStateIterator.
/**
* @param parent parent state
* @param subGoals set of visited sub goals
* @param cache query cache
* @return query state iterator (db iter + unifier + state iter) for this query
*/
public Pair<Iterator<ResolutionState>, MultiUnifier> queryStateIterator(QueryStateBase parent, Set<ReasonerAtomicQuery> subGoals, QueryCache<ReasonerAtomicQuery> cache) {
Iterator<AnswerState> dbIterator;
Iterator<QueryStateBase> subGoalIterator;
if (!this.isRuleResolvable()) {
dbIterator = this.getQuery().stream().map(ans -> ans.explain(new JoinExplanation(this, ans))).map(ans -> new AnswerState(ans, parent.getUnifier(), parent)).iterator();
subGoalIterator = Collections.emptyIterator();
} else {
dbIterator = Collections.emptyIterator();
LinkedList<ReasonerQueryImpl> subQueries = new ResolutionPlan(this).queryPlan();
LOG.trace("CQ plan:\n" + subQueries.stream().map(sq -> sq.toString() + (sq.isRuleResolvable() ? "*" : "")).collect(Collectors.joining("\n")));
subGoalIterator = Iterators.singletonIterator(new CumulativeState(subQueries, new QueryAnswer(), parent.getUnifier(), parent, subGoals, cache));
}
return new Pair<>(Iterators.concat(dbIterator, subGoalIterator), new MultiUnifierImpl());
}
use of ai.grakn.graql.admin.Unifier in project grakn by graknlabs.
the class AtomicState method consumeAnswer.
@Override
Answer consumeAnswer(AnswerState state) {
Answer answer;
ReasonerAtomicQuery query = getQuery();
Answer baseAnswer = state.getSubstitution();
InferenceRule rule = state.getRule();
Unifier unifier = state.getUnifier();
if (rule == null)
answer = state.getSubstitution();
else {
answer = rule.requiresMaterialisation(query.getAtom()) ? materialisedAnswer(baseAnswer, rule, unifier) : ruleAnswer(baseAnswer, rule, unifier);
}
return getCache().recordAnswerWithUnifier(query, answer, getCacheUnifier());
}
use of ai.grakn.graql.admin.Unifier in project grakn by graknlabs.
the class ResourceAtom method getUnifier.
@Override
public Unifier getUnifier(Atom parentAtom) {
if (!(parentAtom instanceof ResourceAtom)) {
return new UnifierImpl(ImmutableMap.of(this.getPredicateVariable(), parentAtom.getVarName()));
}
Unifier unifier = super.getUnifier(parentAtom);
ResourceAtom parent = (ResourceAtom) parentAtom;
// unify relation vars
Var childRelationVarName = this.getRelationVariable();
Var parentRelationVarName = parent.getRelationVariable();
if (parentRelationVarName.isUserDefinedName() && !childRelationVarName.equals(parentRelationVarName)) {
unifier = unifier.merge(new UnifierImpl(ImmutableMap.of(childRelationVarName, parentRelationVarName)));
}
return unifier;
}
Aggregations