Exemplo n.º 1
0
        public void SparqlOptimiserQueryFilterPlacement5()
        {
            // given
            var query = new SparqlQuery {
                QueryType = SparqlQueryType.Select
            };

            query.AddVariable(new SparqlVariable("s", true));
            query.RootGraphPattern = new GraphPattern();
            var subj          = new VariablePattern("s");
            var rdfType       = new NodeMatchPattern(new UriNode(null, new Uri(RdfSpecsHelper.RdfType)));
            var type          = new VariablePattern("type");
            var triplePattern = new TriplePattern(subj, rdfType, type);

            query.RootGraphPattern.AddTriplePattern(triplePattern);
            query.RootGraphPattern.AddFilter(new UnaryExpressionFilter(new InFunction(new VariableTerm("type"), new[]
            {
                new ConstantTerm(new UriNode(null, new Uri("http://example.com/Type1"))),
                new ConstantTerm(new UriNode(null, new Uri("http://example.com/Type2"))),
                new ConstantTerm(new UriNode(null, new Uri("http://example.com/Type3")))
            })));

            // when
            var algebra = query.ToAlgebra();

            // then
            Assert.IsType <Select>(algebra);
            Assert.IsType <Filter>(((Select)algebra).InnerAlgebra);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Formats a Pattern Item in nicely formatted SPARQL syntax
        /// </summary>
        /// <param name="item">Pattern Item</param>
        /// <param name="segment">Triple Pattern Segment</param>
        /// <returns></returns>
        public virtual String Format(PatternItem item, TripleSegment?segment)
        {
            if (item is VariablePattern)
            {
                return(item.ToString());
            }
            else if (item is NodeMatchPattern)
            {
                NodeMatchPattern match = (NodeMatchPattern)item;
                return(this.Format(match.Node, segment));
            }
            else if (item is FixedBlankNodePattern)
            {
                if (segment != null)
                {
                    if (segment == TripleSegment.Predicate)
                    {
                        throw new RdfOutputException("Cannot format a Fixed Blank Node Pattern Item as the Predicate of a Triple Pattern as Blank Nodes are not permitted as Predicates");
                    }
                }

                return(item.ToString());
            }
            else if (item is BlankNodePattern)
            {
                return(item.ToString());
            }
            else
            {
                throw new RdfOutputException("Unable to Format an unknown PatternItem implementation as a String");
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Used to extract the patterns that make up a <see cref="FullTextPattern">FullTextPattern</see>
        /// </summary>
        /// <param name="patterns">Triple Patterns</param>
        /// <returns></returns>
        internal static List <FullTextPattern> ExtractPatterns(IEnumerable <ITriplePattern> patterns)
        {
            //Do a first pass which simply looks to find any pf:textMatch properties
            Dictionary <PatternItem, List <TriplePattern> > ftPatterns = new Dictionary <PatternItem, List <TriplePattern> >();
            List <TriplePattern> ps = patterns.OfType <TriplePattern>().ToList();

            if (ps.Count == 0)
            {
                return(new List <FullTextPattern>());
            }
            foreach (TriplePattern tp in ps)
            {
                NodeMatchPattern predItem = tp.Predicate as NodeMatchPattern;
                if (predItem == null)
                {
                    continue;
                }
                IUriNode predNode = predItem.Node as IUriNode;
                if (predNode == null)
                {
                    continue;
                }
                if (predNode.Uri.ToString().Equals(FullTextMatchPredicateUri))
                {
                    ftPatterns.Add(tp.Subject, new List <TriplePattern>());
                    ftPatterns[tp.Subject].Add(tp);
                }
            }
            //Remove any Patterns we found from the original patterns
            foreach (List <TriplePattern> fps in ftPatterns.Values)
            {
                fps.ForEach(tp => ps.Remove(tp));
            }

            if (ftPatterns.Count == 0)
            {
                return(new List <FullTextPattern>());
            }

            //Now for each pf:textMatch property we found do a further search to see if we are using
            //the (?match ?score) form or the {'text' threshold limit) form rather than the simple ?match form
            foreach (PatternItem key in ftPatterns.Keys)
            {
                if (key.VariableName != null && key.VariableName.StartsWith("_:"))
                {
                    ExtractRelatedPatterns(key, key, ps, ftPatterns);
                }
                PatternItem searchKey = ftPatterns[key].First().Object;
                if (searchKey.VariableName != null && searchKey.VariableName.StartsWith("_:"))
                {
                    ExtractRelatedPatterns(key, searchKey, ps, ftPatterns);
                }
            }

            return((from key in ftPatterns.Keys
                    select new FullTextPattern(ftPatterns[key])).ToList());
        }
Exemplo n.º 4
0
 /// <summary>
 /// Creates a Triple Pattern
 /// </summary>
 /// <param name="subj">Subject</param>
 /// <param name="path">Property Path</param>
 /// <param name="obj">Object</param>
 /// <returns></returns>
 public ITriplePattern GetTriplePattern(PatternItem subj, ISparqlPath path, PatternItem obj)
 {
     if (path is Property)
     {
         NodeMatchPattern nodeMatch = new NodeMatchPattern(((Property)path).Predicate);
         return(new TriplePattern(subj, nodeMatch, obj));
     }
     else
     {
         return(new PropertyPathPattern(subj, path, obj));
     }
 }
Exemplo n.º 5
0
        /// <summary>
        /// Used to help extract the patterns that make up a property function pattern.
        /// </summary>
        /// <param name="key">Key.</param>
        /// <param name="subj">Subject.</param>
        /// <param name="ps">Patterns.</param>
        /// <param name="funcInfo">Function Information.</param>
        /// <param name="argList">Argument List to add discovered arguments to.</param>
        static void ExtractRelatedPatterns(PatternItem key, PatternItem subj, List <IMatchTriplePattern> ps, Dictionary <PatternItem, PropertyFunctionInfo> funcInfo, List <PatternItem> argList)
        {
            bool        recurse = true, any = false, argSeen = false;
            PatternItem nextSubj = subj;

            while (recurse)
            {
                any = false;
                foreach (IMatchTriplePattern tp in ps.ToList())
                {
                    if (tp.Subject.VariableName == nextSubj.VariableName)
                    {
                        NodeMatchPattern predItem = tp.Predicate as NodeMatchPattern;
                        if (predItem == null)
                        {
                            continue;
                        }
                        IUriNode predNode = predItem.Node as IUriNode;
                        if (predNode == null)
                        {
                            continue;
                        }
                        if (!argSeen && predNode.Uri.AbsoluteUri.Equals(RdfSpecsHelper.RdfListFirst))
                        {
                            funcInfo[key].Patterns.Add(tp);
                            argList.Add(tp.Object);
                            ps.Remove(tp);
                            any     = true;
                            argSeen = true;
                        }
                        else if (argSeen && predNode.Uri.AbsoluteUri.Equals(RdfSpecsHelper.RdfListRest))
                        {
                            funcInfo[key].Patterns.Add(tp);
                            ps.Remove(tp);
                            recurse  = tp.Object.VariableName != null;
                            nextSubj = tp.Object;
                            any      = true;
                            argSeen  = false;
                        }
                    }
                }
                if (!any)
                {
                    recurse = false;
                }

                if (nextSubj == null)
                {
                    throw new RdfQueryException("Failed to find expected rdf:rest property");
                }
            }
        }
Exemplo n.º 6
0
        /// <summary>
        /// Used to help extract the patterns that make up a <see cref="FullTextPattern">FullTextPattern</see>
        /// </summary>
        /// <param name="key">Key</param>
        /// <param name="subj">Subject</param>
        /// <param name="ps">Patterns</param>
        /// <param name="ftPatterns">Discovered Full Text Patterns</param>
        internal static void ExtractRelatedPatterns(PatternItem key, PatternItem subj, List <TriplePattern> ps, Dictionary <PatternItem, List <TriplePattern> > ftPatterns)
        {
            bool        recurse  = true;
            PatternItem nextSubj = null;

            foreach (TriplePattern tp in ps)
            {
                if (tp.Subject.VariableName == subj.VariableName)
                {
                    NodeMatchPattern predItem = tp.Predicate as NodeMatchPattern;
                    if (predItem == null)
                    {
                        continue;
                    }
                    IUriNode predNode = predItem.Node as IUriNode;
                    if (predNode == null)
                    {
                        continue;
                    }
                    if (predNode.Uri.ToString().Equals(RdfSpecsHelper.RdfListFirst))
                    {
                        ftPatterns[key].Add(tp);
                    }
                    else if (predNode.Uri.ToString().Equals(RdfSpecsHelper.RdfListRest))
                    {
                        ftPatterns[key].Add(tp);
                        recurse  = tp.Object.VariableName != null;
                        nextSubj = tp.Object;
                    }
                }
            }

            ftPatterns[key].ForEach(tp => ps.Remove(tp));

            if (nextSubj == null)
            {
                throw new RdfQueryException("Failed to find expected rdf:rest property");
            }
            if (recurse)
            {
                ExtractRelatedPatterns(key, nextSubj, ps, ftPatterns);
            }
        }
Exemplo n.º 7
0
        private ISparqlAlgebra GetAlgebraUntransformed(ISparqlPath path, INode start, INode end)
        {
            PatternItem x, y;

            if (start == null)
            {
                x = new VariablePattern("?x");
            }
            else
            {
                x = new NodeMatchPattern(start);
            }
            if (end == null)
            {
                y = new VariablePattern("?y");
            }
            else
            {
                y = new NodeMatchPattern(end);
            }
            return(new Bgp(new PropertyPathPattern(x, path, y)));
        }
Exemplo n.º 8
0
        private ISparqlAlgebra GetAlgebra(ISparqlPath path, INode start, INode end)
        {
            PatternItem x, y;

            if (start == null)
            {
                x = new VariablePattern("?x");
            }
            else
            {
                x = new NodeMatchPattern(start);
            }
            if (end == null)
            {
                y = new VariablePattern("?y");
            }
            else
            {
                y = new NodeMatchPattern(end);
            }
            PathTransformContext context = new PathTransformContext(x, y);

            return(path.ToAlgebra(context));
        }
Exemplo n.º 9
0
        /// <summary>
        /// Optimises the algebra so that all Node terms are virtualised
        /// </summary>
        /// <param name="algebra">Algebra</param>
        /// <returns></returns>
        public ISparqlAlgebra Optimise(ISparqlAlgebra algebra)
        {
            if (algebra is IAbstractJoin)
            {
                return(((IAbstractJoin)algebra).Transform(this));
            }
            else if (algebra is IUnaryOperator)
            {
                return(((IUnaryOperator)algebra).Transform(this));
            }
            else if (algebra is IBgp)
            {
                IBgp current = (IBgp)algebra;
                if (current.PatternCount == 0)
                {
                    return(current);
                }
                else
                {
                    ISparqlAlgebra        result   = new Bgp();
                    List <ITriplePattern> patterns = new List <ITriplePattern>();
                    List <ITriplePattern> ps       = new List <ITriplePattern>(current.TriplePatterns.ToList());
                    TNodeID nullID = this._provider.NullID;

                    for (int i = 0; i < current.PatternCount; i++)
                    {
                        if (ps[i] is FilterPattern || ps[i] is BindPattern)
                        {
                            //First ensure that if we've found any other Triple Patterns up to this point
                            //we dump this into a BGP and join with the result so far
                            if (patterns.Count > 0)
                            {
                                result = Join.CreateJoin(result, new Bgp(patterns));
                                patterns.Clear();
                            }
                            if (ps[i] is FilterPattern)
                            {
                                result = new Filter(result, ((FilterPattern)ps[i]).Filter);
                            }
                            else
                            {
                                BindPattern bind = (BindPattern)ps[i];
                                result = new Extend(result, bind.AssignExpression, bind.VariableName);
                            }
                        }
                        else
                        {
                            //Convert Terms in the Pattern into Virtual Nodes
                            TriplePattern tp = (TriplePattern)ps[i];
                            PatternItem   subj, pred, obj;
                            if (tp.Subject is NodeMatchPattern)
                            {
                                TNodeID id = this._provider.GetID(((NodeMatchPattern)tp.Subject).Node);
                                if (id == null || id.Equals(nullID))
                                {
                                    result = new NullOperator(current.Variables);
                                    break;
                                }
                                else
                                {
                                    subj = new NodeMatchPattern(this.CreateVirtualNode(id, ((NodeMatchPattern)tp.Subject).Node));
                                }
                            }
                            else
                            {
                                subj = tp.Subject;
                            }
                            if (tp.Predicate is NodeMatchPattern)
                            {
                                TNodeID id = this._provider.GetID(((NodeMatchPattern)tp.Predicate).Node);
                                if (id == null || id.Equals(nullID))
                                {
                                    result = new NullOperator(current.Variables);
                                    break;
                                }
                                else
                                {
                                    pred = new NodeMatchPattern(this.CreateVirtualNode(id, ((NodeMatchPattern)tp.Predicate).Node));
                                }
                            }
                            else
                            {
                                pred = tp.Predicate;
                            }
                            if (tp.Object is NodeMatchPattern)
                            {
                                TNodeID id = this._provider.GetID(((NodeMatchPattern)tp.Object).Node);
                                if (id == null || id.Equals(nullID))
                                {
                                    result = new NullOperator(current.Variables);
                                    break;
                                }
                                else
                                {
                                    obj = new NodeMatchPattern(this.CreateVirtualNode(id, ((NodeMatchPattern)tp.Object).Node));
                                }
                            }
                            else
                            {
                                obj = tp.Object;
                            }
                            patterns.Add(new TriplePattern(subj, pred, obj));
                        }
                    }

                    if (result is NullOperator)
                    {
                        return(result);
                    }
                    else if (patterns.Count == current.PatternCount)
                    {
                        //If count of remaining patterns same as original pattern count there was no optimisation
                        //to do so return as is
                        return(current);
                    }
                    else if (patterns.Count > 0)
                    {
                        //If any patterns left at end join as a BGP with result so far
                        result = Join.CreateJoin(result, new Bgp(patterns));
                        return(result);
                    }
                    else
                    {
                        return(result);
                    }
                }
            }
            else if (algebra is ITerminalOperator)
            {
                return(algebra);
            }
            else
            {
                return(algebra);
            }
        }
Exemplo n.º 10
0
        /// <summary>
        /// Used to extract the patterns that make up property functions.
        /// </summary>
        /// <param name="patterns">Triple Patterns.</param>
        /// <param name="localFactories">Locally scoped factories.</param>
        /// <returns></returns>
        public static List <IPropertyFunctionPattern> ExtractPatterns(IEnumerable <ITriplePattern> patterns, IEnumerable <IPropertyFunctionFactory> localFactories)
        {
            // Do a first pass which simply looks to find any 'magic' properties
            Dictionary <PatternItem, PropertyFunctionInfo> funcInfo = new Dictionary <PatternItem, PropertyFunctionInfo>();
            List <IMatchTriplePattern> ps = patterns.OfType <IMatchTriplePattern>().ToList();

            if (ps.Count == 0)
            {
                return(new List <IPropertyFunctionPattern>());
            }
            foreach (IMatchTriplePattern tp in ps)
            {
                NodeMatchPattern predItem = tp.Predicate as NodeMatchPattern;
                if (predItem == null)
                {
                    continue;
                }
                IUriNode predNode = predItem.Node as IUriNode;
                if (predNode == null)
                {
                    continue;
                }
                if (PropertyFunctionFactory.IsPropertyFunction(predNode.Uri, localFactories))
                {
                    PropertyFunctionInfo info = new PropertyFunctionInfo(predNode.Uri);
                    info.Patterns.Add(tp);
                    funcInfo.Add(tp.Subject, info);
                }
            }
            // Remove any Patterns we found from the original patterns
            foreach (PropertyFunctionInfo info in funcInfo.Values)
            {
                info.Patterns.ForEach(tp => ps.Remove(tp));
            }

            if (funcInfo.Count == 0)
            {
                return(new List <IPropertyFunctionPattern>());
            }

            // Now for each 'magic' property we found do a further search to see if we are using
            // the collection forms to provide extended arguments
            foreach (PatternItem key in funcInfo.Keys)
            {
                if (key.VariableName != null && key.VariableName.StartsWith("_:"))
                {
                    // If LHS is a blank node may be collection form
                    int count = funcInfo[key].Patterns.Count;
                    ExtractRelatedPatterns(key, key, ps, funcInfo, funcInfo[key].SubjectArgs);
                    if (funcInfo[key].Patterns.Count == count)
                    {
                        // If no further patterns found just single LHS argument
                        funcInfo[key].SubjectArgs.Add(key);
                    }
                }
                else
                {
                    // Otherwise key is the only LHS argument
                    funcInfo[key].SubjectArgs.Add(key);
                }
                PatternItem searchKey = funcInfo[key].Patterns.First().Object;
                if (searchKey.VariableName != null && searchKey.VariableName.StartsWith("_:"))
                {
                    // If RHS is a blank node may be collection form
                    int count = funcInfo[key].Patterns.Count;
                    ExtractRelatedPatterns(key, searchKey, ps, funcInfo, funcInfo[key].ObjectArgs);
                    if (funcInfo[key].Patterns.Count == count)
                    {
                        // If no further patterns found just single RHS argument
                        funcInfo[key].ObjectArgs.Add(searchKey);
                    }
                }
                else
                {
                    // Otherwise single RHS argument
                    funcInfo[key].ObjectArgs.Add(searchKey);
                }
            }

            // Now try to create actual property functions
            List <IPropertyFunctionPattern> propFunctions = new List <IPropertyFunctionPattern>();

            foreach (PatternItem key in funcInfo.Keys)
            {
                IPropertyFunctionPattern propFunc;
                if (PropertyFunctionFactory.TryCreatePropertyFunction(funcInfo[key], localFactories, out propFunc))
                {
                    propFunctions.Add(propFunc);
                }
            }
            return(propFunctions);
        }
        /// <summary>
        /// Optimises the algebra so that all Node terms are virtualised.
        /// </summary>
        /// <param name="algebra">Algebra.</param>
        /// <returns></returns>
        public ISparqlAlgebra Optimise(ISparqlAlgebra algebra)
        {
            if (algebra is IAbstractJoin)
            {
                return(((IAbstractJoin)algebra).Transform(this));
            }
            else if (algebra is IUnaryOperator)
            {
                return(((IUnaryOperator)algebra).Transform(this));
            }
            else if (algebra is IBgp)
            {
                IBgp current = (IBgp)algebra;
                if (current.PatternCount == 0)
                {
                    return(current);
                }
                else
                {
                    ISparqlAlgebra        result   = new Bgp();
                    List <ITriplePattern> patterns = new List <ITriplePattern>();
                    List <ITriplePattern> ps       = new List <ITriplePattern>(current.TriplePatterns.ToList());
                    TNodeID nullID = _provider.NullID;

                    for (int i = 0; i < current.PatternCount; i++)
                    {
                        if (ps[i].PatternType == TriplePatternType.Filter || ps[i].PatternType == TriplePatternType.BindAssignment || ps[i].PatternType == TriplePatternType.LetAssignment)
                        {
                            // First ensure that if we've found any other Triple Patterns up to this point
                            // we dump this into a BGP and join with the result so far
                            if (patterns.Count > 0)
                            {
                                result = Join.CreateJoin(result, new Bgp(patterns));
                                patterns.Clear();
                            }
                            if (ps[i].PatternType == TriplePatternType.Filter)
                            {
                                result = new Filter(result, new UnaryExpressionFilter(Transform(((IFilterPattern)ps[i]).Filter.Expression)));
                            }
                            else
                            {
                                IAssignmentPattern bind = (IAssignmentPattern)ps[i];
                                result = new Extend(result, Transform(bind.AssignExpression), bind.VariableName);
                            }
                        }
                        else if (ps[i].PatternType == TriplePatternType.Match)
                        {
                            // Convert Terms in the Pattern into Virtual Nodes
                            IMatchTriplePattern tp = (IMatchTriplePattern)ps[i];
                            PatternItem         subj, pred, obj;
                            if (tp.Subject is NodeMatchPattern)
                            {
                                TNodeID id = _provider.GetID(((NodeMatchPattern)tp.Subject).Node);
                                if (id == null || id.Equals(nullID))
                                {
                                    result = new NullOperator(current.Variables);
                                    break;
                                }
                                else
                                {
                                    subj = new NodeMatchPattern(CreateVirtualNode(id, ((NodeMatchPattern)tp.Subject).Node));
                                }
                            }
                            else
                            {
                                subj = tp.Subject;
                            }
                            if (tp.Predicate is NodeMatchPattern)
                            {
                                TNodeID id = _provider.GetID(((NodeMatchPattern)tp.Predicate).Node);
                                if (id == null || id.Equals(nullID))
                                {
                                    result = new NullOperator(current.Variables);
                                    break;
                                }
                                else
                                {
                                    pred = new NodeMatchPattern(CreateVirtualNode(id, ((NodeMatchPattern)tp.Predicate).Node));
                                }
                            }
                            else
                            {
                                pred = tp.Predicate;
                            }
                            if (tp.Object is NodeMatchPattern)
                            {
                                TNodeID id = _provider.GetID(((NodeMatchPattern)tp.Object).Node);
                                if (id == null || id.Equals(nullID))
                                {
                                    result = new NullOperator(current.Variables);
                                    break;
                                }
                                else
                                {
                                    obj = new NodeMatchPattern(CreateVirtualNode(id, ((NodeMatchPattern)tp.Object).Node));
                                }
                            }
                            else
                            {
                                obj = tp.Object;
                            }
                            patterns.Add(new TriplePattern(subj, pred, obj));
                        }
                        else
                        {
                            // Can't optimize if other pattern types involved
                            return(current);
                        }
                    }

                    if (result is NullOperator)
                    {
                        return(result);
                    }
                    else if (patterns.Count > 0)
                    {
                        // If any patterns left at end join as a BGP with result so far
                        result = Join.CreateJoin(result, new Bgp(patterns));
                        return(result);
                    }
                    else
                    {
                        return(result);
                    }
                }
            }
            else if (algebra is ITerminalOperator)
            {
                return(algebra);
            }
            else
            {
                return(algebra);
            }
        }
Exemplo n.º 12
0
        public ISparqlAlgebra Optimise(ISparqlAlgebra algebra)
        {
            try
            {
                if (algebra is Bgp)
                {
                    var bgp = (Bgp)algebra;

                    if (bgp.TriplePatterns.OfType <FilterPattern>().Count() == 1)
                    {
                        var    filter = bgp.TriplePatterns.OfType <FilterPattern>().Select(fp => fp.Filter).First();
                        string var;
                        INode  term;
                        bool   equals;
                        if (IsIdentityExpression(filter.Expression, out var, out term, out equals))
                        {
                            if (equals)
                            {
                                var triplePatterns = new List <ITriplePattern>();
                                foreach (var tp in bgp.TriplePatterns)
                                {
                                    if (tp is FilterPattern)
                                    {
                                        continue;
                                    }
                                    if (tp is TriplePattern)
                                    {
                                        var triplePattern = (TriplePattern)tp;
                                        if (triplePattern.Variables.Contains(var))
                                        {
                                            PatternItem subjPattern = triplePattern.Subject,
                                                        predPattern = triplePattern.Predicate,
                                                        objPattern  = triplePattern.Object;
                                            if (var.Equals(triplePattern.Subject.VariableName))
                                            {
                                                subjPattern = new NodeMatchPattern(term);
                                            }
                                            if (var.Equals(triplePattern.Predicate.VariableName))
                                            {
                                                predPattern = new NodeMatchPattern(term);
                                            }
                                            if (var.Equals(triplePattern.Object.VariableName))
                                            {
                                                objPattern = new NodeMatchPattern(term);
                                            }
                                            triplePatterns.Add(new TriplePattern(subjPattern, predPattern, objPattern));
                                        }
                                        else
                                        {
                                            triplePatterns.Add(triplePattern);
                                        }
                                    }
                                    else
                                    {
                                        triplePatterns.Add(tp);
                                    }
                                }
                                return(new Bgp(triplePatterns));
                            }
                        }
                    }
                }
                else if (algebra is IAbstractJoin)
                {
                    return(((IAbstractJoin)algebra).Transform(this));
                }
                else if (algebra is IUnaryOperator)
                {
                    return(((IUnaryOperator)algebra).Transform(this));
                }
                else
                {
                    return(algebra);
                }
            }
            catch
            {
                return(algebra);
            }
            return(algebra);
        }
Exemplo n.º 13
0
 private bool OptimiseBgp(Bgp bgp, out ISparqlAlgebra optimisedAlgebra)
 {
     if (bgp.TriplePatterns.OfType <FilterPattern>().Count() == 1)
     {
         var    filter = bgp.TriplePatterns.OfType <FilterPattern>().Select(fp => fp.Filter).First();
         string var;
         INode  term;
         bool   equals;
         if (IsIdentityExpression(filter.Expression, out var, out term, out @equals))
         {
             if (@equals)
             {
                 var triplePatterns = new List <ITriplePattern>();
                 foreach (var tp in bgp.TriplePatterns)
                 {
                     if (tp is FilterPattern)
                     {
                         continue;
                     }
                     if (tp is TriplePattern)
                     {
                         var triplePattern = (TriplePattern)tp;
                         if (triplePattern.Variables.Contains(var))
                         {
                             PatternItem subjPattern = triplePattern.Subject,
                                         predPattern = triplePattern.Predicate,
                                         objPattern  = triplePattern.Object;
                             if (var.Equals(triplePattern.Subject.VariableName))
                             {
                                 subjPattern = new NodeMatchPattern(term);
                             }
                             if (var.Equals(triplePattern.Predicate.VariableName))
                             {
                                 predPattern = new NodeMatchPattern(term);
                             }
                             if (var.Equals(triplePattern.Object.VariableName))
                             {
                                 objPattern = new NodeMatchPattern(term);
                             }
                             triplePatterns.Add(new TriplePattern(subjPattern, predPattern, objPattern));
                         }
                         else
                         {
                             triplePatterns.Add(triplePattern);
                         }
                     }
                     else
                     {
                         triplePatterns.Add(tp);
                     }
                 }
                 {
                     optimisedAlgebra = new Bgp(triplePatterns);
                     return(true);
                 }
             }
         }
     }
     optimisedAlgebra = bgp;
     return(false);
 }