/// <summary>
        /// Creates a new Evaluation Context for the given Query over the given Dataset
        /// </summary>
        /// <param name="q">Query</param>
        /// <param name="data">Dataset</param>
        public SparqlEvaluationContext(SparqlQuery q, ISparqlDataset data)
        {
            this._query    = q;
            this._data     = data;
            this._inputSet = new IdentityMultiset();
            this._binder   = new LeviathanResultBinder(this);

            this.CalculateTimeout();
        }
Exemple #2
0
 private void ShowMultiset(BaseMultiset multiset)
 {
     Console.WriteLine(multiset.GetType().ToString());
     foreach (ISet s in multiset.Sets)
     {
         Console.WriteLine(s.ToString());
     }
     Console.WriteLine();
 }
        /// <summary>
        /// Evaluates a property path pattern
        /// </summary>
        /// <param name="context">Evaluation Context</param>
        public override void Evaluate(SparqlEvaluationContext context)
        {
            // Try and generate an Algebra expression
            // Make sure we don't generate clashing temporary variable IDs over the life of the
            // Evaluation
            PathTransformContext transformContext = new PathTransformContext(_subj, _obj);

            if (context["PathTransformID"] != null)
            {
                transformContext.NextID = (int)context["PathTransformID"];
            }
            ISparqlAlgebra algebra = _path.ToAlgebra(transformContext);

            context["PathTransformID"] = transformContext.NextID + 1;

            // Now we can evaluate the resulting algebra
            BaseMultiset initialInput = context.InputMultiset;
            bool         trimMode     = context.TrimTemporaryVariables;
            bool         rigMode      = Options.RigorousEvaluation;

            try
            {
                // Must enable rigorous evaluation or we get incorrect interactions between property and non-property path patterns
                Options.RigorousEvaluation = true;

                // Note: We may need to preserve Blank Node variables across evaluations
                // which we usually don't do BUT because of the way we translate only part of the path
                // into an algebra at a time and may need to do further nested translate calls we do
                // need to do this here
                context.TrimTemporaryVariables = false;
                BaseMultiset result = context.Evaluate(algebra);//algebra.Evaluate(context);
                // Also note that we don't trim temporary variables here even if we've set the setting back
                // to enabled since a Trim will be done at the end of whatever BGP we are being evaluated in

                // Once we have our results can join then into our input
                if (result is NullMultiset)
                {
                    context.OutputMultiset = new NullMultiset();
                }
                else
                {
                    context.OutputMultiset = initialInput.Join(result);
                }

                // If we reach here we've successfully evaluated the simple pattern and can return
                return;
            }
            finally
            {
                context.TrimTemporaryVariables = trimMode;
                Options.RigorousEvaluation     = rigMode;
            }
        }
        public void SparqlPropertyPathEvaluationZeroLengthWithTermStart()
        {
            EnsureTestData();

            FixedCardinality        path    = new FixedCardinality(new Property(this._factory.CreateUriNode(new Uri(RdfSpecsHelper.RdfType))), 0);
            ISparqlAlgebra          algebra = this.GetAlgebra(path, new Graph().CreateUriNode(UriFactory.Create(ConfigurationLoader.ClassHttpHandler)), null);
            SparqlEvaluationContext context = new SparqlEvaluationContext(null, this._data);
            BaseMultiset            results = algebra.Evaluate(context);

            TestTools.ShowMultiset(results);

            Assert.IsFalse(results.IsEmpty, "Results should not be empty");
        }
        public void SparqlPropertyPathEvaluationInverseNegatedPropertySet()
        {
            EnsureTestData();

            NegatedSet              path    = new NegatedSet(Enumerable.Empty <Property>(), new Property[] { new Property(this._factory.CreateUriNode(new Uri(RdfSpecsHelper.RdfType))) });
            ISparqlAlgebra          algebra = this.GetAlgebra(path);
            SparqlEvaluationContext context = new SparqlEvaluationContext(null, this._data);
            BaseMultiset            results = algebra.Evaluate(context);

            TestTools.ShowMultiset(results);

            Assert.IsFalse(results.IsEmpty, "Results should not be empty");
        }
