use of ai.grakn.concept.RelationshipType in project grakn by graknlabs.
the class GreedyTraversalPlan method inferRelationshipTypes.
private static void inferRelationshipTypes(EmbeddedGraknTx<?> tx, Set<Fragment> allFragments) {
Map<Var, Type> labelVarTypeMap = getLabelVarTypeMap(tx, allFragments);
if (labelVarTypeMap.isEmpty())
return;
Multimap<Var, Type> instanceVarTypeMap = getInstanceVarTypeMap(allFragments, labelVarTypeMap);
Multimap<Var, Var> relationshipRolePlayerMap = getRelationshipRolePlayerMap(allFragments, instanceVarTypeMap);
if (relationshipRolePlayerMap.isEmpty())
return;
// for each type, get all possible relationship type it could be in
Multimap<Type, RelationshipType> relationshipMap = HashMultimap.create();
labelVarTypeMap.values().stream().distinct().forEach(type -> addAllPossibleRelationships(relationshipMap, type));
// inferred labels should be kept separately, even if they are already in allFragments set
Map<Label, Var> inferredLabels = new HashMap<>();
relationshipRolePlayerMap.asMap().forEach((relationshipVar, rolePlayerVars) -> {
Set<Type> possibleRelationshipTypes = rolePlayerVars.stream().filter(instanceVarTypeMap::containsKey).map(rolePlayer -> getAllPossibleRelationshipTypes(instanceVarTypeMap.get(rolePlayer), relationshipMap)).reduce(Sets::intersection).orElse(Collections.emptySet());
// TODO: if possibleRelationshipTypes here is empty, the query will not match any data
if (possibleRelationshipTypes.size() == 1) {
Type relationshipType = possibleRelationshipTypes.iterator().next();
Label label = relationshipType.getLabel();
// add label fragment if this label has not been inferred
if (!inferredLabels.containsKey(label)) {
Var labelVar = var();
inferredLabels.put(label, labelVar);
Fragment labelFragment = Fragments.label(LabelProperty.of(label), labelVar, ImmutableSet.of(label));
allFragments.add(labelFragment);
}
// finally, add inferred isa fragments
Var labelVar = inferredLabels.get(label);
IsaProperty isaProperty = IsaProperty.of(labelVar.admin());
EquivalentFragmentSet isaEquivalentFragmentSet = EquivalentFragmentSets.isa(isaProperty, relationshipVar, labelVar, relationshipType.isImplicit());
allFragments.addAll(isaEquivalentFragmentSet.fragments());
}
});
}
use of ai.grakn.concept.RelationshipType in project grakn by graknlabs.
the class RelationshipTypePropertyTest method whenDeletingARelatedRole_TheDirectSuperTypeRelatedRolesAreUnchanged.
@Property
public void whenDeletingARelatedRole_TheDirectSuperTypeRelatedRolesAreUnchanged(@NonMeta RelationshipType subType, @FromTx Role role) {
RelationshipType superType = subType.sup();
Set<Role> previousHasRoles = superType.relates().collect(toSet());
subType.deleteRelates(role);
Set<Role> newHasRoles = superType.relates().collect(toSet());
assertEquals(previousHasRoles, newHasRoles);
}
use of ai.grakn.concept.RelationshipType in project grakn by graknlabs.
the class RelationshipAtom method inferPossibleRelationConfigurations.
/**
* @return a map of relationships and corresponding roles that could be played by this atom
*/
private Multimap<RelationshipType, Role> inferPossibleRelationConfigurations(Answer sub) {
Set<Role> roles = getExplicitRoles().filter(r -> !Schema.MetaSchema.isMetaLabel(r.getLabel())).collect(toSet());
Map<Var, Type> varTypeMap = getParentQuery().getVarTypeMap(sub);
Set<Type> types = getRolePlayers().stream().filter(varTypeMap::containsKey).map(varTypeMap::get).collect(toSet());
if (roles.isEmpty() && types.isEmpty()) {
RelationshipType metaRelationType = tx().admin().getMetaRelationType();
Multimap<RelationshipType, Role> compatibleTypes = HashMultimap.create();
metaRelationType.subs().filter(rt -> !rt.equals(metaRelationType)).forEach(rt -> compatibleTypes.putAll(rt, rt.relates().collect(toSet())));
return compatibleTypes;
}
// intersect relation types from roles and types
Multimap<RelationshipType, Role> compatibleTypes;
Multimap<RelationshipType, Role> compatibleTypesFromRoles = compatibleRelationTypesWithRoles(roles, new RoleConverter());
Multimap<RelationshipType, Role> compatibleTypesFromTypes = compatibleRelationTypesWithRoles(types, new TypeConverter());
if (roles.isEmpty()) {
compatibleTypes = compatibleTypesFromTypes;
} else // no types from roles -> roles correspond to mutually exclusive relations
if (compatibleTypesFromRoles.isEmpty() || types.isEmpty()) {
compatibleTypes = compatibleTypesFromRoles;
} else {
compatibleTypes = multimapIntersection(compatibleTypesFromTypes, compatibleTypesFromRoles);
}
return compatibleTypes;
}
use of ai.grakn.concept.RelationshipType in project grakn by graknlabs.
the class RelationshipAtom method inferRoles.
/**
* attempt to infer role types of this relation and return a fresh relationship with inferred role types
* @return either this if nothing/no roles can be inferred or fresh relation with inferred role types
*/
private RelationshipAtom inferRoles(Answer sub) {
// return if all roles known and non-meta
List<Role> explicitRoles = getExplicitRoles().collect(Collectors.toList());
Map<Var, Type> varTypeMap = getParentQuery().getVarTypeMap(sub);
boolean allRolesMeta = explicitRoles.stream().allMatch(role -> Schema.MetaSchema.isMetaLabel(role.getLabel()));
boolean roleRecomputationViable = allRolesMeta && (!sub.isEmpty() || !Sets.intersection(varTypeMap.keySet(), getRolePlayers()).isEmpty());
if (explicitRoles.size() == getRelationPlayers().size() && !roleRecomputationViable)
return this;
GraknTx graph = getParentQuery().tx();
Role metaRole = graph.admin().getMetaRole();
List<RelationPlayer> allocatedRelationPlayers = new ArrayList<>();
RelationshipType relType = getSchemaConcept() != null ? getSchemaConcept().asRelationshipType() : null;
// explicit role types from castings
List<RelationPlayer> inferredRelationPlayers = new ArrayList<>();
getRelationPlayers().forEach(rp -> {
Var varName = rp.getRolePlayer().var();
VarPatternAdmin rolePattern = rp.getRole().orElse(null);
if (rolePattern != null) {
Label roleLabel = rolePattern.getTypeLabel().orElse(null);
// allocate if variable role or if label non meta
if (roleLabel == null || !Schema.MetaSchema.isMetaLabel(roleLabel)) {
inferredRelationPlayers.add(RelationPlayer.of(rolePattern, varName.admin()));
allocatedRelationPlayers.add(rp);
}
}
});
// remaining roles
// role types can repeat so no matter what has been allocated still the full spectrum of possibilities is present
// TODO make restrictions based on cardinality constraints
Set<Role> possibleRoles = relType != null ? relType.relates().collect(toSet()) : inferPossibleTypes(sub).stream().filter(Concept::isRelationshipType).map(Concept::asRelationshipType).flatMap(RelationshipType::relates).collect(toSet());
// possible role types for each casting based on its type
Map<RelationPlayer, Set<Role>> mappings = new HashMap<>();
getRelationPlayers().stream().filter(rp -> !allocatedRelationPlayers.contains(rp)).forEach(rp -> {
Var varName = rp.getRolePlayer().var();
Type type = varTypeMap.get(varName);
mappings.put(rp, top(type != null ? compatibleRoles(type, possibleRoles) : possibleRoles));
});
// allocate all unambiguous mappings
mappings.entrySet().stream().filter(entry -> entry.getValue().size() == 1).forEach(entry -> {
RelationPlayer rp = entry.getKey();
Var varName = rp.getRolePlayer().var();
Role role = Iterables.getOnlyElement(entry.getValue());
VarPatternAdmin rolePattern = Graql.var().label(role.getLabel()).admin();
inferredRelationPlayers.add(RelationPlayer.of(rolePattern, varName.admin()));
allocatedRelationPlayers.add(rp);
});
// fill in unallocated roles with metarole
getRelationPlayers().stream().filter(rp -> !allocatedRelationPlayers.contains(rp)).forEach(rp -> {
Var varName = rp.getRolePlayer().var();
VarPatternAdmin rolePattern = rp.getRole().orElse(null);
rolePattern = rolePattern != null ? rolePattern.var().label(metaRole.getLabel()).admin() : Graql.var().label(metaRole.getLabel()).admin();
inferredRelationPlayers.add(RelationPlayer.of(rolePattern, varName.admin()));
});
VarPattern relationPattern = relationPattern(getVarName(), inferredRelationPlayers);
VarPatternAdmin newPattern = (isDirect() ? relationPattern.directIsa(getPredicateVariable()) : relationPattern.isa(getPredicateVariable())).admin();
return create(newPattern, getPredicateVariable(), getTypeId(), getParentQuery());
}
use of ai.grakn.concept.RelationshipType in project grakn by graknlabs.
the class CorenessTest method addSchemaAndEntities.
private void addSchemaAndEntities() throws InvalidKBException {
try (GraknTx graph = session.open(GraknTxType.WRITE)) {
EntityType entityType1 = graph.putEntityType(thing);
EntityType entityType2 = graph.putEntityType(anotherThing);
Role role1 = graph.putRole("role1");
Role role2 = graph.putRole("role2");
RelationshipType relationshipType1 = graph.putRelationshipType(related).relates(role1).relates(role2);
Role role3 = graph.putRole("role3");
Role role4 = graph.putRole("role4");
RelationshipType relationshipType2 = graph.putRelationshipType(veryRelated).relates(role3).relates(role4);
entityType1.plays(role1).plays(role2).plays(role3).plays(role4);
entityType2.plays(role1).plays(role2).plays(role3).plays(role4);
Entity entity1 = entityType1.addEntity();
Entity entity2 = entityType1.addEntity();
Entity entity3 = entityType2.addEntity();
Entity entity4 = entityType2.addEntity();
relationshipType1.addRelationship().addRolePlayer(role1, entity1).addRolePlayer(role2, entity2);
relationshipType1.addRelationship().addRolePlayer(role1, entity2).addRolePlayer(role2, entity3);
relationshipType1.addRelationship().addRolePlayer(role1, entity3).addRolePlayer(role2, entity4);
relationshipType1.addRelationship().addRolePlayer(role1, entity4).addRolePlayer(role2, entity1);
relationshipType2.addRelationship().addRolePlayer(role3, entity1).addRolePlayer(role4, entity3);
relationshipType2.addRelationship().addRolePlayer(role3, entity2).addRolePlayer(role4, entity4);
entityId1 = entity1.getId();
entityId2 = entity2.getId();
entityId3 = entity3.getId();
entityId4 = entity4.getId();
graph.commit();
}
}
Aggregations