/** * * @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; }
/** * @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; }
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); }
/** * @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(" when ")).append("{ ").append(concept.asRule().when()).append(" }"); 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; }