From: Rob V. <rv...@do...> - 2012-10-30 18:55:08
|
Hey Tom There's no such thing as a IBooleanSparqlExpression since an expression is not required to evaluate directly to a boolean in order for it to be usable in a FILTER The result of evaluating the expression is transformed into a boolean using the SPARQL Effective Boolean Value rules (http://www.w3.org/TR/sparql11-query/#ebv) The upshot of which is that there should be no need to restrict what expressions can be nested in each other, implementations will throw errors and otherwise behave appropriately if a non-sensical expression results. Other comments inline: On 10/30/12 5:05 AM, "Tomasz Pluskiewicz" <tom...@gm...> wrote: >Hi > >I have recently started implementing filtering part of the fluent API >and I would like your opinion on how it should be designed. > >1. From high level view I imagine we could go for an >IExpressionBuilder as previously discussed. For example there could be >a call like > >graphPattern.Filter(eb => eb.Regex(value, pattern, flags)) > >There are quite a few built-in methods in SPARQL and many more >available in dotNetRDF out-of-the-box so implementing all of those as >builder methods will be an effort but there of course will be an >opening for passing any pre-built ISparqlExpression: > >graphPattern.Filter(eb => eb.Expression(new RegexFunction(...))) > >Also I think we could group some of the functions in extension >classes. XPath, Leviathan or ARQ libraries are some likely candidates. > >2. The expression builder methods will have to be aware of the >expressions' return types so that it should be illegal (ie. compile >error) to call any of the below > >// str function returns literal and not boolean >graphPattern.Filter(eb => eb.Str(literal)) > >// isBlank expects an RDF term and regex returns boolean >graphPattern.Filter(eb => eb.IsBlank(eb.Regex(...))); > >There are two conclusions coming from this. > >* Filter method should have it's signature similar to: >Filter(Func<IExpressionBuilder, IBooleanSparqlExpression> eb) >* Each method on the expression builder should return one of the >expression types depending on the return type > >I can't find anything like IBooleanExpression in the library. There is >just ISparqlExpression. Do you thnik we could add such (marker?) >interfaces to the VDS.RDF.Query.Expressions namespace or just control >the expressions' return types in the builder? See above, this is not necessary > >3. It should be possible to chain expression calls to manipulate them >logically. For example: > >graphPattern.Filter(eb => eb.Regex(value, pattern).Or(eb.Regex(value, >otherPattern))) > >or > >graphPattern.Filter(eb => eb.Regex(value, pattern).Or().Regex(value, >otherPattern)) > >or > >graphPattern.Filter(eb => eb.Or(eb.Regex(value, pattern), >eb.Regex(value, otherPattern))) > >Negation example: > >graphPattern.Filter(eb => eb.Not(eb.Regex(value, pattern)) > >or > >graphPattern.Filter(eb => eb.Not().Regex(value, pattern)) > >We should decide which of the above is the best design as it will >probably influence the internals and flexibility of expression >builder. Or actually, meybe we could comnbine the two... I like the first options for both personally > >4. Many functions accept literal parameters but there can also be a >result of another expression call. For example to match gmail.com >email addresses one would call > >graphPattern.Filter(eb => eb.Regex(eb.Str("email"), "@gmail.com$")) > >However the problem here is to distinguish between plain string and a >variable's name. In the above "email" is a variable and the other >string is of course a simple string. One way to have it would be to >encapsulate the VariableExpression with its own method so the last >call would be rewritten as > >graphPattern.Filter(eb => eb.Regex(eb.Str(eb.Variable("email")), >"@gmail.com$")) > >Then the I am not convicned though as it could be a little too >verbose. Are there any other ideas? I think we may just have to live with having a Variable() and a Constant() method, a Constant() method would be nice because then you can accept a variety of common types as constants and use the existing ToLiteral() extension methods to turn them into appropriate RDF terms e.g. eb.Constant(1); or eb.Constant(1.2e5); or eb.Constant(true); > >5. Lastly, what are expression factories? Are they of any use in this >case? Expression factories allow for creation of functions based on function URIs rather than on keywords, essentially they provide a mechanism to support the SPARQL concept of extension functions (http://www.w3.org/TR/sparql11-query/#extensionFunctions). You may want to provide a general builder call for creating these: eb.Function(uri, args); Making the definition of args flexible enough to allow for zero/more arguments Rob > >Thanks, >Tom > >-------------------------------------------------------------------------- >---- >Everyone hates slow websites. So do we. >Make your web apps faster with AppDynamics >Download AppDynamics Lite for free today: >http://p.sf.net/sfu/appdyn_sfd2d_oct >_______________________________________________ >dotNetRDF-develop mailing list >dot...@li... >https://lists.sourceforge.net/lists/listinfo/dotnetrdf-develop |