
io.mindmaps.graql.internal.reasoner.predicate.AtomBase Maven / Gradle / Ivy
/*
* MindmapsDB - A Distributed Semantic Database
* Copyright (C) 2016 Mindmaps Research Ltd
*
* MindmapsDB 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.
*
* MindmapsDB 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 MindmapsDB. If not, see .
*/
package io.mindmaps.graql.internal.reasoner.predicate;
import com.google.common.collect.Sets;
import io.mindmaps.MindmapsGraph;
import io.mindmaps.concept.Rule;
import io.mindmaps.util.ErrorMessage;
import io.mindmaps.concept.RoleType;
import io.mindmaps.concept.Type;
import io.mindmaps.graql.*;
import io.mindmaps.graql.admin.PatternAdmin;
import io.mindmaps.graql.admin.ValuePredicateAdmin;
import io.mindmaps.graql.admin.VarAdmin;
import io.mindmaps.graql.internal.pattern.Patterns;
import io.mindmaps.graql.internal.reasoner.query.Query;
import java.util.stream.Collectors;
import javafx.util.Pair;
import java.util.*;
public abstract class AtomBase implements Atomic{
protected String varName;
protected Type type = null;
protected final String typeId;
protected final PatternAdmin atomPattern;
private Query parent = null;
public AtomBase() {
this.varName = null;
this.typeId = null;
this.atomPattern = null;
}
public AtomBase(VarAdmin pattern) {
this.atomPattern = pattern;
Pair varData = extractDataFromVar(atomPattern.asVar());
this.varName = varData.getKey();
this.typeId = varData.getValue();
}
public AtomBase(VarAdmin pattern, Query par) {
this(pattern);
this.parent = par;
}
public AtomBase(AtomBase a) {
if (a.getParentQuery() != null)
this.parent = a.getParentQuery();
this.atomPattern = Patterns.mergeVars(Sets.newHashSet(a.atomPattern.asVar()));
Pair varData = extractDataFromVar(atomPattern.asVar());
varName = varData.getKey();
typeId = varData.getValue();
}
public abstract Atomic clone();
private Pair extractDataFromVar(VarAdmin var) {
String vTypeId;
String vName = var.getName();
Map> resourceMap = var.getResourcePredicates();
if (resourceMap.size() != 0) {
if (resourceMap.size() != 1)
throw new IllegalArgumentException(ErrorMessage.MULTIPLE_RESOURCES.getMessage(var.toString()));
Map.Entry> entry = resourceMap.entrySet().iterator().next();
vTypeId = entry.getKey().getId().orElse("");
}
else
vTypeId = var.getType().flatMap(VarAdmin::getId).orElse("");
return new Pair<>(vName, vTypeId);
}
@Override
public String toString(){ return atomPattern.toString(); }
@Override
public boolean isRuleResolvable() {
Type type = getParentQuery().getGraph().orElse(null).getType(getTypeId());
return type != null && !type.getRulesOfConclusion().isEmpty();
}
@Override
public boolean isRecursive(){
if (isResource()) return false;
boolean atomRecursive = false;
String typeId = getTypeId();
if (typeId.isEmpty()) return false;
Type type = getParentQuery().getGraph().orElse(null).getType(typeId);
Collection presentInConclusion = type.getRulesOfConclusion();
Collection presentInHypothesis = type.getRulesOfHypothesis();
for(Rule rule : presentInConclusion)
atomRecursive |= presentInHypothesis.contains(rule);
return atomRecursive;
}
@Override
public boolean containsVar(String name){ return getVarNames().contains(name);}
@Override
public PatternAdmin getPattern(){ return atomPattern;}
@Override
public MatchQuery getMatchQuery(MindmapsGraph graph) {
QueryBuilder qb = Graql.withGraph(graph);
MatchQuery matchQuery = qb.match(getPattern());
//add substitutions
Map varSubMap = getVarSubMap();
Set selectVars = getVarNames();
varSubMap.forEach( (var, sub) -> {
Set patterns = new HashSet<>();
patterns.add(sub.getPattern());
matchQuery.admin().getPattern().getPatterns().add(Patterns.conjunction(patterns));
});
return matchQuery.admin().select(selectVars);
}
@Override
public Query getParentQuery(){
if(parent == null)
throw new IllegalStateException(ErrorMessage.PARENT_MISSING.getMessage(this.toString()));
return parent;
}
@Override
public void setParentQuery(Query q){ parent = q;}
private void setVarName(String var){
varName = var;
atomPattern.asVar().setName(var);
}
@Override
public void unify(String from, String to) {
String var = getVarName();
if (var.equals(from)) {
setVarName(to);
} else if (var.equals(to)) {
setVarName("captured->" + var);
}
}
@Override
public void unify(Map unifiers){
String var = getVarName();
if (unifiers.containsKey(var)) {
setVarName(unifiers.get(var));
}
else if (unifiers.containsValue(var)) {
setVarName("captured->" + var);
}
}
@Override
public String getVarName(){ return varName;}
@Override
public Set getVarNames(){
return Sets.newHashSet(varName);
}
@Override
public Type getType(){
if (type == null)
type = getParentQuery().getGraph().orElse(null).getType(typeId);
return type;
}
@Override
public String getTypeId(){ return typeId;}
@Override
public String getVal(){ return null;}
@Override
public Map getUnifiers(Atomic parentAtom) {
Set varsToAllocate = parentAtom.getVarNames();
Set childBVs = getVarNames();
Map unifiers = new HashMap<>();
Map> childMap = getVarTypeRoleMap();
Map> parentMap = parentAtom.getRoleVarTypeMap();
//try based on substitutions
Query parentQuery = parentAtom.getParentQuery();
getParentQuery().getSubstitutions().stream().filter(sub -> containsVar(sub.getVarName())).forEach(sub -> {
String chVar = sub.getVarName();
String id = sub.getVal();
Set parentSubs = parentQuery.getSubstitutions().stream()
.filter(s -> s.getVal().equals(id)).collect(Collectors.toSet());
String pVar = parentSubs.isEmpty()? "" : parentSubs.iterator().next().getVarName();
if (!pVar.isEmpty()) {
if (!chVar.equals(pVar)) unifiers.put(chVar, pVar);
childBVs.remove(chVar);
varsToAllocate.remove(pVar);
}
});
//try based on roles
for (String chVar : childBVs) {
RoleType role = childMap.containsKey(chVar) ? childMap.get(chVar).getValue() : null;
String pVar = role != null && parentMap.containsKey(role) ? parentMap.get(role).getKey() : "";
if (pVar.isEmpty())
pVar = varsToAllocate.iterator().next();
if (!chVar.equals(pVar)) unifiers.put(chVar, pVar);
varsToAllocate.remove(pVar);
}
return unifiers;
}
@Override
public Set getSubstitutions() {
return getParentQuery().getAtoms().stream()
.filter(Atomic::isSubstitution)
.filter(atom -> containsVar(atom.getVarName()))
.collect(Collectors.toSet());
}
@Override
public Set getTypeConstraints(){
return getParentQuery().getTypeConstraints().stream()
.filter(atom -> containsVar(atom.getVarName()))
.collect(Collectors.toSet());
}
@Override
public Set getValuePredicates(){
return getParentQuery().getAtoms().stream()
.filter(Atomic::isValuePredicate)
.filter(atom -> containsVar(atom.getVarName()))
.collect(Collectors.toSet());
}
@Override
public Map getVarSubMap() {
Map map = new HashMap<>();
getSubstitutions().forEach( sub -> {
String var = sub.getVarName();
map.put(var, sub);
});
return map;
}
@Override
public Map getRoleConceptIdMap(){
Map roleConceptMap = new HashMap<>();
Map varSubMap = getVarSubMap();
Map> roleVarMap = getRoleVarTypeMap();
roleVarMap.forEach( (role, varTypePair) -> {
String var = varTypePair.getKey();
roleConceptMap.put(role, varSubMap.containsKey(var) ? varSubMap.get(var).getVal() : "");
});
return roleConceptMap;
}
public Map> getVarTypeRoleMap() {
Map> roleVarTypeMap = new HashMap<>();
if (getParentQuery() == null) return roleVarTypeMap;
Set vars = getVarNames();
Map varTypeMap = getParentQuery().getVarTypeMap();
vars.forEach(var -> {
Type type = varTypeMap.get(var);
roleVarTypeMap.put(var, new Pair<>(type, null));
});
return roleVarTypeMap;
}
public Map> getRoleVarTypeMap() { return new HashMap<>();}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy