/// <summary>
        /// Generates a Comparer than can be used to do Ordering based on the given Triple Pattern
        /// </summary>
        /// <param name="pattern">Triple Pattern</param>
        /// <returns></returns>
        public override IComparer <Triple> GetComparer(IMatchTriplePattern pattern)
        {
            if (this._expr is VariableTerm)
            {
                IComparer <Triple>         child       = (this._child == null) ? null : this._child.GetComparer(pattern);
                Func <Triple, Triple, int> compareFunc = null;
                String var = this._expr.Variables.First();
                if (var.Equals(pattern.Subject.VariableName))
                {
                    compareFunc = (x, y) => this._comparer.Compare(x.Subject, y.Subject);
                }
                else if (var.Equals(pattern.Predicate.VariableName))
                {
                    compareFunc = (x, y) => this._comparer.Compare(x.Predicate, y.Predicate);
                }
                else if (var.Equals(pattern.Object.VariableName))
                {
                    compareFunc = (x, y) => this._comparer.Compare(x.Object, y.Object);
                }

                if (compareFunc == null)
                {
                    return(null);
                }
                return(new TripleComparer(compareFunc, this.Descending, child));
            }
            else
            {
                return(null);
            }
        }
        public void CanCreateTriplePatternsUsingTypedLiteralObject()
        {
            // when
            _builder.Subject("s").Predicate("p").ObjectLiteral(42, new Uri(XmlSpecsHelper.XmlSchemaDataTypeInteger));

            // then
            Assert.Single(_builder.Patterns);
            IMatchTriplePattern pattern = (IMatchTriplePattern)_builder.Patterns.Single();

            Assert.True(pattern.Object is NodeMatchPattern);
            Assert.Equal("42", ((dynamic)pattern.Object).Node.Value);
            Assert.Equal(new Uri(XmlSpecsHelper.XmlSchemaDataTypeInteger), ((dynamic)pattern.Object).Node.DataType);
        }
        public void CanCreateTriplePatternsUsingLiteralObjectWithLanuageTag2()
        {
            // when
            _builder.Subject("s").Predicate("p").ObjectLiteral(42, "pl-PL");

            // then
            Assert.Single(_builder.Patterns);
            IMatchTriplePattern pattern = (IMatchTriplePattern)_builder.Patterns.Single();

            Assert.True(pattern.Object is NodeMatchPattern);
            Assert.Equal("42", ((dynamic)pattern.Object).Node.Value);
            Assert.Null(((dynamic)pattern.Object).Node.DataType);
            Assert.Equal("pl-pl", ((dynamic)pattern.Object).Node.Language);
        }
        public void CanCreateTriplePatternsUsingIntegerLiteralObject()
        {
            // when
            _builder.Subject("s").Predicate("p").ObjectLiteral(42);

            // then
            Assert.Single(_builder.Patterns);
            IMatchTriplePattern pattern = (IMatchTriplePattern)_builder.Patterns.Single();

            Assert.True(pattern.Object is NodeMatchPattern);
            Assert.Equal("42", ((dynamic)pattern.Object).Node.Value);
            Assert.Null(((dynamic)pattern.Object).Node.DataType);
            Assert.True(string.IsNullOrWhiteSpace(((dynamic)pattern.Object).Node.Language));
        }
        public void CanCreateTriplePatternsUsingBlankNodeForSubject()
        {
            // when
            _builder.Subject <IBlankNode>("s").Predicate("p").Object("o");

            // then
            Assert.Single(_builder.Patterns);
            IMatchTriplePattern pattern = (IMatchTriplePattern)_builder.Patterns.Single();

            Assert.True(pattern.Subject is BlankNodePattern);
            Assert.Equal("_:s", ((BlankNodePattern)pattern.Subject).ID);
            Assert.True(pattern.Predicate is VariablePattern);
            Assert.Equal("p", pattern.Predicate.VariableName);
            Assert.True(pattern.Object is VariablePattern);
            Assert.Equal("o", pattern.Object.VariableName);
        }
        public void CanCreateTriplePatternsUsingUriForObject()
        {
            // when
            _builder.Subject("s").Predicate("p").Object(new Uri("http://xmlns.com/foaf/0.1/Person"));

            // then
            Assert.Single(_builder.Patterns);
            IMatchTriplePattern pattern = (IMatchTriplePattern)_builder.Patterns.Single();

            Assert.True(pattern.Predicate is VariablePattern);
            Assert.Equal("p", pattern.Predicate.VariableName);
            Assert.True(pattern.Subject is VariablePattern);
            Assert.Equal("s", pattern.Subject.VariableName);
            Assert.True(pattern.Object is NodeMatchPattern);
            Assert.Equal(new Uri("http://xmlns.com/foaf/0.1/Person"), ((dynamic)pattern.Object).Node.Uri);
        }
        public void CanCreateTriplePatternUsingVariableNames()
        {
            // when
            _builder.Subject("s").Predicate("p").Object("o");

            // then
            Assert.Single(_builder.Patterns);
            IMatchTriplePattern pattern = (IMatchTriplePattern)_builder.Patterns.Single();

            Assert.True(pattern.Subject is VariablePattern);
            Assert.Equal("s", pattern.Subject.VariableName);
            Assert.True(pattern.Predicate is VariablePattern);
            Assert.Equal("p", pattern.Predicate.VariableName);
            Assert.True(pattern.Object is VariablePattern);
            Assert.Equal("o", pattern.Object.VariableName);
        }
        public void CanCreateTriplePatternsUsingDateTimeLiteralObject()
        {
            // given
            var dateTime = new DateTime(2012, 10, 13, 15, 45, 15);

            // when
            _builder.Subject("s").Predicate("p").ObjectLiteral(dateTime);

            // then
            Assert.Single(_builder.Patterns);
            IMatchTriplePattern pattern = (IMatchTriplePattern)_builder.Patterns.Single();

            Assert.True(pattern.Object is NodeMatchPattern);
            Assert.Equal(dateTime.ToString(XmlSpecsHelper.XmlSchemaDateTimeFormat), ((dynamic)pattern.Object).Node.Value);
            Assert.Null(((dynamic)pattern.Object).Node.DataType);
            Assert.True(string.IsNullOrWhiteSpace(((dynamic)pattern.Object).Node.Language));
        }
        public void CanCreateTriplePatternsUsingDateTimeOffsetLiteralObject()
        {
            // given
            var dateTime = new DateTimeOffset(2012, 10, 13, 20, 35, 10, new TimeSpan(0, 1, 30, 0));

            // when
            _builder.Subject("s").Predicate("p").ObjectLiteral(dateTime);

            // then
            Assert.Single(_builder.Patterns);
            IMatchTriplePattern pattern = (IMatchTriplePattern)_builder.Patterns.Single();

            Assert.True(pattern.Object is NodeMatchPattern);
            Assert.Equal("2012-10-13T20:35:10.000000+01:30", ((dynamic)pattern.Object).Node.Value);
            Assert.Null(((dynamic)pattern.Object).Node.DataType);
            Assert.True(string.IsNullOrWhiteSpace(((dynamic)pattern.Object).Node.Language));
        }
        public void CanCreateTriplePatternsUsingActualPatternItems()
        {
            // given
            PatternItem s = new VariablePattern("s");
            PatternItem p = new VariablePattern("p");
            PatternItem o = new VariablePattern("o");

            // when
            _builder.Subject(s).Predicate(p).Object(o);

            // then
            Assert.Single(_builder.Patterns);
            IMatchTriplePattern pattern = (IMatchTriplePattern)_builder.Patterns.Single();

            Assert.Same(s, pattern.Subject);
            Assert.Same(p, pattern.Predicate);
            Assert.Same(o, pattern.Object);
        }
        public void CanCreateTriplePatternsUsingINodeForObject()
        {
            // given
            var node = new NodeFactory().CreateUriNode(new Uri("http://www.example.com/object"));

            // when
            _builder.Subject("s").Predicate("p").Object(node);

            // then
            Assert.Single(_builder.Patterns);
            IMatchTriplePattern pattern = (IMatchTriplePattern)_builder.Patterns.Single();

            Assert.True(pattern.Object is NodeMatchPattern);
            Assert.Same(node, ((NodeMatchPattern)pattern.Object).Node);
            Assert.True(pattern.Predicate is VariablePattern);
            Assert.Equal("p", pattern.Predicate.VariableName);
            Assert.True(pattern.Subject is VariablePattern);
            Assert.Equal("s", pattern.Subject.VariableName);
        }
        public void CanCreateTriplePatternsUsingINodeForSubject()
        {
            // given
            var node = new NodeFactory().CreateBlankNode("bnode");

            // when
            _builder.Subject(node).Predicate("p").Object("o");

            // then
            Assert.Single(_builder.Patterns);
            IMatchTriplePattern pattern = (IMatchTriplePattern)_builder.Patterns.Single();

            Assert.True(pattern.Subject is NodeMatchPattern);
            Assert.Same(node, ((NodeMatchPattern)pattern.Subject).Node);
            Assert.True(pattern.Predicate is VariablePattern);
            Assert.Equal("p", pattern.Predicate.VariableName);
            Assert.True(pattern.Object is VariablePattern);
            Assert.Equal("o", pattern.Object.VariableName);
        }
