diff --git a/arebac-core/src/main/java/io/github/danthe1st/arebac/gpeval/GPEval.java b/arebac-core/src/main/java/io/github/danthe1st/arebac/gpeval/GPEval.java index 06c9616..bbdeeb7 100644 --- a/arebac-core/src/main/java/io/github/danthe1st/arebac/gpeval/GPEval.java +++ b/arebac-core/src/main/java/io/github/danthe1st/arebac/gpeval/GPEval.java @@ -163,7 +163,7 @@ private Set run(Map> incomingConflicts) {// returns Set currentNodeCandidates = candidates.get(currentNode); Set exclusionConstraints = mutualExclusionConstraints.get(currentNode); if(exclusionConstraints != null){ - filterMutualExclusionConstraints(currentNode, currentNodeCandidates, exclusionConstraints, Objects.requireNonNullElse(incomingConflicts.get(currentNode), new HashSet<>())); + filterMutualExclusionConstraints(currentNodeCandidates, exclusionConstraints, Objects.requireNonNullElse(incomingConflicts.get(currentNode), new HashSet<>())); } for(N candidateNode : currentNodeCandidates){ Map> newCandidates = candidates @@ -171,8 +171,6 @@ private Set run(Map> incomingConflicts) {// returns .stream() .filter(entry -> !entry.getKey().equals(currentNode)) .collect(Collectors.toMap(Map.Entry::getKey, entry -> new HashSet<>(entry.getValue()))); -// Map> newCandidates = new HashMap<>(candidates); -// newCandidates.remove(currentNode); Map newAssignments = new HashMap<>(assignments); newAssignments.put(currentNode, candidateNode); Map> newIncomingConflicts = incomingConflicts// deep copy @@ -241,14 +239,14 @@ private GPNode pickNextNode() { return candidate; } - private void filterMutualExclusionConstraints(GPNode currentNode, Set candidatesForNode, Set exclusionConstraints, Set incomingConflicts) { + private void filterMutualExclusionConstraints(Set candidatesForNode, Set exclusionConstraints, Set incomingConflicts) { for(Iterator it = candidatesForNode.iterator(); it.hasNext();){ - filterMutualExclusionConstraintWithSpecificCandidate(currentNode, exclusionConstraints, incomingConflicts, it); + filterMutualExclusionConstraintWithSpecificCandidate(exclusionConstraints, incomingConflicts, it); } } - private void filterMutualExclusionConstraintWithSpecificCandidate(GPNode currentNode, Set exclusionConstraints, Set incomingConflicts, Iterator it) { + private void filterMutualExclusionConstraintWithSpecificCandidate(Set exclusionConstraints, Set incomingConflicts, Iterator it) { N graphCandidate = it.next(); for(GPNode exclusionConstraint : exclusionConstraints){ if(graphCandidate.equals(assignments.get(exclusionConstraint))){ @@ -277,25 +275,12 @@ private boolean forwardChecking(GPNode currentNode, Map> inc otherNodeCandidates = new HashSet<>(neighbors); candidates.put(otherNode, otherNodeCandidates); }else{ - otherNodeCandidates.addAll(neighbors); + otherNodeCandidates.retainAll(neighbors); } if(otherNodeCandidates.isEmpty()){ outgoingConflicts.add(otherNode); return false; } - }else{ - // not in the paper - // It is possible that two candidates for different nodes in the graph pattern exclude each other via a necessary edge - // In that case, one can be assigned without the other being removed - // This also needs to be tested - - N currentNodeInGraph = Objects.requireNonNull(assignments.get(currentNode)); - List conflictingNodes = checkHasNecessaryEdgesFindConflict(currentNode, otherNode, currentNodeInGraph); - if(!conflictingNodes.isEmpty()){ - incomingConflicts.computeIfAbsent(currentNode, n -> new HashSet<>()).addAll(conflictingNodes); -// outgoingConflicts.addAll(conflictingNodes); - return false; - } } } @@ -328,47 +313,7 @@ private boolean satisfiesRequirements(RelevantEdge currentEdge, E graphEdge, N n return currentEdge.edge.edgeType().equals(graphEdge.edgeType()) && currentEdge.otherNode.nodeType().equals(neighbor.nodeType()) && checkAttributeRequirements(pattern.edgeRequirements().get(currentEdge.edge), graphEdge) && - checkAttributeRequirements(pattern.nodeRequirements().get(currentEdge.otherNode), neighbor) -// && checkHasNecessaryEdges(currentEdge.otherNode, null, neighbor)//the paper isn't exactly clear whether this is necessary - ; - } - -// private boolean checkHasNecessaryEdges(GPNode node, GPNode otherNodeFilter, N graphNode) { -// return checkHasNecessaryEdgesFindConflict(node, otherNodeFilter, graphNode).isEmpty(); -// } - - private List checkHasNecessaryEdgesFindConflict(GPNode node, GPNode otherNodeFilter, N graphNode) { - List conflictAccumulator = new ArrayList<>(); - checkNecessaryEdgesOneDirection( - graph.findOutgoingEdges(graphNode), pattern.graph().outgoingEdges().get(node), - AttributedGraphEdge::target, GPEdge::target, - otherNodeFilter, conflictAccumulator - ); - - checkNecessaryEdgesOneDirection( - graph.findIncomingEdges(graphNode), pattern.graph().incomingEdges().get(node), - AttributedGraphEdge::source, GPEdge::source, - otherNodeFilter, conflictAccumulator - ); - return conflictAccumulator; - } - - private void checkNecessaryEdgesOneDirection(Collection neighboringEdges, Collection patternEdges, Function edgeOtherNodeFinder, Function gpOtherNodeFinder, GPNode otherNodeFilter, List conflictAccumulator) { - for(GPEdge edge : Objects.requireNonNullElse(patternEdges, List.of())){ - boolean isSatisfied = false; - GPNode otherNode = gpOtherNodeFinder.apply(edge); - if(otherNodeFilter == null || otherNode.equals(otherNodeFilter)){ - N otherGraphNode = assignments.get(otherNode); - for(E graphEdge : neighboringEdges){ - if(edge.edgeType().equals(graphEdge.edgeType()) && (otherGraphNode == null || edgeOtherNodeFinder.apply(graphEdge).equals(otherGraphNode))){ - isSatisfied = true; - } - } - if(!isSatisfied){ - conflictAccumulator.add(otherNode); - } - } - } + checkAttributeRequirements(pattern.nodeRequirements().get(currentEdge.otherNode), neighbor); } private boolean checkAttributeRequirements(List requirements, AttributeAware graphElement) {