/// <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);
            }
        }
Ejemplo n.º 2
0
        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);
        }