Ejemplo n.º 1
0
        // Special treatment of nested rdf:Lists
        private int printTriplePattern(List <IElement> elements, int i, ISparqlPrinter p)
        {
            ITriplePattern main = (ITriplePattern)elements[i];

            // Print subject
            List <IResource> leftList = new List <IResource>();

            i = addListMembers(elements, i, leftList);
            if (leftList.Count == 0)
            {
                TupleImpl.print(getModel(), main.getSubject(), p);
            }
            else
            {
                printRDFList(p, leftList);
                main = (ITriplePattern)elements[i];
            }
            p.print(" ");

            // Print predicate
            if (RDFUtil.sameTerm(RDF.PropertyType, main.getPredicate()))
            {
                p.print("a");
            }
            else
            {
                TupleImpl.print(getModel(), main.getPredicate(), p);
            }
            p.print(" ");

            // Print object
            if (nextIsMatchingVarPattern(main, elements, i))
            {
                List <IResource> rightList = new List <IResource>();
                i = addListMembers(elements, i + 1, rightList);
                if (rightList.Count == 0)
                {
                    TupleImpl.print(getModel(), main.getObject(), p);
                    if (leftList.Count != 0)
                    {
                        i--;
                    }
                }
                else
                {
                    printRDFList(p, rightList);
                    i--;
                }
            }
            else
            {
                TupleImpl.print(getModel(), main.getObject(), p);
            }
            return(i);
        }
Ejemplo n.º 2
0
 protected CollapseGroup(ITriplePattern tp, IEnumerable <string> sortVariables)
 {
     Variables     = new List <string>(tp.Variables);
     SortVariables = new List <string>();
     foreach (var sv in sortVariables)
     {
         if (tp.Variables.Contains(sv))
         {
             SortVariables.Add(sv);
         }
     }
 }
Ejemplo n.º 3
0
 protected CollapseGroup(ITriplePattern tp, IEnumerable<string> sortVariables)
 {
     Variables = new List<string>(tp.Variables);
     SortVariables = new List<string>();
     foreach (var sv in sortVariables)
     {
         if (tp.Variables.Contains(sv))
         {
             SortVariables.Add(sv);
         }
     }
 }
Ejemplo n.º 4
0
        public ThreeVarCollapseGroup(IStore store, ITriplePattern tp, IEnumerable<string> globalSortVars, IEnumerable<string> activeGraphUris) : base(tp, globalSortVars)
        {
            _store = store;
            _matchLength = 3;
            SortVariables = new List<string>();
            var triplePattern = tp as TriplePattern;
            // This is the order we get from the store - pred, subj, obj
            SortVariables.Add(triplePattern.Predicate.VariableName);
            SortVariables.Add(triplePattern.Subject.VariableName);
            SortVariables.Add(triplePattern.Object.VariableName);

            _graphUris = activeGraphUris;
        }
Ejemplo n.º 5
0
        public ThreeVarCollapseGroup(IStore store, ITriplePattern tp, IEnumerable <string> globalSortVars, IEnumerable <string> activeGraphUris) : base(tp, globalSortVars)
        {
            _store        = store;
            _matchLength  = 3;
            SortVariables = new List <string>();
            var triplePattern = tp as TriplePattern;

            // This is the order we get from the store - pred, subj, obj
            SortVariables.Add(triplePattern.Predicate.VariableName);
            SortVariables.Add(triplePattern.Subject.VariableName);
            SortVariables.Add(triplePattern.Object.VariableName);

            _graphUris = activeGraphUris;
        }
