Recursion to sum values from rows returned by magic property?

10 views
Skip to first unread message

Jack Hodges

unread,
Jan 4, 2019, 12:44:47 PM1/4/19
to TopBraid Suite Users
I am trying to use 2 columns returned by a magic property (identifiers and values, respectively) and to sum the values of like identifiers.

I wrote a recursive SPIN function that does the job if the arguments are rdf:Lists (since I can recurse on rdf:List). But the magic property that provides the columns is not doing so in the form of rdf:List. So I am looking for alternative approaches to solving the problem. Has anyone done this kind of thing before? I am provided detailed information below:

The original magic property (below) grouped and summed the results nicely, but could not be run as a web service, so we turned to using the efunc:getQuantitySet results as input to another magic property that would group and sum.

SELECT  ?uID (SUM (?demandAS ?total)

WHERE {

    "test1" efunc:relevantBuildings ?resourceID .

    BIND (efunc:getLargestModNum(?arg1, "BID_LOAD", ?resourceIDAS ?modNum) .

    ?eventID ?modNum ?resourceID "BID_LOAD" ) efunc:getQuantitySet ( ?uID ?demand ) .

}

GROUP BY ?uID

ORDER BY (xsd:integer (?uID))

So I defined a new magic property to get just the results of the efunc:getQuantitySet magic property but without the GROUP and SUM (efunc:getLatestForecasts):

 

SELECT DISTINCT ?resourceID ?uID ?demand

WHERE {

    ?arg1 efunc:relevantBuildings ?resourceID .

    BIND (efunc:getLargestModNum(?arg1, "BID_LOAD", ?resourceID) AS ?modNum) .

    ( ?eventID ?modNum ?resourceID "BID_LOAD" ) efunc:getQuantitySet ( ?uID ?demand ) .

}

 

Which, when executed as follows:

 

SELECT ?resourceID ?uID ?demand

WHERE {

    BIND ("178805" AS ?arg1) .

    ?arg1 efunc:getLatestForecasts (?resourceID ?uID ?demand) .

}

 

produces content like this:

 

[resourceID]          uID                  demand

 

(s) AAS                (s) 15              (F) 0.055

(s) AAS                (s) 7                (F) 0.093

(s) CIEE               (s) 0                (F) 0.056

(s) CIEE               (s) 8                (F) 0.073

 

Test the sum SPIN function (efunc:sumForecasts) with expected arguments:

 

SELECT ?result

WHERE {

    ?arg2 rdf:first ?uifirst .

    ?arg2 rdf:rest ?uirest .

    ?arg3 rdf:first ?fcfirst .

    ?arg3 rdf:rest ?fcrest .

    BIND (IF((?arg1 = ?uifirst), IF((?uirest = rdf:nil), ?fcfirst, (?fcfirst + efunc:sumForecasts(?arg1, ?uirest, ?fcrest, ?arg4))), IF((?arg4 != 0), ?fcfirst, IF((?uirest != rdf:nil), efunc:sumForecasts(?arg1, ?uirest, ?fcrest, ?arg4), ?arg4))) AS ?result) .

}

 

Which, when executed as follows:

 

SELECT DISTINCT ?item ?sum

WHERE {

    BIND (nmtest:intervalList AS ?arg2) .

    BIND (nmtest:forecastList AS ?arg3) .

    ?arg2 (rdf:rest)*/rdf:first ?item .

    BIND (efunc:sumForecasts(?item?arg2?arg3, 0) AS ?sum) .

ORDER BY ?item

 

on the following rdf:Lists:

 

nmtest:intervalList: ["0", "0", "1", "2", "2", "3"]

nmtest:forecastList: [0.056, 0.056, 0.054, 0.052, 0.052, 0.4]

 

produces content like this:

 

item            sum

 

(s) 0            0.112

(s) 1            0.054

(s) 2            0.104

(s) 3            0.4

 

It does not seem reasonable to convert the results of efunc:getQuantitySet to rdf:List, so I am looking into a Javascript version to take the original results of efunc:getQuantitySet and sum them. Any advice would be most appreciated.


Jack Hodges, Siemens

Holger Knublauch

unread,
Jan 5, 2019, 3:23:59 AM1/5/19
to topbrai...@googlegroups.com
Hi Jack,

Before I look into the details: does the result require to be a magic property or could it be an SWP script that produces for example JSON output? I ask because you state web services and a script language would be more flexible w.r.t. temporary structures etc.

Holger


Sent from my iPad
--
You received this message because you are subscribed to the Google Groups "TopBraid Suite Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to topbraid-user...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Holger Knublauch

unread,
Jan 6, 2019, 6:51:18 PM1/6/19
to topbrai...@googlegroups.com

Hi Jack,

sorry but I still struggle to understand the problem. You state that the original magic property (with GROUP BY + ORDER BY) worked fine, except that "it could not be run as a web service". Why is that? (Although you have provided many details, the easiest starting point if you want to get help from the list would be an RDF file with data and SPIN function definitions that people can reasily run - it's all too easy to misunderstand the scenario otherwise).

In general, even with JavaScript there are limits. Neither SPINx nor SHACL-JS can be used to define functions that return multiple values (like magic properties). SPINx has the further limitation that it can only process the input arguments but not make queries to iterate over graphs. SHACL-JS can do the latter, but it indeed has its learning curve to get started.

As another general observation, if I need to return multiple values at once, I sometimes produce a concatenated string (e.g. values separated by space) and then have an outer SPARQL query using spif:split to unpack the individual items from the concatenated string. So if you have to switch to JavaScript (which can only return a single value), this JS string could potentially be a concatenation.

Holger

--
Reply all
Reply to author
Forward
0 new messages