Exemple #13
0
        public void CanCreateTriplePatternsUsingIUriNodeForPredicate()
        {
            // given
            var node = new NodeFactory().CreateUriNode(new Uri("http://www.example.com/predicate"));

            // when
            _builder.Subject("s").PredicateUri(node).Object("o");

            // then
            Assert.AreEqual(1, _builder.Patterns.Length);
            IMatchTriplePattern pattern = (IMatchTriplePattern)_builder.Patterns.Single();

            Assert.IsTrue(pattern.Subject is VariablePattern);
            Assert.AreEqual("s", pattern.Subject.VariableName);
            Assert.IsTrue(pattern.Predicate is NodeMatchPattern);
            Assert.AreSame(node, ((NodeMatchPattern)pattern.Predicate).Node);
            Assert.IsTrue(pattern.Object is VariablePattern);
            Assert.AreEqual("o", pattern.Object.VariableName);
        }
        public void CanCreateTriplePatternsUsingUriForPredicate()
        {
            // given
            var predicateUri = new Uri("http://www.example.com/property");

            // when
            _builder.Subject("s").PredicateUri(predicateUri).Object("o");

            // then
            Assert.Single(_builder.Patterns);
            IMatchTriplePattern pattern = (IMatchTriplePattern)_builder.Patterns.Single();

            Assert.True(pattern.Subject is VariablePattern);
            Assert.Equal("s", pattern.Subject.VariableName);
            Assert.True(pattern.Predicate is NodeMatchPattern);
            Assert.Equal(new Uri("http://www.example.com/property"), ((dynamic)pattern.Predicate).Node.Uri);
            Assert.True(pattern.Object is VariablePattern);
            Assert.Equal("o", pattern.Object.VariableName);
        }
        public void CanCreateTriplePatternsUsingQNameForSubject()
        {
            // given
            const string predicateQName = "foaf:name";

            _namespaceMapper.Setup(m => m.GetNamespaceUri("foaf")).Returns(new Uri("http://xmlns.com/foaf/0.1/"));

            // when
            _builder.Subject <IUriNode>(predicateQName).Predicate("p").Object("o");

            // then
            Assert.Single(_builder.Patterns);
            IMatchTriplePattern pattern = (IMatchTriplePattern)_builder.Patterns.Single();

            Assert.True(pattern.Subject is NodeMatchPattern);
            Assert.Equal(new Uri("http://xmlns.com/foaf/0.1/name"), ((dynamic)pattern.Subject).Node.Uri);
            Assert.True(pattern.Predicate is VariablePattern);
            Assert.Equal("p", pattern.Predicate.VariableName);
            Assert.True(pattern.Object is VariablePattern);
            Assert.Equal("o", pattern.Object.VariableName);
        }
