/// <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].PatternType == TriplePatternType.Match || gp.TriplePatterns[p].PatternType == TriplePatternType.BindAssignment || gp.TriplePatterns[p].PatternType == TriplePatternType.LetAssignment) { 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); }