Exemple #6
0
        public void SparqlPropertyPathEvaluationZeroLength()
        {
            EnsureTestData();

            FixedCardinality path =
                new FixedCardinality(new Property(this._factory.CreateUriNode(new Uri(RdfSpecsHelper.RdfType))), 0);
            ISparqlAlgebra          algebra = this.GetAlgebra(path);
            SparqlEvaluationContext context = new SparqlEvaluationContext(null, this._data);
            BaseMultiset            results = algebra.Evaluate(context);

            TestTools.ShowMultiset(results);

            Assert.False(results.IsEmpty, "Results should not be empty");
        }
        public void SparqlPropertyPathEvaluationSequencedAlternatives()
        {
            EnsureTestData();

            INode                   a       = this._factory.CreateUriNode(new Uri(RdfSpecsHelper.RdfType));
            INode                   b       = this._factory.CreateUriNode(new Uri(NamespaceMapper.RDFS + "range"));
            SequencePath            path    = new SequencePath(new AlternativePath(new Property(a), new Property(b)), new AlternativePath(new Property(a), new Property(a)));
            ISparqlAlgebra          algebra = this.GetAlgebraUntransformed(path);
            SparqlEvaluationContext context = new SparqlEvaluationContext(null, this._data);
            BaseMultiset            results = algebra.Evaluate(context);

            TestTools.ShowMultiset(results);

            Assert.IsFalse(results.IsEmpty, "Results should not be empty");
        }
        private void EvalExtend(SparqlEvaluationContext context, BaseMultiset results, ISparqlExpression expr, String var, int id)
        {
            ISet s = results[id].Copy();

            try
            {
                //Make a new assignment
                INode temp = expr.Evaluate(context, id);
                s.Add(var, temp);
            }
            catch
            {
                //No assignment if there's an error but the solution is preserved
            }
            context.OutputMultiset.Add(s);
        }
        public void SparqlPropertyPathEvaluationZeroLengthWithTermEnd()
        {
            EnsureTestData();

            FixedCardinality        path      = new FixedCardinality(new Property(this._factory.CreateUriNode(new Uri(RdfSpecsHelper.RdfType))), 0);
            INode                   rdfsClass = this._factory.CreateUriNode(new Uri(NamespaceMapper.RDFS + "Class"));
            ISparqlAlgebra          algebra   = this.GetAlgebra(path, null, rdfsClass);
            SparqlEvaluationContext context   = new SparqlEvaluationContext(null, this._data);
            BaseMultiset            results   = algebra.Evaluate(context);

            TestTools.ShowMultiset(results);

            Assert.IsFalse(results.IsEmpty, "Results should not be empty");
            Assert.AreEqual(1, results.Count, "Expected 1 Result");
            Assert.AreEqual(rdfsClass, results[1]["x"], "Expected 1 Result set to rdfs:Class");
        }
Exemple #10
0
        /// <summary>
        /// Executes a Graph Pattern style query against the Source
        /// </summary>
        /// <param name="graph">Graph Pattern</param>
        /// <param name="options">Query Options</param>
        /// <param name="sink">Results Sink</param>
        /// <remarks>
        /// <para>
        /// This is implemented by transforming the Graph Pattern which is a set of SemWeb Statement templates into a SPARQL Algebra BGP.  The resulting algebra is then executed using the Leviathan engine and the results converted into VariableBindings for SemWeb
        /// </para>
        /// <para>
        /// The only Query Option that is supported is the Limit option
        /// </para>
        /// </remarks>
        public void Query(Statement[] graph, SW.Query.QueryOptions options, SW.Query.QueryResultSink sink)
        {
            ISparqlAlgebra algebra = this.ToAlgebra(graph);

            if (this._store == null)
            {
                this._store = new TripleStore();
                this._store.Add(this._g);
            }

            SparqlEvaluationContext context = new SparqlEvaluationContext(null, new InMemoryDataset(this._store));
            BaseMultiset            results = context.Evaluate(algebra);//algebra.Evaluate(context);

            sink.Init(results.Variables.Select(v => new Variable(v)).ToArray());
            if (results.Count > 0)
            {
                int c = 0;
                foreach (ISet s in results.Sets)
                {
                    //Apply Limit if applicable
                    if (options.Limit > 0 && c >= options.Limit)
                    {
                        sink.Finished();
                        return;
                    }

                    //Convert the Set to VariableBindings for SemWeb
                    Variable[] vars      = s.Variables.Select(v => new Variable(v)).ToArray();
                    Resource[] resources = s.Variables.Select(v => SemWebConverter.ToSemWeb(s[v], this._mapping)).ToArray();
                    SW.Query.VariableBindings bindings = new SW.Query.VariableBindings(vars, resources);

                    //Keep adding results until the sink tells us to stop
                    if (!sink.Add(bindings))
                    {
                        sink.Finished();
                        return;
                    }
                    c++;
                }
                sink.Finished();
            }
            else
            {
                sink.Finished();
            }
        }
        public void SparqlPropertyPathEvaluationZeroOrMorePath()
        {
            TripleStore store = new TripleStore();
            Graph       g     = new Graph();

            g.LoadFromFile("InferenceTest.ttl");
            store.Add(g);
            InMemoryDataset dataset = new InMemoryDataset(store, g.BaseUri);

            ZeroOrMore     path    = new ZeroOrMore(new Property(this._factory.CreateUriNode(new Uri(NamespaceMapper.RDFS + "subClassOf"))));
            ISparqlAlgebra algebra = this.GetAlgebra(path);
            BaseMultiset   results = algebra.Evaluate(new SparqlEvaluationContext(null, dataset));

            TestTools.ShowMultiset(results);

            Assert.IsFalse(results.IsEmpty, "Results should not be empty");
        }
Exemple #12
0
 public static void ShowMultiset(BaseMultiset multiset)
 {
     if (multiset is NullMultiset)
     {
         Console.WriteLine("NULL");
     }
     else if (multiset is IdentityMultiset)
     {
         Console.WriteLine("IDENTITY");
     }
     else
     {
         foreach (ISet s in multiset.Sets)
         {
             Console.WriteLine(s.ToString());
         }
     }
 }
Exemple #13
0
        /// <summary>
        /// Internal method which evaluates the Graph Pattern
        /// </summary>
        /// <param name="context">Evaluation Context</param>
        /// <remarks>
        /// We only ever need to evaluate the Graph Pattern once to get the Results
        /// </remarks>
        private void EvaluateInternal(SparqlEvaluationContext context)
        {
            if (this._lastInput != context.InputMultiset.GetHashCode())
            {
                this._result    = null;
                this._lastInput = context.InputMultiset.GetHashCode();
            }
            if (this._result != null)
            {
                return;
            }

            //REQ: Optimise the algebra here
            ISparqlAlgebra existsClause = this._pattern.ToAlgebra();
            BaseMultiset   initialInput = context.InputMultiset;

            this._result          = context.Evaluate(existsClause);//existsClause.Evaluate(context);
            context.InputMultiset = initialInput;
        }