Ejemplo n.º 6
0
        internal static INode ToSpinRdf(this ITriplePattern pattern, IGraph g, SpinVariableTable varTable)
        {
            INode p       = g.CreateBlankNode();
            INode rdfType = g.CreateUriNode(new Uri(RdfSpecsHelper.RdfType));

            if (pattern is TriplePattern)
            {
                TriplePattern tp = (TriplePattern)pattern;
                //g.Assert(p, rdfType, g.CreateUriNode(new Uri(SpinClassTriplePattern)));
                g.Assert(p, g.CreateUriNode(new Uri(SpinPropertySubject)), tp.Subject.ToSpinRdf(g, varTable));
                g.Assert(p, g.CreateUriNode(new Uri(SpinPropertyPredicate)), tp.Predicate.ToSpinRdf(g, varTable));
                g.Assert(p, g.CreateUriNode(new Uri(SpinPropertyObject)), tp.Object.ToSpinRdf(g, varTable));
            }
            else if (pattern is SubQueryPattern)
            {
                g.Assert(p, rdfType, g.CreateUriNode(new Uri(SpinClassSubQuery)));
                g.Assert(p, g.CreateUriNode(new Uri(SpinPropertyQuery)), ((SubQueryPattern)pattern).SubQuery.ToSpinRdf(g));
            }
            else if (pattern is FilterPattern)
            {
                g.Assert(p, rdfType, g.CreateUriNode(new Uri(SpinClassFilter)));
                g.Assert(p, g.CreateUriNode(new Uri(SpinPropertyExpression)), ((FilterPattern)pattern).Filter.Expression.ToSpinRdf(g, varTable));
            }
            else if (pattern is PropertyPathPattern)
            {
                PropertyPathPattern pp = (PropertyPathPattern)pattern;
                g.Assert(p, rdfType, g.CreateUriNode(new Uri(SpinClassTriplePath)));
                g.Assert(p, g.CreateUriNode(new Uri(SpinPropertySubject)), pp.Subject.ToSpinRdf(g, varTable));
                g.Assert(p, g.CreateUriNode(new Uri(SpinPropertyPath)), pp.Path.ToSpinRdf(g, varTable));
                g.Assert(p, g.CreateUriNode(new Uri(SpinPropertyObject)), pp.Object.ToSpinRdf(g, varTable));
            }
            else if (pattern is LetPattern)
            {
                g.Assert(p, rdfType, g.CreateUriNode(new Uri(SpinClassLet)));
                INode var = g.CreateBlankNode();
                g.Assert(p, g.CreateUriNode(new Uri(SpinPropertyVariable)), var);
                g.Assert(var, g.CreateUriNode(new Uri(SpinPropertyVariableName)), g.CreateLiteralNode(((LetPattern)pattern).VariableName, new Uri(XmlSpecsHelper.XmlSchemaDataTypeString)));
                g.Assert(p, g.CreateUriNode(new Uri(SpinPropertyExpression)), ((LetPattern)pattern).AssignExpression.ToSpinRdf(g, varTable));
            }
            else if (pattern is BindPattern)
            {
                throw new SpinException("SPARQL 1.1 BINDs are not representable in SPIN RDF Syntax");
            }

            return(p);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Compares a Triple Pattern to another Triple Pattern
        /// </summary>
        /// <param name="other">Other Triple Pattern</param>
        /// <returns></returns>
        /// <remarks>
        /// <para>
        /// The aim of this function is to sort Triple Patterns into what is hopefully an optimal order such that during execution the query space is restricted as early as possible.
        /// </para>
        /// <para>
        /// The basic rules of this are as follows:
        /// <ol>
        ///     <li>Patterns with fewer variables should be executed first</li>
        ///     <li>Patterns using the same variables should be executed in sequence</li>
        ///     <li>Patterns using indexes which are considered more useful should be executed first</li>
        /// </ol>
        /// </para>
        /// </remarks>
        public virtual int CompareTo(ITriplePattern other)
        {
            if (this._vars.Count < other.Variables.Count)
            {
                //We have fewer variables so we go before the other pattern
                return(-1);
            }
            else if (this._vars.Count > other.Variables.Count)
            {
                //We have more variables so we go after the other pattern
                return(1);
            }
            else
            {
                if (this._vars.Count > 0)
                {
                    for (int i = 0; i < this._vars.Count; i++)
                    {
                        int c = this._vars[i].CompareTo(other.Variables[i]);
                        if (c < 0)
                        {
                            //Our variables occur alphabetically sooner than the other patterns so we go before the other pattern
                            return(-1);
                        }
                        else if (c > 0)
                        {
                            //Other variables occur alphabetically sooner than ours so we go after
                            return(1);
                        }
                        //Otherwise we continue checking
                    }

                    //If we reach this point then we contain the same variables
                    //Now we order based on our Index Types
                    TripleIndexSorter sorter = new TripleIndexSorter();
                    return(sorter.Compare(this.IndexType, other.IndexType));
                }
                else
                {
                    //Neither pattern has any variables so we consider these to be equivalent
                    //Order of these patterns has no effect
                    return(0);
                }
            }
        }
Ejemplo n.º 8
0
        internal static INode ToSpinRdf(this ITriplePattern pattern, IGraph g, SpinVariableTable varTable)
        {
            INode p = g.CreateBlankNode();

            if (pattern is TriplePattern)
            {
                TriplePattern tp = (TriplePattern)pattern;
                g.Assert(p, RDF.PropertyType, SP.ClassTriplePattern);
                g.Assert(p, SP.PropertySubject, tp.Subject.ToSpinRdf(g, varTable));
                g.Assert(p, SP.PropertyPredicate, tp.Predicate.ToSpinRdf(g, varTable));
                g.Assert(p, SP.PropertyObject, tp.Object.ToSpinRdf(g, varTable));
            }
            else if (pattern is SubQueryPattern)
            {
                g.Assert(p, RDF.PropertyType, SP.ClassSubQuery);
                g.Assert(p, SP.PropertyQuery, ((SubQueryPattern)pattern).SubQuery.ToSpinRdf(g));
            }
            else if (pattern is FilterPattern)
            {
                g.Assert(p, RDF.PropertyType, SP.ClassFilter);
                g.Assert(p, SP.PropertyExpression, ((FilterPattern)pattern).Filter.Expression.ToSpinRdf(g, varTable));
            }
            else if (pattern is PropertyPathPattern)
            {
                PropertyPathPattern pp = (PropertyPathPattern)pattern;
                g.Assert(p, RDF.PropertyType, SP.ClassTriplePath);
                g.Assert(p, SP.PropertySubject, pp.Subject.ToSpinRdf(g, varTable));
                g.Assert(p, SP.PropertyPath, pp.Path.ToSpinRdf(g, varTable));
                g.Assert(p, SP.PropertyObject, pp.Object.ToSpinRdf(g, varTable));
            }
            else if (pattern is LetPattern)
            {
                g.Assert(p, RDF.PropertyType, SP.ClassLet);
                INode var = g.CreateBlankNode();
                g.Assert(p, SP.PropertyVariable, var);
                g.Assert(var, SP.PropertyVarName, g.CreateLiteralNode(((LetPattern)pattern).VariableName, XSD.string_.Uri));
                g.Assert(p, SP.PropertyExpression, ((LetPattern)pattern).AssignExpression.ToSpinRdf(g, varTable));
            }
            else if (pattern is BindPattern)
            {
                throw new SpinException("SPARQL 1.1 BINDs are not representable in SPIN RDF Syntax");
            }

            return(p);
        }
Ejemplo n.º 9
0
 /// <summary>
 /// Adds a Triple Pattern to the Graph Pattern respecting any BGP breaks
 /// </summary>
 /// <param name="p">Triple Pattern</param>
 internal void AddTriplePattern(ITriplePattern p)
 {
     if (_break)
     {
         if (_broken)
         {
             _graphPatterns.Last().AddTriplePattern(p);
         }
         else
         {
             GraphPattern breakPattern = new GraphPattern();
             breakPattern.AddTriplePattern(p);
             _graphPatterns.Add(breakPattern);
         }
     }
     else
     {
         _triplePatterns.Add(p);
     }
 }
Ejemplo n.º 10
0
        private int addListMembers(List <IElement> elements, int i, List <IResource> members)
        {
            bool first = true;

            while (i < elements.Count - 1 &&
                   elements[i] is ITriplePattern &&
                   elements[i + 1] is ITriplePattern)
            {
                ITriplePattern firstPattern  = (ITriplePattern)elements[i];
                ITriplePattern secondPattern = (ITriplePattern)elements[i + 1];
                if (RDFUtil.sameTerm(RDF.PropertyFirst, firstPattern.getPredicate()) && RDFUtil.sameTerm(RDF.PropertyRest, secondPattern.getPredicate()))
                {
                    IResource firstSubject  = firstPattern.getSubject();
                    IResource secondSubject = secondPattern.getSubject();
                    if (firstSubject is IVariable && secondSubject is IVariable)
                    {
                        IVariable firstVar  = (IVariable)firstSubject;
                        IVariable secondVar = (IVariable)secondSubject;
                        if (firstVar.isBlankNodeVar() && firstVar.getName().Equals(secondVar.getName()))
                        {
                            members.Add(firstPattern.getObject());
                            IResource secondObject = secondPattern.getObject();
                            i++;
                            if (RDFUtil.sameTerm(RDF.Nil, secondObject))
                            {
                                return(i + 1);
                            }
                        }
                    }
                }

                // We are not in a valid list
                if (first && members.Count == 0)
                {
                    break;
                }
                first = false;
                i++;
            }
            return(i);
        }
Ejemplo n.º 11
0
        private static void AddTriplePattern(GraphPattern graphPattern, ITriplePattern tp)
        {
            switch (tp.PatternType)
            {
            case TriplePatternType.Match:
            case TriplePatternType.Path:
            case TriplePatternType.PropertyFunction:
            case TriplePatternType.SubQuery:
                graphPattern.AddTriplePattern(tp);
                break;

            case TriplePatternType.LetAssignment:
            case TriplePatternType.BindAssignment:
                graphPattern.AddAssignment((IAssignmentPattern)tp);
                break;

            case TriplePatternType.Filter:
                graphPattern.AddFilter(((IFilterPattern)tp).Filter);
                break;
            }
        }
Ejemplo n.º 12
0
 /// <summary>
 /// Creates a Streamed BGP containing a single Triple Pattern
 /// </summary>
 /// <param name="p">Triple Pattern</param>
 /// <param name="requiredResults">The number of Results the BGP should attempt to return</param>
 public LazyBgp(ITriplePattern p, int requiredResults)
 {
     if (!IsLazilyEvaluablePattern(p)) throw new ArgumentException("Triple Pattern instance must be a Triple Pattern, BIND or FILTER Pattern", "p");
     this._requiredResults = requiredResults;
     this._triplePatterns.Add(p);
 }
Ejemplo n.º 13
0
 /// <summary>
 /// Adds a Triple Pattern to the Path Transform
 /// </summary>
 /// <param name="p">Triple Pattern</param>
 public void AddTriplePattern(ITriplePattern p)
 {
     this._patterns.Add(p);
 }
Ejemplo n.º 14
0
 /// <summary>
 /// Creates a Streamed BGP containing a single Triple Pattern
 /// </summary>
 /// <param name="p">Triple Pattern</param>
 public LazyBgp(ITriplePattern p)
 {
     if (!IsLazilyEvaluablePattern(p)) throw new ArgumentException("Triple Pattern instance must be a Triple Pattern or a Subquery, BIND or FILTER Pattern", "p");
     this._triplePatterns.Add(p);
 }
Ejemplo n.º 15
0
        private bool IsDisjointOperation(ISparqlAlgebra algebra, List <String> filterVars, out int splitPoint)
        {
            splitPoint = -1;
            if (algebra is IBgp)
            {
                // Get Triple Patterns, can't split into a product if there are blank variables present
                List <ITriplePattern> ps = ((IBgp)algebra).TriplePatterns.ToList();
                if (ps.Any(p => !p.HasNoBlankVariables))
                {
                    return(false);
                }

                // Iterate over the Triple Patterns to see if we can split into a Product
                List <String> vars = new List <String>();
                for (int i = 0; i < ps.Count; i++)
                {
                    // Not a product if we've seen both variables already
                    if (filterVars.All(v => vars.Contains(v)))
                    {
                        return(false);
                    }

                    ITriplePattern p = ps[i];
                    if (p.PatternType == TriplePatternType.Match || p.PatternType == TriplePatternType.SubQuery)
                    {
                        if (vars.Count > 0 && vars.IsDisjoint(p.Variables))
                        {
                            // Is a filterable product if we've not seen all the variables so far and have hit a point where a product occurs
                            // and all the variables are not in the RHS
                            Bgp rhs = new Bgp(ps.Skip(i));
                            if (!filterVars.All(v => rhs.Variables.Contains(v)))
                            {
                                splitPoint = i;
                                return(true);
                            }
                        }
                        vars.AddRange(p.Variables);
                    }
                    else if (p.PatternType == TriplePatternType.BindAssignment || p.PatternType == TriplePatternType.LetAssignment)
                    {
                        vars.Add(((IAssignmentPattern)p).VariableName);
                    }
                    else if (p.PatternType == TriplePatternType.Filter)
                    {
                        continue;
                    }
                    else
                    {
                        return(false);
                    }
                }
                // If we get all the way here then not a product
                return(false);
            }
            else if (algebra is IJoin)
            {
                IJoin join = (IJoin)algebra;
                if (join.Lhs.Variables.IsDisjoint(join.Rhs.Variables))
                {
                    // There a product between the two sides of the join but are the variables spead over different sides of that join?
                    // If all variables occur on one side then this is not a filtered product
                    return(!filterVars.All(v => join.Lhs.Variables.Contains(v)) && !filterVars.All(v => join.Rhs.Variables.Contains(v)));
                }
                else
                {
                    return(false);
                }
            }
            else
            {
                return(false);
            }
        }
Ejemplo n.º 16
0
 private bool IsLazilyEvaluablePattern(ITriplePattern p)
 {
     return(p.PatternType == TriplePatternType.Match || p.PatternType == TriplePatternType.Filter || p.PatternType == TriplePatternType.BindAssignment);
 }
Ejemplo n.º 17
0
        /// <summary>
        /// Formats a Triple Pattern in nicely formatted SPARQL syntax
        /// </summary>
        /// <param name="tp">Triple Pattern</param>
        /// <returns></returns>
        public virtual String Format(ITriplePattern tp)
        {
            StringBuilder output = new StringBuilder();

            if (tp is TriplePattern)
            {
                TriplePattern match = (TriplePattern)tp;
                output.Append(this.Format(match.Subject, TripleSegment.Subject));
                output.Append(' ');
                output.Append(this.Format(match.Predicate, TripleSegment.Predicate));
                output.Append(' ');
                output.Append(this.Format(match.Object, TripleSegment.Object));
                output.Append(" .");
            }
            else if (tp is FilterPattern)
            {
                FilterPattern filter = (FilterPattern)tp;
                output.Append("FILTER(");
                output.Append(this.FormatExpression(filter.Filter.Expression));
                output.Append(")");
            }
            else if (tp is SubQueryPattern)
            {
                SubQueryPattern subquery = (SubQueryPattern)tp;
                output.AppendLine("{");
                output.AppendLineIndented(this.Format(subquery.SubQuery), 2);
                output.AppendLine("}");
            }
            else if (tp is PropertyPathPattern)
            {
                PropertyPathPattern path = (PropertyPathPattern)tp;
                output.Append(this.Format(path.Subject, TripleSegment.Subject));
                output.Append(' ');
                output.Append(this.FormatPath(path.Path));
                output.Append(' ');
                output.Append(this.Format(path.Object, TripleSegment.Object));
                output.Append(" .");
            }
            else if (tp is LetPattern)
            {
                LetPattern let = (LetPattern)tp;
                output.Append("LET(?");
                output.Append(let.VariableName);
                output.Append(" := ");
                output.Append(this.FormatExpression(let.AssignExpression));
                output.Append(")");
            }
            else if (tp is BindPattern)
            {
                BindPattern bind = (BindPattern)tp;
                output.Append("BIND (");
                output.Append(this.FormatExpression(bind.AssignExpression));
                output.Append(" AS ?");
                output.Append(bind.VariableName);
                output.Append(")");
            }
            else
            {
                throw new RdfOutputException("Unable to Format an unknown ITriplePattern implementation as a String");
            }

            return(output.ToString());
        }
Ejemplo n.º 18
0
 /// <summary>
 /// Creates a BGP containing a single Triple Pattern.
 /// </summary>
 /// <param name="p">Triple Pattern.</param>
 public Bgp(ITriplePattern p)
 {
     _triplePatterns.Add(p);
 }
Ejemplo n.º 19
0
 /// <summary>
 /// Adds a Triple Pattern to the Path Transform
 /// </summary>
 /// <param name="p">Triple Pattern</param>
 public void AddTriplePattern(ITriplePattern p)
 {
     this._patterns.Add(p);
 }
Ejemplo n.º 20
0
        override protected void handleTriplePattern(ITriplePattern triplePattern, Dictionary <IResource, IResource> bindings)
        {
            bool      valid   = false;
            IResource subject = triplePattern.getSubject();

            if (RDFUtil.sameTerm(SPIN.Property_this, subject))
            {
                valid = true;
            }
            else if (bindings != null)
            {
                IVariable var = SPINFactory.asVariable(subject);
                if (var != null)
                {
                    String varName = var.getName();
                    foreach (IResource argPredicate in bindings.Keys)
                    {
                        if (varName.Equals(argPredicate.Uri().ToString().Replace(SP.BASE_URI, "").Replace(SPIN.BASE_URI, "")))
                        {
                            IResource b = bindings[argPredicate];
                            if (RDFUtil.sameTerm(SPIN.Property_this, b))
                            {
                                valid = true;
                                break;
                            }
                        }
                    }
                }
            }

            if (valid)
            {
                IResource predicate = triplePattern.getPredicate();
                if (predicate != null)
                {
                    IVariable variable = SPINFactory.asVariable(predicate);
                    if (variable == null)
                    {
                        Uri uri = predicate.Uri();
                        if (uri != null)
                        {
                            properties.Add(Resource.Get(predicate, _targetModel));
                        }
                    }
                    else if (bindings != null)
                    {
                        String varName = variable.getName();
                        foreach (IResource argPredicate in bindings.Keys)
                        {
                            if (varName.Equals(argPredicate.Uri().ToString().Replace(SP.BASE_URI, "").Replace(SPIN.BASE_URI, "")))
                            {
                                IResource b = bindings[argPredicate];
                                if (b != null && b.isUri())
                                {
                                    properties.Add(Resource.Get(b, _targetModel));
                                }
                            }
                        }
                    }
                }
            }
        }
 public PassthroughCollapseGroup(ITriplePattern tp, IEnumerable <string> globalSortVars) : base(tp, globalSortVars)
 {
     _triplePattern = tp;
 }
Ejemplo n.º 22
0
        /**
         * Checks whether a given INode represents a SPARQL element, and returns
         * an instance of a subclass of Element if so.
         * @param resource  the INode to check
         * @return INode as an Element or null if resource is not an element
         */
        public static IElement asElement(IResource resource)
        {
            if (resource == null)
            {
                return(null);
            }
            /*sealed*/
            ITriplePattern triplePattern = asTriplePattern(resource);

            if (triplePattern != null)
            {
                return(triplePattern);
            }
            else if (resource.canAs(SP.ClassTriplePath))
            {
                return((ITriplePath)resource.As(typeof(TriplePathImpl)));
            }
            else if (resource.canAs(SP.ClassFilter))
            {
                return((IFilter)resource.As(typeof(FilterImpl)));
            }
            else if (resource.canAs(SP.ClassBind))
            {
                return((IBind)resource.As(typeof(BindImpl)));
            }
            else if (resource.canAs(SP.ClassOptional))
            {
                return((IOptional)resource.As(typeof(OptionalImpl)));
            }
            else if (resource.canAs(SP.ClassNamedGraph))
            {
                return((INamedGraph)resource.As(typeof(NamedGraphImpl)));
            }
            else if (resource.canAs(SP.ClassMinus))
            {
                return((IMinus)resource.As(typeof(MinusImpl)));
            }
            else if (resource.canAs(SP.ClassExists))
            {
                return((IExists)resource.As(typeof(ExistsImpl)));
            }
            else if (resource.canAs(SP.ClassNotExists))
            {
                return((INotExists)resource.As(typeof(NotExistsImpl)));
            }
            else if (resource.canAs(SP.ClassService))
            {
                return((IService)resource.As(typeof(ServiceImpl)));
            }
            else if (resource.canAs(SP.ClassSubQuery))
            {
                return((ISubQuery)resource.As(typeof(SubQueryImpl)));
            }
            else if (resource.canAs(SP.ClassUnion))
            {
                return((IUnion)resource.As(typeof(UnionImpl)));
            }
            else if (resource.canAs(SP.ClassValues))
            {
                return((IValues)resource.As(typeof(ValuesImpl)));
            }
            else if (isElementList(resource))
            {
                return((IElementList)resource.As(typeof(ElementListImpl)));
            }
            else
            {
                return(null);
            }
        }
Ejemplo n.º 23
0
 /// <summary>
 /// Adds a Triple Pattern to the Graph Pattern respecting any BGP breaks
 /// </summary>
 /// <param name="p">Triple Pattern</param>
 internal void AddTriplePattern(ITriplePattern p)
 {
     if (this._break)
     {
         if (this._broken)
         {
             this._graphPatterns.Last().AddTriplePattern(p);
         }
         else
         {
             GraphPattern breakPattern = new GraphPattern();
             breakPattern.AddTriplePattern(p);
             this._graphPatterns.Add(breakPattern);
         }
     }
     else
     {
         this._triplePatterns.Add(p);
     }
 }
Ejemplo n.º 24
0
 private bool IsLazilyEvaluablePattern(ITriplePattern p)
 {
     return (p is TriplePattern || p is FilterPattern || p is BindPattern);
 }
Ejemplo n.º 25
0
        /// <summary>
        /// Optimises the algebra to include property functions
        /// </summary>
        /// <param name="algebra">Algebra</param>
        /// <returns></returns>
        public ISparqlAlgebra Optimise(ISparqlAlgebra algebra)
        {
            if (algebra is IBgp)
            {
                IBgp current = (IBgp)algebra;
                if (current.PatternCount == 0)
                {
                    return(current);
                }

                List <ITriplePattern>           ps        = current.TriplePatterns.ToList();
                List <IPropertyFunctionPattern> propFuncs = PropertyFunctionHelper.ExtractPatterns(ps, _factories.Value);
                if (propFuncs.Count == 0)
                {
                    return(current);
                }

                // Remove raw Triple Patterns pertaining to extracted property functions
                foreach (IPropertyFunctionPattern propFunc in propFuncs)
                {
                    // Track where we need to insert the property function back into the BGP
                    ITriplePattern first        = propFunc.OriginalPatterns.First();
                    int            origLocation = ps.FindIndex(p => p.Equals(first));
                    foreach (ITriplePattern tp in propFunc.OriginalPatterns)
                    {
                        int location = ps.FindIndex(p => p.Equals(tp));
                        if (location >= 0)
                        {
                            if (location < origLocation)
                            {
                                origLocation--;
                            }
                            ps.RemoveAt(location);
                        }
                        else
                        {
                            throw new RdfQueryException("Bad Property Function extraction");
                        }
                    }

                    // Make the insert
                    if (origLocation >= ps.Count || origLocation < 0 || ps.Count == 0)
                    {
                        ps.Add(propFunc);
                    }
                    else
                    {
                        ps.Insert(origLocation, propFunc);
                    }
                }

                // Return a new BGP
                return(new Bgp(ps));
            }
            else if (algebra is ITerminalOperator)
            {
                return(algebra);
            }
            else if (algebra is IAbstractJoin)
            {
                return(((IAbstractJoin)algebra).Transform(this));
            }
            else if (algebra is IUnaryOperator)
            {
                return(((IUnaryOperator)algebra).Transform(this));
            }
            else
            {
                return(algebra);
            }
        }
Ejemplo n.º 26
0
        private BaseMultiset StreamingEvaluate(SparqlEvaluationContext context, int pattern, out bool halt)
        {
            halt = false;

            //Handle Empty BGPs
            if (pattern == 0 && this._triplePatterns.Count == 0)
            {
                context.OutputMultiset = new IdentityMultiset();
                return(context.OutputMultiset);
            }

            BaseMultiset initialInput, localOutput, results = null;

            //Determine whether the Pattern modifies the existing Input rather than joining to it
            bool modifies = (this._triplePatterns[pattern] is FilterPattern);
            bool extended = (pattern > 0 && this._triplePatterns[pattern - 1] is BindPattern);
            bool modified = (pattern > 0 && this._triplePatterns[pattern - 1] is FilterPattern);

            //Set up the Input and Output Multiset appropriately
            switch (pattern)
            {
            case 0:
                //Input is as given and Output is new empty multiset
                if (!modifies)
                {
                    initialInput = context.InputMultiset;
                }
                else
                {
                    //If the Pattern will modify the Input and is the first thing in the BGP then it actually modifies a new empty input
                    //This takes care of FILTERs being out of scope
                    initialInput = new Multiset();
                }
                localOutput = new Multiset();
                break;

            case 1:
                //Input becomes current Output and Output is new empty multiset
                initialInput = context.OutputMultiset;
                localOutput  = new Multiset();
                break;

            default:
                if (!extended && !modified)
                {
                    //Input is join of previous input and output and Output is new empty multiset
                    if (context.InputMultiset.IsDisjointWith(context.OutputMultiset))
                    {
                        //Disjoint so do a Product
                        initialInput = context.InputMultiset.ProductWithTimeout(context.OutputMultiset, context.RemainingTimeout);
                    }
                    else
                    {
                        //Normal Join
                        initialInput = context.InputMultiset.Join(context.OutputMultiset);
                    }
                }
                else
                {
                    initialInput = context.OutputMultiset;
                }
                localOutput = new Multiset();
                break;
            }
            context.InputMultiset  = initialInput;
            context.OutputMultiset = localOutput;

            //Get the Triple Pattern we're evaluating
            ITriplePattern temp         = this._triplePatterns[pattern];
            int            resultsFound = 0;
            int            prevResults  = -1;

            if (temp is TriplePattern)
            {
                //Find the first Triple which matches the Pattern
                TriplePattern        tp = (TriplePattern)temp;
                IEnumerable <Triple> ts = tp.GetTriples(context);

                //In the case that we're lazily evaluating an optimisable ORDER BY then
                //we need to apply OrderBy()'s to our enumeration
                //This only applies to the 1st pattern
                if (pattern == 0)
                {
                    if (context.Query != null)
                    {
                        if (context.Query.OrderBy != null && context.Query.IsOptimisableOrderBy)
                        {
                            IComparer <Triple> comparer = context.Query.OrderBy.GetComparer(tp);
                            if (comparer != null)
                            {
                                ts = ts.OrderBy(t => t, comparer);
                            }
                            else
                            {
                                //Can't get a comparer so can't optimise
                                this._requiredResults = -1;
                            }
                        }
                    }
                }

                foreach (Triple t in ts)
                {
                    //Remember to check for Timeouts during Lazy Evaluation
                    context.CheckTimeout();

                    if (tp.Accepts(context, t))
                    {
                        resultsFound++;
                        if (tp.IndexType == TripleIndexType.NoVariables)
                        {
                            localOutput            = new IdentityMultiset();
                            context.OutputMultiset = localOutput;
                        }
                        else
                        {
                            context.OutputMultiset.Add(tp.CreateResult(t));
                        }

                        //Recurse unless we're the last pattern
                        if (pattern < this._triplePatterns.Count - 1)
                        {
                            results = this.StreamingEvaluate(context, pattern + 1, out halt);

                            //If recursion leads to a halt then we halt and return immediately
                            if (halt && results.Count >= this._requiredResults && this._requiredResults != -1)
                            {
                                return(results);
                            }
                            else if (halt)
                            {
                                if (results.Count == 0)
                                {
                                    //If recursing leads to no results then eliminate all outputs
                                    //Also reset to prevResults to -1
                                    resultsFound = 0;
                                    localOutput  = new Multiset();
                                    prevResults  = -1;
                                }
                                else if (prevResults > -1)
                                {
                                    if (results.Count == prevResults)
                                    {
                                        //If the amount of results found hasn't increased then this match does not
                                        //generate any further solutions further down the recursion so we can eliminate
                                        //this from the results
                                        localOutput.Remove(localOutput.SetIDs.Max());
                                    }
                                }
                                prevResults = results.Count;

                                //If we're supposed to halt but not reached the number of required results then continue
                                context.InputMultiset  = initialInput;
                                context.OutputMultiset = localOutput;
                            }
                            else
                            {
                                //Otherwise we need to keep going here
                                //So must reset our input and outputs before continuing
                                context.InputMultiset  = initialInput;
                                context.OutputMultiset = new Multiset();
                                resultsFound--;
                            }
                        }
                        else
                        {
                            //If we're at the last pattern and we've found a match then we can halt
                            halt = true;

                            //Generate the final output and return it
                            if (context.InputMultiset.IsDisjointWith(context.OutputMultiset))
                            {
                                //Disjoint so do a Product
                                results = context.InputMultiset.ProductWithTimeout(context.OutputMultiset, context.RemainingTimeout);
                            }
                            else
                            {
                                //Normal Join
                                results = context.InputMultiset.Join(context.OutputMultiset);
                            }

                            //If not reached required number of results continue
                            if (results.Count >= this._requiredResults && this._requiredResults != -1)
                            {
                                context.OutputMultiset = results;
                                return(context.OutputMultiset);
                            }
                        }
                    }
                }
            }
            else if (temp is FilterPattern)
            {
                FilterPattern     filter     = (FilterPattern)temp;
                ISparqlExpression filterExpr = filter.Filter.Expression;

                if (filter.Variables.IsDisjoint(context.InputMultiset.Variables))
                {
                    //Remember to check for Timeouts during Lazy Evaluation
                    context.CheckTimeout();

                    //Filter is Disjoint so determine whether it has any affect or not
                    if (filter.Variables.Any())
                    {
                        //Has Variables but disjoint from input => not in scope so gets ignored

                        //Do we recurse or not?
                        if (pattern < this._triplePatterns.Count - 1)
                        {
                            //Recurse and return
                            results = this.StreamingEvaluate(context, pattern + 1, out halt);
                            return(results);
                        }
                        else
                        {
                            //We don't affect the input in any way so just return it
                            return(context.InputMultiset);
                        }
                    }
                    else
                    {
                        //No Variables so have to evaluate it to see if it gives true otherwise
                        try
                        {
                            if (filterExpr.EffectiveBooleanValue(context, 0))
                            {
                                if (pattern < this._triplePatterns.Count - 1)
                                {
                                    //Recurse and return
                                    results = this.StreamingEvaluate(context, pattern + 1, out halt);
                                    return(results);
                                }
                                else
                                {
                                    //Last Pattern and we evaluate to true so can return the input as-is
                                    halt = true;
                                    return(context.InputMultiset);
                                }
                            }
                        }
                        catch (RdfQueryException)
                        {
                            //Evaluates to false so eliminates all solutions (use an empty Multiset)
                            return(new Multiset());
                        }
                    }
                }
                else
                {
                    //Remember to check for Timeouts during Lazy Evaluation
                    context.CheckTimeout();

                    //Test each solution found so far against the Filter and eliminate those that evalute to false/error
                    foreach (int id in context.InputMultiset.SetIDs.ToList())
                    {
                        try
                        {
                            if (filterExpr.EffectiveBooleanValue(context, id))
                            {
                                //If evaluates to true then add to output
                                context.OutputMultiset.Add(context.InputMultiset[id]);
                            }
                        }
                        catch (RdfQueryException)
                        {
                            //Error means we ignore the solution
                        }
                    }

                    //Remember to check for Timeouts during Lazy Evaluation
                    context.CheckTimeout();

                    //Decide whether to recurse or not
                    resultsFound = context.OutputMultiset.Count;
                    if (pattern < this._triplePatterns.Count - 1)
                    {
                        //Recurse then return
                        //We can never decide whether to recurse again at this point as we are not capable of deciding
                        //which solutions should be dumped (that is the job of an earlier pattern in the BGP)
                        results = this.StreamingEvaluate(context, pattern + 1, out halt);

                        return(results);
                    }
                    else
                    {
                        halt = true;

                        //However many results we need we'll halt - previous patterns can call us again if they find more potential solutions
                        //for us to filter
                        return(context.OutputMultiset);
                    }
                }
            }
            else if (temp is BindPattern)
            {
                BindPattern       bind     = (BindPattern)temp;
                ISparqlExpression bindExpr = bind.AssignExpression;
                String            bindVar  = bind.VariableName;

                if (context.InputMultiset.ContainsVariable(bindVar))
                {
                    throw new RdfQueryException("Cannot use a BIND assigment to BIND to a variable that has previously been used in the Query");
                }
                else
                {
                    //Remember to check for Timeouts during Lazy Evaluation
                    context.CheckTimeout();

                    //Compute the Binding for every value
                    context.OutputMultiset.AddVariable(bindVar);
                    foreach (ISet s in context.InputMultiset.Sets)
                    {
                        ISet x = s.Copy();
                        try
                        {
                            INode val = bindExpr.Value(context, s.ID);
                            x.Add(bindVar, val);
                        }
                        catch (RdfQueryException)
                        {
                            //Equivalent to no assignment but the solution is preserved
                        }
                        context.OutputMultiset.Add(x);
                    }

                    //Remember to check for Timeouts during Lazy Evaluation
                    context.CheckTimeout();

                    //Decide whether to recurse or not
                    resultsFound = context.OutputMultiset.Count;
                    if (pattern < this._triplePatterns.Count - 1)
                    {
                        //Recurse then return
                        results = this.StreamingEvaluate(context, pattern + 1, out halt);
                        return(results);
                    }
                    else
                    {
                        halt = true;

                        //However many results we need we'll halt - previous patterns can call us again if they find more potential solutions
                        //for us to extend
                        return(context.OutputMultiset);
                    }
                }
            }
            else
            {
                throw new RdfQueryException("Encountered a " + temp.GetType().FullName + " which is not a lazily evaluable Pattern");
            }

            //If we found no possibles we return the null multiset
            if (resultsFound == 0)
            {
                return(new NullMultiset());
            }
            else
            {
                //Generate the final output and return it
                if (!modifies)
                {
                    if (context.InputMultiset.IsDisjointWith(context.OutputMultiset))
                    {
                        //Disjoint so do a Product
                        results = context.InputMultiset.ProductWithTimeout(context.OutputMultiset, context.RemainingTimeout);
                    }
                    else
                    {
                        //Normal Join
                        results = context.InputMultiset.Join(context.OutputMultiset);
                    }
                    context.OutputMultiset = results;
                }
                return(context.OutputMultiset);
            }
        }
Ejemplo n.º 27
0
        /// <summary>
        /// Compares a Triple Pattern to another Triple Pattern
        /// </summary>
        /// <param name="other">Other Triple Pattern</param>
        /// <returns></returns>
        /// <remarks>
        /// <para>
        /// The aim of this function is to sort Triple Patterns into what is hopefully an optimal order such that during execution the query space is restricted as early as possible.
        /// </para>
        /// <para>
        /// The basic rules of this are as follows:
        /// <ol>
        ///     <li>Patterns with fewer variables should be executed first</li>
        ///     <li>Patterns using the same variables should be executed in sequence</li>
        ///     <li>Patterns using indexes which are considered more useful should be executed first</li>
        /// </ol>
        /// </para>
        /// </remarks>
        public virtual int CompareTo(ITriplePattern other)
        {
            if (this._vars.Count < other.Variables.Count)
            {
                //We have fewer variables so we go before the other pattern
                return -1;
            }
            else if (this._vars.Count > other.Variables.Count)
            {
                //We have more variables so we go after the other pattern
                return 1;
            }
            else
            {
                if (this._vars.Count > 0)
                {
                    for (int i = 0; i < this._vars.Count; i++)
                    {
                        int c = this._vars[i].CompareTo(other.Variables[i]);
                        if (c < 0)
                        {
                            //Our variables occur alphabetically sooner than the other patterns so we go before the other pattern
                            return -1;
                        }
                        else if (c > 0)
                        {
                            //Other variables occur alphabetically sooner than ours so we go after
                            return 1;
                        }
                        //Otherwise we continue checking
                    }

                    //If we reach this point then we contain the same variables
                    //Now we order based on our Index Types
                    TripleIndexSorter sorter = new TripleIndexSorter();
                    return sorter.Compare(this.IndexType, other.IndexType);
                }
                else
                {
                    //Neither pattern has any variables so we consider these to be equivalent
                    //Order of these patterns has no effect
                    return 0;
                }
            }
        }
Ejemplo n.º 28
0
        private BaseMultiset StreamingEvaluate(SparqlEvaluationContext context, int pattern, out bool halt)
        {
            halt = false;

            //Handle Empty BGPs
            if (pattern == 0 && this._triplePatterns.Count == 0)
            {
                context.OutputMultiset = new IdentityMultiset();
                return(context.OutputMultiset);
            }

            BaseMultiset initialInput, localOutput, results;

            //Set up the Input and Output Multiset appropriately
            switch (pattern)
            {
            case 0:
                //Input is as given and Output is new empty multiset
                initialInput = context.InputMultiset;
                localOutput  = new Multiset();
                break;

            case 1:
                //Input becomes current Output and Output is new empty multiset
                initialInput = context.OutputMultiset;
                localOutput  = new Multiset();
                break;

            default:
                //Input is join of previous input and ouput and Output is new empty multiset
                if (context.InputMultiset.IsDisjointWith(context.OutputMultiset))
                {
                    //Disjoint so do a Product
                    initialInput = context.InputMultiset.Product(context.OutputMultiset);
                }
                else
                {
                    //Normal Join
                    initialInput = context.InputMultiset.Join(context.OutputMultiset);
                }
                localOutput = new Multiset();
                break;
            }
            context.InputMultiset  = initialInput;
            context.OutputMultiset = localOutput;

            //Get the Triple Pattern we're evaluating
            ITriplePattern temp         = this._triplePatterns[pattern];
            int            resultsFound = 0;

            if (temp.PatternType == TriplePatternType.Match)
            {
                //Find the first Triple which matches the Pattern
                IMatchTriplePattern tp = (IMatchTriplePattern)temp;
                foreach (Triple t in tp.GetTriples(context))
                {
                    //Remember to check for Timeout during lazy evaluation
                    context.CheckTimeout();

                    if (tp.Accepts(context, t))
                    {
                        resultsFound++;
                        context.OutputMultiset.Add(tp.CreateResult(t));

                        //Recurse unless we're the last pattern
                        if (pattern < this._triplePatterns.Count - 1)
                        {
                            results = this.StreamingEvaluate(context, pattern + 1, out halt);

                            //If recursion leads to a halt then we halt and return immediately
                            if (halt)
                            {
                                return(results);
                            }

                            //Otherwise we need to keep going here
                            //So must reset our input and outputs before continuing
                            context.InputMultiset  = initialInput;
                            context.OutputMultiset = new Multiset();
                            resultsFound--;
                        }
                        else
                        {
                            //If we're at the last pattern and we've found a match then we can halt
                            halt = true;

                            //Generate the final output and return it
                            if (context.InputMultiset.IsDisjointWith(context.OutputMultiset))
                            {
                                //Disjoint so do a Product
                                context.OutputMultiset = context.InputMultiset.ProductWithTimeout(context.OutputMultiset, context.QueryTimeout - context.QueryTime);
                            }
                            else
                            {
                                //Normal Join
                                context.OutputMultiset = context.InputMultiset.Join(context.OutputMultiset);
                            }
                            return(context.OutputMultiset);
                        }
                    }
                }
            }
            else if (temp.PatternType == TriplePatternType.Filter)
            {
                IFilterPattern    fp     = (IFilterPattern)temp;
                ISparqlFilter     filter = fp.Filter;
                ISparqlExpression expr   = filter.Expression;

                //Find the first result of those we've got so far that matches
                if (context.InputMultiset is IdentityMultiset || context.InputMultiset.IsEmpty)
                {
                    try
                    {
                        //If the Input is the Identity Multiset then the Output is either
                        //the Identity/Null Multiset depending on whether the Expression evaluates to true
                        if (expr.Evaluate(context, 0).AsSafeBoolean())
                        {
                            context.OutputMultiset = new IdentityMultiset();
                        }
                        else
                        {
                            context.OutputMultiset = new NullMultiset();
                        }
                    }
                    catch
                    {
                        //If Expression fails to evaluate then result is NullMultiset
                        context.OutputMultiset = new NullMultiset();
                    }
                }
                else
                {
                    foreach (int id in context.InputMultiset.SetIDs)
                    {
                        //Remember to check for Timeout during lazy evaluation
                        context.CheckTimeout();

                        try
                        {
                            if (expr.Evaluate(context, id).AsSafeBoolean())
                            {
                                resultsFound++;
                                context.OutputMultiset.Add(context.InputMultiset[id].Copy());

                                //Recurse unless we're the last pattern
                                if (pattern < this._triplePatterns.Count - 1)
                                {
                                    results = this.StreamingEvaluate(context, pattern + 1, out halt);

                                    //If recursion leads to a halt then we halt and return immediately
                                    if (halt)
                                    {
                                        return(results);
                                    }

                                    //Otherwise we need to keep going here
                                    //So must reset our input and outputs before continuing
                                    context.InputMultiset  = initialInput;
                                    context.OutputMultiset = new Multiset();
                                    resultsFound--;
                                }
                                else
                                {
                                    //If we're at the last pattern and we've found a match then we can halt
                                    halt = true;

                                    //Generate the final output and return it
                                    if (context.InputMultiset.IsDisjointWith(context.OutputMultiset))
                                    {
                                        //Disjoint so do a Product
                                        context.OutputMultiset = context.InputMultiset.ProductWithTimeout(context.OutputMultiset, context.RemainingTimeout);
                                    }
                                    else
                                    {
                                        //Normal Join
                                        context.OutputMultiset = context.InputMultiset.Join(context.OutputMultiset);
                                    }
                                    return(context.OutputMultiset);
                                }
                            }
                        }
                        catch
                        {
                            //Ignore expression evaluation errors
                        }
                    }
                }
            }

            //If we found no possibles we return the null multiset
            if (resultsFound == 0)
            {
                return(new NullMultiset());
            }

            //We should never reach here so throw an error to that effect
            //The reason we'll never reach here is that this method should always return earlier
            throw new RdfQueryException("Unexpected control flow in evaluating a Streamed BGP for an ASK query");
        }
Ejemplo n.º 29
0
 /// <summary>
 /// Creates a Streamed BGP containing a single Triple Pattern
 /// </summary>
 /// <param name="p">Triple Pattern</param>
 public AskBgp(ITriplePattern p)
 {
     if (!IsAskEvaluablePattern(p)) throw new ArgumentException("Triple Pattern instance must be a Triple Pattern or a FILTER Pattern", "p");
     this._triplePatterns.Add(p);
 }
Ejemplo n.º 30
0
 /// <summary>
 /// Determines whether a Triple Pattern can be evaluated using a Lazy ASK approach
 /// </summary>
 /// <param name="p">Triple Pattern</param>
 /// <returns></returns>
 private bool IsAskEvaluablePattern(ITriplePattern p)
 {
     return(p is TriplePattern || p is FilterPattern);
 }
Ejemplo n.º 31
0
 private bool IsLazilyEvaluablePattern(ITriplePattern p)
 {
     return(p is TriplePattern || p is FilterPattern || p is BindPattern);
 }
Ejemplo n.º 32
0
 /// <summary>
 /// Determines whether a Triple Pattern can be evaluated using a Lazy ASK approach
 /// </summary>
 /// <param name="p">Triple Pattern</param>
 /// <returns></returns>
 private bool IsAskEvaluablePattern(ITriplePattern p)
 {
     return (p is TriplePattern || p is FilterPattern);
 }
Ejemplo n.º 33
0
        private bool IsDisjointOperation(ISparqlAlgebra algebra, String lhsVar, String rhsVar, out int splitPoint)
        {
            splitPoint = -1;
            if (algebra is IBgp)
            {
                // Get Triple Patterns, can't split into a product if there are blank variables present
                List <ITriplePattern> ps = ((IBgp)algebra).TriplePatterns.ToList();
                if (ps.Any(p => !p.HasNoBlankVariables))
                {
                    return(false);
                }

                // Iterate over the Triple Patterns to see if we can split into a Product
                List <String> vars = new List <String>();
                for (int i = 0; i < ps.Count; i++)
                {
                    // Not a product if we've seen both variables already
                    if (vars.Contains(lhsVar) && vars.Contains(rhsVar))
                    {
                        return(false);
                    }

                    ITriplePattern p = ps[i];
                    switch (p.PatternType)
                    {
                    case TriplePatternType.Match:
                    case TriplePatternType.SubQuery:
                        if (vars.Count > 0 && vars.IsDisjoint(p.Variables))
                        {
                            // May be a filterable product if we've seen only one variable so far and have hit a point where a product occurs
                            if (vars.Contains(lhsVar) && !vars.Contains(rhsVar))
                            {
                                Bgp rhs = new Bgp(ps.Skip(i));
                                if (rhs.Variables.Contains(rhsVar))
                                {
                                    splitPoint = i;
                                    return(true);
                                }
                            }
                            else if (vars.Contains(rhsVar) && !vars.Contains(lhsVar))
                            {
                                Bgp rhs = new Bgp(ps.Skip(i));
                                if (rhs.Variables.Contains(lhsVar))
                                {
                                    splitPoint = i;
                                    return(true);
                                }
                            }
                        }
                        vars.AddRange(p.Variables);
                        break;

                    case TriplePatternType.BindAssignment:
                    case TriplePatternType.LetAssignment:
                        vars.Add(((IAssignmentPattern)p).VariableName);
                        break;

                    case TriplePatternType.Filter:
                        continue;

                    default:
                        // Can't determine if it is a disjoint operation if other pattern types are involved
                        return(false);
                    }
                }
                // If we get all the way here then not a product
                return(false);
            }
            else if (algebra is IJoin)
            {
                IJoin join = (IJoin)algebra;
                if (join.Lhs.Variables.IsDisjoint(join.Rhs.Variables))
                {
                    // There a product between the two sides of the join but are the two variables on different sides of that join
                    return(!(join.Lhs.Variables.Contains(lhsVar) && join.Lhs.Variables.Contains(rhsVar)) && !(join.Rhs.Variables.Contains(lhsVar) && join.Rhs.Variables.Contains(rhsVar)));
                }
                else
                {
                    return(false);
                }
            }
            else
            {
                return(false);
            }
        }
Ejemplo n.º 34
0
        /// <summary>
        /// Optimises the Algebra so that BGPs containing relevant patterns are converted to use the <see cref="FullTextMatch">FullTextMatch</see> operator
        /// </summary>
        /// <param name="algebra">Algebra to optimise</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 <FullTextPattern> fps = FullTextHelper.ExtractPatterns(current.TriplePatterns);
                    if (fps.Count == 0)
                    {
                        return(algebra);
                    }
                    List <ITriplePattern> ps = current.TriplePatterns.ToList();

                    //First we want to find where each FullTextPattern is located in the original triple patterns
                    Dictionary <int, int> locations = new Dictionary <int, int>();
                    for (int i = 0; i < fps.Count; i++)
                    {
                        locations.Add(i, -1);
                        ITriplePattern first = fps[i].OriginalPatterns.First();
                        for (int j = 0; j < ps.Count; j++)
                        {
                            if (first.Equals(ps[j]))
                            {
                                locations[i] = j;
                                break;
                            }
                        }
                        //If we fail to locate this we've failed to optimise here so must abort
                        if (locations[i] == -1)
                        {
                            return(algebra);
                        }
                    }

                    //Knowing this we can then start splitting the BGP into several BGPs
                    int locBase = 0;
                    foreach (int i in Enumerable.Range(0, fps.Count).OrderBy(x => locations[x]).ToList())
                    {
                        //Wrap everything up to that point in a BGP excluding any patterns relevant to any FullTextPattern
                        result  = Join.CreateJoin(result, new Bgp(ps.Skip(locBase).Take(locations[i]).Where(tp => !(tp is TriplePattern) || !fps.Any(fp => fp.OriginalPatterns.Contains((TriplePattern)tp)))));
                        locBase = locations[i] + 1;
                        //Then apply the FullTextMatch operator over it
                        FullTextPattern ftp = fps[i];
                        result = new FullTextMatch(this._provider, result, ftp.MatchVariable, ftp.ScoreVariable, ftp.SearchTerm, ftp.Limit, ftp.ScoreThreshold);
                    }

                    //If there are any patterns left over remember to include them
                    if (locBase < ps.Count)
                    {
                        result = Join.CreateJoin(result, new Bgp(ps.Skip(locBase).Where(tp => !(tp is TriplePattern) || !fps.Any(fp => fp.OriginalPatterns.Contains((TriplePattern)tp)))));
                    }
                    return(result);

                    //List<ITriplePattern> patterns = new List<ITriplePattern>();
                    //List<ITriplePattern> ps = new List<ITriplePattern>(current.TriplePatterns.ToList());
                    //for (int i = 0; i < current.PatternCount; i++)
                    //{
                    //    if (!(ps[i] is TriplePattern))
                    //    {
                    //        patterns.Add(ps[i]);
                    //    }
                    //    else
                    //    {
                    //        //Check to see if the Predicate of the Pattern match the Full Text Match Predicate URI
                    //        TriplePattern tp = (TriplePattern)ps[i];
                    //        PatternItem pred = tp.Predicate;
                    //        if (pred is NodeMatchPattern)
                    //        {
                    //            INode predNode = ((NodeMatchPattern)pred).Node;
                    //            if (predNode.NodeType == NodeType.Uri)
                    //            {
                    //                String predUri = ((IUriNode)predNode).Uri.ToString();
                    //                if (predUri.Equals(FullTextHelper.FullTextMatchPredicateUri))
                    //                {
                    //                    if (patterns.Count > 0) result = Join.CreateJoin(result, new Bgp(patterns));
                    //                    result = new FullTextMatch(this._provider, result, tp.Subject, tp.Object);
                    //                    patterns.Clear();
                    //                }
                    //                else
                    //                {
                    //                    patterns.Add(ps[i]);
                    //                }
                    //            }
                    //            else
                    //            {
                    //                patterns.Add(ps[i]);
                    //            }
                    //        }
                    //        else
                    //        {
                    //            patterns.Add(ps[i]);
                    //        }
                    //    }
                    //}

                    //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);
            }
        }
