<commit_before>/*
 * Copyright 2002-2015 The Jamocha Team
 * 
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 * 
 * http://www.jamocha.org/
 * 
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
package org.jamocha.dn.compiler.ecblocks.assignmentgraph;

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.jamocha.dn.ConstructCache;
import org.jamocha.dn.compiler.ecblocks.*;
import org.jamocha.dn.compiler.ecblocks.assignmentgraph.node.binding.*;
import org.jamocha.dn.compiler.ecblocks.assignmentgraph.node.occurrence.ECOccurrenceNode;
import org.jamocha.dn.compiler.ecblocks.assignmentgraph.node.occurrence.FilterOccurrenceNode;
import org.jamocha.dn.compiler.ecblocks.assignmentgraph.node.occurrence.FunctionalExpressionOccurrenceNode;
import org.jamocha.dn.compiler.ecblocks.assignmentgraph.node.occurrence.ImplicitOccurrenceNode;
import org.jamocha.dn.memory.Template;
import org.jamocha.filter.ECFilter;
import org.jamocha.filter.ECFilterSet;
import org.jamocha.filter.ECFilterSetVisitor;
import org.jamocha.function.fwa.*;
import org.jamocha.function.fwatransformer.FWAECLeafToTypeLeafTranslator;
import org.jamocha.languages.common.RuleCondition.EquivalenceClass;
import org.jamocha.languages.common.SingleFactVariable;

import java.util.*;
import java.util.function.BiFunction;

import static org.jamocha.util.Lambdas.newIdentityHashSet;

/**
 * @author <NAME> <<EMAIL>>
 */
@Getter
public class AssignmentGraph {
	// the actual graph
	final UnrestrictedGraph graph = new UnrestrictedGraph();
	// cached bindings for the corresponding equivalence classes
	final IdentityHashMap<EquivalenceClass, List<BindingNode>> ecToElements = new IdentityHashMap<>();

	// needed for block consistency checks:
	// lookup map from filter/functional expression to corresponding occurrence nodes (existential stuff marked)
	// lookup map from fact variable (template instance) to corresponding fact/slot binding nodes

	// explicit filter instance node groups:
	// lookup map from abstract typed FWA to rule to the set of matching filters
	final HashMap<ExistentialInfo.FunctionWithExistentialInfo, Set<ECFilter>> predicateToFilters = new HashMap<>();
	final IdentityHashMap<ECFilter, TreeMap<Integer, FilterOccurrenceNode>> filterToOccurrenceNodes =
			new IdentityHashMap<>();

	// lookup from template to template instances to the corresponding binding nodes
	final IdentityHashMap<Template, Set<SingleFactVariable>> templateToInstances = new IdentityHashMap<>();
	final IdentityHashMap<SingleFactVariable, Set<SlotOrFactBindingNode>> templateInstanceToBindingNodes =
			new IdentityHashMap<>();

	// direct bindings (can't use Leaf directly since constants are contained, too)
	// lookup map from abstract 'templated' FWA to set of matching binding nodes
	final HashMap<FunctionWithArguments<TemplateSlotLeaf>, Set<BindingNode>> directBindingNodes = new HashMap<>();

	final HashMap<FunctionWithArguments<TypeLeaf>, Set<FunctionalExpressionBindingNode>>
			functionalExpressionToBindings = new HashMap<>();
	final IdentityHashMap<FunctionalExpressionBindingNode, TreeMap<Integer, FunctionalExpressionOccurrenceNode>>
			functionalExpressionBindingToOccurrenceNodes = new IdentityHashMap<>();


	// lookup map to get the implicit occurrence node for a binding node (other direction is stored within implicit
	// occurrence node)
	final IdentityHashMap<BindingNode, ImplicitOccurrenceNode> bindingNodeToImplicitOccurrence =
			new IdentityHashMap<>();


	@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
	@Getter
	public static class Edge {
		final ECOccurrenceNode source;
		final BindingNode target;
	}