Exemple #14
0
        public void SparqlPropertyPathEvaluationZeroOrMorePathForward()
        {
            TripleStore store = new TripleStore();
            Graph       g     = new Graph();

            g.LoadFromFile("resources\\InferenceTest.ttl");
            store.Add(g);
            InMemoryDataset dataset = new InMemoryDataset(store);

            ZeroOrMore path =
                new ZeroOrMore(new Property(this._factory.CreateUriNode(new Uri(NamespaceMapper.RDFS + "subClassOf"))));
            INode          sportsCar = this._factory.CreateUriNode(new Uri("http://example.org/vehicles/SportsCar"));
            ISparqlAlgebra algebra   = this.GetAlgebra(path, sportsCar, null);
            BaseMultiset   results   = algebra.Evaluate(new SparqlEvaluationContext(null, dataset));

            TestTools.ShowMultiset(results);

            Assert.False(results.IsEmpty, "Results should not be empty");
        }
 /// <summary>
 /// Creates a new LeftJoin Binder
 /// </summary>
 /// <param name="multiset">Input Multiset</param>
 public LeviathanLeftJoinBinder(BaseMultiset multiset)
     : base()
 {
     this._input = multiset;
 }
Exemple #16
0
        /// <summary>
        /// Internal method which evaluates the Graph Pattern
        /// </summary>
        /// <param name="context">Evaluation Context</param>
        /// <remarks>
        /// We only ever need to evaluate the Graph Pattern once to get the Results
        /// </remarks>
        private void EvaluateInternal(SparqlEvaluationContext context)
        {
            this._result    = null;
            this._lastInput = context.InputMultiset.GetHashCode();
            this._lastCount = context.InputMultiset.Count;

            //REQ: Optimise the algebra here
            ISparqlAlgebra existsClause = this._pattern.ToAlgebra();
            BaseMultiset   initialInput = context.InputMultiset;

            this._result          = context.Evaluate(existsClause);
            context.InputMultiset = initialInput;

            //This is the new algorithm which is also correct but is O(3n) so much faster and scalable
            //Downside is that it does require more memory than the old algorithm
            this._joinVars = context.InputMultiset.Variables.Where(v => this._result.Variables.Contains(v)).ToList();
            if (this._joinVars.Count == 0)
            {
                return;
            }

            List <HashTable <INode, int> > values = new List <HashTable <INode, int> >();
            List <List <int> >             nulls  = new List <List <int> >();

            foreach (System.String var in this._joinVars)
            {
                values.Add(new HashTable <INode, int>(HashTableBias.Enumeration));
                nulls.Add(new List <int>());
            }

            //First do a pass over the LHS Result to find all possible values for joined variables
            foreach (ISet x in context.InputMultiset.Sets)
            {
                int i = 0;
                foreach (System.String var in this._joinVars)
                {
                    INode value = x[var];
                    if (value != null)
                    {
                        values[i].Add(value, x.ID);
                    }
                    else
                    {
                        nulls[i].Add(x.ID);
                    }
                    i++;
                }
            }

            //Then do a pass over the RHS and work out the intersections
            this._exists = new HashSet <int>();
            foreach (ISet y in this._result.Sets)
            {
                IEnumerable <int> possMatches = null;
                int i = 0;
                foreach (System.String var in this._joinVars)
                {
                    INode value = y[var];
                    if (value != null)
                    {
                        if (values[i].ContainsKey(value))
                        {
                            possMatches = (possMatches == null ? values[i].GetValues(value).Concat(nulls[i]) : possMatches.Intersect(values[i].GetValues(value).Concat(nulls[i])));
                        }
                        else
                        {
                            possMatches = Enumerable.Empty <int>();
                            break;
                        }
                    }
                    else
                    {
                        //Don't forget that a null will be potentially compatible with everything
                        possMatches = (possMatches == null ? context.InputMultiset.SetIDs : possMatches.Intersect(context.InputMultiset.SetIDs));
                    }
                    i++;
                }
                if (possMatches == null)
                {
                    continue;
                }

                //Look at possible matches, if is a valid match then mark the set as having an existing match
                //Don't reconsider sets which have already been marked as having an existing match
                foreach (int poss in possMatches)
                {
                    if (this._exists.Contains(poss))
                    {
                        continue;
                    }
                    if (context.InputMultiset[poss].IsCompatibleWith(y, this._joinVars))
                    {
                        this._exists.Add(poss);
                    }
                }
            }
        }
        /// <summary>
        /// Evaluates the Command in the given Context
        /// </summary>
        /// <param name="context">Evaluation Context</param>
        public override void Evaluate(SparqlUpdateEvaluationContext context)
        {
            bool datasetOk  = false;
            bool defGraphOk = false;

            try
            {
                //First evaluate the WHERE pattern to get the affected bindings
                ISparqlAlgebra where = this._wherePattern.ToAlgebra();
                if (context.Commands != null)
                {
                    where = context.Commands.ApplyAlgebraOptimisers(where);
                }

                //Set Active Graph for the WHERE
                //Don't bother if there are USING URIs as these would override any Active Graph we set here
                //so we can save ourselves the effort of doing this
                if (!this.UsingUris.Any())
                {
                    if (this._graphUri != null)
                    {
                        context.Data.SetActiveGraph(this._graphUri);
                        defGraphOk = true;
                    }
                    else
                    {
                        context.Data.SetActiveGraph((Uri)null);
                        defGraphOk = true;
                    }
                }

                //We need to make a dummy SparqlQuery object since if the Command has used any
                //USING NAMEDs along with GRAPH clauses then the algebra needs to have the
                //URIs available to it which it gets from the Query property of the Context
                //object
                SparqlQuery query = new SparqlQuery();
                foreach (Uri u in this.UsingUris)
                {
                    query.AddDefaultGraph(u);
                }
                foreach (Uri u in this.UsingNamedUris)
                {
                    query.AddNamedGraph(u);
                }
                SparqlEvaluationContext queryContext = new SparqlEvaluationContext(query, context.Data, context.QueryProcessor);
                if (this.UsingUris.Any())
                {
                    //If there are USING URIs set the Active Graph to be formed of the Graphs with those URIs
                    context.Data.SetActiveGraph(this._usingUris);
                    datasetOk = true;
                }
                BaseMultiset results = queryContext.Evaluate(where);
                if (results is IdentityMultiset)
                {
                    queryContext.OutputMultiset = new SingletonMultiset(results.Variables);
                }
                if (this.UsingUris.Any())
                {
                    //If there are USING URIs reset the Active Graph afterwards
                    //Also flag the dataset as no longer being OK as this flag is used in the finally
                    //block to determine whether the Active Graph needs resetting which it may do if the
                    //evaluation of the query fails for any reason
                    context.Data.ResetActiveGraph();
                    datasetOk = false;
                }

                //Reset Active Graph for the WHERE
                if (defGraphOk)
                {
                    context.Data.ResetActiveGraph();
                    defGraphOk = false;
                }

                //TODO: Need to detect when we create a Graph for Insertion but then fail to insert anything since in this case the Inserted Graph should be removed

                //Get the Graph to which we are inserting Triples with no explicit Graph clause
                IGraph g = null;
                if (this._insertPattern.TriplePatterns.Count > 0)
                {
                    if (context.Data.HasGraph(this._graphUri))
                    {
                        g = context.Data.GetModifiableGraph(this._graphUri);
                    }
                    else
                    {
                        //insertedGraphs.Add(this._graphUri);
                        g         = new Graph();
                        g.BaseUri = this._graphUri;
                        context.Data.AddGraph(g);
                        g = context.Data.GetModifiableGraph(this._graphUri);
                    }
                }

                //Keep a record of graphs to which we insert
                MultiDictionary <Uri, IGraph> graphs = new MultiDictionary <Uri, IGraph>(u => (u != null ? u.GetEnhancedHashCode() : 0), true, new UriComparer(), MultiDictionaryMode.AVL);

                //Insert the Triples for each Solution
                foreach (ISet s in queryContext.OutputMultiset.Sets)
                {
                    List <Triple> insertedTriples = new List <Triple>();

                    try
                    {
                        //Create a new Construct Context for each Solution
                        ConstructContext constructContext = new ConstructContext(null, s, true);

                        //Triples from raw Triple Patterns
                        if (this._insertPattern.TriplePatterns.Count > 0)
                        {
                            foreach (IConstructTriplePattern p in this._insertPattern.TriplePatterns.OfType <IConstructTriplePattern>())
                            {
                                try
                                {
                                    insertedTriples.Add(p.Construct(constructContext));
                                }
                                catch (RdfQueryException)
                                {
                                    //If we throw an error this means we couldn't construct a specific Triple
                                    //so we continue anyway
                                }
                            }
                            g.Assert(insertedTriples);
                        }

                        //Triples from GRAPH clauses
                        foreach (GraphPattern gp in this._insertPattern.ChildGraphPatterns)
                        {
                            insertedTriples.Clear();
                            try
                            {
                                String graphUri;
                                switch (gp.GraphSpecifier.TokenType)
                                {
                                case Token.URI:
                                    graphUri = gp.GraphSpecifier.Value;
                                    break;

                                case Token.VARIABLE:
                                    String graphVar = gp.GraphSpecifier.Value.Substring(1);
                                    if (s.ContainsVariable(graphVar))
                                    {
                                        INode temp = s[graphVar];
                                        if (temp == null)
                                        {
                                            //If the Variable is not bound then skip
                                            continue;
                                        }
                                        else if (temp.NodeType == NodeType.Uri)
                                        {
                                            graphUri = temp.ToSafeString();
                                        }
                                        else
                                        {
                                            //If the Variable is not bound to a URI then skip
                                            continue;
                                        }
                                    }
                                    else
                                    {
                                        //If the Variable is not bound for this solution then skip
                                        continue;
                                    }
                                    break;

                                default:
                                    //Any other Graph Specifier we have to ignore this solution
                                    continue;
                                }

                                //Ensure the Graph we're inserting to exists in the dataset creating it if necessary
                                IGraph h;
                                Uri    destUri = UriFactory.Create(graphUri);
                                if (graphs.ContainsKey(destUri))
                                {
                                    h = graphs[destUri];
                                }
                                else
                                {
                                    if (context.Data.HasGraph(destUri))
                                    {
                                        h = context.Data.GetModifiableGraph(destUri);
                                    }
                                    else
                                    {
                                        //insertedGraphs.Add(destUri);
                                        h         = new Graph();
                                        h.BaseUri = destUri;
                                        context.Data.AddGraph(h);
                                        h = context.Data.GetModifiableGraph(destUri);
                                    }
                                    graphs.Add(destUri, h);
                                }

                                //Do the actual Insertions
                                foreach (IConstructTriplePattern p in gp.TriplePatterns.OfType <IConstructTriplePattern>())
                                {
                                    try
                                    {
                                        insertedTriples.Add(p.Construct(constructContext));
                                    }
                                    catch (RdfQueryException)
                                    {
                                        //If we throw an error this means we couldn't construct a specific Triple
                                        //so we continue anyway
                                    }
                                }
                                h.Assert(insertedTriples);
                            }
                            catch (RdfQueryException)
                            {
                                //If we throw an error this means we couldn't construct for this solution so the
                                //solution is ignored for this Graph
                            }
                        }
                    }
                    catch (RdfQueryException)
                    {
                        //If we throw an error this means we couldn't construct for this solution so the
                        //solution is ignored for this graph
                    }
                }
            }
            finally
            {
                //If the Dataset was set and an error occurred in doing the WHERE clause then
                //we'll need to Reset the Active Graph
                if (datasetOk)
                {
                    context.Data.ResetActiveGraph();
                }
                if (defGraphOk)
                {
                    context.Data.ResetActiveGraph();
                }
            }
        }
