@Override public Set<String> validateAsRuleHead(Rule rule) { return Sets.newHashSet(ErrorMessage.VALIDATION_RULE_ILLEGAL_ATOMIC_IN_HEAD.getMessage(rule.then(), rule.label())); }
@Override public Set<String> validateAsRuleHead(Rule rule) { return Sets.newHashSet(ErrorMessage.VALIDATION_RULE_ILLEGAL_ATOMIC_IN_HEAD.getMessage(rule.then(), rule.label())); }
@Override public Set<String> validateAsRuleHead(Rule rule) { return Sets.newHashSet(ErrorMessage.VALIDATION_RULE_ILLEGAL_ATOMIC_IN_HEAD.getMessage(rule.then(), rule.label())); }
/** * @param graph of interest * @return true if at least one inference rule is present in the graph */ public static boolean hasRules(GraknTx graph) { return graph.admin().getMetaRule().subs().anyMatch(rule -> !rule.label().equals(Schema.MetaSchema.RULE.getLabel())); }
@Override public Set<String> validateAsRuleHead(Rule rule){ Set<String> errors = new HashSet<>(); Set<Atomic> parentAtoms = getParentQuery().getAtoms(Atomic.class).filter(at -> !at.equals(this)).collect(toSet()); Set<Var> varNames = Sets.difference( getVarNames(), this.getInnerPredicates().map(Atomic::getVarName).collect(toSet()) ); boolean unboundVariables = varNames.stream() .anyMatch(var -> parentAtoms.stream().noneMatch(at -> at.getVarNames().contains(var))); if (unboundVariables) { errors.add(ErrorMessage.VALIDATION_RULE_ILLEGAL_HEAD_ATOM_WITH_UNBOUND_VARIABLE.getMessage(rule.then(), rule.label())); } SchemaConcept schemaConcept = getSchemaConcept(); if (schemaConcept == null){ errors.add(ErrorMessage.VALIDATION_RULE_ILLEGAL_HEAD_ATOM_WITH_AMBIGUOUS_SCHEMA_CONCEPT.getMessage(rule.then(), rule.label())); } else if (schemaConcept.isImplicit()){ errors.add(ErrorMessage.VALIDATION_RULE_ILLEGAL_HEAD_ATOM_WITH_IMPLICIT_SCHEMA_CONCEPT.getMessage(rule.then(), rule.label())); } return errors; }
/** * @param graph graph used to ensure the rule is a valid Horn clause * @param rule the rule to be validated * @return Error messages if the rule is not a valid Horn clause (in implication form, conjunction in the body, single-atom conjunction in the head) */ static Set<String> validateRuleIsValidHornClause(GraknTx graph, Rule rule){ Set<String> errors = new HashSet<>(); if (rule.when().admin().isDisjunction()){ errors.add(ErrorMessage.VALIDATION_RULE_DISJUNCTION_IN_BODY.getMessage(rule.label())); } if (errors.isEmpty()){ errors.addAll(validateRuleHead(graph, rule)); } return errors; }
@Override Label transform(MatchableConcept item) { Concept concept = item.get(); return concept.isRule() ? concept.asRule().label() : null; } };
/** * @param graph graph used to ensure the rule head is valid * @param rule the rule to be validated * @return Error messages if the rule head is invalid - is not a single-atom conjunction, doesn't contain illegal atomics and is ontologically valid */ private static Set<String> validateRuleHead(GraknTx graph, Rule rule) { Set<String> errors = new HashSet<>(); Set<Conjunction<VarPatternAdmin>> headPatterns = rule.then().admin().getDisjunctiveNormalForm().getPatterns(); if (headPatterns.size() != 1){ errors.add(ErrorMessage.VALIDATION_RULE_DISJUNCTION_IN_HEAD.getMessage(rule.label())); } else { ReasonerQuery bodyQuery = Iterables.getOnlyElement(rule.when().admin().getDisjunctiveNormalForm().getPatterns()).toReasonerQuery(graph); ReasonerQuery headQuery = Iterables.getOnlyElement(headPatterns).toReasonerQuery(graph); ReasonerQuery combinedQuery = headQuery.conjunction(bodyQuery); Set<Atomic> headAtoms = headQuery.getAtoms(); combinedQuery.getAtoms().stream() .filter(headAtoms::contains) .map(at -> at.validateAsRuleHead(rule)) .forEach(errors::addAll); Set<Atomic> selectableHeadAtoms = headAtoms.stream() .filter(Atomic::isAtom) .filter(Atomic::isSelectable) .collect(Collectors.toSet()); if (selectableHeadAtoms.size() > 1) { errors.add(ErrorMessage.VALIDATION_RULE_HEAD_NON_ATOMIC.getMessage(rule.label())); } } return errors; }
private Set<String> validateRelationPlayers(Rule rule){ Set<String> errors = new HashSet<>(); getRelationPlayers().forEach(rp -> { VarPatternAdmin role = rp.getRole().orElse(null); if (role == null){ errors.add(ErrorMessage.VALIDATION_RULE_ILLEGAL_HEAD_RELATION_WITH_AMBIGUOUS_ROLE.getMessage(rule.then(), rule.label())); } else { Label roleLabel = role.getTypeLabel().orElse(null); if (roleLabel == null){ errors.add(ErrorMessage.VALIDATION_RULE_ILLEGAL_HEAD_RELATION_WITH_AMBIGUOUS_ROLE.getMessage(rule.then(), rule.label())); } else { if (Schema.MetaSchema.isMetaLabel(roleLabel)) { errors.add(ErrorMessage.VALIDATION_RULE_ILLEGAL_HEAD_RELATION_WITH_AMBIGUOUS_ROLE.getMessage(rule.then(), rule.label())); } Role roleType = tx().getRole(roleLabel.getValue()); if (roleType != null && roleType.isImplicit()) { errors.add(ErrorMessage.VALIDATION_RULE_ILLEGAL_HEAD_RELATION_WITH_IMPLICIT_ROLE.getMessage(rule.then(), rule.label())); } } } }); return errors; }
@Override public Set<String> validateAsRuleHead(Rule rule){ Set<String> errors = super.validateAsRuleHead(rule); if (getSchemaConcept() == null || getMultiPredicate().size() > 1){ errors.add(ErrorMessage.VALIDATION_RULE_ILLEGAL_HEAD_RESOURCE_WITH_AMBIGUOUS_PREDICATES.getMessage(rule.then(), rule.label())); } if (getMultiPredicate().isEmpty()){ boolean predicateBound = getParentQuery().getAtoms(Atom.class) .filter(at -> !at.equals(this)) .anyMatch(at -> at.getVarNames().contains(getPredicateVariable())); if (!predicateBound) { errors.add(ErrorMessage.VALIDATION_RULE_ILLEGAL_HEAD_ATOM_WITH_UNBOUND_VARIABLE.getMessage(rule.then(), rule.label())); } } getMultiPredicate().stream() .filter(p -> !p.getPredicate().isSpecific()) .forEach( p -> errors.add(ErrorMessage.VALIDATION_RULE_ILLEGAL_HEAD_RESOURCE_WITH_NONSPECIFIC_PREDICATE.getMessage(rule.then(), rule.label())) ); return errors; }
SchemaConcept schemaConcept = graph.getSchemaConcept(typeLabel); if(schemaConcept == null){ errors.add(ErrorMessage.VALIDATION_RULE_MISSING_ELEMENTS.getMessage(side, rule.label(), typeLabel)); } else { if(Schema.VertexProperty.RULE_WHEN.equals(side)){
@Override public String toString() { if (concept.isAttribute()) { return "hasValue(" + valueToString(concept.asAttribute().value()) + ")"; } else if (concept.isThing()) { Thing thing = concept.asThing(); Stream<Attribute<?>> resources = thing.attributes(); Optional<?> value = resources .filter(resource -> NAME_TYPES.contains(resource.type().label())) .map(Attribute::value).findFirst(); return "instance(" + value.map(StringUtil::valueToString).orElse("") + ") isa " + thing.type().label(); } else if (concept.isType()) { return "type(" + concept.asType().label() + ")"; } else if (concept.isRole()) { return "role(" + concept.asRole().label() + ")"; } else if (concept.isRule()) { return "rule(" + concept.asRule().label() + ")"; } else { throw CommonUtil.unreachableStatement("Unrecognised concept " + concept); } }