@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 rule The rule to be validated * @return Error messages if the when or then of a rule refers to a non existent type */ static Set<String> validateRuleSchemaConceptExist(GraknTx graph, Rule rule){ Set<String> errors = new HashSet<>(); errors.addAll(checkRuleSideInvalid(graph, rule, Schema.VertexProperty.RULE_WHEN, rule.when())); errors.addAll(checkRuleSideInvalid(graph, rule, Schema.VertexProperty.RULE_THEN, rule.then())); return errors; }
@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; }
@Override public Rule putRule(Label label, Pattern when, Pattern then) { Rule rule = putSchemaConcept(label, Schema.BaseType.RULE, false, v -> factory().buildRule(v, getMetaRule(), when, then)); //NB: thenTypes() will be empty as type edges added on commit //NB: this will cache also non-committed rules if (rule.then() != null){ rule.then().admin().varPatterns().stream() .flatMap(v -> v.getTypeLabels().stream()) .map(vl -> this.admin().<SchemaConcept>getSchemaConcept(vl)) .filter(Objects::nonNull) .filter(Concept::isType) .forEach(type -> ruleCache.updateRules(type, rule)); } return rule; }
private static ReasonerQuery combinedRuleQuery(GraknTx graph, Rule rule){ ReasonerQuery bodyQuery = rule.when().admin().getDisjunctiveNormalForm().getPatterns().iterator().next().toReasonerQuery(graph); ReasonerQuery headQuery = rule.then().admin().getDisjunctiveNormalForm().getPatterns().iterator().next().toReasonerQuery(graph); return headQuery.conjunction(bodyQuery); }
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; }
/** * @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; }
output.append(colorKeyword(" then ")).append("{ ").append(concept.asRule().then()).append(" }");
public InferenceRule(Rule rule, EmbeddedGraknTx<?> tx){ this.tx = tx; this.rule = rule; //TODO simplify once changes propagated to rule objects this.body = ReasonerQueries.create(conjunction(rule.when().admin()), tx); this.head = ReasonerQueries.atomic(conjunction(rule.then().admin()), tx); }
@Override protected Json concept(Concept concept) { Json json = Json.object("id", concept.id().getValue()); if (concept.isSchemaConcept()) { json.set("name", concept.asSchemaConcept().label().getValue()); SchemaConcept superConcept = concept.asSchemaConcept().sup(); if (superConcept != null) json.set("sub", superConcept.label().getValue()); } else if (concept.isThing()) { json.set("isa", concept.asThing().type().label().getValue()); } else { throw CommonUtil.unreachableStatement("Unrecognised concept " + concept); } if (concept.isAttribute()) { json.set("value", concept.asAttribute().value()); } if (concept.isRule()) { Pattern when = concept.asRule().when(); if (when != null) { json.set("when", when.toString()); } Pattern then = concept.asRule().then(); if (then != null) { json.set("then", then.toString()); } } return json; }