Ejemplo n.º 35
0
 /// <summary>
 /// Determines whether a Triple Pattern can be evaluated using a Lazy ASK approach
 /// </summary>
 /// <param name="p">Triple Pattern</param>
 /// <returns></returns>
 private bool IsAskEvaluablePattern(ITriplePattern p)
 {
     return(p.PatternType == TriplePatternType.Match || p.PatternType == TriplePatternType.Filter);
 }
Ejemplo n.º 36
0
        /// <summary>
        /// Formats a Triple Pattern in nicely formatted SPARQL syntax
        /// </summary>
        /// <param name="tp">Triple Pattern</param>
        /// <returns></returns>
        public virtual String Format(ITriplePattern tp)
        {
            StringBuilder output = new StringBuilder();
            if (tp is TriplePattern)
            {
                TriplePattern match = (TriplePattern)tp;
                output.Append(this.Format(match.Subject, TripleSegment.Subject));
                output.Append(' ');
                output.Append(this.Format(match.Predicate, TripleSegment.Predicate));
                output.Append(' ');
                output.Append(this.Format(match.Object, TripleSegment.Object));
                output.Append(" .");
            }
            else if (tp is FilterPattern)
            {
                FilterPattern filter = (FilterPattern)tp;
                output.Append("FILTER(");
                output.Append(this.FormatExpression(filter.Filter.Expression));
                output.Append(")");
            }
            else if (tp is SubQueryPattern)
            {
                SubQueryPattern subquery = (SubQueryPattern)tp;
                output.AppendLine("{");
                output.AppendLineIndented(this.Format(subquery.SubQuery), 2);
                output.AppendLine("}");
            }
            else if (tp is PropertyPathPattern)
            {
                PropertyPathPattern path = (PropertyPathPattern)tp;
                output.Append(this.Format(path.Subject, TripleSegment.Subject));
                output.Append(' ');
                output.Append(this.FormatPath(path.Path));
                output.Append(' ');
                output.Append(this.Format(path.Object, TripleSegment.Object));
                output.Append(" .");
            }
            else if (tp is LetPattern)
            {
                LetPattern let = (LetPattern)tp;
                output.Append("LET(?");
                output.Append(let.VariableName);
                output.Append(" := ");
                output.Append(this.FormatExpression(let.AssignExpression));
                output.Append(")");
            }
            else if (tp is BindPattern)
            {
                BindPattern bind = (BindPattern)tp;
                output.Append("BIND (");
                output.Append(this.FormatExpression(bind.AssignExpression));
                output.Append(" AS ?");
                output.Append(bind.VariableName);
                output.Append(")");
            }
            else
            {
                throw new RdfOutputException("Unable to Format an unknown ITriplePattern implementation as a String");
            }

            return output.ToString();
        }
