/// <summary> /// Tries to create property functions. /// </summary> /// <param name="info">Function information.</param> /// <param name="function">Property Function.</param> /// <returns></returns> public bool TryCreatePropertyFunction(PropertyFunctionInfo info, out IPropertyFunctionPattern function) { function = null; switch (info.FunctionUri.AbsoluteUri) { case FullTextHelper.FullTextMatchPredicateUri: function = new PropertyFunctionPattern(info, new FullTextMatchPropertyFunction(info)); return(true); default: return(false); } }
/// <summary> /// Formats a Triple Pattern in nicely formatted SPARQL syntax /// </summary> /// <param name="tp">Triple Pattern</param> /// <returns></returns> public virtual String Format(ITriplePattern tp) { StringBuilder output = new StringBuilder(); switch (tp.PatternType) { case TriplePatternType.Match: IMatchTriplePattern match = (IMatchTriplePattern)tp; output.Append(this.Format(match.Subject, TripleSegment.Subject)); output.Append(' '); output.Append(this.Format(match.Predicate, TripleSegment.Predicate)); output.Append(' '); output.Append(this.Format(match.Object, TripleSegment.Object)); output.Append(" ."); break; case TriplePatternType.Filter: IFilterPattern filter = (IFilterPattern)tp; output.Append("FILTER("); output.Append(this.FormatExpression(filter.Filter.Expression)); output.Append(")"); break; case TriplePatternType.SubQuery: ISubQueryPattern subquery = (ISubQueryPattern)tp; output.AppendLine("{"); output.AppendLineIndented(this.Format(subquery.SubQuery), 2); output.AppendLine("}"); break; case TriplePatternType.Path: IPropertyPathPattern path = (IPropertyPathPattern)tp; output.Append(this.Format(path.Subject, TripleSegment.Subject)); output.Append(' '); output.Append(this.FormatPath(path.Path)); output.Append(' '); output.Append(this.Format(path.Object, TripleSegment.Object)); output.Append(" ."); break; case TriplePatternType.LetAssignment: IAssignmentPattern let = (IAssignmentPattern)tp; output.Append("LET(?"); output.Append(let.VariableName); output.Append(" := "); output.Append(this.FormatExpression(let.AssignExpression)); output.Append(")"); break; case TriplePatternType.BindAssignment: IAssignmentPattern bind = (IAssignmentPattern)tp; output.Append("BIND ("); output.Append(this.FormatExpression(bind.AssignExpression)); output.Append(" AS ?"); output.Append(bind.VariableName); output.Append(")"); break; case TriplePatternType.PropertyFunction: IPropertyFunctionPattern propFunc = (IPropertyFunctionPattern)tp; if (propFunc.SubjectArgs.Count() > 1) { output.Append("( "); foreach (PatternItem arg in propFunc.SubjectArgs) { output.Append(this.Format(arg, TripleSegment.Subject)); output.Append(' '); } output.Append(')'); } else { output.Append(this.Format(propFunc.SubjectArgs.First(), TripleSegment.Subject)); } output.Append(" <"); output.Append(this.FormatUri(propFunc.PropertyFunction.FunctionUri)); output.Append("> "); if (propFunc.ObjectArgs.Count() > 1) { output.Append("( "); foreach (PatternItem arg in propFunc.ObjectArgs) { output.Append(this.Format(arg, TripleSegment.Object)); output.Append(' '); } output.Append(')'); } else { output.Append(this.Format(propFunc.ObjectArgs.First(), TripleSegment.Object)); } output.Append(" ."); break; default: throw new RdfOutputException("Unable to Format an unknown ITriplePattern implementation as a String"); } return(output.ToString()); }
/// <summary> /// Tries to create a property function /// </summary> /// <param name="info">Property Function information</param> /// <param name="localFactories">Locally Scoped factories</param> /// <param name="function">Property Function</param> /// <returns></returns> public static bool TryCreatePropertyFunction(PropertyFunctionInfo info, IEnumerable <IPropertyFunctionFactory> localFactories, out IPropertyFunctionPattern function) { function = null; // First try locally scoped factories foreach (IPropertyFunctionFactory factory in localFactories) { if (factory.TryCreatePropertyFunction(info, out function)) { return(true); } } // Then try global factories foreach (IPropertyFunctionFactory factory in _factories) { if (factory.TryCreatePropertyFunction(info, out function)) { return(true); } } return(false); }
/// <summary> /// Tries to create a property function /// </summary> /// <param name="info">Property Function information</param> /// <param name="function">Property Function</param> /// <returns></returns> public static bool TryCreatePropertyFunction(PropertyFunctionInfo info, out IPropertyFunctionPattern function) { return(TryCreatePropertyFunction(info, Enumerable.Empty <IPropertyFunctionFactory>(), out function)); }
/// <summary> /// Optimises BGPs in the Algebra to use Filter() and Extend() rather than the embedded FILTER and BIND /// </summary> /// <param name="algebra">Algebra to optimise</param> /// <returns></returns> public ISparqlAlgebra Optimise(ISparqlAlgebra algebra) { if (algebra is IAbstractJoin) { return(((IAbstractJoin)algebra).Transform(this)); } else if (algebra is IUnaryOperator) { return(((IUnaryOperator)algebra).Transform(this)); } else if (algebra is IBgp) { // Don't integerfer with other optimisers which have added custom BGP implementations if (!(algebra is Bgp)) { return(algebra); } 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()); for (int i = 0; i < current.PatternCount; i++) { // Can't split the BGP if there are Blank Nodes present if (!ps[i].HasNoBlankVariables) { return(current); } if (ps[i].PatternType != TriplePatternType.Match) { // 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(); } // Then generate the appropriate strict algebra operator switch (ps[i].PatternType) { case TriplePatternType.Filter: result = new Filter(result, ((IFilterPattern)ps[i]).Filter); break; case TriplePatternType.BindAssignment: case TriplePatternType.LetAssignment: IAssignmentPattern assignment = (IAssignmentPattern)ps[i]; result = new Extend(result, assignment.AssignExpression, assignment.VariableName); break; case TriplePatternType.SubQuery: ISubQueryPattern sq = (ISubQueryPattern)ps[i]; result = Join.CreateJoin(result, new SubQuery(sq.SubQuery)); break; case TriplePatternType.Path: IPropertyPathPattern pp = (IPropertyPathPattern)ps[i]; result = Join.CreateJoin(result, new PropertyPath(pp.Subject, pp.Path, pp.Object)); break; case TriplePatternType.PropertyFunction: IPropertyFunctionPattern pf = (IPropertyFunctionPattern)ps[i]; result = new PropertyFunction(result, pf.PropertyFunction); break; default: throw new RdfQueryException("Cannot apply strict algebra form to a BGP containing a unknown triple pattern type"); } } else { patterns.Add(ps[i]); } } if (patterns.Count == current.PatternCount) { // If count of remaining patterns same as original pattern count there was no optimisation // to do so return as is return(current); } else if (patterns.Count > 0) { // If any patterns left at end join as a BGP with result so far result = Join.CreateJoin(result, new Bgp(patterns)); return(result); } else { return(result); } } } else if (algebra is ITerminalOperator) { return(algebra); } else { return(algebra); } }
/// <summary> /// Compares a property function pattern to another /// </summary> /// <param name="other">Pattern</param> /// <returns></returns> public int CompareTo(IPropertyFunctionPattern other) { return(base.CompareTo(other)); }