	public abstract class Graph {
		final IdentityHashMap<ECOccurrenceNode, Set<Edge>> outgoingEdges = new IdentityHashMap<>();
		final IdentityHashMap<BindingNode, Set<Edge>> incomingEdges = new IdentityHashMap<>();
		final Set<Edge> edgeSet = Sets.newIdentityHashSet();

		public Set<Edge> edgeSet() {
			return ImmutableSet.copyOf(this.edgeSet);
		}

		public boolean containsEdge(final Edge edge) {
			return this.edgeSet.contains(edge);
		}

		public boolean containsEdge(final ECOccurrenceNode source, final BindingNode target) {
			return null != getEdge(source, target);
		}

		public Edge getEdge(final ECOccurrenceNode source, final BindingNode target) {
			return this.outgoingEdges.get(source).stream().filter(e -> e.getTarget() == target).findAny().orElse(null);
		}

		protected Set<Edge> getIncomingEdges(final BindingNode target) {
			final Set<Edge> edges = this.incomingEdges.get(target);
			return null != edges ? edges : ImmutableSet.of();
		}

		public Set<Edge> incomingEdgesOf(final BindingNode target) {
			return ImmutableSet.copyOf(getIncomingEdges(target));
		}

		public int inDegreeOf(final BindingNode target) {
			return getIncomingEdges(target).size();
		}

		protected Set<Edge> getOutgoingEdges(final ECOccurrenceNode source) {
			final Set<Edge> edges = this.outgoingEdges.get(source);
			return null != edges ? edges : ImmutableSet.of();
		}

		public Set<Edge> outgoingEdgesOf(final ECOccurrenceNode source) {
			return ImmutableSet.copyOf(getOutgoingEdges(source));
		}

		public int outDegreeOf(final ECOccurrenceNode source) {
			return getOutgoingEdges(source).size();
		}<commit_msg>AssignmentGraph: added getters for node sets to graphs<commit_after>/*
 * Copyright 2002-2015 The Jamocha Team
 * 
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 * 
 * http://www.jamocha.org/
 * 
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
package org.jamocha.dn.compiler.ecblocks.assignmentgraph;

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.jamocha.dn.ConstructCache;
import org.jamocha.dn.compiler.ecblocks.*;
import org.jamocha.dn.compiler.ecblocks.assignmentgraph.node.binding.*;
import org.jamocha.dn.compiler.ecblocks.assignmentgraph.node.occurrence.ECOccurrenceNode;
import org.jamocha.dn.compiler.ecblocks.assignmentgraph.node.occurrence.FilterOccurrenceNode;
import org.jamocha.dn.compiler.ecblocks.assignmentgraph.node.occurrence.FunctionalExpressionOccurrenceNode;
import org.jamocha.dn.compiler.ecblocks.assignmentgraph.node.occurrence.ImplicitOccurrenceNode;
import org.jamocha.dn.memory.Template;
import org.jamocha.filter.ECFilter;
import org.jamocha.filter.ECFilterSet;
import org.jamocha.filter.ECFilterSetVisitor;
import org.jamocha.function.fwa.*;
import org.jamocha.function.fwatransformer.FWAECLeafToTypeLeafTranslator;
import org.jamocha.languages.common.RuleCondition.EquivalenceClass;
import org.jamocha.languages.common.SingleFactVariable;

import java.util.*;
import java.util.function.BiFunction;

import static org.jamocha.util.Lambdas.newIdentityHashSet;

/**
 * @author <NAME> <<EMAIL>>
 */
@Getter
public class AssignmentGraph {
	// the actual graph
	final UnrestrictedGraph graph = new UnrestrictedGraph();
	// cached bindings for the corresponding equivalence classes
	final IdentityHashMap<EquivalenceClass, List<BindingNode>> ecToElements = new IdentityHashMap<>();

	// needed for block consistency checks:
	// lookup map from filter/functional expression to corresponding occurrence nodes (existential stuff marked)
	// lookup map from fact variable (template instance) to corresponding fact/slot binding nodes

