/// <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); } }
PropertyFunction GetFunction(XElement xElement, EvaluatedProperties prop) { if (xElement == null) { throw new ArgumentException("xElement was null"); } var uom = ParseUOM((string)xElement.Attribute("units")); var tfunc = new PropertyFunction() { Type = GetFunctionType((int)xElement.Element("eqno").Attribute("value")), Property = prop, MinimumX = GetVariable(xElement.Element("Tmin"), "Tmin"), MaximumX = GetVariable(xElement.Element("Tmax"), "Tmax"), XUnit = GetVariable(xElement.Element("Tmax"), "Tmax").InternalUnit, YUnit = uom }; var a = xElement.Element("A"); if (a != null) { tfunc.Coefficients.Add(new Variable("A", (double)a.Attribute("value")) { IsConstant = true, IsFixed = true }); } var b = xElement.Element("B"); if (b != null) { tfunc.Coefficients.Add(new Variable("B", (double)b.Attribute("value")) { IsConstant = true, IsFixed = true }); } var c = xElement.Element("C"); if (c != null) { tfunc.Coefficients.Add(new Variable("C", (double)c.Attribute("value")) { IsConstant = true, IsFixed = true }); } var d = xElement.Element("D"); if (d != null) { tfunc.Coefficients.Add(new Variable("D", (double)d.Attribute("value")) { IsConstant = true, IsFixed = true }); } var e = xElement.Element("E"); if (e != null) { tfunc.Coefficients.Add(new Variable("E", (double)e.Attribute("value")) { IsConstant = true, IsFixed = true }); } return(tfunc); }