/** * Helper method to get implicit relationship types of attributes * * @param types * @return a set of type Labels */ private static Set<Label> getAttributeImplicitRelationTypeLabes(Set<Type> types) { // If the sub graph contains attributes, we may need to add implicit relations to the path return types.stream() .filter(Concept::isAttributeType) .map(attributeType -> Schema.ImplicitType.HAS.getLabel(attributeType.label())) .collect(Collectors.toSet()); }
private Set<Integer> implicitLabelsToIds(Set<Label> labels, Set<Schema.ImplicitType> implicitTypes){ return labels.stream() .flatMap(label -> implicitTypes.stream().map(it -> it.getLabel(label))) .map(label -> vertex().tx().convertToId(label)) .filter(id -> !id.equals(LabelId.invalid())) .map(LabelId::getValue) .collect(toSet()); }
private Stream<AttributeType> attributes(Schema.ImplicitType implicitType){ //TODO: Make this less convoluted String [] implicitIdentifiers = implicitType.getLabel("").getValue().split("--"); String prefix = implicitIdentifiers[0] + "-"; String suffix = "-" + implicitIdentifiers[1]; //A traversal is not used in this so that caching can be taken advantage of. return playing().map(role -> role.label().getValue()). filter(roleLabel -> roleLabel.startsWith(prefix) && roleLabel.endsWith(suffix)). map(roleLabel -> { String attributeTypeLabel = roleLabel.replace(prefix, "").replace(suffix, ""); return vertex().tx().getAttributeType(attributeTypeLabel); }); }
cluster.has(name); tx.getType(Schema.ImplicitType.HAS.getLabel("title")).has(provenance);
/** * Creates a relation type which allows this type and a {@link ai.grakn.concept.Attribute} type to be linked. * @param attributeType The {@link AttributeType} which instances of this type should be allowed to play. * @param has the implicit relation type to build * @param hasValue the implicit role type to build for the {@link AttributeType} * @param hasOwner the implicit role type to build for the type * @param required Indicates if the {@link ai.grakn.concept.Attribute} is required on the entity * @return The {@link Type} itself */ private T has(AttributeType attributeType, Schema.ImplicitType has, Schema.ImplicitType hasValue, Schema.ImplicitType hasOwner, boolean required){ Label attributeLabel = attributeType.label(); Role ownerRole = vertex().tx().putRoleTypeImplicit(hasOwner.getLabel(attributeLabel)); Role valueRole = vertex().tx().putRoleTypeImplicit(hasValue.getLabel(attributeLabel)); RelationshipType relationshipType = vertex().tx().putRelationTypeImplicit(has.getLabel(attributeLabel)). relates(ownerRole). relates(valueRole); //this plays ownerRole; this.play(ownerRole, required); //TODO: Use explicit cardinality of 0-1 rather than just false //attributeType plays valueRole; ((AttributeTypeImpl) attributeType).play(valueRole, false); updateAttributeRelationHierarchy(attributeType, has, hasValue, hasOwner, ownerRole, valueRole, relationshipType); return getThis(); }
/** * @throws GraqlQueryException if no label is specified on {@code resourceType} */ public static HasAttributeTypeProperty of(VarPatternAdmin resourceType, boolean required) { Label resourceLabel = resourceType.getTypeLabel().orElseThrow(() -> GraqlQueryException.noLabelSpecifiedForHas(resourceType) ); VarPattern role = Graql.label(Schema.MetaSchema.ROLE.getLabel()); VarPatternAdmin ownerRole = var().sub(role).admin(); VarPatternAdmin valueRole = var().sub(role).admin(); VarPattern relationType = var().sub(Graql.label(Schema.MetaSchema.RELATIONSHIP.getLabel())); // If a key, limit only to the implicit key type if(required){ ownerRole = ownerRole.label(KEY_OWNER.getLabel(resourceLabel)).admin(); valueRole = valueRole.label(KEY_VALUE.getLabel(resourceLabel)).admin(); relationType = relationType.label(KEY.getLabel(resourceLabel)); } VarPatternAdmin relationOwner = relationType.relates(ownerRole).admin(); VarPatternAdmin relationValue = relationType.admin().var().relates(valueRole).admin(); return new AutoValue_HasAttributeTypeProperty( resourceType, ownerRole, valueRole, relationOwner, relationValue, required); }
private void updateAttributeRelationHierarchy(AttributeType attributeType, Schema.ImplicitType has, Schema.ImplicitType hasValue, Schema.ImplicitType hasOwner, Role ownerRole, Role valueRole, RelationshipType relationshipType){ AttributeType attributeTypeSuper = attributeType.sup(); Label superLabel = attributeTypeSuper.label(); Role ownerRoleSuper = vertex().tx().putRoleTypeImplicit(hasOwner.getLabel(superLabel)); Role valueRoleSuper = vertex().tx().putRoleTypeImplicit(hasValue.getLabel(superLabel)); RelationshipType relationshipTypeSuper = vertex().tx().putRelationTypeImplicit(has.getLabel(superLabel)). relates(ownerRoleSuper).relates(valueRoleSuper); //Create the super type edges from sub role/relations to super roles/relation ownerRole.sup(ownerRoleSuper); valueRole.sup(valueRoleSuper); relationshipType.sup(relationshipTypeSuper); if (!Schema.MetaSchema.ATTRIBUTE.getLabel().equals(superLabel)) { //Make sure the supertype attribute is linked with the role as well ((AttributeTypeImpl) attributeTypeSuper).plays(valueRoleSuper); updateAttributeRelationHierarchy(attributeTypeSuper, has, hasValue, hasOwner, ownerRoleSuper, valueRoleSuper, relationshipTypeSuper); } } /**
private Relationship attributeRelationship(Attribute attribute, boolean isInferred) { Schema.ImplicitType has = Schema.ImplicitType.HAS; Schema.ImplicitType hasValue = Schema.ImplicitType.HAS_VALUE; Schema.ImplicitType hasOwner = Schema.ImplicitType.HAS_OWNER; //Is this attribute a key to me? if(type().keys().anyMatch(rt -> rt.equals(attribute.type()))){ has = Schema.ImplicitType.KEY; hasValue = Schema.ImplicitType.KEY_VALUE; hasOwner = Schema.ImplicitType.KEY_OWNER; } Label label = attribute.type().label(); RelationshipType hasAttribute = vertex().tx().getSchemaConcept(has.getLabel(label)); Role hasAttributeOwner = vertex().tx().getSchemaConcept(hasOwner.getLabel(label)); Role hasAttributeValue = vertex().tx().getSchemaConcept(hasValue.getLabel(label)); if(hasAttribute == null || hasAttributeOwner == null || hasAttributeValue == null || type().playing().noneMatch(play -> play.equals(hasAttributeOwner))){ throw GraknTxOperationException.hasNotAllowed(this, attribute); } EdgeElement attributeEdge = addEdge(AttributeImpl.from(attribute), Schema.EdgeLabel.ATTRIBUTE); if(isInferred) attributeEdge.property(Schema.EdgeProperty.IS_INFERRED, true); return vertex().tx().factory().buildRelation(attributeEdge, hasAttribute, hasAttributeOwner, hasAttributeValue); }
@Override public Collection<EquivalentFragmentSet> match(Var start) { Label type = type(); Label has = Schema.ImplicitType.HAS.getLabel(type); Label key = Schema.ImplicitType.KEY.getLabel(type); Label hasOwnerRole = Schema.ImplicitType.HAS_OWNER.getLabel(type); Label keyOwnerRole = Schema.ImplicitType.KEY_OWNER.getLabel(type); Label hasValueRole= Schema.ImplicitType.HAS_VALUE.getLabel(type); Label keyValueRole = Schema.ImplicitType.KEY_VALUE.getLabel(type); Var edge1 = Graql.var(); Var edge2 = Graql.var(); return ImmutableSet.of( //owner rolePlayer edge rolePlayer(this, relationship().var(), edge1, start, null, ImmutableSet.of(hasOwnerRole, keyOwnerRole), ImmutableSet.of(has, key)), //value rolePlayer edge rolePlayer(this, relationship().var(), edge2, attribute().var(), null, ImmutableSet.of(hasValueRole, keyValueRole), ImmutableSet.of(has, key)), neq(this, edge1, edge2) ); }
/** * Helper method to delete a {@link AttributeType} which is possible linked to this {@link Type}. * The link to {@link AttributeType} is removed if <code>attributeToRemove</code> is in the candidate list * <code>attributeTypes</code> * * @param implicitType the {@link Schema.ImplicitType} which specifies which implicit {@link Role} should be removed * @param attributeTypes The list of candidate which potentially contains the {@link AttributeType} to remove * @param attributeToRemove the {@link AttributeType} to remove * @return the {@link Type} itself */ private T deleteAttribute(Schema.ImplicitType implicitType, Stream<AttributeType> attributeTypes, AttributeType attributeToRemove){ if(attributeTypes.anyMatch(a -> a.equals(attributeToRemove))){ Label label = implicitType.getLabel(attributeToRemove.label()); Role role = vertex().tx().getSchemaConcept(label); if(role != null) unplay(role); } return getThis(); }
@Override public RelationshipAtom toRelationshipAtom(){ SchemaConcept type = getSchemaConcept(); if (type == null) throw GraqlQueryException.illegalAtomConversion(this, RelationshipAtom.class); GraknTx tx = getParentQuery().tx(); Label typeLabel = Schema.ImplicitType.HAS.getLabel(type.label()); return RelationshipAtom.create( Graql.var() .rel(Schema.ImplicitType.HAS_OWNER.getLabel(type.label()).getValue(), getVarName()) .rel(Schema.ImplicitType.HAS_VALUE.getLabel(type.label()).getValue(), getPredicateVariable()) .isa(typeLabel.getValue()) .admin(), getPredicateVariable(), tx.getSchemaConcept(typeLabel).id(), getParentQuery() ); }
/** * Check if the given {@link Attribute} conforms to the has syntax and structural requirements * @param attribute {@link Attribute} to check * @return true if the {@link Attribute} is target of has relation */ private static boolean isHasResourceResource(Attribute attribute){ AttributeType attributeType = attribute.type(); // TODO: Make sure this is tested boolean plays = attributeType.playing().map(Role::label) .allMatch(c -> c.equals(HAS_VALUE.getLabel(attributeType.label()))); return attribute.owners().findAny().isPresent() && plays; } }
@Override public T unhas(Attribute attribute){ Role roleHasOwner = vertex().tx().getSchemaConcept(Schema.ImplicitType.HAS_OWNER.getLabel(attribute.type().label())); Role roleKeyOwner = vertex().tx().getSchemaConcept(Schema.ImplicitType.KEY_OWNER.getLabel(attribute.type().label())); Role roleHasValue = vertex().tx().getSchemaConcept(Schema.ImplicitType.HAS_VALUE.getLabel(attribute.type().label())); Role roleKeyValue = vertex().tx().getSchemaConcept(Schema.ImplicitType.KEY_VALUE.getLabel(attribute.type().label())); Stream<Relationship> relationships = relationships(filterNulls(roleHasOwner, roleKeyOwner)); relationships.filter(relationship -> { Stream<Thing> rolePlayers = relationship.rolePlayers(filterNulls(roleHasValue, roleKeyValue)); return rolePlayers.anyMatch(rolePlayer -> rolePlayer.equals(attribute)); }).forEach(Concept::delete); return getThis(); }
/** * Make a name for a resource role player representing the value of an OWL data property. */ default Label resourceRole(Label resourceLabel) { return Schema.ImplicitType.HAS_VALUE.getLabel(resourceLabel); } }
/** * Make a name for a resource relation type representing the value of an OWL data property. */ default Label resourceRelation(Label resourceLabel) { return Schema.ImplicitType.HAS.getLabel(resourceLabel); } /**
/** * The name of the entity role type in an entity-role relation representing an OWL data property */ default Label entityRole(Label resourceLabel) { return Schema.ImplicitType.HAS_OWNER.getLabel(resourceLabel); } /**