Java tutorial
/* * Grakn - A Distributed Semantic Database * Copyright (C) 2016 Grakn Labs Limited * * Grakn is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Grakn is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Grakn. If not, see <http://www.gnu.org/licenses/gpl.txt>. */ package ai.grakn.graql.internal.hal; import ai.grakn.concept.Concept; import ai.grakn.concept.Instance; import ai.grakn.concept.Type; import ai.grakn.concept.TypeLabel; import ai.grakn.graql.MatchQuery; import ai.grakn.graql.Var; import ai.grakn.graql.admin.Answer; import ai.grakn.graql.admin.AnswerExplanation; import ai.grakn.graql.admin.VarPatternAdmin; import ai.grakn.graql.internal.pattern.property.IsaProperty; import ai.grakn.graql.internal.pattern.property.RelationProperty; import ai.grakn.graql.internal.reasoner.atom.Atom; import ai.grakn.graql.internal.reasoner.atom.binary.Relation; import ai.grakn.graql.internal.reasoner.query.ReasonerAtomicQuery; import ai.grakn.util.CommonUtil; import ai.grakn.util.Schema; import com.google.common.collect.Sets; import com.theoryinpractise.halbuilder.api.Representation; import javafx.util.Pair; import java.util.HashMap; import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; /** * Utils class used by HALBuilders * * @author Marco Scoppetta */ public class HALUtils { final static String EXPLORE_CONCEPT_LINK = "explore"; // - Edges names final static String ISA_EDGE = "isa"; final static String SUB_EDGE = "sub"; final static String OUTBOUND_EDGE = "OUT"; final static String INBOUND_EDGE = "IN"; final static String HAS_ROLE_EDGE = "has-role"; final static String HAS_RESOURCE_EDGE = "has-resource"; final static String PLAYS_ROLE_EDGE = "plays-role"; final static String HAS_EMPTY_ROLE_EDGE = "EMPTY-GRAKN-ROLE"; // - State properties public final static String ID_PROPERTY = "_id"; public final static String TYPE_PROPERTY = "_type"; public final static String BASETYPE_PROPERTY = "_baseType"; public final static String DIRECTION_PROPERTY = "_direction"; public final static String VALUE_PROPERTY = "_value"; public final static String NAME_PROPERTY = "_name"; static Schema.BaseType getBaseType(Instance instance) { if (instance.isEntity()) { return Schema.BaseType.ENTITY; } else if (instance.isRelation()) { return Schema.BaseType.RELATION; } else if (instance.isResource()) { return Schema.BaseType.RESOURCE; } else if (instance.isRule()) { return Schema.BaseType.RULE; } else { throw CommonUtil.unreachableStatement("Unrecognised base type of " + instance); } } static Schema.BaseType getBaseType(Type type) { if (type.isEntityType()) { return Schema.BaseType.ENTITY_TYPE; } else if (type.isRelationType()) { return Schema.BaseType.RELATION_TYPE; } else if (type.isResourceType()) { return Schema.BaseType.RESOURCE_TYPE; } else if (type.isRuleType()) { return Schema.BaseType.RULE_TYPE; } else if (type.isRoleType()) { return Schema.BaseType.ROLE_TYPE; } else if (type.getLabel().equals(Schema.MetaSchema.CONCEPT.getLabel())) { return Schema.BaseType.TYPE; } else { throw CommonUtil.unreachableStatement("Unrecognised base type of " + type); } } static void generateConceptState(Representation resource, Concept concept) { resource.withProperty(ID_PROPERTY, concept.getId().getValue()); if (concept.isInstance()) { Instance instance = concept.asInstance(); resource.withProperty(TYPE_PROPERTY, instance.type().getLabel().getValue()) .withProperty(BASETYPE_PROPERTY, getBaseType(instance).name()); } else { resource.withProperty(BASETYPE_PROPERTY, getBaseType(concept.asType()).name()); } if (concept.isResource()) { resource.withProperty(VALUE_PROPERTY, concept.asResource().getValue()); } if (concept.isType()) { resource.withProperty(NAME_PROPERTY, concept.asType().getLabel().getValue()); } } static Map<VarPatternAdmin, Pair<Map<Var, String>, String>> computeRoleTypesFromQuery(MatchQuery matchQuery, Answer firstAnswer) { final Map<VarPatternAdmin, Pair<Map<Var, String>, String>> roleTypes = new HashMap<>(); AnswerExplanation firstExplanation = firstAnswer.getExplanation(); if (firstExplanation.isEmpty()) { return computeRoleTypesFromQueryNoReasoner(matchQuery); } else { if (firstExplanation.isRuleExplanation() || firstExplanation.isLookupExplanation()) { updateRoleTypesFromAnswer(roleTypes, firstAnswer, matchQuery); } else { firstAnswer.getExplanation().getAnswers() .forEach(answer -> updateRoleTypesFromAnswer(roleTypes, answer, matchQuery)); } return roleTypes; } } private static void updateRoleTypesFromAnswer(Map<VarPatternAdmin, Pair<Map<Var, String>, String>> roleTypes, Answer answer, MatchQuery matchQuery) { Atom atom = ((ReasonerAtomicQuery) answer.getExplanation().getQuery()).getAtom(); if (atom.isRelation()) { Optional<VarPatternAdmin> var = atom.getPattern().getVars().stream() .filter(x -> x.hasProperty(RelationProperty.class)).findFirst(); VarPatternAdmin varAdmin = atom.getPattern().asVar(); if (var.isPresent() && !var.get().getVarName().isUserDefinedName() && bothRolePlayersAreSelected(atom, matchQuery)) { roleTypes.put(varAdmin, pairVarNamesRelationType(atom)); } } } private static boolean bothRolePlayersAreSelected(Atom atom, MatchQuery matchQuery) { Relation reasonerRel = ((Relation) atom); Set<Var> rolePlayersInAtom = reasonerRel.getRolePlayers().stream().collect(Collectors.toSet()); Set<Var> selectedVars = matchQuery.admin().getSelectedNames(); //If all the role players contained in the current relation are also selected in the user query return Sets.intersection(rolePlayersInAtom, selectedVars).equals(rolePlayersInAtom); } private static boolean bothRolePlayersAreSelectedNoReasoner(VarPatternAdmin var, MatchQuery matchQuery) { Set<Var> rolePlayersInVar = var.getProperty(RelationProperty.class).get().getRelationPlayers() .map(x -> x.getRolePlayer().getVarName()).collect(Collectors.toSet()); Set<Var> selectedVars = matchQuery.admin().getSelectedNames(); //If all the role players contained in the current relation are also selected in the user query return Sets.intersection(rolePlayersInVar, selectedVars).equals(rolePlayersInVar); } private static Map<VarPatternAdmin, Pair<Map<Var, String>, String>> computeRoleTypesFromQueryNoReasoner( MatchQuery matchQuery) { final Map<VarPatternAdmin, Pair<Map<Var, String>, String>> roleTypes = new HashMap<>(); matchQuery.admin().getPattern().getVars().forEach(var -> { if (var.getProperty(RelationProperty.class).isPresent() && !var.getVarName().isUserDefinedName() && bothRolePlayersAreSelectedNoReasoner(var, matchQuery)) { Map<Var, String> tempMap = new HashMap<>(); var.getProperty(RelationProperty.class).get().getRelationPlayers().forEach(x -> { tempMap.put(x.getRolePlayer().getVarName(), (x.getRoleType().isPresent()) ? x.getRoleType().get().getPrintableName() : HAS_EMPTY_ROLE_EDGE); }); String relationType = null; if (var.getProperty(IsaProperty.class).isPresent()) { Optional<TypeLabel> relOptional = var.getProperty(IsaProperty.class).get().getType() .getTypeLabel(); relationType = (relOptional.isPresent()) ? relOptional.get().getValue() : ""; } else { relationType = ""; } roleTypes.put(var, new Pair<>(tempMap, relationType)); } }); return roleTypes; } private static Pair<Map<Var, String>, String> pairVarNamesRelationType(Atom atom) { Relation reasonerRel = ((Relation) atom); Map<Var, String> varNamesToRole = new HashMap<>(); // Put all the varNames in the map with EMPTY-ROLE role reasonerRel.getRolePlayers().forEach(varName -> varNamesToRole.put(varName, HAS_EMPTY_ROLE_EDGE)); // Overrides the varNames that have roles in the previous map reasonerRel.getRoleVarMap().entries().stream() .filter(entry -> !Schema.MetaSchema.isMetaLabel(entry.getKey().getLabel())) .forEach(entry -> varNamesToRole.put(entry.getValue(), entry.getKey().getLabel().getValue())); String relationType = (reasonerRel.getType() != null) ? reasonerRel.getType().getLabel().getValue() : ""; return new Pair<>(varNamesToRole, relationType); } static Map<VarPatternAdmin, Boolean> buildInferredRelationsMap(Answer firstAnswer) { final Map<VarPatternAdmin, Boolean> inferredRelations = new HashMap<>(); AnswerExplanation firstExplanation = firstAnswer.getExplanation(); if (firstExplanation.isRuleExplanation() || firstExplanation.isLookupExplanation()) { Atom atom = ((ReasonerAtomicQuery) firstAnswer.getExplanation().getQuery()).getAtom(); if (atom.isRelation()) { VarPatternAdmin varAdmin = atom.getPattern().asVar(); inferredRelations.put(varAdmin, firstAnswer.getExplanation().isRuleExplanation()); } } else { firstAnswer.getExplanation().getAnswers().forEach(answer -> { Atom atom = ((ReasonerAtomicQuery) answer.getExplanation().getQuery()).getAtom(); if (atom.isRelation()) { VarPatternAdmin varAdmin = atom.getPattern().asVar(); inferredRelations.put(varAdmin, answer.getExplanation().isRuleExplanation()); } }); } return inferredRelations; } }