Ejemplo n.º 37
0
        private void ProcessSkipTopFilterOrderBy()
        {
            if (QueryOptions.Skip != null || QueryOptions.Top != null ||
                (QueryOptions.OrderBy != null && QueryOptions.OrderBy.OrderByClause != null))
            {
                NodeFactory           nodeFactory = new NodeFactory();
                var                   edmNode     = EdmNodeList[EdmNodeList.Count - 1];
                ITriplePattern[]      tps;
                List <ITriplePattern> optionList = new List <ITriplePattern>();
                if (EdmNodeList.Count > 1 && (EdmNodeList[EdmNodeList.Count - 2].RdfNode is NodeMatchPattern))
                {
                    var prevEdmNode = EdmNodeList[EdmNodeList.Count - 2];
                    Dictionary <string, Tuple <Type, Uri> > properties = GetAllProperties(prevEdmNode.ItemEdmType);
                    tps = new ITriplePattern[] {
                        new TriplePattern(prevEdmNode.RdfNode,
                                          new NodeMatchPattern(nodeFactory.CreateUriNode(new Uri(properties[edmNode.RdfNode.VariableName].Item2.AbsoluteUri))),
                                          edmNode.RdfNode),
                        new TriplePattern(edmNode.RdfNode,
                                          new NodeMatchPattern(nodeFactory.CreateUriNode(new Uri(RdfSpecsHelper.RdfType))),
                                          new NodeMatchPattern(nodeFactory.CreateUriNode(GetUri(edmNode.ItemEdmType))))
                    };
                    foreach (var prop in edmNode.StructProperties.Where(p => p.Name != "LocalId"))
                    {
                        var propTriple = new TriplePattern(edmNode.RdfNode,
                                                           new NodeMatchPattern(nodeFactory.CreateUriNode(new Uri(properties[prop.Name].Item2.AbsoluteUri))),
                                                           new VariablePattern($"{prop.Name}"));
                        optionList.Add(propTriple);
                    }
                }
                else
                {
                    tps = new ITriplePattern[] { new TriplePattern(edmNode.RdfNode,
                                                                   new NodeMatchPattern(nodeFactory.CreateUriNode(new Uri(RdfSpecsHelper.RdfType))),
                                                                   new NodeMatchPattern(nodeFactory.CreateUriNode(GetUri(edmNode.ItemEdmType)))) };
                    Dictionary <string, Tuple <Type, Uri> > properties = GetAllProperties(edmNode.ItemEdmType);
                    foreach (var prop in edmNode.StructProperties.Where(p => p.Name != "LocalId"))
                    {
                        var propTriple = new TriplePattern(edmNode.RdfNode,
                                                           new NodeMatchPattern(nodeFactory.CreateUriNode(new Uri(properties[prop.Name].Item2.AbsoluteUri))),
                                                           new VariablePattern($"{prop.Name}"));
                        optionList.Add(propTriple);
                    }
                }

                IQueryBuilder subqueryBuilder = QueryBuilder.Select(new string[] { edmNode.Name }).
                                                Where(tps);

                foreach (var tp in optionList)
                {
                    subqueryBuilder.Optional(gp => gp.Where(tp));
                }

                if (QueryOptions.Skip != null)
                {
                    subqueryBuilder = subqueryBuilder.Offset(QueryOptions.Skip.Value);
                }
                if (QueryOptions.Top != null)
                {
                    subqueryBuilder = subqueryBuilder.Limit(QueryOptions.Top.Value);
                }
                if (FilterExp != null)
                {
                    subqueryBuilder = subqueryBuilder.Filter(FilterExp);
                    FilterExp       = null;
                }
                if (QueryOptions.OrderBy != null && QueryOptions.OrderBy.OrderByClause != null)
                {
                    foreach (var node in QueryOptions.OrderBy.OrderByNodes)
                    {
                        var typedNode = node as OrderByPropertyNode;
                        var ordName   = typedNode.Property.Name;
                        if (ordName.ToLower() == "localid")
                        {
                            ordName = edmNode.Name;
                        }
                        if (typedNode.OrderByClause.Direction == OrderByDirection.Ascending)
                        {
                            subqueryBuilder.OrderBy(ordName);
                        }
                        else
                        {
                            subqueryBuilder.OrderByDescending(ordName);
                        }
                    }
                }
                SubQueryTriplePatterns.Add(new SubQueryPattern(subqueryBuilder.BuildQuery()));
            }
        }
