private static void MakeLeanMSG2(Store msg, ResSet predicates, StatementSink removed, ResSet nodesremoved, BNode startingnode) { // Find every pair of two distinct outgoing edges from startingnode // with the same predicate, targeting entities only. MultiMap edges = new MultiMap(); foreach (Statement s in msg.Select(new Statement(startingnode, null, null))) { if (s.Object is Entity) { edges.Put(new Edge(true, startingnode, s.Predicate, null), s.Object); } } foreach (Statement s in msg.Select(new Statement(null, null, startingnode))) { edges.Put(new Edge(false, startingnode, s.Predicate, null), s.Subject); } foreach (Edge e in edges.Keys) { // Make sure we have a distinct set of targets. ResSet targets_set = new ResSet(); foreach (Entity r in edges.Get(e)) { targets_set.Add(r); } if (targets_set.Count == 1) { continue; } IList targets = targets_set.ToEntityArray(); // Take every pair of targets, provided // one is a bnode that can be a variable. for (int i = 0; i < targets.Count; i++) { if (!(targets[i] is BNode) || predicates.Contains((BNode)targets[i])) { continue; } if (nodesremoved.Contains((BNode)targets[i])) { continue; } for (int j = 0; j < targets.Count; j++) { if (i == j) { continue; } // Create a new synchronous-path object. SyncPath p = new SyncPath(); p.FixedNodes.Add((Resource)targets[j]); p.FrontierVariables.Add((Resource)targets[i]); p.Mapping[targets[i]] = targets[j]; p.Path[new Edge(e.Direction, e.Start, e.Predicate, (BNode)targets[i])] = p.Path; if (MakeLeanMSG3(msg, predicates, removed, nodesremoved, p)) { break; // the target was removed } } } } }