Exemple #18
0
        public void SparqlMultisetLeftJoin()
        {
            //Create a load of Nodes to use in the tests
            Graph g = new Graph();

            g.NamespaceMap.AddNamespace(String.Empty, new Uri("http://example.org"));
            IUriNode     s1        = g.CreateUriNode(":s1");
            IUriNode     s2        = g.CreateUriNode(":s2");
            IUriNode     p1        = g.CreateUriNode(":p1");
            IUriNode     p2        = g.CreateUriNode(":p2");
            IUriNode     rdfsLabel = g.CreateUriNode("rdfs:label");
            ILiteralNode o1        = g.CreateLiteralNode("Some Text");
            ILiteralNode o2        = g.CreateLiteralNode("1", new Uri(XmlSpecsHelper.XmlSchemaDataTypeInteger));

            //Create an ID and Null Multiset
            IdentityMultiset id      = new IdentityMultiset();
            NullMultiset     nullset = new NullMultiset();

            //Create and Populate a Multiset
            Multiset m = new Multiset();
            Set      s = new Set();

            s.Add("s", s1);
            s.Add("p", p1);
            s.Add("o", o1);
            m.Add(s);
            s = new Set();
            s.Add("s", s2);
            s.Add("p", p2);
            s.Add("o", o2);
            m.Add(s);

            //Create and Populate another Multiset
            Multiset n = new Multiset();

            s = new Set();
            s.Add("s", s1);
            s.Add("label", o1);
            n.Add(s);

            //Create and Populate another Multiset
            Multiset d = new Multiset();

            s = new Set();
            s.Add("s1", s1);
            s.Add("p1", p1);
            s.Add("o1", o1);
            d.Add(s);
            s = new Set();
            s.Add("s1", s2);
            s.Add("p1", p2);
            s.Add("o1", o2);
            d.Add(s);

            //Show the Sets
            Console.WriteLine("LHS");
            foreach (ISet set in m.Sets)
            {
                Console.WriteLine(set.ToString());
            }
            Console.WriteLine();
            Console.WriteLine("RHS");
            foreach (ISet set in n.Sets)
            {
                Console.WriteLine(set.ToString());
            }
            Console.WriteLine();
            Console.WriteLine("D");
            foreach (ISet set in d.Sets)
            {
                Console.WriteLine(set.ToString());
            }
            Console.WriteLine();

            //Try a Join to Identity
            Console.WriteLine("Join ID-LHS");
            BaseMultiset join = id.Join(m);

            foreach (ISet set in join.Sets)
            {
                Console.WriteLine(set.ToString());
            }
            Console.WriteLine();

            //Try a Join to Identity
            Console.WriteLine("Join LHS-ID");
            join = m.Join(id);
            foreach (ISet set in join.Sets)
            {
                Console.WriteLine(set.ToString());
            }
            Console.WriteLine();

            //Try a Join to Null
            Console.WriteLine("Join NULL-LHS");
            join = nullset.Join(m);
            foreach (ISet set in join.Sets)
            {
                Console.WriteLine(set.ToString());
            }
            Console.WriteLine();

            //Try a Join to Null
            Console.WriteLine("Join LHS-NULL");
            join = m.Join(nullset);
            foreach (ISet set in join.Sets)
            {
                Console.WriteLine(set.ToString());
            }
            Console.WriteLine();

            //Try a LeftJoin
            Console.WriteLine("LeftJoin NULL-LHS");
            BaseMultiset leftjoin = nullset.LeftJoin(m, new ConstantTerm(new BooleanNode(null, true)));

            foreach (ISet set in leftjoin.Sets)
            {
                Console.WriteLine(set.ToString());
            }
            Console.WriteLine();

            //Try a LeftJoin
            Console.WriteLine("LeftJoin LHS-NULL");
            leftjoin = m.LeftJoin(nullset, new ConstantTerm(new BooleanNode(null, true)));
            foreach (ISet set in leftjoin.Sets)
            {
                Console.WriteLine(set.ToString());
            }
            Console.WriteLine();

            //Try a Join
            Console.WriteLine("Join LHS-RHS");
            join = m.Join(n);
            foreach (ISet set in join.Sets)
            {
                Console.WriteLine(set.ToString());
            }
            Console.WriteLine();

            //Try a LeftOuterJoin
            Console.WriteLine("LeftJoin LHS-RHS");
            leftjoin = m.LeftJoin(n, new ConstantTerm(new BooleanNode(null, true)));
            foreach (ISet set in leftjoin.Sets)
            {
                Console.WriteLine(set.ToString());
            }
            Console.WriteLine();

            //Try a Produce
            Console.WriteLine("Product LHS-RHS");
            BaseMultiset product = m.Product(n);

            foreach (ISet set in product.Sets)
            {
                Console.WriteLine(set.ToString());
            }
            Console.WriteLine();

            //Try a Join to Self
            Console.WriteLine("Product LHS-D");
            product = m.Product(d);
            foreach (ISet set in product.Sets)
            {
                Console.WriteLine(set.ToString());
            }
            Console.WriteLine();

            //Try a Union
            Console.WriteLine("Union LHS-RHS");
            BaseMultiset union = m.Union(n);

            foreach (ISet set in union.Sets)
            {
                Console.WriteLine(set.ToString());
            }
            Console.WriteLine();
        }
