/// <summary> /// Tries to place filters at the earliest point possible i.e. the first point after which all required variables have occurred /// </summary> /// <param name="gp">Graph Pattern</param> /// <param name="filter">Filter to place</param> /// <returns></returns> private bool TryPlaceFilter(GraphPattern gp, ISparqlFilter filter) { //Firstly we need to find out what variables are needed in the Filter List<String> variablesNeeded = filter.Variables.Distinct().ToList(); //Then we need to move through the Triple Patterns and find the first place at which all the //Variables used in the Filter have been used in ordinary Triple Patterns List<String> variablesUsed = new List<string>(); for (int p = 0; p < gp.TriplePatterns.Count; p++) { if (gp.TriplePatterns[p] is TriplePattern || gp.TriplePatterns[p] is IAssignmentPattern) { foreach (String var in gp.TriplePatterns[p].Variables) { if (!variablesUsed.Contains(var)) variablesUsed.Add(var); } //Have all the Variables we need now been used in a Pattern? if (variablesNeeded.All(v => variablesUsed.Contains(v))) { //We can place this Filter after the Pattern we were just looking at gp.InsertFilter(filter, p + 1); return true; } } } //If we reach here then this means that all the Variables used in the Filter did not occur //in the Triple Patterns which means they likely occur in child graph patterns (or the query //is malformed). In this case we cannot place the Filter and it has to be applied post-commit //rather than during Triple Pattern execution return false; }