private IEnumerable <ulong[]> GetPredicateObjectMatchEnumeration(TriplePattern tp) { var subjMatch = tp.Subject as NodeMatchPattern; var uri = subjMatch.Node as IUriNode; return(_store.GetPredicateObjectMatchEnumeration(uri.Uri.ToString(), _graphUris)); }
/// <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(TriplePattern pattern) { if (this._expr is VariableExpressionTerm) { 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 string ProcessBGP(Bgp bgp) { List <ITriplePattern> patterns = bgp.TriplePatterns.ToList(); if (patterns.Count == 2) { TriplePattern p1 = patterns[0] as TriplePattern; TriplePattern p2 = patterns[1] as TriplePattern; MapNode mNode1 = mapping.GetMapNodeForTripple(p1.Subject.ToString(), p1.Predicate.ToString(), p1.Object.ToString()); MapNode mNode2 = mapping.GetMapNodeForTripple(p2.Subject.ToString(), p2.Predicate.ToString(), p2.Object.ToString()); //perform inner joins between them string sql1 = mapping.MergeSqlDBString(mNode1); string sql2 = mapping.MergeSqlDBString(mNode2); string sql = $"{InnerJoin(sql1, sql2)}"; return(sql); //sql += $"{InnerJoin(patterns[0], patterns[1])}"; } else if (patterns.Count == 1) { TriplePattern p = patterns[0] as TriplePattern; MapNode mNode = mapping.GetMapNodeForTripple(p.Subject.ToString(), p.Predicate.ToString(), p.Object.ToString()); string sqlTripple = mapping.MergeSqlDBString(mNode); string sql = $"({sqlTripple})"; return(sql); } else if (patterns.Count > 2) { //here we run the cyclic joins on each 2 queries, //optimizing the queries after each join } return(null); }
public void SparqlAlgebraVariableClassification3() { TriplePattern tp = MakeTriplePattern(this._factory.CreateVariableNode("s"), this._rdfType, this._factory.CreateVariableNode("type")); IBgp lhs = new Bgp(tp); this.TestClassification(lhs, new String[] { "s", "type" }, this._emptyList); tp = MakeTriplePattern(this._factory.CreateVariableNode("s"), this._factory.CreateVariableNode("p"), this._factory.CreateVariableNode("o")); IBgp rhs = new Bgp(tp); this.TestClassification(rhs, new String[] { "s", "p", "o" }, this._emptyList); // In a join everything should end up fixed since everything started as fixed IJoin join = new Join(lhs, rhs); this.TestClassification(join, new String[] { "s", "type", "p", "o" }, this._emptyList); // In the left join only the LHS variables should be fixed, others should be floating ILeftJoin leftJoin = new LeftJoin(lhs, rhs); this.TestClassification(leftJoin, new String[] { "s", "type" }, new String[] { "p", "o" }); leftJoin = new LeftJoin(rhs, lhs); this.TestClassification(leftJoin, new String[] { "s", "p", "o" }, new String[] { "type" }); // In the union only fixed variables on both sides are fixed, others should be floating IUnion union = new Union(lhs, rhs); this.TestClassification(union, new String[] { "s" }, new String[] { "p", "o", "type" }); }
public void SparqlOptimiserQueryFilterPlacement5() { // given var query = new SparqlQuery { QueryType = SparqlQueryType.Select }; query.AddVariable(new SparqlVariable("s", true)); query.RootGraphPattern = new GraphPattern(); var subj = new VariablePattern("s"); var rdfType = new NodeMatchPattern(new UriNode(null, new Uri(RdfSpecsHelper.RdfType))); var type = new VariablePattern("type"); var triplePattern = new TriplePattern(subj, rdfType, type); query.RootGraphPattern.AddTriplePattern(triplePattern); query.RootGraphPattern.AddFilter(new UnaryExpressionFilter(new InFunction(new VariableTerm("type"), new[] { new ConstantTerm(new UriNode(null, new Uri("http://example.com/Type1"))), new ConstantTerm(new UriNode(null, new Uri("http://example.com/Type2"))), new ConstantTerm(new UriNode(null, new Uri("http://example.com/Type3"))) }))); // when var algebra = query.ToAlgebra(); // then Assert.IsType <Select>(algebra); Assert.IsType <Filter>(((Select)algebra).InnerAlgebra); }
public void SparqlAlgebraVariableClassification2() { TriplePattern tp = MakeTriplePattern(this._factory.CreateVariableNode("s"), this._p, this._o); IBgp bgp = new Bgp(tp); this.TestClassification(bgp, new String[] { "s" }, this._emptyList); }
public void SparqlAlgebraVariableClassification1() { TriplePattern tp = MakeTriplePattern(this._s, this._p, this._o); IBgp bgp = new Bgp(tp); this.TestClassification(bgp, this._emptyList, this._emptyList); }
private IEnumerable <ulong[]> GetAllTriplesEnumeration(TriplePattern tp) { int[] variableIndexes = new int[3]; variableIndexes[0] = SortVariables.IndexOf(tp.Predicate.VariableName); variableIndexes[1] = SortVariables.IndexOf(tp.Subject.VariableName); variableIndexes[2] = SortVariables.IndexOf(tp.Object.VariableName); foreach (var entry in _store.MatchAllTriples(_graphUris)) { bool addRow = true; ulong[] newRow = new ulong[2]; for (int i = 0; i < 3; i++) { ulong currentValue = newRow[variableIndexes[i]]; if (currentValue > 0 && entry[i] != currentValue) { addRow = false; break; } newRow[variableIndexes[i]] = entry[i]; } if (addRow) { yield return(newRow); } } }
private (string, string, string) getNames(TriplePattern item) { var subject = getName(item.Subject); //(item as TriplePattern).Subject; var predicate = getName(item.Predicate); var obj = getName(item.Object); return(subject, predicate, obj); }
private IEnumerable <ulong> GetMatchEnumeration(TriplePattern tp) { if (tp.Object.VariableName != null) { var subjectMatch = tp.Subject as NodeMatchPattern; var predMatch = tp.Predicate as NodeMatchPattern; var subj = (subjectMatch.Node as IUriNode).Uri; var pred = (predMatch.Node as IUriNode).Uri; return(_store.GetMatchEnumeration(subj.ToString(), pred.ToString(), null, false, null, null, _graphUris)); } if (tp.Subject.VariableName != null) { var predMatch = tp.Predicate as NodeMatchPattern; var objMatch = tp.Object as NodeMatchPattern; if (objMatch.Node is ILiteralNode) { var litNode = (objMatch.Node as ILiteralNode); var pred = (predMatch.Node as IUriNode).Uri; return(_store.GetMatchEnumeration(null, pred.ToString(), litNode.Value, true, litNode.DataType == null ? Constants.DefaultDatatypeUri : litNode.DataType.ToString(), litNode.Language, _graphUris)); } else { var pred = (predMatch.Node as IUriNode).Uri; var obj = (objMatch.Node as IUriNode).Uri; return(_store.GetMatchEnumeration(null, pred.ToString(), obj.ToString(), false, null, null, _graphUris)); } } if (tp.Predicate.VariableName != null) { var subjMatch = tp.Subject as NodeMatchPattern; var objMatch = tp.Object as NodeMatchPattern; if (objMatch.Node is ILiteralNode) { var litNode = (objMatch.Node as ILiteralNode); var subj = (subjMatch.Node as IUriNode); return(_store.GetMatchEnumeration(subj.ToString(), null, litNode.Value, true, litNode.DataType == null ? Constants.DefaultDatatypeUri : litNode.DataType.ToString(), litNode.Language, _graphUris)); } else { var subj = (subjMatch.Node as IUriNode).Uri; var obj = (objMatch.Node as IUriNode).Uri; return(_store.GetMatchEnumeration(subj.ToString(), null, obj.ToString(), false, null, null, _graphUris)); } } throw new BrightstarInternalException("Error determining match enumeration."); }
public TwoVarCollapseGroup(IStore store, TriplePattern tp, IEnumerable <string> sortVars, IEnumerable <string> graphUris) : base(tp, sortVars) { _store = store; _triplePatterns = new List <TriplePattern> { tp }; _matchLength = 2; _matchEnumerations = new List <IEnumerator <ulong[]> >(); _graphUris = graphUris; }
private IEnumerable <ulong[]> GetObjectPredicateMatchEnumeration(TriplePattern tp) { /* * var intermediate = GetPredicateObjectMatchEnumeration(tp).ToList(); * var sorted = * intermediate.OrderBy(x => x[1]).ThenBy(x => x[0]).Select(x => new ulong[] {x[1], x[0]}).ToList(); * return sorted; */ return(GetPredicateObjectMatchEnumeration(tp).OrderBy(x => x[1]).ThenBy(x => x[0]).Select(x => new ulong[] { x[1], x[0] })); }
public SingleVarCollapseGroup(IStore store, TriplePattern tp, IEnumerable <string> globalSortVars, IEnumerable <string> graphUris) : base(tp, globalSortVars) { _store = store; if (tp.GetVariableCount() != 1) { throw new ArgumentException("Triple pattern must bind a single variable"); } _triplePatterns = new List <TriplePattern> { tp }; _matchEnumerations = new List <IEnumerator <ulong> >(); _graphUris = graphUris; }
public void CanAddTriplePatternsAsObjects() { // given TriplePattern p1 = new TriplePattern(new VariablePattern("s"), new VariablePattern("p"), new VariablePattern("o")); TriplePattern p2 = new TriplePattern(new VariablePattern("s"), new VariablePattern("p"), new VariablePattern("o")); // when var q = QueryBuilder.SelectAll().Where(p1, p2).BuildQuery(); // then Assert.NotNull(q.RootGraphPattern); Assert.Equal(2, q.RootGraphPattern.TriplePatterns.Count()); Assert.Contains(p1, q.RootGraphPattern.TriplePatterns); Assert.Contains(p2, q.RootGraphPattern.TriplePatterns); }
internal static INode ToSpinRdf(this ITriplePattern pattern, IGraph g, SpinVariableTable varTable) { INode p = g.CreateBlankNode(); INode rdfType = g.CreateUriNode(new Uri(RdfSpecsHelper.RdfType)); if (pattern is TriplePattern) { TriplePattern tp = (TriplePattern)pattern; //g.Assert(p, rdfType, g.CreateUriNode(new Uri(SpinClassTriplePattern))); g.Assert(p, g.CreateUriNode(new Uri(SpinPropertySubject)), tp.Subject.ToSpinRdf(g, varTable)); g.Assert(p, g.CreateUriNode(new Uri(SpinPropertyPredicate)), tp.Predicate.ToSpinRdf(g, varTable)); g.Assert(p, g.CreateUriNode(new Uri(SpinPropertyObject)), tp.Object.ToSpinRdf(g, varTable)); } else if (pattern is SubQueryPattern) { g.Assert(p, rdfType, g.CreateUriNode(new Uri(SpinClassSubQuery))); g.Assert(p, g.CreateUriNode(new Uri(SpinPropertyQuery)), ((SubQueryPattern)pattern).SubQuery.ToSpinRdf(g)); } else if (pattern is FilterPattern) { g.Assert(p, rdfType, g.CreateUriNode(new Uri(SpinClassFilter))); g.Assert(p, g.CreateUriNode(new Uri(SpinPropertyExpression)), ((FilterPattern)pattern).Filter.Expression.ToSpinRdf(g, varTable)); } else if (pattern is PropertyPathPattern) { PropertyPathPattern pp = (PropertyPathPattern)pattern; g.Assert(p, rdfType, g.CreateUriNode(new Uri(SpinClassTriplePath))); g.Assert(p, g.CreateUriNode(new Uri(SpinPropertySubject)), pp.Subject.ToSpinRdf(g, varTable)); g.Assert(p, g.CreateUriNode(new Uri(SpinPropertyPath)), pp.Path.ToSpinRdf(g, varTable)); g.Assert(p, g.CreateUriNode(new Uri(SpinPropertyObject)), pp.Object.ToSpinRdf(g, varTable)); } else if (pattern is LetPattern) { g.Assert(p, rdfType, g.CreateUriNode(new Uri(SpinClassLet))); INode var = g.CreateBlankNode(); g.Assert(p, g.CreateUriNode(new Uri(SpinPropertyVariable)), var); g.Assert(var, g.CreateUriNode(new Uri(SpinPropertyVariableName)), g.CreateLiteralNode(((LetPattern)pattern).VariableName, new Uri(XmlSpecsHelper.XmlSchemaDataTypeString))); g.Assert(p, g.CreateUriNode(new Uri(SpinPropertyExpression)), ((LetPattern)pattern).AssignExpression.ToSpinRdf(g, varTable)); } else if (pattern is BindPattern) { throw new SpinException("SPARQL 1.1 BINDs are not representable in SPIN RDF Syntax"); } return(p); }
internal static INode ToSpinRdf(this ITriplePattern pattern, IGraph g, SpinVariableTable varTable) { INode p = g.CreateBlankNode(); if (pattern is TriplePattern) { TriplePattern tp = (TriplePattern)pattern; g.Assert(p, RDF.PropertyType, SP.ClassTriplePattern); g.Assert(p, SP.PropertySubject, tp.Subject.ToSpinRdf(g, varTable)); g.Assert(p, SP.PropertyPredicate, tp.Predicate.ToSpinRdf(g, varTable)); g.Assert(p, SP.PropertyObject, tp.Object.ToSpinRdf(g, varTable)); } else if (pattern is SubQueryPattern) { g.Assert(p, RDF.PropertyType, SP.ClassSubQuery); g.Assert(p, SP.PropertyQuery, ((SubQueryPattern)pattern).SubQuery.ToSpinRdf(g)); } else if (pattern is FilterPattern) { g.Assert(p, RDF.PropertyType, SP.ClassFilter); g.Assert(p, SP.PropertyExpression, ((FilterPattern)pattern).Filter.Expression.ToSpinRdf(g, varTable)); } else if (pattern is PropertyPathPattern) { PropertyPathPattern pp = (PropertyPathPattern)pattern; g.Assert(p, RDF.PropertyType, SP.ClassTriplePath); g.Assert(p, SP.PropertySubject, pp.Subject.ToSpinRdf(g, varTable)); g.Assert(p, SP.PropertyPath, pp.Path.ToSpinRdf(g, varTable)); g.Assert(p, SP.PropertyObject, pp.Object.ToSpinRdf(g, varTable)); } else if (pattern is LetPattern) { g.Assert(p, RDF.PropertyType, SP.ClassLet); INode var = g.CreateBlankNode(); g.Assert(p, SP.PropertyVariable, var); g.Assert(var, SP.PropertyVarName, g.CreateLiteralNode(((LetPattern)pattern).VariableName, XSD.string_.Uri)); g.Assert(p, SP.PropertyExpression, ((LetPattern)pattern).AssignExpression.ToSpinRdf(g, varTable)); } else if (pattern is BindPattern) { throw new SpinException("SPARQL 1.1 BINDs are not representable in SPIN RDF Syntax"); } return(p); }
private IEnumerable <ulong[]> GetObjectSubjectMatchEnumeration(TriplePattern tp) { var predMatch = tp.Predicate as NodeMatchPattern; var pred = (predMatch.Node as UriNode).Uri; if (_haveFixedBinding) { if (!string.IsNullOrEmpty(_fixedSubjectBinding)) { return(_store.EnumerateObjectsForPredicate(pred.ToString(), _graphUris, true)); } if (!string.IsNullOrEmpty(_fixedObjectBinding)) { return(_store.EnumerateSubjectsForPredicate(pred.ToString(), _graphUris, false)); } } return(_store.GetObjectSubjectMatchEnumeration(pred.ToString(), _graphUris)); }
private IEnumerable <ulong[]> GetPredicateSubjectMatchEnumeration(TriplePattern tp) { var objMatch = tp.Object as NodeMatchPattern; if (objMatch.Node is ILiteralNode) { var lit = objMatch.Node as ILiteralNode; return(_store.GetPredicateSubjectMatchEnumeration( lit.Value, true, lit.DataType == null ? Constants.DefaultDatatypeUri : lit.DataType.ToString(), lit.Language, _graphUris)); } else { var uri = objMatch.Node as IUriNode; return(_store.GetPredicateSubjectMatchEnumeration( uri.Uri.ToString(), false, null, null, _graphUris)); } }
public void SparqlGraphPatternToAlgebra9() { GraphPattern gp = new GraphPattern(); gp.IsGraph = true; gp.GraphSpecifier = new VariableToken("g", 0, 0, 1); ISparqlAlgebra algebra = gp.ToAlgebra(); Assert.IsType <Graph>(algebra); Graph g = (Graph)algebra; Assert.IsAssignableFrom <IBgp>(g.InnerAlgebra); // Nest in another graph pattern with same specifier but also with another BGP GraphPattern parent = new GraphPattern(); parent.IsGraph = true; parent.GraphSpecifier = gp.GraphSpecifier; parent.AddGraphPattern(gp); ITriplePattern tp = new TriplePattern(new VariablePattern("s"), new VariablePattern("p"), new VariablePattern("o")); parent.AddTriplePattern(tp); // Resulting algebra will keep both graph clauses because of the join algebra = parent.ToAlgebra(); Assert.IsType <Graph>(algebra); g = (Graph)algebra; Assert.IsType <Join>(g.InnerAlgebra); Join join = (Join)g.InnerAlgebra; Assert.IsType <Graph>(join.Lhs); g = (Graph)join.Lhs; Assert.IsAssignableFrom <IBgp>(g.InnerAlgebra); }
private IEnumerable <ulong[]> GetMatchEnumeration(TriplePattern tp) { if (tp.Subject.VariableName == null) { if (tp.Predicate.VariableName.Equals(SortVariables[0])) { return(GetPredicateObjectMatchEnumeration(tp)); } else { return(GetObjectPredicateMatchEnumeration(tp)); } } if (tp.Predicate.VariableName == null) { if (tp.Subject.VariableName.Equals(SortVariables[0])) { return(GetSubjectObjectMatchEnumeration(tp)); } else { return(GetObjectSubjectMatchEnumeration(tp)); } } if (tp.Object.VariableName == null) { if (tp.Subject.VariableName.Equals(SortVariables[0])) { return(GetSubjectPredicateMatchEnumeration(tp)); } else { return(GetPredicateSubjectMatchEnumeration(tp)); } } return(GetAllTriplesEnumeration(tp)); //throw new BrightstarInternalException("Invalid two-variable triple pattern"); }
public void SparqlAlgebraVariableClassification4() { TriplePattern tp = MakeTriplePattern(this._factory.CreateVariableNode("s"), this._rdfType, this._factory.CreateVariableNode("type")); IBgp lhs = new Bgp(tp); tp = MakeTriplePattern(this._factory.CreateVariableNode("s"), this._factory.CreateVariableNode("p"), this._factory.CreateVariableNode("o")); IBgp rhs = new Bgp(tp); // In the left join only the LHS variables should be fixed, others should be floating ILeftJoin leftJoin = new LeftJoin(lhs, rhs); this.TestClassification(leftJoin, new String[] { "s", "type" }, new String[] { "p", "o" }); tp = MakeTriplePattern(this._factory.CreateVariableNode("s"), this._factory.CreateUriNode(new Uri(NamespaceMapper.RDFS + "label")), this._factory.CreateVariableNode("label")); Bgp top = new Bgp(tp); // Everything in the RHS not fixed on the LHS is floating ILeftJoin parentJoin = new LeftJoin(top, leftJoin); this.TestClassification(parentJoin, new String[] { "s", "label" }, new String[] { "p", "o", "type" }); parentJoin = new LeftJoin(leftJoin, top); this.TestClassification(parentJoin, new String[] { "s", "type" }, new String[] { "p", "o", "label" }); }
/// <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(TriplePattern pattern) { IComparer <Triple> child = (this._child == null) ? null : this._child.GetComparer(pattern); Func <Triple, Triple, int> compareFunc = null; if (this._varname.Equals(pattern.Subject.VariableName)) { compareFunc = (x, y) => this._comparer.Compare(x.Subject, y.Subject); } else if (this._varname.Equals(pattern.Predicate.VariableName)) { compareFunc = (x, y) => this._comparer.Compare(x.Predicate, y.Predicate); } else if (this._varname.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)); }
/// <summary> /// Returns the number of pattern items in the triple pattern that have a /// non-null VariableName /// </summary> /// <param name="tp"></param> /// <returns></returns> /// <remarks>This method is provided as an alternative to using TriplePattern.Variables.Count() /// as in some cases the Variables list repeats a variable that is only actually bound once /// in the triple pattern. Perhaps this is a dotNetRdf bug that will get fixed ? /// </remarks> public static int GetVariableCount(this TriplePattern tp) { return((new[] { tp.Subject, tp.Predicate, tp.Object }).Count(i => i.VariableName != null)); }
private void ProcessSkipTopFilterOrderBy() { if (QueryOptions.Skip != null || QueryOptions.Top != null || (QueryOptions.OrderBy != null && QueryOptions.OrderBy.OrderByClause != null)) { NodeFactory nodeFactory = new NodeFactory(); var edmNode = EdmNodeList[EdmNodeList.Count - 1]; ITriplePattern[] tps; List <ITriplePattern> optionList = new List <ITriplePattern>(); if (EdmNodeList.Count > 1 && (EdmNodeList[EdmNodeList.Count - 2].RdfNode is NodeMatchPattern)) { var prevEdmNode = EdmNodeList[EdmNodeList.Count - 2]; Dictionary <string, Tuple <Type, Uri> > properties = GetAllProperties(prevEdmNode.ItemEdmType); tps = new ITriplePattern[] { new TriplePattern(prevEdmNode.RdfNode, new NodeMatchPattern(nodeFactory.CreateUriNode(new Uri(properties[edmNode.RdfNode.VariableName].Item2.AbsoluteUri))), edmNode.RdfNode), new TriplePattern(edmNode.RdfNode, new NodeMatchPattern(nodeFactory.CreateUriNode(new Uri(RdfSpecsHelper.RdfType))), new NodeMatchPattern(nodeFactory.CreateUriNode(GetUri(edmNode.ItemEdmType)))) }; foreach (var prop in edmNode.StructProperties.Where(p => p.Name != "LocalId")) { var propTriple = new TriplePattern(edmNode.RdfNode, new NodeMatchPattern(nodeFactory.CreateUriNode(new Uri(properties[prop.Name].Item2.AbsoluteUri))), new VariablePattern($"{prop.Name}")); optionList.Add(propTriple); } } else { tps = new ITriplePattern[] { new TriplePattern(edmNode.RdfNode, new NodeMatchPattern(nodeFactory.CreateUriNode(new Uri(RdfSpecsHelper.RdfType))), new NodeMatchPattern(nodeFactory.CreateUriNode(GetUri(edmNode.ItemEdmType)))) }; Dictionary <string, Tuple <Type, Uri> > properties = GetAllProperties(edmNode.ItemEdmType); foreach (var prop in edmNode.StructProperties.Where(p => p.Name != "LocalId")) { var propTriple = new TriplePattern(edmNode.RdfNode, new NodeMatchPattern(nodeFactory.CreateUriNode(new Uri(properties[prop.Name].Item2.AbsoluteUri))), new VariablePattern($"{prop.Name}")); optionList.Add(propTriple); } } IQueryBuilder subqueryBuilder = QueryBuilder.Select(new string[] { edmNode.Name }). Where(tps); foreach (var tp in optionList) { subqueryBuilder.Optional(gp => gp.Where(tp)); } if (QueryOptions.Skip != null) { subqueryBuilder = subqueryBuilder.Offset(QueryOptions.Skip.Value); } if (QueryOptions.Top != null) { subqueryBuilder = subqueryBuilder.Limit(QueryOptions.Top.Value); } if (FilterExp != null) { subqueryBuilder = subqueryBuilder.Filter(FilterExp); FilterExp = null; } if (QueryOptions.OrderBy != null && QueryOptions.OrderBy.OrderByClause != null) { foreach (var node in QueryOptions.OrderBy.OrderByNodes) { var typedNode = node as OrderByPropertyNode; var ordName = typedNode.Property.Name; if (ordName.ToLower() == "localid") { ordName = edmNode.Name; } if (typedNode.OrderByClause.Direction == OrderByDirection.Ascending) { subqueryBuilder.OrderBy(ordName); } else { subqueryBuilder.OrderByDescending(ordName); } } } SubQueryTriplePatterns.Add(new SubQueryPattern(subqueryBuilder.BuildQuery())); } }
private string ConstructSparql() { NodeFactory nodeFactory = new NodeFactory(); List <ITriplePattern> constructList = new List <ITriplePattern>(); List <ITriplePattern> whereList = new List <ITriplePattern>(); List <ITriplePattern> optionList = new List <ITriplePattern>(); List <ITriplePattern> optSubQueryTriplePatterns = new List <ITriplePattern>(); EdmNode previousEdmNode = null; EdmNode endEdmNode = EdmNodeList.Last(); foreach (var edmNode in EdmNodeList) { var isaTriple = new TriplePattern(edmNode.RdfNode, new NodeMatchPattern(nodeFactory.CreateUriNode(new Uri(RdfSpecsHelper.RdfType))), new NodeMatchPattern(nodeFactory.CreateUriNode(GetUri(edmNode.ItemEdmType)))); if (edmNode == endEdmNode) { constructList.Add(isaTriple); } whereList.Add(isaTriple); if (previousEdmNode != null) { Dictionary <string, Tuple <Type, Uri> > preProperties = GetAllProperties(previousEdmNode.ItemEdmType); var relationTriple = new TriplePattern(previousEdmNode.RdfNode, new NodeMatchPattern(nodeFactory.CreateUriNode(new Uri(preProperties[edmNode.Name].Item2.AbsoluteUri))), edmNode.RdfNode); if (edmNode == endEdmNode) { constructList.Add(relationTriple); } whereList.Add(relationTriple); } previousEdmNode = edmNode; if (edmNode == endEdmNode) { Dictionary <string, Tuple <Type, Uri> > properties = GetAllProperties(edmNode.ItemEdmType); foreach (var prop in edmNode.StructProperties.Where(p => p.Name != "LocalId")) { var propTriple = new TriplePattern(edmNode.RdfNode, new NodeMatchPattern(nodeFactory.CreateUriNode(new Uri(properties[prop.Name].Item2.AbsoluteUri))), new VariablePattern($"{prop.Name}")); constructList.Add(propTriple); optionList.Add(propTriple); } ConstructFromNavProperties(edmNode, constructList, optSubQueryTriplePatterns); } } IQueryBuilder queryBuilder = QueryBuilder.Construct(q => q.Where(constructList.ToArray())) .Where(whereList.Concat(SubQueryTriplePatterns).ToArray()); foreach (var tp in optionList) { queryBuilder.Optional(gp => gp.Where(tp)); } foreach (var tp in optSubQueryTriplePatterns) { queryBuilder.Optional(gp => gp.Where(tp)); } if (FilterExp != null) { queryBuilder.Filter(FilterExp); } ///*OrderBy options*/ //if (QueryOptions.OrderBy != null && QueryOptions.OrderBy.OrderByClause != null) //{ // var edmNode = EdmNodeList[EdmNodeList.Count - 1]; // foreach (var node in QueryOptions.OrderBy.OrderByNodes) // { // var typedNode = node as OrderByPropertyNode; // var ordName = typedNode.Property.Name; // if (ordName.ToLower() == "localid") // ordName = edmNode.Name; // if (typedNode.OrderByClause.Direction == OrderByDirection.Ascending) // queryBuilder.OrderBy(ordName); // else // queryBuilder.OrderByDescending(ordName); // } //} return(queryBuilder.BuildQuery().ToString()); }
private void ConstructFromNavProperties(EdmNode edmNode, List <ITriplePattern> constructList, List <ITriplePattern> optSubQueryTriplePatterns) { NodeFactory nodeFactory = new NodeFactory(); Dictionary <string, Tuple <Type, Uri> > properties = GetAllProperties(edmNode.ItemEdmType); if (edmNode.NavProperties.Count > 0) { foreach (var expProp in edmNode.NavProperties) { var expEntityType = expProp.NavigationProperty.Type.Definition.AsElementType() as EdmEntityType; List <ITriplePattern> tripleList = new List <ITriplePattern>(); tripleList.Add(new TriplePattern(new VariablePattern($"?{expProp.NavigationProperty.Name}"), new NodeMatchPattern(nodeFactory.CreateUriNode(new Uri(RdfSpecsHelper.RdfType))), new NodeMatchPattern(nodeFactory.CreateUriNode(GetUri(expEntityType))))); tripleList.Add(new TriplePattern(edmNode.RdfNode, new NodeMatchPattern(nodeFactory.CreateUriNode(new Uri(properties[expProp.NavigationProperty.Name].Item2.AbsoluteUri))), new VariablePattern($"?{expProp.NavigationProperty.Name}"))); constructList.AddRange(tripleList); List <ITriplePattern> predTripleList = new List <ITriplePattern>(); Dictionary <string, Tuple <Type, Uri> > expandProperties = GetAllProperties(expEntityType); List <IEdmStructuralProperty> structProps = expProp.StructProperties; if (structProps == null) { structProps = expEntityType.StructuralProperties().ToList(); } foreach (var prop in structProps.Where(p => p.Name != "LocalId")) { var expPropTriple = new TriplePattern(new VariablePattern($"?{expProp.NavigationProperty.Name}"), new NodeMatchPattern(nodeFactory.CreateUriNode(new Uri(expandProperties[prop.Name].Item2.AbsoluteUri))), new VariablePattern($"?{prop.Name}Expand")); predTripleList.Add(expPropTriple); constructList.Add(expPropTriple); } IQueryBuilder subqueryBuilder = null; var variableList = structProps.Where(p => p.Name != "LocalId") .Select(p => $"?{p.Name}Expand").ToList(); variableList.Add(expProp.NavigationProperty.Name); if (edmNode.RdfNode is VariablePattern) { variableList.Add(edmNode.Name); } subqueryBuilder = QueryBuilder.Select(variableList.ToArray()).Where(tripleList.ToArray()); foreach (var tp in predTripleList) { subqueryBuilder.Optional(gp => gp.Where(tp)); } if (expProp.Filters != null) { ISparqlExpression FilterExp = BuildSparqlFilter(expProp.Filters, "Expand"); subqueryBuilder.Filter(FilterExp); } if (expProp.Top != null & expProp.Top != 0) { subqueryBuilder.Limit(Convert.ToInt32(expProp.Top)); } if (expProp.Skip != null & expProp.Skip != 0) { subqueryBuilder.Offset(Convert.ToInt32(expProp.Skip)); } if (expProp.OrderBy != null) { foreach (var node in expProp.OrderBy.AsEnumerable()) { //var typedNode = node as OrderByPropertyNode; var ordName = (node.Expression as SingleValuePropertyAccessNode).Property.Name; if (ordName.ToLower() == "localid") { ordName = expProp.NavigationProperty.Name; } else { ordName = $"?{ordName}Expand"; } if (node.Direction == OrderByDirection.Ascending) { subqueryBuilder.OrderBy(ordName); } else { subqueryBuilder.OrderByDescending(ordName); } } } optSubQueryTriplePatterns.Add(new SubQueryPattern(subqueryBuilder.BuildQuery())); if (expProp.NestedEdmNodes != null && expProp.NestedEdmNodes.Count > 0) { foreach (var nestedEdmNode in expProp.NestedEdmNodes) { ConstructFromNavProperties(nestedEdmNode, constructList, optSubQueryTriplePatterns); } } } } }
/// <summary> /// Optimises the algebra so that all Node terms are virtualised /// </summary> /// <param name="algebra">Algebra</param> /// <returns></returns> public ISparqlAlgebra Optimise(ISparqlAlgebra algebra) { if (algebra is IAbstractJoin) { return(((IAbstractJoin)algebra).Transform(this)); } else if (algebra is IUnaryOperator) { return(((IUnaryOperator)algebra).Transform(this)); } else if (algebra is IBgp) { IBgp current = (IBgp)algebra; if (current.PatternCount == 0) { return(current); } else { ISparqlAlgebra result = new Bgp(); List <ITriplePattern> patterns = new List <ITriplePattern>(); List <ITriplePattern> ps = new List <ITriplePattern>(current.TriplePatterns.ToList()); TNodeID nullID = this._provider.NullID; for (int i = 0; i < current.PatternCount; i++) { if (ps[i] is FilterPattern || ps[i] is BindPattern) { //First ensure that if we've found any other Triple Patterns up to this point //we dump this into a BGP and join with the result so far if (patterns.Count > 0) { result = Join.CreateJoin(result, new Bgp(patterns)); patterns.Clear(); } if (ps[i] is FilterPattern) { result = new Filter(result, ((FilterPattern)ps[i]).Filter); } else { BindPattern bind = (BindPattern)ps[i]; result = new Extend(result, bind.AssignExpression, bind.VariableName); } } else { //Convert Terms in the Pattern into Virtual Nodes TriplePattern tp = (TriplePattern)ps[i]; PatternItem subj, pred, obj; if (tp.Subject is NodeMatchPattern) { TNodeID id = this._provider.GetID(((NodeMatchPattern)tp.Subject).Node); if (id == null || id.Equals(nullID)) { result = new NullOperator(current.Variables); break; } else { subj = new NodeMatchPattern(this.CreateVirtualNode(id, ((NodeMatchPattern)tp.Subject).Node)); } } else { subj = tp.Subject; } if (tp.Predicate is NodeMatchPattern) { TNodeID id = this._provider.GetID(((NodeMatchPattern)tp.Predicate).Node); if (id == null || id.Equals(nullID)) { result = new NullOperator(current.Variables); break; } else { pred = new NodeMatchPattern(this.CreateVirtualNode(id, ((NodeMatchPattern)tp.Predicate).Node)); } } else { pred = tp.Predicate; } if (tp.Object is NodeMatchPattern) { TNodeID id = this._provider.GetID(((NodeMatchPattern)tp.Object).Node); if (id == null || id.Equals(nullID)) { result = new NullOperator(current.Variables); break; } else { obj = new NodeMatchPattern(this.CreateVirtualNode(id, ((NodeMatchPattern)tp.Object).Node)); } } else { obj = tp.Object; } patterns.Add(new TriplePattern(subj, pred, obj)); } } if (result is NullOperator) { return(result); } else if (patterns.Count == current.PatternCount) { //If count of remaining patterns same as original pattern count there was no optimisation //to do so return as is return(current); } else if (patterns.Count > 0) { //If any patterns left at end join as a BGP with result so far result = Join.CreateJoin(result, new Bgp(patterns)); return(result); } else { return(result); } } } else if (algebra is ITerminalOperator) { return(algebra); } else { return(algebra); } }
private BaseMultiset StreamingEvaluate(SparqlEvaluationContext context, int pattern, out bool halt) { halt = false; //Handle Empty BGPs if (pattern == 0 && this._triplePatterns.Count == 0) { context.OutputMultiset = new IdentityMultiset(); return(context.OutputMultiset); } BaseMultiset initialInput, localOutput, results = null; //Determine whether the Pattern modifies the existing Input rather than joining to it bool modifies = (this._triplePatterns[pattern] is FilterPattern); bool extended = (pattern > 0 && this._triplePatterns[pattern - 1] is BindPattern); bool modified = (pattern > 0 && this._triplePatterns[pattern - 1] is FilterPattern); //Set up the Input and Output Multiset appropriately switch (pattern) { case 0: //Input is as given and Output is new empty multiset if (!modifies) { initialInput = context.InputMultiset; } else { //If the Pattern will modify the Input and is the first thing in the BGP then it actually modifies a new empty input //This takes care of FILTERs being out of scope initialInput = new Multiset(); } localOutput = new Multiset(); break; case 1: //Input becomes current Output and Output is new empty multiset initialInput = context.OutputMultiset; localOutput = new Multiset(); break; default: if (!extended && !modified) { //Input is join of previous input and output and Output is new empty multiset if (context.InputMultiset.IsDisjointWith(context.OutputMultiset)) { //Disjoint so do a Product initialInput = context.InputMultiset.ProductWithTimeout(context.OutputMultiset, context.RemainingTimeout); } else { //Normal Join initialInput = context.InputMultiset.Join(context.OutputMultiset); } } else { initialInput = context.OutputMultiset; } localOutput = new Multiset(); break; } context.InputMultiset = initialInput; context.OutputMultiset = localOutput; //Get the Triple Pattern we're evaluating ITriplePattern temp = this._triplePatterns[pattern]; int resultsFound = 0; int prevResults = -1; if (temp is TriplePattern) { //Find the first Triple which matches the Pattern TriplePattern tp = (TriplePattern)temp; IEnumerable <Triple> ts = tp.GetTriples(context); //In the case that we're lazily evaluating an optimisable ORDER BY then //we need to apply OrderBy()'s to our enumeration //This only applies to the 1st pattern if (pattern == 0) { if (context.Query != null) { if (context.Query.OrderBy != null && context.Query.IsOptimisableOrderBy) { IComparer <Triple> comparer = context.Query.OrderBy.GetComparer(tp); if (comparer != null) { ts = ts.OrderBy(t => t, comparer); } else { //Can't get a comparer so can't optimise this._requiredResults = -1; } } } } foreach (Triple t in ts) { //Remember to check for Timeouts during Lazy Evaluation context.CheckTimeout(); if (tp.Accepts(context, t)) { resultsFound++; if (tp.IndexType == TripleIndexType.NoVariables) { localOutput = new IdentityMultiset(); context.OutputMultiset = localOutput; } else { context.OutputMultiset.Add(tp.CreateResult(t)); } //Recurse unless we're the last pattern if (pattern < this._triplePatterns.Count - 1) { results = this.StreamingEvaluate(context, pattern + 1, out halt); //If recursion leads to a halt then we halt and return immediately if (halt && results.Count >= this._requiredResults && this._requiredResults != -1) { return(results); } else if (halt) { if (results.Count == 0) { //If recursing leads to no results then eliminate all outputs //Also reset to prevResults to -1 resultsFound = 0; localOutput = new Multiset(); prevResults = -1; } else if (prevResults > -1) { if (results.Count == prevResults) { //If the amount of results found hasn't increased then this match does not //generate any further solutions further down the recursion so we can eliminate //this from the results localOutput.Remove(localOutput.SetIDs.Max()); } } prevResults = results.Count; //If we're supposed to halt but not reached the number of required results then continue context.InputMultiset = initialInput; context.OutputMultiset = localOutput; } else { //Otherwise we need to keep going here //So must reset our input and outputs before continuing context.InputMultiset = initialInput; context.OutputMultiset = new Multiset(); resultsFound--; } } else { //If we're at the last pattern and we've found a match then we can halt halt = true; //Generate the final output and return it if (context.InputMultiset.IsDisjointWith(context.OutputMultiset)) { //Disjoint so do a Product results = context.InputMultiset.ProductWithTimeout(context.OutputMultiset, context.RemainingTimeout); } else { //Normal Join results = context.InputMultiset.Join(context.OutputMultiset); } //If not reached required number of results continue if (results.Count >= this._requiredResults && this._requiredResults != -1) { context.OutputMultiset = results; return(context.OutputMultiset); } } } } } else if (temp is FilterPattern) { FilterPattern filter = (FilterPattern)temp; ISparqlExpression filterExpr = filter.Filter.Expression; if (filter.Variables.IsDisjoint(context.InputMultiset.Variables)) { //Remember to check for Timeouts during Lazy Evaluation context.CheckTimeout(); //Filter is Disjoint so determine whether it has any affect or not if (filter.Variables.Any()) { //Has Variables but disjoint from input => not in scope so gets ignored //Do we recurse or not? if (pattern < this._triplePatterns.Count - 1) { //Recurse and return results = this.StreamingEvaluate(context, pattern + 1, out halt); return(results); } else { //We don't affect the input in any way so just return it return(context.InputMultiset); } } else { //No Variables so have to evaluate it to see if it gives true otherwise try { if (filterExpr.EffectiveBooleanValue(context, 0)) { if (pattern < this._triplePatterns.Count - 1) { //Recurse and return results = this.StreamingEvaluate(context, pattern + 1, out halt); return(results); } else { //Last Pattern and we evaluate to true so can return the input as-is halt = true; return(context.InputMultiset); } } } catch (RdfQueryException) { //Evaluates to false so eliminates all solutions (use an empty Multiset) return(new Multiset()); } } } else { //Remember to check for Timeouts during Lazy Evaluation context.CheckTimeout(); //Test each solution found so far against the Filter and eliminate those that evalute to false/error foreach (int id in context.InputMultiset.SetIDs.ToList()) { try { if (filterExpr.EffectiveBooleanValue(context, id)) { //If evaluates to true then add to output context.OutputMultiset.Add(context.InputMultiset[id]); } } catch (RdfQueryException) { //Error means we ignore the solution } } //Remember to check for Timeouts during Lazy Evaluation context.CheckTimeout(); //Decide whether to recurse or not resultsFound = context.OutputMultiset.Count; if (pattern < this._triplePatterns.Count - 1) { //Recurse then return //We can never decide whether to recurse again at this point as we are not capable of deciding //which solutions should be dumped (that is the job of an earlier pattern in the BGP) results = this.StreamingEvaluate(context, pattern + 1, out halt); return(results); } else { halt = true; //However many results we need we'll halt - previous patterns can call us again if they find more potential solutions //for us to filter return(context.OutputMultiset); } } } else if (temp is BindPattern) { BindPattern bind = (BindPattern)temp; ISparqlExpression bindExpr = bind.AssignExpression; String bindVar = bind.VariableName; if (context.InputMultiset.ContainsVariable(bindVar)) { throw new RdfQueryException("Cannot use a BIND assigment to BIND to a variable that has previously been used in the Query"); } else { //Remember to check for Timeouts during Lazy Evaluation context.CheckTimeout(); //Compute the Binding for every value context.OutputMultiset.AddVariable(bindVar); foreach (ISet s in context.InputMultiset.Sets) { ISet x = s.Copy(); try { INode val = bindExpr.Value(context, s.ID); x.Add(bindVar, val); } catch (RdfQueryException) { //Equivalent to no assignment but the solution is preserved } context.OutputMultiset.Add(x); } //Remember to check for Timeouts during Lazy Evaluation context.CheckTimeout(); //Decide whether to recurse or not resultsFound = context.OutputMultiset.Count; if (pattern < this._triplePatterns.Count - 1) { //Recurse then return results = this.StreamingEvaluate(context, pattern + 1, out halt); return(results); } else { halt = true; //However many results we need we'll halt - previous patterns can call us again if they find more potential solutions //for us to extend return(context.OutputMultiset); } } } else { throw new RdfQueryException("Encountered a " + temp.GetType().FullName + " which is not a lazily evaluable Pattern"); } //If we found no possibles we return the null multiset if (resultsFound == 0) { return(new NullMultiset()); } else { //Generate the final output and return it if (!modifies) { if (context.InputMultiset.IsDisjointWith(context.OutputMultiset)) { //Disjoint so do a Product results = context.InputMultiset.ProductWithTimeout(context.OutputMultiset, context.RemainingTimeout); } else { //Normal Join results = context.InputMultiset.Join(context.OutputMultiset); } context.OutputMultiset = results; } return(context.OutputMultiset); } }
/// <summary> /// Processes SPARQL Algebra /// </summary> /// <param name="algebra">Algebra</param> /// <param name="context">SPARQL Evaluation Context</param> public string ProcessAlgebra(ISparqlAlgebra algebra) { string sql = ""; if (algebra is IBgp) //a tripple pattern { //here use the value from mapping Bgp bgp = algebra as Bgp; //foreach(TriplePattern triplePattern in bgp.TriplePatterns) //{ // sql += this.mapping.GetMappingForTripple(triplePattern.Subject.ToString(), triplePattern.Predicate.ToString(), triplePattern.Object.ToString()); //} List <ITriplePattern> patterns = bgp.TriplePatterns.ToList(); if (patterns.Count >= 2) { TriplePattern p1 = patterns[0] as TriplePattern; TriplePattern p2 = patterns[1] as TriplePattern; MapNode mNode1 = mapping.GetMapNodeForTripple(p1.Subject.ToString(), p1.Predicate.ToString(), p1.Object.ToString()); MapNode mNode2 = mapping.GetMapNodeForTripple(p2.Subject.ToString(), p2.Predicate.ToString(), p2.Object.ToString()); //perform inner joins between them string sql1 = mapping.MergeSqlDBString(mNode1); string sql2 = mapping.MergeSqlDBString(mNode2); sql = $"{InnerJoin(sql1, sql2)}"; Console.WriteLine("\n\n{0}", sql); //sql += $"{InnerJoin(patterns[0], patterns[1])}"; } else { sql += $"({patterns[0]})"; } } else if (algebra is Select) { Select select = algebra as Select; string variables = select.IsSelectAll ? "*" : string.Join(",", select.FixedVariables); string from = ProcessAlgebra(select.InnerAlgebra); sql = $"SELECT {variables}\nFROM ({from}) \nWHERE *"; } //else if (algebra is IFilter) //{ // return this.ProcessFilter((IFilter)algebra); //} ////else if (algebra is Algebra.Graph) ////{ //// return this.ProcessGraph((Algebra.Graph)algebra, context); ////} //else if (algebra is IJoin) //{ // return this.ProcessJoin((IJoin)algebra); //} //else if (algebra is ILeftJoin) //{ // return this.ProcessLeftJoin((ILeftJoin)algebra); //} //else if (algebra is IUnion) //{ // return this.ProcessUnion((IUnion)algebra); //} //else //{ // //Unknown Algebra // throw new Exception("ProcessAlgebra(): Unknown algebra!"); //} return(sql); }
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(); } }