Exemple #19
0
        /// <summary>
        /// Internal method which evaluates the Graph Pattern
        /// </summary>
        /// <param name="origContext">Evaluation Context</param>
        /// <remarks>
        /// We only ever need to evaluate the Graph Pattern once to get the Results
        /// </remarks>
        private void EvaluateInternal(SparqlEvaluationContext origContext)
        {
            this._result = null;

            //We must take a copy of the original context as otherwise we can have strange results
            SparqlEvaluationContext context = new SparqlEvaluationContext(origContext.Query, origContext.Data);

            context.InputMultiset  = origContext.InputMultiset;
            context.OutputMultiset = new Multiset();
            this._lastInput        = context.InputMultiset.GetHashCode();
            this._lastCount        = context.InputMultiset.Count;

            //REQ: Optimise the algebra here
            ISparqlAlgebra existsClause = this._pattern.ToAlgebra();

            this._result = context.Evaluate(existsClause);

            //This is the new algorithm which is also correct but is O(3n) so much faster and scalable
            //Downside is that it does require more memory than the old algorithm
            this._joinVars = origContext.InputMultiset.Variables.Where(v => this._result.Variables.Contains(v)).ToList();
            if (this._joinVars.Count == 0)
            {
                return;
            }

            List <MultiDictionary <INode, List <int> > > values = new List <MultiDictionary <INode, List <int> > >();
            List <List <int> > nulls = new List <List <int> >();

            foreach (System.String var in this._joinVars)
            {
                values.Add(new MultiDictionary <INode, List <int> >(new FastVirtualNodeComparer()));
                nulls.Add(new List <int>());
            }

            //First do a pass over the LHS Result to find all possible values for joined variables
            foreach (ISet x in origContext.InputMultiset.Sets)
            {
                int i = 0;
                foreach (System.String var in this._joinVars)
                {
                    INode value = x[var];
                    if (value != null)
                    {
                        List <int> ids;
                        if (values[i].TryGetValue(value, out ids))
                        {
                            ids.Add(x.ID);
                        }
                        else
                        {
                            values[i].Add(value, new List <int> {
                                x.ID
                            });
                        }
                    }
                    else
                    {
                        nulls[i].Add(x.ID);
                    }
                    i++;
                }
            }

            //Then do a pass over the RHS and work out the intersections
            this._exists = new HashSet <int>();
            foreach (ISet y in this._result.Sets)
            {
                IEnumerable <int> possMatches = null;
                int i = 0;
                foreach (System.String var in this._joinVars)
                {
                    INode value = y[var];
                    if (value != null)
                    {
                        if (values[i].ContainsKey(value))
                        {
                            possMatches = (possMatches == null ? values[i][value].Concat(nulls[i]) : possMatches.Intersect(values[i][value].Concat(nulls[i])));
                        }
                        else
                        {
                            possMatches = Enumerable.Empty <int>();
                            break;
                        }
                    }
                    else
                    {
                        //Don't forget that a null will be potentially compatible with everything
                        possMatches = (possMatches == null ? origContext.InputMultiset.SetIDs : possMatches.Intersect(origContext.InputMultiset.SetIDs));
                    }
                    i++;
                }
                if (possMatches == null)
                {
                    continue;
                }

                //Look at possible matches, if is a valid match then mark the set as having an existing match
                //Don't reconsider sets which have already been marked as having an existing match
                foreach (int poss in possMatches)
                {
                    if (this._exists.Contains(poss))
                    {
                        continue;
                    }
                    if (origContext.InputMultiset[poss].IsCompatibleWith(y, this._joinVars))
                    {
                        this._exists.Add(poss);
                    }
                }
            }
        }