Exemple #16
0
        /// <summary>
        /// Generates a Comparer than can be used to do Ordering based on the given Triple Pattern.
        /// </summary>
        /// <param name="pattern">Triple Pattern.</param>
        /// <returns></returns>
        public override IComparer <Triple> GetComparer(IMatchTriplePattern pattern)
        {
            IComparer <Triple>         child       = (_child == null) ? null : _child.GetComparer(pattern);
            Func <Triple, Triple, int> compareFunc = null;

            if (_varname.Equals(pattern.Subject.VariableName))
            {
                compareFunc = (x, y) => _comparer.Compare(x.Subject, y.Subject);
            }
            else if (_varname.Equals(pattern.Predicate.VariableName))
            {
                compareFunc = (x, y) => _comparer.Compare(x.Predicate, y.Predicate);
            }
            else if (_varname.Equals(pattern.Object.VariableName))
            {
                compareFunc = (x, y) => _comparer.Compare(x.Object, y.Object);
            }

            if (compareFunc == null)
            {
                return(null);
            }
            return(new TripleComparer(compareFunc, Descending, child));
        }
Exemple #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();

            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());
        }
        /// <summary>
        /// Attempts to do variable substitution within the given algebra
        /// </summary>
        /// <param name="algebra">Algebra</param>
        /// <returns></returns>
        public ISparqlAlgebra Optimise(ISparqlAlgebra algebra)
        {
            // By default we are only safe to replace objects in a scope if we are replacing with a constant
            // Note that if we also make a replace in a subject/predicate position for a variable replace then
            // that makes object replacement safe for that scope only
            bool canReplaceObjects = (this._canReplaceCustom ? this._canReplaceObjects : this._replaceItem is NodeMatchPattern);

            if (algebra is IBgp)
            {
                IBgp bgp = (IBgp)algebra;
                if (bgp.PatternCount == 0)
                {
                    return(bgp);
                }

                // Do variable substitution on the patterns
                List <ITriplePattern> ps = new List <ITriplePattern>();
                foreach (ITriplePattern p in bgp.TriplePatterns)
                {
                    switch (p.PatternType)
                    {
                    case TriplePatternType.Match:
                        IMatchTriplePattern tp   = (IMatchTriplePattern)p;
                        PatternItem         subj = tp.Subject.VariableName != null && tp.Subject.VariableName.Equals(this._findVar) ? this._replaceItem : tp.Subject;
                        if (ReferenceEquals(subj, this._replaceItem))
                        {
                            canReplaceObjects = (this._canReplaceCustom ? this._canReplaceObjects : true);
                        }
                        PatternItem pred = tp.Predicate.VariableName != null && tp.Predicate.VariableName.Equals(this._findVar) ? this._replaceItem : tp.Predicate;
                        if (ReferenceEquals(pred, this._replaceItem))
                        {
                            canReplaceObjects = (this._canReplaceCustom ? this._canReplaceObjects : true);
                        }
                        PatternItem obj = tp.Object.VariableName != null && tp.Object.VariableName.Equals(this._findVar) ? this._replaceItem : tp.Object;
                        if (ReferenceEquals(obj, this._replaceItem) && !canReplaceObjects)
                        {
                            throw new Exception("Unable to substitute a variable into the object position in this scope");
                        }
                        ps.Add(new TriplePattern(subj, pred, obj));
                        break;

                    case TriplePatternType.Filter:
                        IFilterPattern fp = (IFilterPattern)p;
                        ps.Add(new FilterPattern(new UnaryExpressionFilter(this.Transform(fp.Filter.Expression))));
                        break;

                    case TriplePatternType.BindAssignment:
                        IAssignmentPattern bp = (IAssignmentPattern)p;
                        ps.Add(new BindPattern(bp.VariableName, this.Transform(bp.AssignExpression)));
                        break;

                    case TriplePatternType.LetAssignment:
                        IAssignmentPattern lp = (IAssignmentPattern)p;
                        ps.Add(new LetPattern(lp.VariableName, this.Transform(lp.AssignExpression)));
                        break;

                    case TriplePatternType.SubQuery:
                        throw new RdfQueryException("Cannot do variable substitution when a sub-query is present");

                    case TriplePatternType.Path:
                        throw new RdfQueryException("Cannot do variable substitution when a property path is present");

                    case TriplePatternType.PropertyFunction:
                        throw new RdfQueryException("Cannot do variable substituion when a property function is present");

                    default:
                        throw new RdfQueryException("Cannot do variable substitution on unknown triple patterns");
                    }
                }
                return(new Bgp(ps));
            }
            else if (algebra is Service)
            {
                throw new RdfQueryException("Cannot do variable substitution when a SERVICE clause is present");
            }
            else if (algebra is SubQuery)
            {
                throw new RdfQueryException("Cannot do variable substitution when a sub-query is present");
            }
            else if (algebra is IPathOperator)
            {
                throw new RdfQueryException("Cannot do variable substitution when a property path is present");
            }
            else if (algebra is Algebra.Graph)
            {
                Algebra.Graph g = (Algebra.Graph)((IUnaryOperator)algebra).Transform(this);
                if (g.GraphSpecifier is VariableToken && g.GraphSpecifier.Value.Equals("?" + this._findVar))
                {
                    if (this._replaceToken != null)
                    {
                        return(new Algebra.Graph(g.InnerAlgebra, this._replaceToken));
                    }
                    else
                    {
                        throw new RdfQueryException("Cannot do a variable substitution when the variable is used for a GRAPH specifier and the replacement term is not a URI");
                    }
                }
                else
                {
                    return(g);
                }
            }
            else if (algebra is IUnaryOperator)
            {
                return(((IUnaryOperator)algebra).Transform(this));
            }
            else if (algebra is IAbstractJoin)
            {
                return(((IAbstractJoin)algebra).Transform(this));
            }
            else if (algebra is ITerminalOperator)
            {
                return(algebra);
            }
            else
            {
                throw new RdfQueryException("Cannot do variable substitution on unknown algebra");
            }
        }
        private void GetSelectivities(ITriplePattern x, out double subj, out double pred, out double obj)
        {
            switch (x.PatternType)
            {
            case TriplePatternType.Match:
                IMatchTriplePattern p = (IMatchTriplePattern)x;
                switch (p.IndexType)
                {
                case TripleIndexType.NoVariables:
                    subj = _weights.SubjectWeighting(((NodeMatchPattern)p.Subject).Node);
                    pred = _weights.PredicateWeighting(((NodeMatchPattern)p.Predicate).Node);
                    obj  = _weights.ObjectWeighting(((NodeMatchPattern)p.Object).Node);
                    break;

                case TripleIndexType.Object:
                    subj = _weights.DefaultVariableWeighting;
                    pred = _weights.DefaultVariableWeighting;
                    obj  = _weights.ObjectWeighting(((NodeMatchPattern)p.Object).Node);
                    break;

                case TripleIndexType.Predicate:
                    subj = _weights.DefaultVariableWeighting;
                    pred = _weights.PredicateWeighting(((NodeMatchPattern)p.Predicate).Node);
                    obj  = _weights.DefaultVariableWeighting;
                    break;

                case TripleIndexType.PredicateObject:
                    subj = _weights.DefaultVariableWeighting;
                    pred = _weights.PredicateWeighting(((NodeMatchPattern)p.Predicate).Node);
                    obj  = _weights.ObjectWeighting(((NodeMatchPattern)p.Object).Node);
                    break;

                case TripleIndexType.Subject:
                    subj = _weights.SubjectWeighting(((NodeMatchPattern)p.Subject).Node);
                    pred = _weights.DefaultVariableWeighting;
                    obj  = _weights.DefaultVariableWeighting;
                    break;

                case TripleIndexType.SubjectObject:
                    subj = _weights.SubjectWeighting(((NodeMatchPattern)p.Subject).Node);
                    pred = _weights.DefaultVariableWeighting;
                    obj  = _weights.PredicateWeighting(((NodeMatchPattern)p.Object).Node);
                    break;

                case TripleIndexType.SubjectPredicate:
                    subj = _weights.SubjectWeighting(((NodeMatchPattern)p.Subject).Node);
                    pred = _weights.PredicateWeighting(((NodeMatchPattern)p.Predicate).Node);
                    obj  = _weights.DefaultVariableWeighting;
                    break;

                default:
                    // Shouldn't see an unknown index type but have to keep the compiler happy
                    subj = 1d;
                    pred = 1d;
                    obj  = 1d;
                    break;
                }
                break;

            default:
                // Otherwise all are considered to have equivalent selectivity
                subj = 1d;
                pred = 1d;
                obj  = 1d;
                break;
            }
        }