	// explicit filter instance node groups:
	// lookup map from abstract typed FWA to rule to the set of matching filters
	final HashMap<ExistentialInfo.FunctionWithExistentialInfo, Set<ECFilter>> predicateToFilters = new HashMap<>();
	final IdentityHashMap<ECFilter, TreeMap<Integer, FilterOccurrenceNode>> filterToOccurrenceNodes =
			new IdentityHashMap<>();

	// lookup from template to template instances to the corresponding binding nodes
	final IdentityHashMap<Template, Set<SingleFactVariable>> templateToInstances = new IdentityHashMap<>();
	final IdentityHashMap<SingleFactVariable, Set<SlotOrFactBindingNode>> templateInstanceToBindingNodes =
			new IdentityHashMap<>();

	// direct bindings (can't use Leaf directly since constants are contained, too)
	// lookup map from abstract 'templated' FWA to set of matching binding nodes
	final HashMap<FunctionWithArguments<TemplateSlotLeaf>, Set<BindingNode>> directBindingNodes = new HashMap<>();

	final HashMap<FunctionWithArguments<TypeLeaf>, Set<FunctionalExpressionBindingNode>>
			functionalExpressionToBindings = new HashMap<>();
	final IdentityHashMap<FunctionalExpressionBindingNode, TreeMap<Integer, FunctionalExpressionOccurrenceNode>>
			functionalExpressionBindingToOccurrenceNodes = new IdentityHashMap<>();


	// lookup map to get the implicit occurrence node for a binding node (other direction is stored within implicit
	// occurrence node)
	final IdentityHashMap<BindingNode, ImplicitOccurrenceNode> bindingNodeToImplicitOccurrence =
			new IdentityHashMap<>();


	@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
	@Getter
	public static class Edge {
		final ECOccurrenceNode source;
		final BindingNode target;
	}

	public abstract class Graph {
		final IdentityHashMap<ECOccurrenceNode, Set<Edge>> outgoingEdges = new IdentityHashMap<>();
		final IdentityHashMap<BindingNode, Set<Edge>> incomingEdges = new IdentityHashMap<>();
		final Set<Edge> edgeSet = Sets.newIdentityHashSet();

		public Set<Edge> edgeSet() {
			return ImmutableSet.copyOf(this.edgeSet);
		}

		public boolean containsEdge(final Edge edge) {
			return this.edgeSet.contains(edge);
		}

		public boolean containsEdge(final ECOccurrenceNode source, final BindingNode target) {
			return null != getEdge(source, target);
		}

		public Edge getEdge(final ECOccurrenceNode source, final BindingNode target) {
			return this.outgoingEdges.get(source).stream().filter(e -> e.getTarget() == target).findAny().orElse(null);
		}

		protected Set<Edge> getIncomingEdges(final BindingNode target) {
			final Set<Edge> edges = this.incomingEdges.get(target);
			return null != edges ? edges : ImmutableSet.of();
		}

		public Set<Edge> incomingEdgesOf(final BindingNode target) {
			return ImmutableSet.copyOf(getIncomingEdges(target));
		}

		public int inDegreeOf(final BindingNode target) {
			return getIncomingEdges(target).size();
		}

		protected Set<Edge> getOutgoingEdges(final ECOccurrenceNode source) {
			final Set<Edge> edges = this.outgoingEdges.get(source);
			return null != edges ? edges : ImmutableSet.of();
		}

		public Set<Edge> outgoingEdgesOf(final ECOccurrenceNode source) {
			return ImmutableSet.copyOf(getOutgoingEdges(source));
		}

		public int outDegreeOf(final ECOccurrenceNode source) {
			return getOutgoingEdges(source).size();
		}

		public Set<ECOccurrenceNode> getECOccurrenceNodes() {
			return this.outgoingEdges.keySet();
		}

		public Set<BindingNode> getBindingNodes() {
			return this.incomingEdges.keySet();
		}
{'fraction_non_alphanumeric': 0.09087817733571368, 'fraction_numerical': 0.0017002465357476835, 'mean_word_length': 5.729977116704806, 'pattern_counts': {'":': 0, '<': 95, '<?xml version=': 0, '>': 97, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3958528', 'n_tokens_mistral': 3533, 'n_tokens_neox': 3230, 'n_words': 893}