Exemple #20
0
        /// <summary>
        /// Evaluates the Command in the given Context
        /// </summary>
        /// <param name="context">Evaluation Context</param>
        public override void Evaluate(SparqlUpdateEvaluationContext context)
        {
            bool defGraphOk = false;
            bool datasetOk  = false;

            try
            {
                //First evaluate the WHERE pattern to get the affected bindings
                ISparqlAlgebra where = this._wherePattern.ToAlgebra();
                if (context.Commands != null)
                {
                    where = context.Commands.ApplyAlgebraOptimisers(where);
                }

                //Set Active Graph for the WHERE based upon the WITH clause
                //Don't bother if there are USING URIs as these would override any Active Graph we set here
                //so we can save ourselves the effort of doing this
                if (!this.UsingUris.Any())
                {
                    if (this._graphUri != null)
                    {
                        context.Data.SetActiveGraph(this._graphUri);
                        defGraphOk = true;
                    }
                    else
                    {
                        context.Data.SetActiveGraph((Uri)null);
                        defGraphOk = true;
                    }
                }

                //We need to make a dummy SparqlQuery object since if the Command has used any
                //USING/USING NAMEDs along with GRAPH clauses then the algebra needs to have the
                //URIs available to it which it gets from the Query property of the Context
                //object
                SparqlQuery query = new SparqlQuery();
                foreach (Uri u in this.UsingUris)
                {
                    query.AddDefaultGraph(u);
                }
                foreach (Uri u in this.UsingNamedUris)
                {
                    query.AddNamedGraph(u);
                }
                SparqlEvaluationContext queryContext = new SparqlEvaluationContext(query, context.Data, context.QueryProcessor);
                if (this.UsingUris.Any())
                {
                    //If there are USING URIs set the Active Graph to be formed of the Graphs with those URIs
                    context.Data.SetActiveGraph(this._usingUris);
                    datasetOk = true;
                }
                BaseMultiset results = queryContext.Evaluate(where);
                if (results is IdentityMultiset)
                {
                    results = new SingletonMultiset(results.Variables);
                }
                if (this.UsingUris.Any())
                {
                    //If there are USING URIs reset the Active Graph afterwards
                    //Also flag the dataset as no longer being OK as this flag is used in the finally
                    //block to determine whether the Active Graph needs resetting which it may do if the
                    //evaluation of the
                    context.Data.ResetActiveGraph();
                    datasetOk = false;
                }

                //Reset Active Graph for the WHERE
                if (defGraphOk)
                {
                    context.Data.ResetActiveGraph();
                    defGraphOk = false;
                }

                //Get the Graph from which we are deleting
                IGraph g = context.Data.GetModifiableGraph(this._graphUri);

                //Delete the Triples for each Solution
                foreach (ISet s in results.Sets)
                {
                    List <Triple> deletedTriples = new List <Triple>();

                    //Triples from raw Triple Patterns
                    try
                    {
                        ConstructContext constructContext = new ConstructContext(g, s, true);
                        foreach (IConstructTriplePattern p in this._deletePattern.TriplePatterns.OfType <IConstructTriplePattern>())
                        {
                            try
                            {
                                deletedTriples.Add(p.Construct(constructContext));
                            }
                            catch (RdfQueryException)
                            {
                                //If we get an error here then we couldn't construct a specific Triple
                                //so we continue anyway
                            }
                        }
                        g.Retract(deletedTriples);
                    }
                    catch (RdfQueryException)
                    {
                        //If we throw an error this means we couldn't construct for this solution so the
                        //solution is ignored this graph
                    }

                    //Triples from GRAPH clauses
                    foreach (GraphPattern gp in this._deletePattern.ChildGraphPatterns)
                    {
                        deletedTriples.Clear();
                        try
                        {
                            String graphUri;
                            switch (gp.GraphSpecifier.TokenType)
                            {
                            case Token.URI:
                                graphUri = gp.GraphSpecifier.Value;
                                break;

                            case Token.VARIABLE:
                                String graphVar = gp.GraphSpecifier.Value.Substring(1);
                                if (s.ContainsVariable(graphVar))
                                {
                                    INode temp = s[graphVar];
                                    if (temp == null)
                                    {
                                        //If the Variable is not bound then skip
                                        continue;
                                    }
                                    else if (temp.NodeType == NodeType.Uri)
                                    {
                                        graphUri = temp.ToSafeString();
                                    }
                                    else
                                    {
                                        //If the Variable is not bound to a URI then skip
                                        continue;
                                    }
                                }
                                else
                                {
                                    //If the Variable is not bound for this solution then skip
                                    continue;
                                }
                                break;

                            default:
                                //Any other Graph Specifier we have to ignore this solution
                                continue;
                            }

                            //If the Dataset doesn't contain the Graph then no need to do the Deletions
                            if (!context.Data.HasGraph(UriFactory.Create(graphUri)))
                            {
                                continue;
                            }

                            //Do the actual Deletions
                            IGraph           h = context.Data.GetModifiableGraph(UriFactory.Create(graphUri));
                            ConstructContext constructContext = new ConstructContext(h, s, true);
                            foreach (IConstructTriplePattern p in gp.TriplePatterns.OfType <IConstructTriplePattern>())
                            {
                                try
                                {
                                    deletedTriples.Add(p.Construct(constructContext));
                                }
                                catch (RdfQueryException)
                                {
                                    //If we get an error here then we couldn't construct a specific
                                    //triple so we continue anyway
                                }
                            }
                            h.Retract(deletedTriples);
                        }
                        catch (RdfQueryException)
                        {
                            //If we get an error here this means we couldn't construct for this solution so the
                            //solution is ignored for this graph
                        }
                    }
                }
            }
            finally
            {
                //If the Dataset was set and an error occurred in doing the WHERE clause then
                //we'll need to Reset the Active Graph
                if (datasetOk)
                {
                    context.Data.ResetActiveGraph();
                }
                if (defGraphOk)
                {
                    context.Data.ResetActiveGraph();
                }
            }
        }