Exemple #20
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");
        }
 /// <summary>
 /// Compares a triple pattern to another.
 /// </summary>
 /// <param name="other">Pattern.</param>
 /// <returns></returns>
 public int CompareTo(IMatchTriplePattern other)
 {
     return(base.CompareTo(other));
 }
Exemple #22
0
        private BaseMultiset StreamingEvaluate(SparqlEvaluationContext context, int pattern, out bool halt)
        {
            // Remember to check for Timeouts during Lazy Evaluation
            context.CheckTimeout();

            halt = false;

            // Handle Empty BGPs
            if (pattern == 0 && _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 = (_triplePatterns[pattern].PatternType == TriplePatternType.Filter);
            bool extended = (pattern > 0 && _triplePatterns[pattern - 1].PatternType == TriplePatternType.BindAssignment);
            bool modified = (pattern > 0 && _triplePatterns[pattern - 1].PatternType == TriplePatternType.Filter);

            // 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         = _triplePatterns[pattern];
            int            resultsFound = 0;
            int            prevResults  = -1;

            if (temp.PatternType == TriplePatternType.Match)
            {
                // Find the first Triple which matches the Pattern
                IMatchTriplePattern  tp = (IMatchTriplePattern)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
                                // Thus required results is everything so just use normal evaluation as otherwise
                                // lazy evaluation will significantly impact performance and lead to an apparent infinite loop
                                return(base.Evaluate(context));
                            }
                        }
                    }
                }

                foreach (Triple t in ts)
                {
                    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 < _triplePatterns.Count - 1)
                {
                    results = StreamingEvaluate(context, pattern + 1, out halt);

                    // If recursion leads to a halt then we halt and return immediately
                    if (halt && results.Count >= _requiredResults && _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 >= _requiredResults && _requiredResults != -1)
                    {
                        context.OutputMultiset = results;
                        return(context.OutputMultiset);
                    }
                }
                context.InputMultiset = results;
            }
            else if (temp.PatternType == TriplePatternType.Filter)
            {
                IFilterPattern    filter     = (IFilterPattern)temp;
                ISparqlExpression filterExpr = filter.Filter.Expression;

                if (filter.Variables.IsDisjoint(context.InputMultiset.Variables))
                {
                    // 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 < _triplePatterns.Count - 1)
                        {
                            // Recurse and return
                            results = 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.Evaluate(context, 0).AsSafeBoolean())
                            {
                                if (pattern < _triplePatterns.Count - 1)
                                {
                                    // Recurse and return
                                    results = 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
                {
                    // 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.Evaluate(context, id).AsSafeBoolean())
                            {
                                // If evaluates to true then add to output
                                context.OutputMultiset.Add(context.InputMultiset[id].Copy());
                            }
                        }
                        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 < _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 = 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
                {
                    // 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.Evaluate(context, s.ID);
                            x.Add(bindVar, val);
                        }
                        catch (RdfQueryException)
                        {
                            // Equivalent to no assignment but the solution is preserved
                        }
                        context.OutputMultiset.Add(x.Copy());
                    }

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

                    // Decide whether to recurse or not
                    resultsFound = context.OutputMultiset.Count;
                    if (pattern < _triplePatterns.Count - 1)
                    {
                        // Recurse then return
                        results = 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
            {
                // Remember to check for Timeouts during Lazy Evaluation
                context.CheckTimeout();

                // 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);
            }
        }
        /// <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);
            }
        }
 /// <summary>
 /// Generates a Comparer than can be used to do Ordering based on the given Triple Pattern
 /// </summary>
 /// <param name="pattern">Triple Pattern</param>
 /// <returns></returns>
 public abstract IComparer <Triple> GetComparer(IMatchTriplePattern pattern);