use of ai.grakn.graql.internal.reasoner.atom.predicate.ValuePredicate in project grakn by graknlabs.
the class InferenceRule method propagateConstraints.
/**
* @param parentAtom atom containing constraints (parent)
* @param unifier unifier unifying parent with the rule
* @return rule with propagated constraints from parent
*/
public InferenceRule propagateConstraints(Atom parentAtom, Unifier unifier) {
if (!parentAtom.isRelation() && !parentAtom.isResource())
return this;
Atom headAtom = head.getAtom();
Set<Atomic> bodyAtoms = new HashSet<>(body.getAtoms());
// transfer value predicates
parentAtom.getPredicates(ValuePredicate.class).flatMap(vp -> vp.unify(unifier).stream()).forEach(bodyAtoms::add);
// if head is a resource merge vps into head
if (headAtom.isResource() && ((ResourceAtom) headAtom).getMultiPredicate().isEmpty()) {
ResourceAtom resourceHead = (ResourceAtom) headAtom;
Set<ValuePredicate> innerVps = parentAtom.getInnerPredicates(ValuePredicate.class).flatMap(vp -> vp.unify(unifier).stream()).peek(bodyAtoms::add).collect(toSet());
headAtom = ResourceAtom.create(headAtom.getPattern(), headAtom.getPredicateVariable(), resourceHead.getRelationVariable(), resourceHead.getTypeId(), innerVps, headAtom.getParentQuery());
}
Set<TypeAtom> unifiedTypes = parentAtom.getTypeConstraints().flatMap(type -> type.unify(unifier).stream()).collect(toSet());
// set rule body types to sub types of combined query+rule types
Set<TypeAtom> ruleTypes = body.getAtoms(TypeAtom.class).filter(t -> !t.isRelation()).collect(toSet());
Set<TypeAtom> allTypes = Sets.union(unifiedTypes, ruleTypes);
allTypes.stream().filter(ta -> {
SchemaConcept schemaConcept = ta.getSchemaConcept();
SchemaConcept subType = allTypes.stream().map(Atom::getSchemaConcept).filter(Objects::nonNull).filter(t -> ReasonerUtils.supers(t).contains(schemaConcept)).findFirst().orElse(null);
return schemaConcept == null || subType == null;
}).forEach(t -> bodyAtoms.add(t.copy(body)));
return new InferenceRule(ReasonerQueries.atomic(headAtom), ReasonerQueries.create(bodyAtoms, tx), ruleId, tx);
}
use of ai.grakn.graql.internal.reasoner.atom.predicate.ValuePredicate in project grakn by graknlabs.
the class ResourceAtom method isRuleApplicableViaAtom.
@Override
public boolean isRuleApplicableViaAtom(Atom ruleAtom) {
// findbugs complains about cast without it
if (!(ruleAtom instanceof ResourceAtom))
return false;
ResourceAtom childAtom = (ResourceAtom) ruleAtom;
ReasonerQueryImpl childQuery = (ReasonerQueryImpl) childAtom.getParentQuery();
// check type bindings compatiblity
Type parentType = this.getParentQuery().getVarTypeMap().get(this.getVarName());
Type childType = childQuery.getVarTypeMap().get(childAtom.getVarName());
if (parentType != null && childType != null && areDisjointTypes(parentType, childType) || !childQuery.isTypeRoleCompatible(ruleAtom.getVarName(), parentType))
return false;
// check value predicate compatibility
if (childAtom.getMultiPredicate().isEmpty() || getMultiPredicate().isEmpty())
return true;
for (ValuePredicate childPredicate : childAtom.getMultiPredicate()) {
Iterator<ValuePredicate> parentIt = getMultiPredicate().iterator();
boolean predicateCompatible = false;
while (parentIt.hasNext() && !predicateCompatible) {
ValuePredicate parentPredicate = parentIt.next();
predicateCompatible = parentPredicate.isCompatibleWith(childPredicate);
}
if (!predicateCompatible)
return false;
}
return true;
}
use of ai.grakn.graql.internal.reasoner.atom.predicate.ValuePredicate in project grakn by graknlabs.
the class HasAttributeProperty method mapToAtom.
@Override
public Atomic mapToAtom(VarPatternAdmin var, Set<VarPatternAdmin> vars, ReasonerQuery parent) {
// NB: HasAttributeProperty always has (type) label specified
Var varName = var.var().asUserDefined();
Var relationVariable = relationship().var();
Var attributeVariable = attribute().var().asUserDefined();
Set<ValuePredicate> predicates = getValuePredicates(attributeVariable, attribute(), vars, parent);
IsaProperty isaProp = attribute().getProperties(IsaProperty.class).findFirst().orElse(null);
VarPatternAdmin typeVar = isaProp != null ? isaProp.type() : null;
IdPredicate predicate = typeVar != null ? getIdPredicate(attributeVariable, typeVar, vars, parent) : null;
ConceptId predicateId = predicate != null ? predicate.getPredicate() : null;
// add resource atom
VarPatternAdmin resVar = relationVariable.isUserDefinedName() ? varName.has(type(), attributeVariable, relationVariable).admin() : varName.has(type(), attributeVariable).admin();
return ResourceAtom.create(resVar, attributeVariable, relationVariable, predicateId, predicates, parent);
}
use of ai.grakn.graql.internal.reasoner.atom.predicate.ValuePredicate 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());
}
use of ai.grakn.graql.internal.reasoner.atom.predicate.ValuePredicate in project grakn by graknlabs.
the class ResourceAtom method hasMultiPredicateEquivalentWith.
private boolean hasMultiPredicateEquivalentWith(ResourceAtom atom) {
if (this.getMultiPredicate().size() != atom.getMultiPredicate().size())
return false;
for (ValuePredicate vp : getMultiPredicate()) {
Iterator<ValuePredicate> objIt = atom.getMultiPredicate().iterator();
boolean predicateHasEquivalent = false;
while (objIt.hasNext() && !predicateHasEquivalent) {
predicateHasEquivalent = vp.isAlphaEquivalent(objIt.next());
}
if (!predicateHasEquivalent)
return false;
}
return true;
}
Aggregations