Exemple #21
0
        public void SparqlStreamingBgpSelectEvaluation()
        {
            //Get the Data we want to query
            TripleStore store = new TripleStore();
            Graph       g     = new Graph();

            FileLoader.Load(g, "resources\\InferenceTest.ttl");
            store.Add(g);
            //g = new Graph();
            //g.LoadFromFile("noise.ttl");
            //store.Add(g);

            Console.WriteLine(store.Triples.Count() + " Triples in Store");

            //Create the Triple Pattern we want to query with
            IUriNode fordFiesta = g.CreateUriNode(new Uri("http://example.org/vehicles/FordFiesta"));
            IUriNode rdfType    = g.CreateUriNode(new Uri(RdfSpecsHelper.RdfType));
            IUriNode rdfsLabel  = g.CreateUriNode(new Uri(NamespaceMapper.RDFS + "label"));
            IUriNode speed      = g.CreateUriNode(new Uri("http://example.org/vehicles/Speed"));
            IUriNode carClass   = g.CreateUriNode(new Uri("http://example.org/vehicles/Car"));

            TriplePattern allTriples            = new TriplePattern(new VariablePattern("?s"), new VariablePattern("?p"), new VariablePattern("?o"));
            TriplePattern allTriples2           = new TriplePattern(new VariablePattern("?x"), new VariablePattern("?y"), new VariablePattern("?z"));
            TriplePattern tp1                   = new TriplePattern(new VariablePattern("?s"), new NodeMatchPattern(rdfType), new NodeMatchPattern(carClass));
            TriplePattern tp2                   = new TriplePattern(new VariablePattern("?s"), new NodeMatchPattern(speed), new VariablePattern("?speed"));
            TriplePattern tp3                   = new TriplePattern(new VariablePattern("?s"), new NodeMatchPattern(rdfsLabel), new VariablePattern("?label"));
            TriplePattern novars                = new TriplePattern(new NodeMatchPattern(fordFiesta), new NodeMatchPattern(rdfType), new NodeMatchPattern(carClass));
            TriplePattern novars2               = new TriplePattern(new NodeMatchPattern(fordFiesta), new NodeMatchPattern(rdfsLabel), new NodeMatchPattern(carClass));
            FilterPattern blankSubject          = new FilterPattern(new UnaryExpressionFilter(new IsBlankFunction(new VariableTerm("?s"))));
            List <List <ITriplePattern> > tests = new List <List <ITriplePattern> >()
            {
                new List <ITriplePattern>()
                {
                },
                new List <ITriplePattern>()
                {
                    allTriples
                },
                new List <ITriplePattern>()
                {
                    allTriples, allTriples2
                },
                new List <ITriplePattern>()
                {
                    tp1
                },
                new List <ITriplePattern>()
                {
                    tp1, tp2
                },
                new List <ITriplePattern>()
                {
                    tp1, tp3
                },
                new List <ITriplePattern>()
                {
                    novars
                },
                new List <ITriplePattern>()
                {
                    novars, tp1
                },
                new List <ITriplePattern>()
                {
                    novars, tp1, tp2
                },
                new List <ITriplePattern>()
                {
                    novars2
                },
                new List <ITriplePattern>()
                {
                    tp1, blankSubject
                }
            };

            foreach (List <ITriplePattern> tps in tests)
            {
                Console.WriteLine(tps.Count + " Triple Patterns in the Query");
                foreach (ITriplePattern tp in tps)
                {
                    Console.WriteLine(tp.ToString());
                }
                Console.WriteLine();

                ISparqlAlgebra select          = new Bgp(tps);
                ISparqlAlgebra selectOptimised = new LazyBgp(tps, 10);

                //Evaluate with timings
                Stopwatch timer = new Stopwatch();
                TimeSpan  unopt, opt;
                timer.Start();
                BaseMultiset results1 = select.Evaluate(new SparqlEvaluationContext(null, new InMemoryDataset(store)));
                timer.Stop();
                unopt = timer.Elapsed;
                timer.Reset();
                timer.Start();
                BaseMultiset results2 = selectOptimised.Evaluate(new SparqlEvaluationContext(null, new InMemoryDataset(store)));
                timer.Stop();
                opt = timer.Elapsed;

                Console.WriteLine("SELECT = " + results1.GetType().ToString() + " (" + results1.Count + " Results) in " + unopt.ToString());
                Console.WriteLine("SELECT Optimised = " + results2.GetType().ToString() + " (" + results2.Count + " Results) in " + opt.ToString());

                Console.WriteLine();
                Console.WriteLine("Optimised Results");
                foreach (ISet s in results2.Sets)
                {
                    Console.WriteLine(s.ToString());
                }

                Assert.IsTrue(results1.Count >= results2.Count, "Optimised Select should have produced as many/fewer results than Unoptimised Select");

                Console.WriteLine();
            }
        }