Ejemplo n.º 38
0
 /// <summary>
 /// Creates a BGP containing a single Triple Pattern
 /// </summary>
 /// <param name="p">Triple Pattern</param>
 public Bgp(ITriplePattern p)
 {
     this._triplePatterns.Add(p);
 }
Ejemplo n.º 39
0
        /// <summary>
        /// Formats a Triple Pattern in nicely formatted SPARQL syntax
        /// </summary>
        /// <param name="tp">Triple Pattern</param>
        /// <returns></returns>
        public virtual String Format(ITriplePattern tp)
        {
            StringBuilder output = new StringBuilder();

            switch (tp.PatternType)
            {
            case TriplePatternType.Match:
                IMatchTriplePattern match = (IMatchTriplePattern)tp;
                output.Append(this.Format(match.Subject, TripleSegment.Subject));
                output.Append(' ');
                output.Append(this.Format(match.Predicate, TripleSegment.Predicate));
                output.Append(' ');
                output.Append(this.Format(match.Object, TripleSegment.Object));
                output.Append(" .");
                break;

            case TriplePatternType.Filter:
                IFilterPattern filter = (IFilterPattern)tp;
                output.Append("FILTER(");
                output.Append(this.FormatExpression(filter.Filter.Expression));
                output.Append(")");
                break;

            case TriplePatternType.SubQuery:
                ISubQueryPattern subquery = (ISubQueryPattern)tp;
                output.AppendLine("{");
                output.AppendLineIndented(this.Format(subquery.SubQuery), 2);
                output.AppendLine("}");
                break;

            case TriplePatternType.Path:
                IPropertyPathPattern path = (IPropertyPathPattern)tp;
                output.Append(this.Format(path.Subject, TripleSegment.Subject));
                output.Append(' ');
                output.Append(this.FormatPath(path.Path));
                output.Append(' ');
                output.Append(this.Format(path.Object, TripleSegment.Object));
                output.Append(" .");
                break;

            case TriplePatternType.LetAssignment:
                IAssignmentPattern let = (IAssignmentPattern)tp;
                output.Append("LET(?");
                output.Append(let.VariableName);
                output.Append(" := ");
                output.Append(this.FormatExpression(let.AssignExpression));
                output.Append(")");
                break;

            case TriplePatternType.BindAssignment:
                IAssignmentPattern bind = (IAssignmentPattern)tp;
                output.Append("BIND (");
                output.Append(this.FormatExpression(bind.AssignExpression));
                output.Append(" AS ?");
                output.Append(bind.VariableName);
                output.Append(")");
                break;

            case TriplePatternType.PropertyFunction:
                IPropertyFunctionPattern propFunc = (IPropertyFunctionPattern)tp;
                if (propFunc.SubjectArgs.Count() > 1)
                {
                    output.Append("( ");
                    foreach (PatternItem arg in propFunc.SubjectArgs)
                    {
                        output.Append(this.Format(arg, TripleSegment.Subject));
                        output.Append(' ');
                    }
                    output.Append(')');
                }
                else
                {
                    output.Append(this.Format(propFunc.SubjectArgs.First(), TripleSegment.Subject));
                }
                output.Append(" <");
                output.Append(this.FormatUri(propFunc.PropertyFunction.FunctionUri));
                output.Append("> ");
                if (propFunc.ObjectArgs.Count() > 1)
                {
                    output.Append("( ");
                    foreach (PatternItem arg in propFunc.ObjectArgs)
                    {
                        output.Append(this.Format(arg, TripleSegment.Object));
                        output.Append(' ');
                    }
                    output.Append(')');
                }
                else
                {
                    output.Append(this.Format(propFunc.ObjectArgs.First(), TripleSegment.Object));
                }
                output.Append(" .");
                break;

            default:
                throw new RdfOutputException("Unable to Format an unknown ITriplePattern implementation as a String");
            }

            return(output.ToString());
        }
 public PassthroughCollapseGroup(ITriplePattern tp, IEnumerable<string> globalSortVars):base(tp, globalSortVars)
 {
     _triplePattern = tp;
 }